9 ABTI_thread_htable *ABTI_thread_htable_create(uint32_t num_rows)
11 ABTI_STATIC_ASSERT(
sizeof(ABTI_thread_queue) == 192);
13 ABTI_thread_htable *p_htable;
14 size_t q_size = num_rows *
sizeof(ABTI_thread_queue);
16 p_htable = (ABTI_thread_htable *)
ABTU_malloc(
sizeof(ABTI_thread_htable));
17 #if defined(HAVE_LH_LOCK_H)
18 lh_lock_init(&p_htable->mutex);
19 #elif defined(HAVE_CLH_H)
20 clh_init(&p_htable->mutex);
21 #elif defined(USE_PTHREAD_MUTEX)
22 int ret = pthread_mutex_init(&p_htable->mutex, NULL);
25 ABTI_spinlock_clear(&p_htable->mutex);
27 ABTD_atomic_relaxed_store_uint32(&p_htable->num_elems, 0);
28 p_htable->num_rows = num_rows;
29 p_htable->queue = (ABTI_thread_queue *)
ABTU_memalign(64, q_size);
30 memset(p_htable->queue, 0, q_size);
31 p_htable->h_list = NULL;
32 p_htable->l_list = NULL;
37 void ABTI_thread_htable_free(ABTI_thread_htable *p_htable)
39 ABTI_ASSERT(ABTD_atomic_relaxed_load_uint32(&p_htable->num_elems) == 0);
41 #if defined(HAVE_LH_LOCK_H)
42 lh_lock_destroy(&p_htable->mutex);
43 #elif defined(HAVE_CLH_H)
44 clh_destroy(&p_htable->mutex);
45 #elif defined(USE_PTHREAD_MUTEX)
46 int ret = pthread_mutex_destroy(&p_htable->mutex);
55 void ABTI_thread_htable_push(ABTI_thread_htable *p_htable,
int idx,
56 ABTI_thread *p_thread)
58 ABTI_thread_queue *p_queue;
60 if (idx >= p_htable->num_rows) {
65 uint32_t cur_size, new_size;
66 cur_size = p_htable->num_rows;
67 new_size = (idx / cur_size + 1) * cur_size;
68 p_htable->queue = (ABTI_thread_queue *)
69 ABTU_realloc(p_htable->queue, cur_size *
sizeof(ABTI_thread_queue),
70 new_size *
sizeof(ABTI_thread_queue));
71 memset(&p_htable->queue[cur_size], 0,
72 (new_size - cur_size) *
sizeof(ABTI_thread_queue));
73 p_htable->num_rows = new_size;
78 p_queue = &p_htable->queue[idx];
79 ABTI_thread_queue_acquire_mutex(p_queue);
80 if (p_queue->head == NULL) {
81 p_queue->head = p_thread;
82 p_queue->tail = p_thread;
84 p_queue->tail->unit_def.p_next = &p_thread->unit_def;
85 p_queue->tail = p_thread;
87 p_queue->num_threads++;
88 ABTI_thread_queue_release_mutex(p_queue);
89 ABTD_atomic_fetch_add_uint32(&p_htable->num_elems, 1);
94 ABT_bool ABTI_thread_htable_add(ABTI_thread_htable *p_htable,
int idx,
95 ABTI_thread *p_thread)
97 ABTI_thread_queue *p_queue;
99 p_queue = &p_htable->queue[idx];
101 ABTI_thread_queue_acquire_mutex(p_queue);
102 if (p_queue->head == NULL) {
103 ABTI_ASSERT(p_queue->num_threads == 0);
104 ABTI_thread_queue_release_mutex(p_queue);
108 ABTI_thread_set_blocked(p_thread);
110 p_queue->tail->unit_def.p_next = &p_thread->unit_def;
111 p_queue->tail = p_thread;
113 p_queue->num_threads++;
114 ABTI_thread_queue_release_mutex(p_queue);
115 ABTD_atomic_fetch_add_uint32(&p_htable->num_elems, 1);
119 void ABTI_thread_htable_push_low(ABTI_thread_htable *p_htable,
int idx,
120 ABTI_thread *p_thread)
122 ABTI_thread_queue *p_queue;
124 if (idx >= p_htable->num_rows) {
129 uint32_t cur_size, new_size;
130 cur_size = p_htable->num_rows;
131 new_size = (idx / cur_size + 1) * cur_size;
132 p_htable->queue = (ABTI_thread_queue *)
133 ABTU_realloc(p_htable->queue, cur_size *
sizeof(ABTI_thread_queue),
134 new_size *
sizeof(ABTI_thread_queue));
135 memset(&p_htable->queue[cur_size], 0,
136 (new_size - cur_size) *
sizeof(ABTI_thread_queue));
137 p_htable->num_rows = new_size;
142 p_queue = &p_htable->queue[idx];
143 ABTI_thread_queue_acquire_low_mutex(p_queue);
144 if (p_queue->low_head == NULL) {
145 p_queue->low_head = p_thread;
146 p_queue->low_tail = p_thread;
148 p_queue->low_tail->unit_def.p_next = &p_thread->unit_def;
149 p_queue->low_tail = p_thread;
151 p_queue->low_num_threads++;
152 ABTI_thread_queue_release_low_mutex(p_queue);
153 ABTD_atomic_fetch_add_uint32(&p_htable->num_elems, 1);
158 ABT_bool ABTI_thread_htable_add_low(ABTI_thread_htable *p_htable,
int idx,
159 ABTI_thread *p_thread)
161 ABTI_thread_queue *p_queue;
163 p_queue = &p_htable->queue[idx];
165 ABTI_thread_queue_acquire_low_mutex(p_queue);
166 if (p_queue->low_head == NULL) {
167 ABTI_ASSERT(p_queue->low_num_threads == 0);
168 ABTI_thread_queue_release_low_mutex(p_queue);
172 ABTI_thread_set_blocked(p_thread);
174 p_queue->low_tail->unit_def.p_next = &p_thread->unit_def;
175 p_queue->low_tail = p_thread;
177 p_queue->low_num_threads++;
178 ABTI_thread_queue_release_low_mutex(p_queue);
179 ABTD_atomic_fetch_add_uint32(&p_htable->num_elems, 1);
183 ABTI_thread *ABTI_thread_htable_pop(ABTI_thread_htable *p_htable,
184 ABTI_thread_queue *p_queue)
186 ABTI_thread *p_thread = NULL;
188 ABTI_thread_queue_acquire_mutex(p_queue);
190 ABTD_atomic_fetch_sub_uint32(&p_htable->num_elems, 1);
191 p_thread = p_queue->head;
192 if (p_queue->head == p_queue->tail) {
193 p_queue->head = NULL;
194 p_queue->tail = NULL;
196 p_queue->head = ABTI_unit_get_thread(p_thread->unit_def.p_next);
199 p_queue->num_threads--;
201 ABTI_thread_queue_release_mutex(p_queue);
206 ABTI_thread *ABTI_thread_htable_pop_low(ABTI_thread_htable *p_htable,
207 ABTI_thread_queue *p_queue)
209 ABTI_thread *p_thread = NULL;
211 ABTI_thread_queue_acquire_low_mutex(p_queue);
212 if (p_queue->low_head) {
213 ABTD_atomic_fetch_sub_uint32(&p_htable->num_elems, 1);
214 p_thread = p_queue->low_head;
215 if (p_queue->low_head == p_queue->low_tail) {
216 p_queue->low_head = NULL;
217 p_queue->low_tail = NULL;
219 p_queue->low_head = ABTI_unit_get_thread(p_thread->unit_def.p_next);
222 p_queue->low_num_threads--;
224 ABTI_thread_queue_release_low_mutex(p_queue);
229 ABT_bool ABTI_thread_htable_switch_low(ABTI_xstream **pp_local_xstream,
230 ABTI_thread_queue *p_queue,
231 ABTI_thread *p_thread,
232 ABTI_thread_htable *p_htable,
236 ABTI_thread *p_target = NULL;
237 ABTI_xstream *p_local_xstream = *pp_local_xstream;
239 ABTI_thread_queue_acquire_low_mutex(p_queue);
240 if (p_queue->low_head) {
241 p_target = p_queue->low_head;
244 ABTD_atomic_release_store_int(&p_thread->unit_def.state,
245 ABTI_UNIT_STATE_BLOCKED);
246 ABTI_tool_event_thread_suspend(p_local_xstream, p_thread,
247 p_thread->unit_def.p_parent,
248 sync_event_type, p_sync);
249 if (p_queue->low_head == p_queue->low_tail) {
250 p_queue->low_head = p_thread;
251 p_queue->low_tail = p_thread;
253 p_queue->low_head = ABTI_unit_get_thread(p_target->unit_def.p_next);
254 p_queue->low_tail->unit_def.p_next = &p_thread->unit_def;
255 p_queue->low_tail = p_thread;
258 ABTI_thread_queue_release_low_mutex(p_queue);
261 LOG_DEBUG(
"switch -> U%" PRIu64
"\n", ABTI_thread_get_id(p_target));
264 ABTD_atomic_release_store_int(&p_target->unit_def.state,
265 ABTI_UNIT_STATE_RUNNING);
266 ABTI_tool_event_thread_resume(p_local_xstream, p_target,
267 p_local_xstream ? p_local_xstream->p_unit
269 ABTI_thread *p_prev =
270 ABTI_thread_context_switch_to_sibling(pp_local_xstream, p_thread,
272 ABTI_tool_event_thread_run(*pp_local_xstream, p_thread,
274 p_thread->unit_def.p_parent);
#define ABTU_unreachable()
static void * ABTU_malloc(size_t size)
static void * ABTU_realloc(void *ptr, size_t old_size, size_t new_size)
#define LOG_DEBUG(fmt,...)
static void * ABTU_memalign(size_t alignment, size_t size)
static void ABTU_free(void *ptr)