Helixis 1.0
Task Programming API
sources/liblfds/queue/queue_query.c
Go to the documentation of this file.
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 */
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines