![]() |
Helixis 1.0
Task Programming API
|
00001 #include "queue_internal.h" 00002 #if defined(HLX_BUILD_WITH_PARALLEL_THREADING) 00003 00004 extern hlx_api gl_api; 00005 00006 00007 00008 /****************************************************************************/ 00009 int queue_new( struct queue_state **qs, atom_t number_elements ) 00010 { 00011 int 00012 rv = 0; 00013 00014 struct queue_element 00015 *qe[QUEUE_PAC_SIZE]; 00016 00017 /* TRD : number_elements can be any value in its range */ 00018 00019 *qs = (struct queue_state *) gl_api.aligned_malloc_entry( sizeof(struct queue_state), ALIGN_DOUBLE_POINTER ); 00020 00021 if( *qs != 0 ) 00022 { 00023 /* TRD : the size of the freelist is the size of the queue (+1 for the leading dummy element, which is hidden from the caller) */ 00024 freelist_new( &(*qs)->fs, number_elements+1, queue_internal_freelist_init_function, 0 ); 00025 00026 if( (*qs)->fs != 0 ) 00027 { 00028 queue_internal_new_element_from_freelist( *qs, qe, 0 ); 00029 (*qs)->enqueue[QUEUE_POINTER] = (*qs)->dequeue[QUEUE_POINTER] = qe[QUEUE_POINTER]; 00030 (*qs)->aba_counter = 0; 00031 rv = 1; 00032 } 00033 00034 if( (*qs)->fs == 0 ) 00035 { 00036 gl_api.aligned_free_entry( *qs ); 00037 *qs = 0; 00038 } 00039 } 00040 00041 return( rv ); 00042 } 00043 00044 00045 00046 00047 00048 /****************************************************************************/ 00049 #pragma warning( disable : 4100 ) 00050 00051 int queue_internal_freelist_init_function( void **user_data, void *user_state ) 00052 { 00053 int 00054 rv = 0; 00055 00056 *user_data = gl_api.aligned_malloc_entry( sizeof(struct queue_element), ALIGN_DOUBLE_POINTER ); 00057 00058 if( *user_data != 0 ) 00059 rv = 1; 00060 00061 return( rv ); 00062 } 00063 00064 #pragma warning( default : 4100 ) 00065 00066 00067 00068 00069 00070 /****************************************************************************/ 00071 void queue_internal_new_element_from_freelist( struct queue_state *qs, struct queue_element *qe[QUEUE_PAC_SIZE], void *user_data ) 00072 { 00073 struct freelist_element 00074 *fe; 00075 00076 /* TRD : user_data can be any value in its range */ 00077 00078 qe[QUEUE_POINTER] = 0; 00079 00080 freelist_pop( qs->fs, &fe ); 00081 00082 if( fe != 0 ) 00083 queue_internal_init_element( qs, qe, fe, user_data ); 00084 00085 return; 00086 } 00087 00088 00089 00090 00091 00092 /****************************************************************************/ 00093 void queue_internal_guaranteed_new_element_from_freelist( struct queue_state *qs, struct queue_element *qe[QUEUE_PAC_SIZE], void *user_data ) 00094 { 00095 struct freelist_element 00096 *fe; 00097 00098 /* TRD : user_data can be any value in its range */ 00099 00100 qe[QUEUE_POINTER] = 0; 00101 00102 freelist_guaranteed_pop( qs->fs, &fe ); 00103 00104 if( fe != 0 ) 00105 queue_internal_init_element( qs, qe, fe, user_data ); 00106 00107 return; 00108 } 00109 00110 00111 00112 00113 00114 /****************************************************************************/ 00115 void queue_internal_init_element( struct queue_state *qs, struct queue_element *qe[QUEUE_PAC_SIZE], struct freelist_element *fe, void *user_data ) 00116 { 00117 /* TRD : user_data can be any value in its range */ 00118 00119 freelist_get_user_data_from_element( fe, (void **) &qe[QUEUE_POINTER] ); 00120 qe[QUEUE_COUNTER] = (struct queue_element *) gl_api.atomic_incr_entry( (atom_t *) &qs->aba_counter ); 00121 00122 qe[QUEUE_POINTER]->next[QUEUE_POINTER] = 0; 00123 qe[QUEUE_POINTER]->next[QUEUE_COUNTER] = (struct queue_element *) gl_api.atomic_incr_entry( (atom_t *) &qs->aba_counter ); 00124 00125 qe[QUEUE_POINTER]->fe = fe; 00126 qe[QUEUE_POINTER]->user_data = user_data; 00127 00128 return; 00129 } 00130 00131 #endif /* !HLX_BUILD_WITH_PARALLEL_THREADING */