Home | History | Annotate | Download | only in utils
      1 /*
      2  * Copyright (C) 2007 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #ifndef _LIBS_UTILS_MUTEX_H
     18 #define _LIBS_UTILS_MUTEX_H
     19 
     20 #include <stdint.h>
     21 #include <sys/types.h>
     22 #include <time.h>
     23 
     24 #if !defined(_WIN32)
     25 # include <pthread.h>
     26 #endif
     27 
     28 #include <utils/Errors.h>
     29 #include <utils/Timers.h>
     30 
     31 // Enable thread safety attributes only with clang.
     32 // The attributes can be safely erased when compiling with other compilers.
     33 #if defined(__clang__) && (!defined(SWIG))
     34 #define THREAD_ANNOTATION_ATTRIBUTE__(x) __attribute__((x))
     35 #else
     36 #define THREAD_ANNOTATION_ATTRIBUTE__(x)  // no-op
     37 #endif
     38 
     39 #define CAPABILITY(x) THREAD_ANNOTATION_ATTRIBUTE__(capability(x))
     40 
     41 #define SCOPED_CAPABILITY THREAD_ANNOTATION_ATTRIBUTE__(scoped_lockable)
     42 
     43 #define GUARDED_BY(x) THREAD_ANNOTATION_ATTRIBUTE__(guarded_by(x))
     44 
     45 #define PT_GUARDED_BY(x) THREAD_ANNOTATION_ATTRIBUTE__(pt_guarded_by(x))
     46 
     47 #define ACQUIRED_BEFORE(...) THREAD_ANNOTATION_ATTRIBUTE__(acquired_before(__VA_ARGS__))
     48 
     49 #define ACQUIRED_AFTER(...) THREAD_ANNOTATION_ATTRIBUTE__(acquired_after(__VA_ARGS__))
     50 
     51 #define REQUIRES(...) THREAD_ANNOTATION_ATTRIBUTE__(requires_capability(__VA_ARGS__))
     52 
     53 #define REQUIRES_SHARED(...) THREAD_ANNOTATION_ATTRIBUTE__(requires_shared_capability(__VA_ARGS__))
     54 
     55 #define ACQUIRE(...) THREAD_ANNOTATION_ATTRIBUTE__(acquire_capability(__VA_ARGS__))
     56 
     57 #define ACQUIRE_SHARED(...) THREAD_ANNOTATION_ATTRIBUTE__(acquire_shared_capability(__VA_ARGS__))
     58 
     59 #define RELEASE(...) THREAD_ANNOTATION_ATTRIBUTE__(release_capability(__VA_ARGS__))
     60 
     61 #define RELEASE_SHARED(...) THREAD_ANNOTATION_ATTRIBUTE__(release_shared_capability(__VA_ARGS__))
     62 
     63 #define TRY_ACQUIRE(...) THREAD_ANNOTATION_ATTRIBUTE__(try_acquire_capability(__VA_ARGS__))
     64 
     65 #define TRY_ACQUIRE_SHARED(...) \
     66     THREAD_ANNOTATION_ATTRIBUTE__(try_acquire_shared_capability(__VA_ARGS__))
     67 
     68 #define EXCLUDES(...) THREAD_ANNOTATION_ATTRIBUTE__(locks_excluded(__VA_ARGS__))
     69 
     70 #define ASSERT_CAPABILITY(x) THREAD_ANNOTATION_ATTRIBUTE__(assert_capability(x))
     71 
     72 #define ASSERT_SHARED_CAPABILITY(x) THREAD_ANNOTATION_ATTRIBUTE__(assert_shared_capability(x))
     73 
     74 #define RETURN_CAPABILITY(x) THREAD_ANNOTATION_ATTRIBUTE__(lock_returned(x))
     75 
     76 #define NO_THREAD_SAFETY_ANALYSIS THREAD_ANNOTATION_ATTRIBUTE__(no_thread_safety_analysis)
     77 
     78 // ---------------------------------------------------------------------------
     79 namespace android {
     80 // ---------------------------------------------------------------------------
     81 
     82 class Condition;
     83 
     84 /*
     85  * NOTE: This class is for code that builds on Win32.  Its usage is
     86  * deprecated for code which doesn't build for Win32.  New code which
     87  * doesn't build for Win32 should use std::mutex and std::lock_guard instead.
     88  *
     89  * Simple mutex class.  The implementation is system-dependent.
     90  *
     91  * The mutex must be unlocked by the thread that locked it.  They are not
     92  * recursive, i.e. the same thread can't lock it multiple times.
     93  */
     94 class CAPABILITY("mutex") Mutex {
     95   public:
     96     enum {
     97         PRIVATE = 0,
     98         SHARED = 1
     99     };
    100 
    101     Mutex();
    102     explicit Mutex(const char* name);
    103     explicit Mutex(int type, const char* name = NULL);
    104     ~Mutex();
    105 
    106     // lock or unlock the mutex
    107     status_t lock() ACQUIRE();
    108     void unlock() RELEASE();
    109 
    110     // lock if possible; returns 0 on success, error otherwise
    111     status_t tryLock() TRY_ACQUIRE(true);
    112 
    113 #if defined(__ANDROID__)
    114     // Lock the mutex, but don't wait longer than timeoutNs (relative time).
    115     // Returns 0 on success, TIMED_OUT for failure due to timeout expiration.
    116     //
    117     // OSX doesn't have pthread_mutex_timedlock() or equivalent. To keep
    118     // capabilities consistent across host OSes, this method is only available
    119     // when building Android binaries.
    120     //
    121     // FIXME?: pthread_mutex_timedlock is based on CLOCK_REALTIME,
    122     // which is subject to NTP adjustments, and includes time during suspend,
    123     // so a timeout may occur even though no processes could run.
    124     // Not holding a partial wakelock may lead to a system suspend.
    125     status_t timedLock(nsecs_t timeoutNs) TRY_ACQUIRE(true);
    126 #endif
    127 
    128     // Manages the mutex automatically. It'll be locked when Autolock is
    129     // constructed and released when Autolock goes out of scope.
    130     class SCOPED_CAPABILITY Autolock {
    131       public:
    132         inline explicit Autolock(Mutex& mutex) ACQUIRE(mutex) : mLock(mutex) { mLock.lock(); }
    133         inline explicit Autolock(Mutex* mutex) ACQUIRE(mutex) : mLock(*mutex) { mLock.lock(); }
    134         inline ~Autolock() RELEASE() { mLock.unlock(); }
    135 
    136       private:
    137         Mutex& mLock;
    138         // Cannot be copied or moved - declarations only
    139         Autolock(const Autolock&);
    140         Autolock& operator=(const Autolock&);
    141     };
    142 
    143   private:
    144     friend class Condition;
    145 
    146     // A mutex cannot be copied
    147     Mutex(const Mutex&);
    148     Mutex& operator=(const Mutex&);
    149 
    150 #if !defined(_WIN32)
    151     pthread_mutex_t mMutex;
    152 #else
    153     void _init();
    154     void* mState;
    155 #endif
    156 };
    157 
    158 // ---------------------------------------------------------------------------
    159 
    160 #if !defined(_WIN32)
    161 
    162 inline Mutex::Mutex() {
    163     pthread_mutex_init(&mMutex, NULL);
    164 }
    165 inline Mutex::Mutex(__attribute__((unused)) const char* name) {
    166     pthread_mutex_init(&mMutex, NULL);
    167 }
    168 inline Mutex::Mutex(int type, __attribute__((unused)) const char* name) {
    169     if (type == SHARED) {
    170         pthread_mutexattr_t attr;
    171         pthread_mutexattr_init(&attr);
    172         pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED);
    173         pthread_mutex_init(&mMutex, &attr);
    174         pthread_mutexattr_destroy(&attr);
    175     } else {
    176         pthread_mutex_init(&mMutex, NULL);
    177     }
    178 }
    179 inline Mutex::~Mutex() {
    180     pthread_mutex_destroy(&mMutex);
    181 }
    182 inline status_t Mutex::lock() {
    183     return -pthread_mutex_lock(&mMutex);
    184 }
    185 inline void Mutex::unlock() {
    186     pthread_mutex_unlock(&mMutex);
    187 }
    188 inline status_t Mutex::tryLock() {
    189     return -pthread_mutex_trylock(&mMutex);
    190 }
    191 #if defined(__ANDROID__)
    192 inline status_t Mutex::timedLock(nsecs_t timeoutNs) {
    193     timeoutNs += systemTime(SYSTEM_TIME_REALTIME);
    194     const struct timespec ts = {
    195         /* .tv_sec = */ static_cast<time_t>(timeoutNs / 1000000000),
    196         /* .tv_nsec = */ static_cast<long>(timeoutNs % 1000000000),
    197     };
    198     return -pthread_mutex_timedlock(&mMutex, &ts);
    199 }
    200 #endif
    201 
    202 #endif // !defined(_WIN32)
    203 
    204 // ---------------------------------------------------------------------------
    205 
    206 /*
    207  * Automatic mutex.  Declare one of these at the top of a function.
    208  * When the function returns, it will go out of scope, and release the
    209  * mutex.
    210  */
    211 
    212 typedef Mutex::Autolock AutoMutex;
    213 
    214 // ---------------------------------------------------------------------------
    215 }; // namespace android
    216 // ---------------------------------------------------------------------------
    217 
    218 #endif // _LIBS_UTILS_MUTEX_H
    219