6 #ifndef ABTI_THREAD_HTABLE_H_INCLUDED
7 #define ABTI_THREAD_HTABLE_H_INCLUDED
11 #if defined(HAVE_LH_LOCK_H)
13 #elif defined(HAVE_CLH_H)
16 #define USE_PTHREAD_MUTEX
19 struct ABTI_thread_queue {
20 ABTD_atomic_uint32 mutex;
21 uint32_t num_handovers;
26 char pad1[64 -
sizeof(ABTD_atomic_uint32) -
sizeof(uint32_t) * 3 -
27 sizeof(ABTI_thread *) * 2];
30 ABTD_atomic_uint32 low_mutex;
31 uint32_t low_num_threads;
32 ABTI_thread *low_head;
33 ABTI_thread *low_tail;
34 char pad2[64 -
sizeof(ABTD_atomic_uint32) -
sizeof(uint32_t) -
35 sizeof(ABTI_thread *) * 2];
38 ABTI_thread_queue *p_h_next;
39 ABTI_thread_queue *p_h_prev;
40 ABTI_thread_queue *p_l_next;
41 ABTI_thread_queue *p_l_prev;
42 char pad3[64 -
sizeof(ABTI_thread_queue *) * 4];
45 struct ABTI_thread_htable {
46 #if defined(HAVE_LH_LOCK_H)
48 #elif defined(HAVE_CLH_H)
50 #elif defined(USE_PTHREAD_MUTEX)
51 pthread_mutex_t mutex;
55 ABTD_atomic_uint32 num_elems;
57 ABTI_thread_queue *queue;
59 ABTI_thread_queue *h_list;
60 ABTI_thread_queue *l_list;
63 #if defined(HAVE_LH_LOCK_H)
64 #define ABTI_THREAD_HTABLE_LOCK(m) lh_acquire_lock(&m)
65 #define ABTI_THREAD_HTABLE_UNLOCK(m) lh_release_lock(&m)
66 #elif defined(HAVE_CLH_H)
67 #define ABTI_THREAD_HTABLE_LOCK(m) clh_acquire(&m)
68 #define ABTI_THREAD_HTABLE_UNLOCK(m) clh_release(&m)
69 #elif defined(USE_PTHREAD_MUTEX)
70 #define ABTI_THREAD_HTABLE_LOCK(m) pthread_mutex_lock(&m)
71 #define ABTI_THREAD_HTABLE_UNLOCK(m) pthread_mutex_unlock(&m)
73 #define ABTI_THREAD_HTABLE_LOCK(m) ABTI_spinlock_acquire(&m)
74 #define ABTI_THREAD_HTABLE_UNLOCK(m) ABTI_spinlock_release(&m)
77 static inline void ABTI_thread_queue_acquire_mutex(ABTI_thread_queue *p_queue)
79 while (!ABTD_atomic_bool_cas_weak_uint32(&p_queue->mutex, 0, 1)) {
80 while (ABTD_atomic_acquire_load_uint32(&p_queue->mutex) != 0)
85 static inline void ABTI_thread_queue_release_mutex(ABTI_thread_queue *p_queue)
87 ABTD_atomic_release_store_uint32(&p_queue->mutex, 0);
91 ABTI_thread_queue_acquire_low_mutex(ABTI_thread_queue *p_queue)
93 while (!ABTD_atomic_bool_cas_weak_uint32(&p_queue->low_mutex, 0, 1)) {
94 while (ABTD_atomic_acquire_load_uint32(&p_queue->low_mutex) != 0)
100 ABTI_thread_queue_release_low_mutex(ABTI_thread_queue *p_queue)
102 ABTD_atomic_release_store_uint32(&p_queue->low_mutex, 0);
105 static inline void ABTI_thread_htable_add_h_node(ABTI_thread_htable *p_htable,
106 ABTI_thread_queue *p_node)
108 ABTI_thread_queue *p_curr = p_htable->h_list;
110 p_node->p_h_next = p_node;
111 p_node->p_h_prev = p_node;
112 p_htable->h_list = p_node;
113 }
else if (!p_node->p_h_next) {
114 p_node->p_h_next = p_curr;
115 p_node->p_h_prev = p_curr->p_h_prev;
116 p_curr->p_h_prev->p_h_next = p_node;
117 p_curr->p_h_prev = p_node;
121 static inline void ABTI_thread_htable_del_h_head(ABTI_thread_htable *p_htable)
123 ABTI_thread_queue *p_prev, *p_next;
124 ABTI_thread_queue *p_node = p_htable->h_list;
126 if (p_node == p_node->p_h_next) {
127 p_node->p_h_next = NULL;
128 p_node->p_h_prev = NULL;
129 p_htable->h_list = NULL;
131 p_prev = p_node->p_h_prev;
132 p_next = p_node->p_h_next;
133 p_prev->p_h_next = p_next;
134 p_next->p_h_prev = p_prev;
135 p_node->p_h_next = NULL;
136 p_node->p_h_prev = NULL;
137 p_htable->h_list = p_next;
141 static inline void ABTI_thread_htable_add_l_node(ABTI_thread_htable *p_htable,
142 ABTI_thread_queue *p_node)
144 ABTI_thread_queue *p_curr = p_htable->l_list;
146 p_node->p_l_next = p_node;
147 p_node->p_l_prev = p_node;
148 p_htable->l_list = p_node;
149 }
else if (!p_node->p_l_next) {
150 p_node->p_l_next = p_curr;
151 p_node->p_l_prev = p_curr->p_l_prev;
152 p_curr->p_l_prev->p_l_next = p_node;
153 p_curr->p_l_prev = p_node;
157 static inline void ABTI_thread_htable_del_l_head(ABTI_thread_htable *p_htable)
159 ABTI_thread_queue *p_prev, *p_next;
160 ABTI_thread_queue *p_node = p_htable->l_list;
162 if (p_node == p_node->p_l_next) {
163 p_node->p_l_next = NULL;
164 p_node->p_l_prev = NULL;
165 p_htable->l_list = NULL;
167 p_prev = p_node->p_l_prev;
168 p_next = p_node->p_l_next;
169 p_prev->p_l_next = p_next;
170 p_next->p_l_prev = p_prev;
171 p_node->p_l_next = NULL;
172 p_node->p_l_prev = NULL;
173 p_htable->l_list = p_next;