コード例 #1
0
ファイル: queue.c プロジェクト: deadcafe/trash
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;
}
コード例 #2
0
ファイル: fifo.hpp プロジェクト: coxlab/audiomonitor
    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;
                    }
                }
            }
        }
    }
コード例 #3
0
ファイル: fifo.hpp プロジェクト: coxlab/audiomonitor
    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());
            }
        }
    }
コード例 #4
0
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 );
  }
}
コード例 #5
0
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;
}
コード例 #6
0
ファイル: queue.c プロジェクト: deadcafe/trash
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 );
}
コード例 #7
0
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;
}