ARGOBOTS  1.1
fifo.c
Go to the documentation of this file.
1 /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
2 /*
3  * See COPYRIGHT in top-level directory.
4  */
5 
6 #include "abti.h"
7 #include <time.h>
8 
9 /* FIFO pool implementation */
10 
11 static int pool_init(ABT_pool pool, ABT_pool_config config);
12 static int pool_free(ABT_pool pool);
13 static size_t pool_get_size(ABT_pool pool);
14 static void pool_push_shared(ABT_pool pool, ABT_unit unit);
15 static void pool_push_private(ABT_pool pool, ABT_unit unit);
16 static ABT_unit pool_pop_shared(ABT_pool pool);
18 static ABT_unit pool_pop_wait(ABT_pool pool, double time_secs);
19 static ABT_unit pool_pop_timedwait(ABT_pool pool, double abstime_secs);
20 static int pool_remove_shared(ABT_pool pool, ABT_unit unit);
21 static int pool_remove_private(ABT_pool pool, ABT_unit unit);
22 static int pool_print_all(ABT_pool pool, void *arg,
23  void (*print_fn)(void *, ABT_unit));
24 
25 static ABT_bool unit_is_in_pool(ABT_unit unit);
27 static void unit_free(ABT_unit *unit);
28 
29 struct data {
31  size_t num_threads;
34  /* If the pool is empty, pop() accesses only is_empty so that pop() does not
35  * slow down a push operation. */
36  ABTD_atomic_int is_empty; /* Whether the pool is empty or not. */
37 };
38 typedef struct data data_t;
39 
40 static inline data_t *pool_get_data_ptr(void *p_data)
41 {
42  return (data_t *)p_data;
43 }
44 
46 {
47  if (ABTD_atomic_acquire_load_int(&p_data->is_empty)) {
48  /* The pool is empty. Lock is not taken. */
49  return 1;
50  }
51  while (ABTD_spinlock_try_acquire(&p_data->mutex)) {
52  /* Lock acquisition failed. Check the size. */
53  while (1) {
54  if (ABTD_atomic_acquire_load_int(&p_data->is_empty)) {
55  /* The pool becomes empty. Lock is not taken. */
56  return 1;
57  } else if (!ABTD_spinlock_is_locked(&p_data->mutex)) {
58  /* Lock seems released. Let's try to take a lock again. */
59  break;
60  }
61  }
62  }
63  /* Lock is acquired. */
64  return 0;
65 }
66 
67 /* Obtain the FIFO pool definition according to the access type */
69  ABTI_pool_def *p_def)
70 {
71  /* Definitions according to the access type */
72  /* FIXME: need better implementation, e.g., lock-free one */
73  switch (access) {
75  p_def->p_push = pool_push_private;
76  p_def->p_pop = pool_pop_private;
78  break;
79 
84  p_def->p_push = pool_push_shared;
85  p_def->p_pop = pool_pop_shared;
87  break;
88 
89  default:
91  }
92 
93  /* Common definitions regardless of the access type */
94  p_def->access = access;
95  p_def->p_init = pool_init;
96  p_def->p_free = pool_free;
97  p_def->p_get_size = pool_get_size;
98  p_def->p_pop_wait = pool_pop_wait;
100  p_def->p_print_all = pool_print_all;
101  p_def->u_is_in_pool = unit_is_in_pool;
103  p_def->u_free = unit_free;
104 
105  return ABT_SUCCESS;
106 }
107 
108 /* Pool functions */
109 
110 static int pool_init(ABT_pool pool, ABT_pool_config config)
111 {
112  ABTI_UNUSED(config);
113  int abt_errno = ABT_SUCCESS;
114  ABTI_pool *p_pool = ABTI_pool_get_ptr(pool);
115  ABT_pool_access access;
116 
117  data_t *p_data;
118  abt_errno = ABTU_malloc(sizeof(data_t), (void **)&p_data);
119  ABTI_CHECK_ERROR(abt_errno);
120 
121  access = p_pool->access;
122 
123  if (access != ABT_POOL_ACCESS_PRIV) {
124  /* Initialize the mutex */
125  ABTD_spinlock_clear(&p_data->mutex);
126  }
127 
128  p_data->num_threads = 0;
129  p_data->p_head = NULL;
130  p_data->p_tail = NULL;
131  ABTD_atomic_relaxed_store_int(&p_data->is_empty, 1);
132 
133  p_pool->data = p_data;
134 
135  return abt_errno;
136 }
137 
138 static int pool_free(ABT_pool pool)
139 {
140  int abt_errno = ABT_SUCCESS;
141  ABTI_pool *p_pool = ABTI_pool_get_ptr(pool);
142  data_t *p_data = pool_get_data_ptr(p_pool->data);
143 
144  ABTU_free(p_data);
145 
146  return abt_errno;
147 }
148 
149 static size_t pool_get_size(ABT_pool pool)
150 {
151  ABTI_pool *p_pool = ABTI_pool_get_ptr(pool);
152  data_t *p_data = pool_get_data_ptr(p_pool->data);
153  return p_data->num_threads;
154 }
155 
156 static void pool_push_shared(ABT_pool pool, ABT_unit unit)
157 {
158  ABTI_pool *p_pool = ABTI_pool_get_ptr(pool);
159  data_t *p_data = pool_get_data_ptr(p_pool->data);
161 
162  ABTD_spinlock_acquire(&p_data->mutex);
163  if (p_data->num_threads == 0) {
164  p_thread->p_prev = p_thread;
165  p_thread->p_next = p_thread;
166  p_data->p_head = p_thread;
167  p_data->p_tail = p_thread;
168  p_data->num_threads = 1;
170  } else {
171  ABTI_thread *p_head = p_data->p_head;
172  ABTI_thread *p_tail = p_data->p_tail;
173  p_tail->p_next = p_thread;
174  p_head->p_prev = p_thread;
175  p_thread->p_prev = p_tail;
176  p_thread->p_next = p_head;
177  p_data->p_tail = p_thread;
178  p_data->num_threads++;
179  }
180 
182  ABTD_spinlock_release(&p_data->mutex);
183 }
184 
185 static void pool_push_private(ABT_pool pool, ABT_unit unit)
186 {
187  ABTI_pool *p_pool = ABTI_pool_get_ptr(pool);
188  data_t *p_data = pool_get_data_ptr(p_pool->data);
190 
191  if (p_data->num_threads == 0) {
192  p_thread->p_prev = p_thread;
193  p_thread->p_next = p_thread;
194  p_data->p_head = p_thread;
195  p_data->p_tail = p_thread;
196  p_data->num_threads = 1;
198  } else {
199  ABTI_thread *p_head = p_data->p_head;
200  ABTI_thread *p_tail = p_data->p_tail;
201  p_tail->p_next = p_thread;
202  p_head->p_prev = p_thread;
203  p_thread->p_prev = p_tail;
204  p_thread->p_next = p_head;
205  p_data->p_tail = p_thread;
206  p_data->num_threads++;
207  }
208 
210 }
211 
212 static ABT_unit pool_pop_wait(ABT_pool pool, double time_secs)
213 {
214  ABTI_pool *p_pool = ABTI_pool_get_ptr(pool);
215  data_t *p_data = pool_get_data_ptr(p_pool->data);
216  ABTI_thread *p_thread = NULL;
217 
218  double time_start = 0.0;
219 
220  while (1) {
221  if (spinlock_acquire_if_not_empty(p_data) == 0) {
222  ABT_unit h_unit = ABT_UNIT_NULL;
223  if (p_data->num_threads > 0) {
224  p_thread = p_data->p_head;
225  if (p_data->num_threads == 1) {
226  p_data->p_head = NULL;
227  p_data->p_tail = NULL;
228  p_data->num_threads = 0;
230  } else {
231  p_thread->p_prev->p_next = p_thread->p_next;
232  p_thread->p_next->p_prev = p_thread->p_prev;
233  p_data->p_head = p_thread->p_next;
234  p_data->num_threads--;
235  }
236 
237  p_thread->p_prev = NULL;
238  p_thread->p_next = NULL;
240 
241  h_unit = ABTI_unit_get_builtin_unit(p_thread);
242  }
243  ABTD_spinlock_release(&p_data->mutex);
244  if (h_unit != ABT_UNIT_NULL)
245  return h_unit;
246  }
247  if (time_start == 0.0) {
248  time_start = ABTI_get_wtime();
249  } else {
250  double elapsed = ABTI_get_wtime() - time_start;
251  if (elapsed > time_secs)
252  return ABT_UNIT_NULL;
253  }
254  /* Sleep. */
255  const int sleep_nsecs = 100;
256  struct timespec ts = { 0, sleep_nsecs };
257  nanosleep(&ts, NULL);
258  }
259 }
260 
261 static ABT_unit pool_pop_timedwait(ABT_pool pool, double abstime_secs)
262 {
263  ABTI_pool *p_pool = ABTI_pool_get_ptr(pool);
264  data_t *p_data = pool_get_data_ptr(p_pool->data);
265  ABTI_thread *p_thread = NULL;
266 
267  while (1) {
268  if (spinlock_acquire_if_not_empty(p_data) == 0) {
269  ABT_unit h_unit = ABT_UNIT_NULL;
270  if (p_data->num_threads > 0) {
271  p_thread = p_data->p_head;
272  if (p_data->num_threads == 1) {
273  p_data->p_head = NULL;
274  p_data->p_tail = NULL;
275  p_data->num_threads = 0;
277  } else {
278  p_thread->p_prev->p_next = p_thread->p_next;
279  p_thread->p_next->p_prev = p_thread->p_prev;
280  p_data->p_head = p_thread->p_next;
281  p_data->num_threads--;
282  }
283 
284  p_thread->p_prev = NULL;
285  p_thread->p_next = NULL;
287 
288  h_unit = ABTI_unit_get_builtin_unit(p_thread);
289  }
290  ABTD_spinlock_release(&p_data->mutex);
291  if (h_unit != ABT_UNIT_NULL)
292  return h_unit;
293  }
294  const int sleep_nsecs = 100;
295  struct timespec ts = { 0, sleep_nsecs };
296  nanosleep(&ts, NULL);
297 
298  if (ABTI_get_wtime() > abstime_secs)
299  return ABT_UNIT_NULL;
300  }
301 }
302 
304 {
305  ABTI_pool *p_pool = ABTI_pool_get_ptr(pool);
306  data_t *p_data = pool_get_data_ptr(p_pool->data);
307  ABTI_thread *p_thread = NULL;
308 
309  if (spinlock_acquire_if_not_empty(p_data) == 0) {
310  ABT_unit h_unit = ABT_UNIT_NULL;
311  if (p_data->num_threads > 0) {
312  p_thread = p_data->p_head;
313  if (p_data->num_threads == 1) {
314  p_data->p_head = NULL;
315  p_data->p_tail = NULL;
316  p_data->num_threads = 0;
318  } else {
319  p_thread->p_prev->p_next = p_thread->p_next;
320  p_thread->p_next->p_prev = p_thread->p_prev;
321  p_data->p_head = p_thread->p_next;
322  p_data->num_threads--;
323  }
324 
325  p_thread->p_prev = NULL;
326  p_thread->p_next = NULL;
328 
329  h_unit = ABTI_unit_get_builtin_unit(p_thread);
330  }
331  ABTD_spinlock_release(&p_data->mutex);
332  return h_unit;
333  } else {
334  return ABT_UNIT_NULL;
335  }
336 }
337 
339 {
340  ABTI_pool *p_pool = ABTI_pool_get_ptr(pool);
341  data_t *p_data = pool_get_data_ptr(p_pool->data);
342  ABTI_thread *p_thread = NULL;
343 
344  ABT_unit h_unit = ABT_UNIT_NULL;
345  if (p_data->num_threads > 0) {
346  p_thread = p_data->p_head;
347  if (p_data->num_threads == 1) {
348  p_data->p_head = NULL;
349  p_data->p_tail = NULL;
350  p_data->num_threads = 0;
352  } else {
353  p_thread->p_prev->p_next = p_thread->p_next;
354  p_thread->p_next->p_prev = p_thread->p_prev;
355  p_data->p_head = p_thread->p_next;
356  p_data->num_threads--;
357  }
358 
359  p_thread->p_prev = NULL;
360  p_thread->p_next = NULL;
362 
363  h_unit = ABTI_unit_get_builtin_unit(p_thread);
364  }
365  return h_unit;
366 }
367 
368 static int pool_remove_shared(ABT_pool pool, ABT_unit unit)
369 {
370  ABTI_pool *p_pool = ABTI_pool_get_ptr(pool);
371  data_t *p_data = pool_get_data_ptr(p_pool->data);
373 
376  ABT_ERR_POOL);
377 
378  ABTD_spinlock_acquire(&p_data->mutex);
379  if (p_data->num_threads == 1) {
380  p_data->p_head = NULL;
381  p_data->p_tail = NULL;
382  p_data->num_threads = 0;
384  } else {
385  p_thread->p_prev->p_next = p_thread->p_next;
386  p_thread->p_next->p_prev = p_thread->p_prev;
387  if (p_thread == p_data->p_head) {
388  p_data->p_head = p_thread->p_next;
389  } else if (p_thread == p_data->p_tail) {
390  p_data->p_tail = p_thread->p_prev;
391  }
392  p_data->num_threads--;
393  }
394 
396  ABTD_spinlock_release(&p_data->mutex);
397 
398  p_thread->p_prev = NULL;
399  p_thread->p_next = NULL;
400 
401  return ABT_SUCCESS;
402 }
403 
404 static int pool_remove_private(ABT_pool pool, ABT_unit unit)
405 {
406  ABTI_pool *p_pool = ABTI_pool_get_ptr(pool);
407  data_t *p_data = pool_get_data_ptr(p_pool->data);
409 
412  ABT_ERR_POOL);
413 
414  if (p_data->num_threads == 1) {
415  p_data->p_head = NULL;
416  p_data->p_tail = NULL;
417  p_data->num_threads = 0;
419  } else {
420  p_thread->p_prev->p_next = p_thread->p_next;
421  p_thread->p_next->p_prev = p_thread->p_prev;
422  if (p_thread == p_data->p_head) {
423  p_data->p_head = p_thread->p_next;
424  } else if (p_thread == p_data->p_tail) {
425  p_data->p_tail = p_thread->p_prev;
426  }
427  p_data->num_threads--;
428  }
429 
431  p_thread->p_prev = NULL;
432  p_thread->p_next = NULL;
433 
434  return ABT_SUCCESS;
435 }
436 
437 static int pool_print_all(ABT_pool pool, void *arg,
438  void (*print_fn)(void *, ABT_unit))
439 {
440  ABT_pool_access access;
441  ABTI_pool *p_pool = ABTI_pool_get_ptr(pool);
442  data_t *p_data = pool_get_data_ptr(p_pool->data);
443 
444  access = p_pool->access;
445  if (access != ABT_POOL_ACCESS_PRIV) {
446  ABTD_spinlock_acquire(&p_data->mutex);
447  }
448 
449  size_t num_threads = p_data->num_threads;
450  ABTI_thread *p_thread = p_data->p_head;
451  while (num_threads--) {
452  ABTI_ASSERT(p_thread);
453  ABT_unit unit = ABTI_unit_get_builtin_unit(p_thread);
454  print_fn(arg, unit);
455  p_thread = p_thread->p_next;
456  }
457 
458  if (access != ABT_POOL_ACCESS_PRIV) {
459  ABTD_spinlock_release(&p_data->mutex);
460  }
461 
462  return ABT_SUCCESS;
463 }
464 
465 /* Unit functions */
466 
468 {
471  : ABT_FALSE;
472 }
473 
475 {
476  /* Call ABTI_unit_init_builtin() instead. */
477  ABTI_ASSERT(0);
478  return ABT_UNIT_NULL;
479 }
480 
481 static void unit_free(ABT_unit *unit)
482 {
483  /* A built-in unit does not need to be freed. This function may not be
484  * called. */
485  ABTI_ASSERT(0);
486 }
ABTI_pool_def::p_init
ABT_pool_init_fn p_init
Definition: abti.h:360
ABTI_pool_def::p_get_size
ABT_pool_get_size_fn p_get_size
Definition: abti.h:361
ABT_bool
int ABT_bool
Boolean type.
Definition: abt.h:1001
ABTD_atomic_int
Definition: abtd_atomic.h:15
pool_push_private
static void pool_push_private(ABT_pool pool, ABT_unit unit)
Definition: fifo.c:185
ABTI_pool_def::p_remove
ABT_pool_remove_fn p_remove
Definition: abti.h:366
ABT_thread
struct ABT_thread_opaque * ABT_thread
Work unit handle type.
Definition: abt.h:890
ABTI_pool_def::p_print_all
ABT_pool_print_all_fn p_print_all
Definition: abti.h:368
ABTI_pool_get_fifo_def
ABTU_ret_err int ABTI_pool_get_fifo_def(ABT_pool_access access, ABTI_pool_def *p_def)
Definition: fifo.c:68
ABTI_pool_def
Definition: abti.h:354
ABTI_unit_get_builtin_unit
static ABT_unit ABTI_unit_get_builtin_unit(ABTI_thread *p_thread)
Definition: abti_unit.h:23
ABT_ERR_POOL
#define ABT_ERR_POOL
Error code: error related to a pool.
Definition: abt.h:282
ABTI_CHECK_ERROR
#define ABTI_CHECK_ERROR(abt_errno)
Definition: abti_error.h:120
data
Definition: fifo.c:29
ABTI_thread::p_next
ABTI_thread * p_next
Definition: abti.h:373
ABT_POOL_ACCESS_MPMC
@ ABT_POOL_ACCESS_MPMC
Definition: abt.h:541
unit_free
static void unit_free(ABT_unit *unit)
Definition: fifo.c:481
ABTI_unit_get_thread_from_builtin_unit
static ABTI_thread * ABTI_unit_get_thread_from_builtin_unit(ABT_unit unit)
Definition: abti_unit.h:37
ABTI_UNUSED
#define ABTI_UNUSED(a)
Definition: abti.h:106
ABTI_thread
Definition: abti.h:371
pool_free
static int pool_free(ABT_pool pool)
Definition: fifo.c:138
data::is_empty
ABTD_atomic_int is_empty
Definition: fifo.c:36
ABT_pool
struct ABT_pool_opaque * ABT_pool
Pool handle type.
Definition: abt.h:841
ABTD_spinlock
Definition: abtd_spinlock.h:9
unit_create_from_thread
static ABT_unit unit_create_from_thread(ABT_thread thread)
Definition: fifo.c:474
pool_pop_shared
static ABT_unit pool_pop_shared(ABT_pool pool)
Definition: fifo.c:303
ABTI_pool_def::u_free
ABT_unit_free_fn u_free
Definition: abti.h:359
ABT_POOL_ACCESS_MPSC
@ ABT_POOL_ACCESS_MPSC
Definition: abt.h:535
pool_remove_private
static int pool_remove_private(ABT_pool pool, ABT_unit unit)
Definition: fifo.c:404
ABT_POOL_ACCESS_PRIV
@ ABT_POOL_ACCESS_PRIV
Definition: abt.h:526
ABTI_pool
Definition: abti.h:327
pool_get_size
static size_t pool_get_size(ABT_pool pool)
Definition: fifo.c:149
pool_pop_timedwait
static ABT_unit pool_pop_timedwait(ABT_pool pool, double abstime_secs)
Definition: fifo.c:261
ABTI_pool_def::u_is_in_pool
ABT_unit_is_in_pool_fn u_is_in_pool
Definition: abti.h:357
abti.h
ABTI_pool::data
void * data
Definition: abti.h:334
ABTD_spinlock_acquire
static void ABTD_spinlock_acquire(ABTD_spinlock *p_lock)
Definition: abtd_spinlock.h:28
ABTI_HANDLE_ERROR
#define ABTI_HANDLE_ERROR(n)
Definition: abti_error.h:114
ABT_pool_config
struct ABT_pool_config_opaque * ABT_pool_config
Pool configuration handle type.
Definition: abt.h:848
ABTU_malloc
static ABTU_ret_err int ABTU_malloc(size_t size, void **p_ptr)
Definition: abtu.h:262
spinlock_acquire_if_not_empty
static ABTU_ret_err int spinlock_acquire_if_not_empty(data_t *p_data)
Definition: fifo.c:45
ABTD_atomic_relaxed_store_int
static void ABTD_atomic_relaxed_store_int(ABTD_atomic_int *ptr, int val)
Definition: abtd_atomic.h:996
ABT_ERR_INV_POOL_ACCESS
#define ABT_ERR_INV_POOL_ACCESS
Error code: invalid pool access type.
Definition: abt.h:166
pool_remove_shared
static int pool_remove_shared(ABT_pool pool, ABT_unit unit)
Definition: fifo.c:368
ABT_unit
struct ABT_unit_opaque * ABT_unit
Work unit handle type for scheduling.
Definition: abt.h:869
ABTI_pool_def::u_create_from_thread
ABT_unit_create_from_thread_fn u_create_from_thread
Definition: abti.h:358
ABTI_ASSERT
#define ABTI_ASSERT(cond)
Definition: abti_error.h:12
ABTI_pool_def::p_push
ABT_pool_push_fn p_push
Definition: abti.h:362
ABTI_pool_def::p_pop_timedwait
ABT_pool_pop_timedwait_fn p_pop_timedwait
Definition: abti.h:365
ABTI_thread::is_in_pool
ABTD_atomic_int is_in_pool
Definition: abti.h:374
pool_pop_wait
static ABT_unit pool_pop_wait(ABT_pool pool, double time_secs)
Definition: fifo.c:212
ABTD_spinlock_try_acquire
static ABT_bool ABTD_spinlock_try_acquire(ABTD_spinlock *p_lock)
Definition: abtd_spinlock.h:37
ABT_SUCCESS
#define ABT_SUCCESS
Error code: the routine returns successfully.
Definition: abt.h:92
ABTU_ret_err
#define ABTU_ret_err
Definition: abtu.h:146
ABTI_pool_def::p_free
ABT_pool_free_fn p_free
Definition: abti.h:367
ABTI_pool_def::p_pop_wait
ABT_pool_pop_wait_fn p_pop_wait
Definition: abti.h:364
ABTD_atomic_acquire_load_int
static int ABTD_atomic_acquire_load_int(const ABTD_atomic_int *ptr)
Definition: abtd_atomic.h:878
pool_print_all
static int pool_print_all(ABT_pool pool, void *arg, void(*print_fn)(void *, ABT_unit))
Definition: fifo.c:437
ABT_TRUE
#define ABT_TRUE
True constant for ABT_bool.
Definition: abt.h:748
ABTI_pool_get_ptr
static ABTI_pool * ABTI_pool_get_ptr(ABT_pool pool)
Definition: abti_pool.h:11
ABT_POOL_ACCESS_SPMC
@ ABT_POOL_ACCESS_SPMC
Definition: abt.h:539
ABTD_spinlock_clear
static void ABTD_spinlock_clear(ABTD_spinlock *p_lock)
Definition: abtd_spinlock.h:23
pool_get_data_ptr
static data_t * pool_get_data_ptr(void *p_data)
Definition: fifo.c:40
ABT_FALSE
#define ABT_FALSE
False constant for ABT_bool.
Definition: abt.h:750
ABTI_pool::access
ABT_pool_access access
Definition: abti.h:328
ABTI_pool_def::p_pop
ABT_pool_pop_fn p_pop
Definition: abti.h:363
ABT_POOL_ACCESS_SPSC
@ ABT_POOL_ACCESS_SPSC
Definition: abt.h:531
ABTU_free
static void ABTU_free(void *ptr)
Definition: abtu.h:217
ABTD_spinlock_release
static void ABTD_spinlock_release(ABTD_spinlock *p_lock)
Definition: abtd_spinlock.h:42
data::num_threads
size_t num_threads
Definition: fifo.c:31
data::mutex
ABTD_spinlock mutex
Definition: fifo.c:30
ABTI_thread::p_prev
ABTI_thread * p_prev
Definition: abti.h:372
unit_is_in_pool
static ABT_bool unit_is_in_pool(ABT_unit unit)
Definition: fifo.c:467
ABTI_CHECK_TRUE
#define ABTI_CHECK_TRUE(cond, abt_errno)
Definition: abti_error.h:130
ABTD_spinlock_is_locked
static ABT_bool ABTD_spinlock_is_locked(const ABTD_spinlock *p_lock)
Definition: abtd_spinlock.h:18
pool_init
static int pool_init(ABT_pool pool, ABT_pool_config config)
Definition: fifo.c:110
ABTI_pool_def::access
ABT_pool_access access
Definition: abti.h:355
pool_pop_private
static ABT_unit pool_pop_private(ABT_pool pool)
Definition: fifo.c:338
ABT_UNIT_NULL
#define ABT_UNIT_NULL
Definition: abt.h:1061
pool_push_shared
static void pool_push_shared(ABT_pool pool, ABT_unit unit)
Definition: fifo.c:156
ABTD_atomic_release_store_int
static void ABTD_atomic_release_store_int(ABTD_atomic_int *ptr, int val)
Definition: abtd_atomic.h:1065
data::p_tail
ABTI_thread * p_tail
Definition: fifo.c:33
ABTI_get_wtime
static double ABTI_get_wtime(void)
Definition: abti_timer.h:11
data::p_head
ABTI_thread * p_head
Definition: fifo.c:32
ABT_pool_access
ABT_pool_access
Pool access type.
Definition: abt.h:522