]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/jemalloc/include/jemalloc/internal/mutex_pool.h
Re-add opencsd as a vendor import from the dist directory
[FreeBSD/FreeBSD.git] / contrib / jemalloc / include / jemalloc / internal / mutex_pool.h
1 #ifndef JEMALLOC_INTERNAL_MUTEX_POOL_H
2 #define JEMALLOC_INTERNAL_MUTEX_POOL_H
3
4 #include "jemalloc/internal/hash.h"
5 #include "jemalloc/internal/mutex.h"
6 #include "jemalloc/internal/witness.h"
7
8 /* We do mod reductions by this value, so it should be kept a power of 2. */
9 #define MUTEX_POOL_SIZE 256
10
11 typedef struct mutex_pool_s mutex_pool_t;
12 struct mutex_pool_s {
13         malloc_mutex_t mutexes[MUTEX_POOL_SIZE];
14 };
15
16 bool mutex_pool_init(mutex_pool_t *pool, const char *name, witness_rank_t rank);
17
18 /* Internal helper - not meant to be called outside this module. */
19 static inline malloc_mutex_t *
20 mutex_pool_mutex(mutex_pool_t *pool, uintptr_t key) {
21         size_t hash_result[2];
22         hash(&key, sizeof(key), 0xd50dcc1b, hash_result);
23         return &pool->mutexes[hash_result[0] % MUTEX_POOL_SIZE];
24 }
25
26 static inline void
27 mutex_pool_assert_not_held(tsdn_t *tsdn, mutex_pool_t *pool) {
28         for (int i = 0; i < MUTEX_POOL_SIZE; i++) {
29                 malloc_mutex_assert_not_owner(tsdn, &pool->mutexes[i]);
30         }
31 }
32
33 /*
34  * Note that a mutex pool doesn't work exactly the way an embdedded mutex would.
35  * You're not allowed to acquire mutexes in the pool one at a time.  You have to
36  * acquire all the mutexes you'll need in a single function call, and then
37  * release them all in a single function call.
38  */
39
40 static inline void
41 mutex_pool_lock(tsdn_t *tsdn, mutex_pool_t *pool, uintptr_t key) {
42         mutex_pool_assert_not_held(tsdn, pool);
43
44         malloc_mutex_t *mutex = mutex_pool_mutex(pool, key);
45         malloc_mutex_lock(tsdn, mutex);
46 }
47
48 static inline void
49 mutex_pool_unlock(tsdn_t *tsdn, mutex_pool_t *pool, uintptr_t key) {
50         malloc_mutex_t *mutex = mutex_pool_mutex(pool, key);
51         malloc_mutex_unlock(tsdn, mutex);
52
53         mutex_pool_assert_not_held(tsdn, pool);
54 }
55
56 static inline void
57 mutex_pool_lock2(tsdn_t *tsdn, mutex_pool_t *pool, uintptr_t key1,
58     uintptr_t key2) {
59         mutex_pool_assert_not_held(tsdn, pool);
60
61         malloc_mutex_t *mutex1 = mutex_pool_mutex(pool, key1);
62         malloc_mutex_t *mutex2 = mutex_pool_mutex(pool, key2);
63         if ((uintptr_t)mutex1 < (uintptr_t)mutex2) {
64                 malloc_mutex_lock(tsdn, mutex1);
65                 malloc_mutex_lock(tsdn, mutex2);
66         } else if ((uintptr_t)mutex1 == (uintptr_t)mutex2) {
67                 malloc_mutex_lock(tsdn, mutex1);
68         } else {
69                 malloc_mutex_lock(tsdn, mutex2);
70                 malloc_mutex_lock(tsdn, mutex1);
71         }
72 }
73
74 static inline void
75 mutex_pool_unlock2(tsdn_t *tsdn, mutex_pool_t *pool, uintptr_t key1,
76     uintptr_t key2) {
77         malloc_mutex_t *mutex1 = mutex_pool_mutex(pool, key1);
78         malloc_mutex_t *mutex2 = mutex_pool_mutex(pool, key2);
79         if (mutex1 == mutex2) {
80                 malloc_mutex_unlock(tsdn, mutex1);
81         } else {
82                 malloc_mutex_unlock(tsdn, mutex1);
83                 malloc_mutex_unlock(tsdn, mutex2);
84         }
85
86         mutex_pool_assert_not_held(tsdn, pool);
87 }
88
89 static inline void
90 mutex_pool_assert_owner(tsdn_t *tsdn, mutex_pool_t *pool, uintptr_t key) {
91         malloc_mutex_assert_owner(tsdn, mutex_pool_mutex(pool, key));
92 }
93
94 #endif /* JEMALLOC_INTERNAL_MUTEX_POOL_H */