![]() |
Helixis 1.0
Task Programming API
|
00001 #include "queue_internal.h" 00002 #if defined(HLX_BUILD_WITH_PARALLEL_THREADING) 00003 00004 00005 00006 00007 /****************************************************************************/ 00008 #pragma warning( disable : 4100 ) 00009 00010 void queue_query( struct queue_state *qs, enum queue_query_type query_type, void *query_input, void *query_output ) 00011 { 00012 /* TRD : query_type can be any value in its range */ 00013 /* TRD : query_input can be 0 */ 00014 00015 switch( query_type ) 00016 { 00017 case QUEUE_QUERY_ELEMENT_COUNT: 00018 freelist_query( qs->fs, FREELIST_QUERY_ELEMENT_COUNT, 0, query_output ); 00019 break; 00020 00021 case QUEUE_QUERY_VALIDATE: 00022 /* TRD : query_input can be 0 */ 00023 00024 queue_internal_validate( qs, (struct validation_info *) query_input, (enum data_structure_validity *) query_output, ((enum data_structure_validity *) query_output)+1 ); 00025 break; 00026 } 00027 00028 return; 00029 } 00030 00031 #pragma warning( default : 4100 ) 00032 00033 00034 00035 00036 00037 /****************************************************************************/ 00038 void queue_internal_validate( struct queue_state *qs, struct validation_info *vi, enum data_structure_validity *queue_validity, enum data_structure_validity *freelist_validity ) 00039 { 00040 struct queue_element 00041 *qe, 00042 *qe_slow, 00043 *qe_fast; 00044 00045 atom_t 00046 element_count = 0, 00047 total_elements; 00048 00049 struct validation_info 00050 freelist_vi; 00051 00052 /* TRD : vi can be 0 */ 00053 *queue_validity = VALIDITY_VALID; 00054 00055 qe_slow = qe_fast = (struct queue_element *) qs->dequeue[QUEUE_POINTER]; 00056 00057 /* TRD : first, check for a loop 00058 we have two pointers 00059 both of which start at the dequeue end of the queue 00060 we enter a loop 00061 and on each iteration 00062 we advance one pointer by one element 00063 and the other by two 00064 00065 we exit the loop when both pointers are 0 00066 (have reached the end of the queue) 00067 00068 or 00069 00070 if we fast pointer 'sees' the slow pointer 00071 which means we have a loop 00072 */ 00073 00074 if( qe_slow != 0 ) 00075 do 00076 { 00077 qe_slow = qe_slow->next[QUEUE_POINTER]; 00078 00079 if( qe_fast != 0 ) 00080 qe_fast = qe_fast->next[QUEUE_POINTER]; 00081 00082 if( qe_fast != 0 ) 00083 qe_fast = qe_fast->next[QUEUE_POINTER]; 00084 } 00085 while( qe_slow != 0 and qe_fast != qe_slow ); 00086 00087 if( qe_fast != 0 and qe_slow != 0 and qe_fast == qe_slow ) 00088 *queue_validity = VALIDITY_INVALID_LOOP; 00089 00090 /* TRD : now check for expected number of elements 00091 vi can be 0, in which case we do not check 00092 we know we don't have a loop from our earlier check 00093 */ 00094 00095 if( *queue_validity == VALIDITY_VALID and vi != 0 ) 00096 { 00097 qe = (struct queue_element *) qs->dequeue[QUEUE_POINTER]; 00098 00099 while( qe != 0 ) 00100 { 00101 element_count++; 00102 qe = (struct queue_element *) qe->next[QUEUE_POINTER]; 00103 } 00104 00105 /* TRD : remember there is a dummy element in the queue */ 00106 element_count--; 00107 00108 if( element_count < vi->min_elements ) 00109 *queue_validity = VALIDITY_INVALID_MISSING_ELEMENTS; 00110 00111 if( element_count > vi->max_elements ) 00112 *queue_validity = VALIDITY_INVALID_ADDITIONAL_ELEMENTS; 00113 } 00114 00115 /* TRD : now we validate the freelist 00116 00117 we may be able to check for the expected number of 00118 elements in the freelist 00119 00120 if the caller has given us an expected min and max 00121 number of elements in the queue, then the total number 00122 of elements in the freelist, minus that min and max, 00123 gives us the expected number of elements in the 00124 freelist 00125 */ 00126 00127 if( vi != 0 ) 00128 { 00129 freelist_query( qs->fs, FREELIST_QUERY_ELEMENT_COUNT, 0, (void *) &total_elements ); 00130 00131 /* TRD : remember there is a dummy element in the queue */ 00132 total_elements--; 00133 00134 freelist_vi.min_elements = total_elements - vi->max_elements; 00135 freelist_vi.max_elements = total_elements - vi->min_elements; 00136 00137 freelist_query( qs->fs, FREELIST_QUERY_VALIDATE, (void *) &freelist_vi, (void *) freelist_validity ); 00138 } 00139 00140 if( vi == 0 ) 00141 freelist_query( qs->fs, FREELIST_QUERY_VALIDATE, 0, (void *) freelist_validity ); 00142 00143 return; 00144 } 00145 00146 #endif /* !HLX_BUILD_WITH_PARALLEL_THREADING */