![]() |
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;
}
1.7.4