xref: /OK3568_Linux_fs/external/rknpu2/examples/3rdparty/rga/RV110X/include/RgaMutex.h (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun  * Copyright (C) 2020 Rockchip Electronics Co., Ltd.
3*4882a593Smuzhiyun  * Authors:
4*4882a593Smuzhiyun  *  PutinLee <putin.lee@rock-chips.com>
5*4882a593Smuzhiyun  *
6*4882a593Smuzhiyun  * Licensed under the Apache License, Version 2.0 (the "License");
7*4882a593Smuzhiyun  * you may not use this file except in compliance with the License.
8*4882a593Smuzhiyun  * You may obtain a copy of the License at
9*4882a593Smuzhiyun  *
10*4882a593Smuzhiyun  *      http://www.apache.org/licenses/LICENSE-2.0
11*4882a593Smuzhiyun  *
12*4882a593Smuzhiyun  * Unless required by applicable law or agreed to in writing, software
13*4882a593Smuzhiyun  * distributed under the License is distributed on an "AS IS" BASIS,
14*4882a593Smuzhiyun  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15*4882a593Smuzhiyun  * See the License for the specific language governing permissions and
16*4882a593Smuzhiyun  * limitations under the License.
17*4882a593Smuzhiyun  */
18*4882a593Smuzhiyun 
19*4882a593Smuzhiyun 
20*4882a593Smuzhiyun #ifndef _LIBS_RGA_MUTEX_H
21*4882a593Smuzhiyun #define _LIBS_RGA_MUTEX_H
22*4882a593Smuzhiyun 
23*4882a593Smuzhiyun #ifndef ANDROID
24*4882a593Smuzhiyun #include <stdint.h>
25*4882a593Smuzhiyun #include <sys/types.h>
26*4882a593Smuzhiyun #include <time.h>
27*4882a593Smuzhiyun 
28*4882a593Smuzhiyun #include <pthread.h>
29*4882a593Smuzhiyun 
30*4882a593Smuzhiyun 
31*4882a593Smuzhiyun // Enable thread safety attributes only with clang.
32*4882a593Smuzhiyun // The attributes can be safely erased when compiling with other compilers.
33*4882a593Smuzhiyun #if defined(__clang__) && (!defined(SWIG))
34*4882a593Smuzhiyun #define THREAD_ANNOTATION_ATTRIBUTE__(x) __attribute__((x))
35*4882a593Smuzhiyun #else
36*4882a593Smuzhiyun #define THREAD_ANNOTATION_ATTRIBUTE__(x)  // no-op
37*4882a593Smuzhiyun #endif
38*4882a593Smuzhiyun 
39*4882a593Smuzhiyun #define CAPABILITY(x) THREAD_ANNOTATION_ATTRIBUTE__(capability(x))
40*4882a593Smuzhiyun 
41*4882a593Smuzhiyun #define SCOPED_CAPABILITY THREAD_ANNOTATION_ATTRIBUTE__(scoped_lockable)
42*4882a593Smuzhiyun 
43*4882a593Smuzhiyun #define GUARDED_BY(x) THREAD_ANNOTATION_ATTRIBUTE__(guarded_by(x))
44*4882a593Smuzhiyun 
45*4882a593Smuzhiyun #define PT_GUARDED_BY(x) THREAD_ANNOTATION_ATTRIBUTE__(pt_guarded_by(x))
46*4882a593Smuzhiyun 
47*4882a593Smuzhiyun #define ACQUIRED_BEFORE(...) THREAD_ANNOTATION_ATTRIBUTE__(acquired_before(__VA_ARGS__))
48*4882a593Smuzhiyun 
49*4882a593Smuzhiyun #define ACQUIRED_AFTER(...) THREAD_ANNOTATION_ATTRIBUTE__(acquired_after(__VA_ARGS__))
50*4882a593Smuzhiyun 
51*4882a593Smuzhiyun #define REQUIRES(...) THREAD_ANNOTATION_ATTRIBUTE__(requires_capability(__VA_ARGS__))
52*4882a593Smuzhiyun 
53*4882a593Smuzhiyun #define REQUIRES_SHARED(...) THREAD_ANNOTATION_ATTRIBUTE__(requires_shared_capability(__VA_ARGS__))
54*4882a593Smuzhiyun 
55*4882a593Smuzhiyun #define ACQUIRE(...) THREAD_ANNOTATION_ATTRIBUTE__(acquire_capability(__VA_ARGS__))
56*4882a593Smuzhiyun 
57*4882a593Smuzhiyun #define ACQUIRE_SHARED(...) THREAD_ANNOTATION_ATTRIBUTE__(acquire_shared_capability(__VA_ARGS__))
58*4882a593Smuzhiyun 
59*4882a593Smuzhiyun #define RELEASE(...) THREAD_ANNOTATION_ATTRIBUTE__(release_capability(__VA_ARGS__))
60*4882a593Smuzhiyun 
61*4882a593Smuzhiyun #define RELEASE_SHARED(...) THREAD_ANNOTATION_ATTRIBUTE__(release_shared_capability(__VA_ARGS__))
62*4882a593Smuzhiyun 
63*4882a593Smuzhiyun #define TRY_ACQUIRE(...) THREAD_ANNOTATION_ATTRIBUTE__(try_acquire_capability(__VA_ARGS__))
64*4882a593Smuzhiyun 
65*4882a593Smuzhiyun #define TRY_ACQUIRE_SHARED(...) \
66*4882a593Smuzhiyun     THREAD_ANNOTATION_ATTRIBUTE__(try_acquire_shared_capability(__VA_ARGS__))
67*4882a593Smuzhiyun 
68*4882a593Smuzhiyun #define EXCLUDES(...) THREAD_ANNOTATION_ATTRIBUTE__(locks_excluded(__VA_ARGS__))
69*4882a593Smuzhiyun 
70*4882a593Smuzhiyun #define ASSERT_CAPABILITY(x) THREAD_ANNOTATION_ATTRIBUTE__(assert_capability(x))
71*4882a593Smuzhiyun 
72*4882a593Smuzhiyun #define ASSERT_SHARED_CAPABILITY(x) THREAD_ANNOTATION_ATTRIBUTE__(assert_shared_capability(x))
73*4882a593Smuzhiyun 
74*4882a593Smuzhiyun #define RETURN_CAPABILITY(x) THREAD_ANNOTATION_ATTRIBUTE__(lock_returned(x))
75*4882a593Smuzhiyun 
76*4882a593Smuzhiyun #define NO_THREAD_SAFETY_ANALYSIS THREAD_ANNOTATION_ATTRIBUTE__(no_thread_safety_analysis)
77*4882a593Smuzhiyun 
78*4882a593Smuzhiyun class Condition;
79*4882a593Smuzhiyun 
80*4882a593Smuzhiyun /*
81*4882a593Smuzhiyun  * NOTE: This class is for code that builds on Win32.  Its usage is
82*4882a593Smuzhiyun  * deprecated for code which doesn't build for Win32.  New code which
83*4882a593Smuzhiyun  * doesn't build for Win32 should use std::mutex and std::lock_guard instead.
84*4882a593Smuzhiyun  *
85*4882a593Smuzhiyun  * Simple mutex class.  The implementation is system-dependent.
86*4882a593Smuzhiyun  *
87*4882a593Smuzhiyun  * The mutex must be unlocked by the thread that locked it.  They are not
88*4882a593Smuzhiyun  * recursive, i.e. the same thread can't lock it multiple times.
89*4882a593Smuzhiyun  */
90*4882a593Smuzhiyun class CAPABILITY("mutex") Mutex {
91*4882a593Smuzhiyun   public:
92*4882a593Smuzhiyun     enum {
93*4882a593Smuzhiyun         PRIVATE = 0,
94*4882a593Smuzhiyun         SHARED = 1
95*4882a593Smuzhiyun     };
96*4882a593Smuzhiyun 
97*4882a593Smuzhiyun     Mutex();
98*4882a593Smuzhiyun     explicit Mutex(const char* name);
99*4882a593Smuzhiyun     explicit Mutex(int type, const char* name = nullptr);
100*4882a593Smuzhiyun     ~Mutex();
101*4882a593Smuzhiyun 
102*4882a593Smuzhiyun     // lock or unlock the mutex
103*4882a593Smuzhiyun     int32_t lock() ACQUIRE();
104*4882a593Smuzhiyun     void unlock() RELEASE();
105*4882a593Smuzhiyun 
106*4882a593Smuzhiyun     // lock if possible; returns 0 on success, error otherwise
107*4882a593Smuzhiyun     int32_t tryLock() TRY_ACQUIRE(0);
108*4882a593Smuzhiyun 
109*4882a593Smuzhiyun     int32_t timedLock(int64_t timeoutNs) TRY_ACQUIRE(0);
110*4882a593Smuzhiyun 
111*4882a593Smuzhiyun     // Manages the mutex automatically. It'll be locked when Autolock is
112*4882a593Smuzhiyun     // constructed and released when Autolock goes out of scope.
113*4882a593Smuzhiyun     class SCOPED_CAPABILITY Autolock {
114*4882a593Smuzhiyun       public:
Autolock(Mutex & mutex)115*4882a593Smuzhiyun         inline explicit Autolock(Mutex& mutex) ACQUIRE(mutex) : mLock(mutex) {
116*4882a593Smuzhiyun             mLock.lock();
117*4882a593Smuzhiyun         }
Autolock(Mutex * mutex)118*4882a593Smuzhiyun         inline explicit Autolock(Mutex* mutex) ACQUIRE(mutex) : mLock(*mutex) {
119*4882a593Smuzhiyun             mLock.lock();
120*4882a593Smuzhiyun         }
RELEASE()121*4882a593Smuzhiyun         inline ~Autolock() RELEASE() {
122*4882a593Smuzhiyun             mLock.unlock();
123*4882a593Smuzhiyun         }
124*4882a593Smuzhiyun 
125*4882a593Smuzhiyun       private:
126*4882a593Smuzhiyun         Mutex& mLock;
127*4882a593Smuzhiyun         // Cannot be copied or moved - declarations only
128*4882a593Smuzhiyun         Autolock(const Autolock&);
129*4882a593Smuzhiyun         Autolock& operator=(const Autolock&);
130*4882a593Smuzhiyun     };
131*4882a593Smuzhiyun 
132*4882a593Smuzhiyun   private:
133*4882a593Smuzhiyun     friend class Condition;
134*4882a593Smuzhiyun 
135*4882a593Smuzhiyun     // A mutex cannot be copied
136*4882a593Smuzhiyun     Mutex(const Mutex&);
137*4882a593Smuzhiyun     Mutex& operator=(const Mutex&);
138*4882a593Smuzhiyun 
139*4882a593Smuzhiyun     pthread_mutex_t mMutex;
140*4882a593Smuzhiyun };
141*4882a593Smuzhiyun 
142*4882a593Smuzhiyun // ---------------------------------------------------------------------------
Mutex()143*4882a593Smuzhiyun inline Mutex::Mutex() {
144*4882a593Smuzhiyun     pthread_mutex_init(&mMutex, nullptr);
145*4882a593Smuzhiyun }
Mutex(const char * name)146*4882a593Smuzhiyun inline Mutex::Mutex(__attribute__((unused)) const char* name) {
147*4882a593Smuzhiyun     pthread_mutex_init(&mMutex, nullptr);
148*4882a593Smuzhiyun }
Mutex(int type,const char * name)149*4882a593Smuzhiyun inline Mutex::Mutex(int type, __attribute__((unused)) const char* name) {
150*4882a593Smuzhiyun     if (type == SHARED) {
151*4882a593Smuzhiyun         pthread_mutexattr_t attr;
152*4882a593Smuzhiyun         pthread_mutexattr_init(&attr);
153*4882a593Smuzhiyun         pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED);
154*4882a593Smuzhiyun         pthread_mutex_init(&mMutex, &attr);
155*4882a593Smuzhiyun         pthread_mutexattr_destroy(&attr);
156*4882a593Smuzhiyun     } else {
157*4882a593Smuzhiyun         pthread_mutex_init(&mMutex, nullptr);
158*4882a593Smuzhiyun     }
159*4882a593Smuzhiyun }
~Mutex()160*4882a593Smuzhiyun inline Mutex::~Mutex() {
161*4882a593Smuzhiyun     pthread_mutex_destroy(&mMutex);
162*4882a593Smuzhiyun }
lock()163*4882a593Smuzhiyun inline int32_t Mutex::lock() {
164*4882a593Smuzhiyun     return -pthread_mutex_lock(&mMutex);
165*4882a593Smuzhiyun }
unlock()166*4882a593Smuzhiyun inline void Mutex::unlock() {
167*4882a593Smuzhiyun     pthread_mutex_unlock(&mMutex);
168*4882a593Smuzhiyun }
tryLock()169*4882a593Smuzhiyun inline int32_t Mutex::tryLock() {
170*4882a593Smuzhiyun     return -pthread_mutex_trylock(&mMutex);
171*4882a593Smuzhiyun }
timedLock(int64_t timeoutNs)172*4882a593Smuzhiyun inline int32_t Mutex::timedLock(int64_t timeoutNs) {
173*4882a593Smuzhiyun     timespec now;
174*4882a593Smuzhiyun     clock_gettime(CLOCK_REALTIME, &now);
175*4882a593Smuzhiyun     timeoutNs += now.tv_sec*1000000000 + now.tv_nsec;
176*4882a593Smuzhiyun     const struct timespec ts = {
177*4882a593Smuzhiyun         /* .tv_sec = */ static_cast<time_t>(timeoutNs / 1000000000),
178*4882a593Smuzhiyun         /* .tv_nsec = */ static_cast<long>(timeoutNs % 1000000000),
179*4882a593Smuzhiyun     };
180*4882a593Smuzhiyun     return -pthread_mutex_timedlock(&mMutex, &ts);
181*4882a593Smuzhiyun }
182*4882a593Smuzhiyun 
183*4882a593Smuzhiyun // ---------------------------------------------------------------------------
184*4882a593Smuzhiyun 
185*4882a593Smuzhiyun /*
186*4882a593Smuzhiyun  * Automatic mutex.  Declare one of these at the top of a function.
187*4882a593Smuzhiyun  * When the function returns, it will go out of scope, and release the
188*4882a593Smuzhiyun  * mutex.
189*4882a593Smuzhiyun  */
190*4882a593Smuzhiyun 
191*4882a593Smuzhiyun typedef Mutex::Autolock AutoMutex;
192*4882a593Smuzhiyun #endif // __ANDROID_VNDK__
193*4882a593Smuzhiyun #endif // _LIBS_RGA_MUTEX_H
194