1 /******************************************************************************/
2 #ifdef JEMALLOC_H_TYPES
3
4 typedef struct malloc_mutex_s malloc_mutex_t;
5
6 #ifdef _WIN32
7 # define MALLOC_MUTEX_INITIALIZER
8 #elif (defined(JEMALLOC_OS_UNFAIR_LOCK))
9 # define MALLOC_MUTEX_INITIALIZER \
10 {OS_UNFAIR_LOCK_INIT, WITNESS_INITIALIZER(WITNESS_RANK_OMIT)}
11 #elif (defined(JEMALLOC_OSSPIN))
12 # define MALLOC_MUTEX_INITIALIZER {0, WITNESS_INITIALIZER(WITNESS_RANK_OMIT)}
13 #elif (defined(JEMALLOC_MUTEX_INIT_CB))
14 # define MALLOC_MUTEX_INITIALIZER \
15 {PTHREAD_MUTEX_INITIALIZER, NULL, WITNESS_INITIALIZER(WITNESS_RANK_OMIT)}
16 #else
17 # if (defined(JEMALLOC_HAVE_PTHREAD_MUTEX_ADAPTIVE_NP) && \
18 defined(PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP))
19 # define MALLOC_MUTEX_TYPE PTHREAD_MUTEX_ADAPTIVE_NP
20 # define MALLOC_MUTEX_INITIALIZER \
21 {PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP, \
22 WITNESS_INITIALIZER(WITNESS_RANK_OMIT)}
23 # else
24 # define MALLOC_MUTEX_TYPE PTHREAD_MUTEX_DEFAULT
25 # define MALLOC_MUTEX_INITIALIZER \
26 {PTHREAD_MUTEX_INITIALIZER, WITNESS_INITIALIZER(WITNESS_RANK_OMIT)}
27 # endif
28 #endif
29
30 #endif /* JEMALLOC_H_TYPES */
31 /******************************************************************************/
32 #ifdef JEMALLOC_H_STRUCTS
33
34 struct malloc_mutex_s {
35 #ifdef _WIN32
36 # if _WIN32_WINNT >= 0x0600
37 SRWLOCK lock;
38 # else
39 CRITICAL_SECTION lock;
40 # endif
41 #elif (defined(JEMALLOC_OS_UNFAIR_LOCK))
42 os_unfair_lock lock;
43 #elif (defined(JEMALLOC_OSSPIN))
44 OSSpinLock lock;
45 #elif (defined(JEMALLOC_MUTEX_INIT_CB))
46 pthread_mutex_t lock;
47 malloc_mutex_t *postponed_next;
48 #else
49 pthread_mutex_t lock;
50 #endif
51 witness_t witness;
52 };
53
54 #endif /* JEMALLOC_H_STRUCTS */
55 /******************************************************************************/
56 #ifdef JEMALLOC_H_EXTERNS
57
58 #ifdef JEMALLOC_LAZY_LOCK
59 extern bool isthreaded;
60 #else
61 # undef isthreaded /* Undo private_namespace.h definition. */
62 # define isthreaded true
63 #endif
64
65 bool malloc_mutex_init(malloc_mutex_t *mutex, const char *name,
66 witness_rank_t rank);
67 void malloc_mutex_prefork(tsdn_t *tsdn, malloc_mutex_t *mutex);
68 void malloc_mutex_postfork_parent(tsdn_t *tsdn, malloc_mutex_t *mutex);
69 void malloc_mutex_postfork_child(tsdn_t *tsdn, malloc_mutex_t *mutex);
70 bool malloc_mutex_boot(void);
71
72 #endif /* JEMALLOC_H_EXTERNS */
73 /******************************************************************************/
74 #ifdef JEMALLOC_H_INLINES
75
76 #ifndef JEMALLOC_ENABLE_INLINE
77 void malloc_mutex_lock(tsdn_t *tsdn, malloc_mutex_t *mutex);
78 void malloc_mutex_unlock(tsdn_t *tsdn, malloc_mutex_t *mutex);
79 void malloc_mutex_assert_owner(tsdn_t *tsdn, malloc_mutex_t *mutex);
80 void malloc_mutex_assert_not_owner(tsdn_t *tsdn, malloc_mutex_t *mutex);
81 #endif
82
83 #if (defined(JEMALLOC_ENABLE_INLINE) || defined(JEMALLOC_MUTEX_C_))
84 JEMALLOC_INLINE void
malloc_mutex_lock(tsdn_t * tsdn,malloc_mutex_t * mutex)85 malloc_mutex_lock(tsdn_t *tsdn, malloc_mutex_t *mutex)
86 {
87
88 if (isthreaded) {
89 witness_assert_not_owner(tsdn, &mutex->witness);
90 #ifdef _WIN32
91 # if _WIN32_WINNT >= 0x0600
92 AcquireSRWLockExclusive(&mutex->lock);
93 # else
94 EnterCriticalSection(&mutex->lock);
95 # endif
96 #elif (defined(JEMALLOC_OS_UNFAIR_LOCK))
97 os_unfair_lock_lock(&mutex->lock);
98 #elif (defined(JEMALLOC_OSSPIN))
99 OSSpinLockLock(&mutex->lock);
100 #else
101 pthread_mutex_lock(&mutex->lock);
102 #endif
103 witness_lock(tsdn, &mutex->witness);
104 }
105 }
106
107 JEMALLOC_INLINE void
malloc_mutex_unlock(tsdn_t * tsdn,malloc_mutex_t * mutex)108 malloc_mutex_unlock(tsdn_t *tsdn, malloc_mutex_t *mutex)
109 {
110
111 if (isthreaded) {
112 witness_unlock(tsdn, &mutex->witness);
113 #ifdef _WIN32
114 # if _WIN32_WINNT >= 0x0600
115 ReleaseSRWLockExclusive(&mutex->lock);
116 # else
117 LeaveCriticalSection(&mutex->lock);
118 # endif
119 #elif (defined(JEMALLOC_OS_UNFAIR_LOCK))
120 os_unfair_lock_unlock(&mutex->lock);
121 #elif (defined(JEMALLOC_OSSPIN))
122 OSSpinLockUnlock(&mutex->lock);
123 #else
124 pthread_mutex_unlock(&mutex->lock);
125 #endif
126 }
127 }
128
129 JEMALLOC_INLINE void
malloc_mutex_assert_owner(tsdn_t * tsdn,malloc_mutex_t * mutex)130 malloc_mutex_assert_owner(tsdn_t *tsdn, malloc_mutex_t *mutex)
131 {
132
133 if (isthreaded)
134 witness_assert_owner(tsdn, &mutex->witness);
135 }
136
137 JEMALLOC_INLINE void
malloc_mutex_assert_not_owner(tsdn_t * tsdn,malloc_mutex_t * mutex)138 malloc_mutex_assert_not_owner(tsdn_t *tsdn, malloc_mutex_t *mutex)
139 {
140
141 if (isthreaded)
142 witness_assert_not_owner(tsdn, &mutex->witness);
143 }
144 #endif
145
146 #endif /* JEMALLOC_H_INLINES */
147 /******************************************************************************/
148