60 ABTI_future *p_future;
62 p_future = (ABTI_future *)
ABTU_malloc(
sizeof(ABTI_future));
63 ABTI_spinlock_clear(&p_future->lock);
64 ABTD_atomic_relaxed_store_uint32(&p_future->counter, 0);
65 p_future->compartments = compartments;
66 p_future->array =
ABTU_malloc(compartments *
sizeof(
void *));
67 p_future->p_callback = cb_func;
68 p_future->p_head = NULL;
69 p_future->p_tail = NULL;
71 *newfuture = ABTI_future_get_handle(p_future);
91 ABTI_future *p_future = ABTI_future_get_ptr(*future);
92 ABTI_CHECK_NULL_FUTURE_PTR(p_future);
97 ABTI_spinlock_acquire(&p_future->lock);
130 ABTI_local *p_local = ABTI_local_get_local();
131 ABTI_future *p_future = ABTI_future_get_ptr(future);
132 ABTI_CHECK_NULL_FUTURE_PTR(p_future);
134 ABTI_spinlock_acquire(&p_future->lock);
135 if (ABTD_atomic_relaxed_load_uint32(&p_future->counter) <
136 p_future->compartments) {
137 ABTI_thread *p_current;
140 ABTD_atomic_int32 ext_signal = ABTD_ATOMIC_INT32_STATIC_INITIALIZER(0);
142 if (p_local != NULL) {
143 p_current = p_local->p_thread;
144 #ifndef ABT_CONFIG_DISABLE_ERROR_CHECK 145 if (p_current == NULL) {
147 ABTI_spinlock_release(&p_future->lock);
152 p_unit = &p_current->unit_def;
153 p_unit->handle.thread = ABTI_thread_get_handle(p_current);
158 p_unit = (ABTI_unit *)
ABTU_calloc(1,
sizeof(ABTI_unit));
161 ABTI_STATIC_ASSERT(
sizeof(ext_signal) <=
162 sizeof(p_unit->handle.thread));
163 p_unit->handle.thread = (
ABT_thread)&ext_signal;
167 p_unit->p_next = NULL;
168 if (p_future->p_head == NULL) {
169 p_future->p_head = p_unit;
170 p_future->p_tail = p_unit;
172 p_future->p_tail->p_next = p_unit;
173 p_future->p_tail = p_unit;
177 ABTI_thread_set_blocked(p_current);
179 ABTI_spinlock_release(&p_future->lock);
182 ABTI_thread_suspend(&p_local, p_current);
185 ABTI_spinlock_release(&p_future->lock);
189 while (!ABTD_atomic_acquire_load_int32(&ext_signal))
194 ABTI_spinlock_release(&p_future->lock);
220 ABTI_future *p_future = ABTI_future_get_ptr(future);
221 ABTI_CHECK_NULL_FUTURE_PTR(p_future);
223 uint32_t counter = ABTD_atomic_acquire_load_uint32(&p_future->counter);
254 ABTI_local *p_local = ABTI_local_get_local();
255 ABTI_future *p_future = ABTI_future_get_ptr(future);
256 ABTI_CHECK_NULL_FUTURE_PTR(p_future);
258 ABTI_spinlock_acquire(&p_future->lock);
260 int counter = ABTD_atomic_relaxed_load_uint32(&p_future->counter);
261 #ifndef ABT_CONFIG_DISABLE_ERROR_CHECK 262 if (counter >= p_future->compartments) {
264 ABTI_spinlock_release(&p_future->lock);
268 p_future->array[counter] = value;
270 ABTD_atomic_release_store_uint32(&p_future->counter, counter);
272 if (counter == p_future->compartments) {
273 if (p_future->p_callback != NULL)
274 (*p_future->p_callback)(p_future->array);
276 if (p_future->p_head == NULL) {
277 ABTI_spinlock_release(&p_future->lock);
282 ABTI_unit *p_head = p_future->p_head;
283 ABTI_unit *p_unit = p_head;
285 ABTI_unit *p_next = p_unit->p_next;
288 p_unit->p_next = NULL;
291 ABTI_thread *p_thread =
292 ABTI_thread_get_ptr(p_unit->handle.thread);
293 ABTI_thread_set_ready(p_local, p_thread);
296 ABTD_atomic_int32 *p_ext_signal =
297 (ABTD_atomic_int32 *)p_unit->handle.thread;
298 ABTD_atomic_release_store_int32(p_ext_signal, 1);
302 if (p_next != NULL) {
308 p_future->p_head = NULL;
309 p_future->p_tail = NULL;
312 ABTI_spinlock_release(&p_future->lock);
337 ABTI_future *p_future = ABTI_future_get_ptr(future);
338 ABTI_CHECK_NULL_FUTURE_PTR(p_future);
340 ABTI_spinlock_acquire(&p_future->lock);
341 ABTD_atomic_release_store_uint32(&p_future->counter, 0);
342 ABTI_spinlock_release(&p_future->lock);
int ABT_future_set(ABT_future future, void *value)
Signal the future.
int ABT_future_test(ABT_future future, ABT_bool *flag)
Test whether the future is ready.
static void * ABTU_malloc(size_t size)
struct ABT_thread_opaque * ABT_thread
int ABT_future_free(ABT_future *future)
Free the future object.
int ABT_future_wait(ABT_future future)
Wait on the future.
int ABT_future_create(uint32_t compartments, void(*cb_func)(void **arg), ABT_future *newfuture)
Create a future.
#define HANDLE_ERROR_FUNC_WITH_CODE(n)
struct ABT_future_opaque * ABT_future
int ABT_future_reset(ABT_future future)
Reset the readiness of the target future.
static void ABTU_free(void *ptr)
static void * ABTU_calloc(size_t num, size_t size)