void mpmcq_push(mpmcq_t* q, void* data) { mpmcq_node_t* node = POOL_ALLOC(mpmcq_node_t); node->data = data; node->next = NULL; mpmcq_node_t* prev = (mpmcq_node_t*)_atomic_exchange(&q->head, node); _atomic_store(&prev->next, node); }
bool ponyint_messageq_push(messageq_t* q, pony_msg_t* m) { m->next = NULL; pony_msg_t* prev = (pony_msg_t*)_atomic_exchange(&q->head, m); bool was_empty = ((uintptr_t)prev & 1) != 0; prev = (pony_msg_t*)((uintptr_t)prev & ~(uintptr_t)1); _atomic_store(&prev->next, m); return was_empty; }
static void _freed_pool_put (freed_pool_t *pool, void *ptr) { int i = pool->top; if (_atomic_store (&pool->pool[i], ptr)) { pool->top = i + 1; return; } /* either full or contended */ for (i = 0; i < ARRAY_LENGTH (pool->pool); i++) { if (_atomic_store (&pool->pool[i], ptr)) { pool->top = i + 1; return; } } /* full */ pool->top = ARRAY_LENGTH (pool->pool); free (ptr); }
void _freed_pool_put_search (freed_pool_t *pool, void *ptr) { int i; for (i = 0; i < ARRAY_LENGTH (pool->pool); i++) { if (_atomic_store (&pool->pool[i], ptr)) { _cairo_atomic_int_set_relaxed (&pool->top, i + 1); return; } } /* full */ _cairo_atomic_int_set_relaxed (&pool->top, i); free (ptr); }
void* ponyint_mpmcq_pop(mpmcq_t* q) { mpmcq_dwcas_t cmp, xchg; mpmcq_node_t* next; cmp.aba = q->tail.aba; cmp.node = q->tail.node; do { // Get the next node rather than the tail. The tail is either a stub or has // already been consumed. next = _atomic_load(&cmp.node->next); // Bailout if we have no next node. if(next == NULL) return NULL; // Make the next node the tail, incrementing the aba counter. If this // fails, cmp becomes the new tail and we retry the loop. xchg.aba = cmp.aba + 1; xchg.node = next; } while(!_atomic_dwcas(&q->tail.dw, &cmp.dw, xchg.dw)); // We'll return the data pointer from the next node. void* data = _atomic_load(&next->data); // Since we will be freeing the old tail, we need to be sure no other // consumer is still reading the old tail. To do this, we set the data // pointer of our new tail to NULL, and we wait until the data pointer of // the old tail is NULL. _atomic_store(&next->data, NULL); while(_atomic_load(&cmp.node->data) != NULL) ponyint_cpu_relax(); // Free the old tail. The new tail is the next node. POOL_FREE(mpmcq_node_t, cmp.node); return data; }
void pony_exitcode(int code) { _atomic_store(&exit_code, code); }
void pony_exitcode(int code) { _atomic_store(&exit_code, code, __ATOMIC_RELEASE); }