![]() |
Helixis 1.0
Task Programming API
|
#include "queue_internal.h"
Go to the source code of this file.
Functions | |
int | queue_enqueue (struct queue_state *qs, void *user_data) |
int | queue_guaranteed_enqueue (struct queue_state *qs, void *user_data) |
void | queue_internal_queue (struct queue_state *qs, struct queue_element *qe[2]) |
int | queue_dequeue (struct queue_state *qs, void **user_data) |
Variables | |
hlx_api | gl_api |
int queue_dequeue | ( | struct queue_state * | qs, |
void ** | user_data | ||
) |
Definition at line 101 of file queue_queue.c.
References ALIGN, ALIGN_DOUBLE_POINTER, and, hlx_api::atomic_dcas_entry, queue_state::dequeue, queue_state::enqueue, queue_element::fe, freelist_push(), queue_state::fs, LOWERED, queue_element::next, QUEUE_COUNTER, QUEUE_PAC_SIZE, QUEUE_POINTER, QUEUE_STATE_ATTEMPT_DEQUEUE, QUEUE_STATE_EMPTY, QUEUE_STATE_ENQUEUE_OUT_OF_PLACE, QUEUE_STATE_UNKNOWN, and RAISED.
Referenced by hlx_group_destruct(), hlx_group_flush_task_buffer(), and queue_delete().
{ ALIGN(ALIGN_DOUBLE_POINTER) struct queue_element *enqueue[QUEUE_PAC_SIZE], *dequeue[QUEUE_PAC_SIZE], *next[QUEUE_PAC_SIZE]; unsigned char cas_result = 0; int rv = 1, state = QUEUE_STATE_UNKNOWN, finished_flag = LOWERED; do { dequeue[QUEUE_POINTER] = qs->dequeue[QUEUE_POINTER]; dequeue[QUEUE_COUNTER] = qs->dequeue[QUEUE_COUNTER]; enqueue[QUEUE_POINTER] = qs->enqueue[QUEUE_POINTER]; enqueue[QUEUE_COUNTER] = qs->enqueue[QUEUE_COUNTER]; next[QUEUE_POINTER] = dequeue[QUEUE_POINTER]->next[QUEUE_POINTER]; next[QUEUE_COUNTER] = dequeue[QUEUE_POINTER]->next[QUEUE_COUNTER]; /* TRD : confirm that dequeue didn't move between reading it and reading its next pointer */ if( dequeue[QUEUE_POINTER] == qs->dequeue[QUEUE_POINTER] and dequeue[QUEUE_COUNTER] == qs->dequeue[QUEUE_COUNTER] ) { if( enqueue[QUEUE_POINTER] == dequeue[QUEUE_POINTER] and next[QUEUE_POINTER] == 0 ) state = QUEUE_STATE_EMPTY; if( enqueue[QUEUE_POINTER] == dequeue[QUEUE_POINTER] and next[QUEUE_POINTER] != 0 ) state = QUEUE_STATE_ENQUEUE_OUT_OF_PLACE; if( enqueue[QUEUE_POINTER] != dequeue[QUEUE_POINTER] ) state = QUEUE_STATE_ATTEMPT_DEQUEUE; switch( state ) { case QUEUE_STATE_EMPTY: *user_data = 0; rv = 0; finished_flag = RAISED; break; case QUEUE_STATE_ENQUEUE_OUT_OF_PLACE: next[QUEUE_COUNTER] = enqueue[QUEUE_COUNTER] + 1; gl_api.atomic_dcas_entry( (volatile atom_t *) qs->enqueue, (atom_t *) next, (atom_t *) enqueue ); break; case QUEUE_STATE_ATTEMPT_DEQUEUE: *user_data = next[QUEUE_POINTER]->user_data; next[QUEUE_COUNTER] = dequeue[QUEUE_COUNTER] + 1; cas_result = gl_api.atomic_dcas_entry( (volatile atom_t *) qs->dequeue, (atom_t *) next, (atom_t *) dequeue ); if( cas_result == 1 ) finished_flag = RAISED; break; } } } while( finished_flag == LOWERED ); if( cas_result == 1 ) freelist_push( qs->fs, dequeue[QUEUE_POINTER]->fe ); return( rv ); }
int queue_enqueue | ( | struct queue_state * | qs, |
void * | user_data | ||
) |
Definition at line 8 of file queue_queue.c.
References ALIGN, ALIGN_DOUBLE_POINTER, queue_internal_new_element_from_freelist(), queue_internal_queue(), QUEUE_PAC_SIZE, and QUEUE_POINTER.
Referenced by hlx_group_bufferize_task().
{ ALIGN(ALIGN_DOUBLE_POINTER) struct queue_element *qe[QUEUE_PAC_SIZE]; /* TRD : user_data can be 0 */ queue_internal_new_element_from_freelist( qs, qe, user_data ); if( qe[QUEUE_POINTER] == 0 ) return( 0 ); queue_internal_queue( qs, qe ); return( 1 ); }
int queue_guaranteed_enqueue | ( | struct queue_state * | qs, |
void * | user_data | ||
) |
Definition at line 30 of file queue_queue.c.
References ALIGN, ALIGN_DOUBLE_POINTER, queue_internal_guaranteed_new_element_from_freelist(), queue_internal_queue(), QUEUE_PAC_SIZE, and QUEUE_POINTER.
Referenced by hlx_group_bufferize_task().
{ ALIGN(ALIGN_DOUBLE_POINTER) struct queue_element *qe[QUEUE_PAC_SIZE]; /* TRD : user_data can be 0 */ queue_internal_guaranteed_new_element_from_freelist( qs, qe, user_data ); if( qe[QUEUE_POINTER] == 0 ) return( 0 ); queue_internal_queue( qs, qe ); return( 1 ); }
void queue_internal_queue | ( | struct queue_state * | qs, |
struct queue_element * | qe[2] | ||
) |
Definition at line 52 of file queue_queue.c.
References ALIGN, ALIGN_DOUBLE_POINTER, and, hlx_api::atomic_dcas_entry, queue_state::enqueue, queue_element::next, QUEUE_COUNTER, QUEUE_PAC_SIZE, and QUEUE_POINTER.
Referenced by queue_enqueue(), and queue_guaranteed_enqueue().
{ ALIGN(ALIGN_DOUBLE_POINTER) struct queue_element *enqueue[QUEUE_PAC_SIZE], *next[QUEUE_PAC_SIZE]; unsigned char cas_result = 0; do { enqueue[QUEUE_POINTER] = qs->enqueue[QUEUE_POINTER]; enqueue[QUEUE_COUNTER] = qs->enqueue[QUEUE_COUNTER]; next[QUEUE_POINTER] = enqueue[QUEUE_POINTER]->next[QUEUE_POINTER]; next[QUEUE_COUNTER] = enqueue[QUEUE_POINTER]->next[QUEUE_COUNTER]; /* TRD : this if() ensures that the next we read, just above, really is from qs->enqueue (which we copied into enqueue) */ if( qs->enqueue[QUEUE_POINTER] == enqueue[QUEUE_POINTER] and qs->enqueue[QUEUE_COUNTER] == enqueue[QUEUE_COUNTER] ) { if( next[QUEUE_POINTER] == 0 ) { qe[QUEUE_COUNTER] = next[QUEUE_COUNTER] + 1; cas_result = gl_api.atomic_dcas_entry( (volatile atom_t *) enqueue[QUEUE_POINTER]->next, (atom_t *) qe, (atom_t *) next ); } else { next[QUEUE_COUNTER] = enqueue[QUEUE_COUNTER] + 1; gl_api.atomic_dcas_entry( (volatile atom_t *) qs->enqueue, (atom_t *) next, (atom_t *) enqueue ); } } } while( cas_result == 0 ); qe[QUEUE_COUNTER] = enqueue[QUEUE_COUNTER] + 1; gl_api.atomic_dcas_entry( (volatile atom_t *) qs->enqueue, (atom_t *) qe, (atom_t *) enqueue ); return; }