void * dequeue( queue *queue ) { debug( "Dequeueing a data from a queue ( queue = %p, length = %d ).", queue, queue != NULL ? queue->length : 0 ); assert( queue != NULL ); assert( queue->length >= 0 ); volatile queue_element *tail = queue->tail; read_memory_barrier(); if ( queue->divider != tail ) { queue_element *next = queue->divider->next; void *data = next->data; next->data = NULL; // data must be freed by caller queue->divider = next; write_memory_barrier(); __sync_sub_and_fetch( &queue->length, 1 ); debug( "Dequeue completed ( queue = %p, length = %d, data = %p ).", queue, queue->length, data ); return data; } debug( "Dequeue completed ( queue = %p, length = %d, data = %p ).", queue, queue->length, NULL ); return NULL; }
bool dequeue (T * ret) { for (;;) { atomic_node_ptr head (head_); read_memory_barrier(); atomic_node_ptr tail(tail_); node * next = head->next.get_ptr(); if (likely(head == head_)) { if (head.get_ptr() == tail.get_ptr()) { if (next == 0) return false; tail_.cas(tail, next); } else { *ret = next->data; if (head_.cas(head, next)) { dealloc_node(head.get_ptr()); return true; } } } } }
bool enqueue(T const & t) { node * n = alloc_node(t); if (n == NULL) return false; for (;;) { atomic_node_ptr tail (tail_); read_memory_barrier(); atomic_node_ptr next (tail->next); if (likely(tail == tail_)) { if (next.get_ptr() == 0) { if ( tail->next.cas(next, n) ) { tail_.cas(tail, n); return true; } } else tail_.cas(tail, next.get_ptr()); } } }
static void collect_garbage( queue *queue ) { while ( 1 ) { volatile queue_element *divider = queue->divider; read_memory_barrier(); if ( queue->head == divider ) { break; } queue_element *e = queue->head; queue->head = queue->head->next; free( e ); } }
void * peek( queue *queue ) { assert( queue != NULL ); volatile queue_element *divider = queue->divider; volatile queue_element *tail = queue->tail; read_memory_barrier(); if ( divider != tail ) { return divider->next->data; } return NULL; }
static void collect_garbage( queue *queue ) { debug( "Collecting garbage in a queue ( queue = %p, length = %d ).", queue, queue != NULL ? queue->length : 0 ); assert( queue != NULL ); assert( queue->length >= 0 ); while ( 1 ) { volatile queue_element *divider = queue->divider; read_memory_barrier(); if ( queue->head == divider ) { break; } queue_element *e = queue->head; queue->head = queue->head->next; xfree( e ); } debug( "Garbage collection completed ( queue = %p, length = %d ).", queue, queue->length ); }
void * dequeue( queue *queue ) { assert( queue != NULL ); volatile queue_element *tail = queue->tail; read_memory_barrier(); if ( queue->divider != tail ) { queue_element *next = queue->divider->next; void *data = next->data; next->data = NULL; // data must be freed by caller queue->divider = next; write_memory_barrier(); __sync_sub_and_fetch( &queue->length, 1 ); return data; } return NULL; }