1 #ifndef LLVM_LIBC_SRC_SUPPORT_THREAD_MUTEX_H
2 #define LLVM_LIBC_SRC_SUPPORT_THREAD_MUTEX_H
3 
4 namespace __llvm_libc {
5 
6 enum class MutexError : int {
7   NONE,
8   BUSY,
9   TIMEOUT,
10   UNLOCK_WITHOUT_LOCK,
11   BAD_LOCK_STATE,
12 };
13 
14 } // namespace __llvm_libc
15 
16 // Platform independent code will include this header file which pulls
17 // the platfrom specific specializations using platform macros.
18 //
19 // The platform specific specializations should define a class by name
20 // Mutex with non-static methods having the following signature:
21 //
22 // MutexError lock();
23 // MutexError trylock();
24 // MutexError timedlock(...);
25 // MutexError unlock();
26 // MutexError reset(); // Used to reset inconsistent robust mutexes.
27 //
28 // Apart from the above non-static methods, the specializations should
29 // also provide few static methods with the following signature:
30 //
31 // static MutexError init(mtx_t *);
32 // static MutexError destroy(mtx_t *);
33 //
34 // All of the static and non-static methods should ideally be implemented
35 // as inline functions so that implementations of public functions can
36 // call them without a function call overhead.
37 //
38 // Another point to keep in mind that is that the libc internally needs a
39 // few global locks. So, to avoid static initialization order fiasco, we
40 // want the constructors of the Mutex classes to be constexprs.
41 
42 #ifdef __unix__
43 #include "linux/mutex.h"
44 #endif // __unix__
45 
46 namespace __llvm_libc {
47 
48 static_assert(sizeof(Mutex) <= sizeof(mtx_t),
49               "The public mtx_t type cannot accommodate the internal mutex "
50               "type.");
51 
52 // An RAII class for easy locking and unlocking of mutexes.
53 class MutexLock {
54   Mutex *mutex;
55 
56 public:
57   explicit MutexLock(Mutex *m) : mutex(m) { mutex->lock(); }
58 
59   ~MutexLock() { mutex->unlock(); }
60 };
61 
62 } // namespace __llvm_libc
63 
64 #endif // LLVM_LIBC_SRC_SUPPORT_THREAD_MUTEX_H
65