void hb_fifo_flush( hb_fifo_t * f ) { hb_buffer_t * b; while( ( b = hb_fifo_get( f ) ) ) { hb_buffer_close( &b ); } hb_lock( f->lock ); hb_cond_signal( f->cond_empty ); hb_cond_signal( f->cond_full ); hb_unlock( f->lock ); }
// Appends the specified packet list to the end of the specified FIFO. void hb_fifo_push( hb_fifo_t * f, hb_buffer_t * b ) { if( !b ) { return; } hb_lock( f->lock ); if( f->size > 0 ) { f->last->next = b; } else { f->first = b; } f->last = b; f->size += 1; while( f->last->next ) { f->size += 1; f->last = f->last->next; } if( f->wait_empty && f->size >= 1 ) { f->wait_empty = 0; hb_cond_signal( f->cond_empty ); } hb_unlock( f->lock ); }
// Pushes the specified buffer onto the specified FIFO, // blocking until the FIFO has space available. void hb_fifo_push_wait( hb_fifo_t * f, hb_buffer_t * b ) { if( !b ) { return; } hb_lock( f->lock ); if( f->size >= f->capacity ) { f->wait_full = 1; hb_cond_timedwait( f->cond_full, f->lock, FIFO_TIMEOUT ); } if( f->size > 0 ) { f->last->next = b; } else { f->first = b; } f->last = b; f->size += 1; while( f->last->next ) { f->size += 1; f->last = f->last->next; } if( f->wait_empty && f->size >= 1 ) { f->wait_empty = 0; hb_cond_signal( f->cond_empty ); } hb_unlock( f->lock ); }
// Pulls the first packet out of this FIFO, blocking until such a packet is available. // Returns NULL if this FIFO has been closed or flushed. hb_buffer_t * hb_fifo_get_wait( hb_fifo_t * f ) { hb_buffer_t * b; hb_lock( f->lock ); if( f->size < 1 ) { f->wait_empty = 1; hb_cond_timedwait( f->cond_empty, f->lock, FIFO_TIMEOUT ); if( f->size < 1 ) { hb_unlock( f->lock ); return NULL; } } b = f->first; f->first = b->next; b->next = NULL; f->size -= 1; if( f->wait_full && f->size == f->capacity - f->thresh ) { f->wait_full = 0; hb_cond_signal( f->cond_full ); } hb_unlock( f->lock ); return b; }
/* * Current thread has completed its work. Indicate completion, * and if all threads in this task set have completed, wakeup * anyone waiting for this condition. */ void taskset_thread_complete( taskset_t *ts, int thr_idx ) { hb_lock( ts->task_cond_lock ); bit_set( ts->task_complete_bitmap, thr_idx ); if( allbits_set( ts->task_complete_bitmap, ts->bitmap_elements ) ) { hb_cond_signal( ts->task_complete ); } hb_unlock( ts->task_cond_lock ); }
// Pulls a packet out of this FIFO, or returns NULL if no packet is available. hb_buffer_t * hb_fifo_get( hb_fifo_t * f ) { hb_buffer_t * b; hb_lock( f->lock ); if( f->size < 1 ) { hb_unlock( f->lock ); return NULL; } b = f->first; f->first = b->next; b->next = NULL; f->size -= 1; if( f->wait_full && f->size == f->capacity - f->thresh ) { f->wait_full = 0; hb_cond_signal( f->cond_full ); } hb_unlock( f->lock ); return b; }