1 #include "lfds600_queue_internal.h"
7 /****************************************************************************/
8 #pragma warning( disable : 4100 )
10 void lfds600_queue_query( struct lfds600_queue_state *qs, enum lfds600_queue_query_type query_type, void *query_input, void *query_output )
13 // TRD : query_type can be any value in its range
14 // TRD : query_input can be NULL
15 assert( query_output != NULL );
19 case LFDS600_QUEUE_QUERY_ELEMENT_COUNT:
20 assert( query_input == NULL );
22 lfds600_freelist_query( qs->fs, LFDS600_FREELIST_QUERY_ELEMENT_COUNT, NULL, query_output );
25 case LFDS600_QUEUE_QUERY_VALIDATE:
26 // TRD : query_input can be NULL
28 lfds600_queue_internal_validate( qs, (struct lfds600_validation_info *) query_input, (enum data_structure_validity *) query_output, ((enum data_structure_validity *) query_output)+1 );
35 #pragma warning( default : 4100 )
41 /****************************************************************************/
42 void lfds600_queue_internal_validate( struct lfds600_queue_state *qs, struct lfds600_validation_info *vi, enum data_structure_validity *lfds600_queue_validity, enum data_structure_validity *lfds600_freelist_validity )
44 struct lfds600_queue_element
53 struct lfds600_validation_info
57 // TRD : vi can be NULL
58 assert( lfds600_queue_validity != NULL );
59 assert( lfds600_freelist_validity != NULL );
61 *lfds600_queue_validity = VALIDITY_VALID;
63 qe_slow = qe_fast = (struct lfds600_queue_element *) qs->dequeue[LFDS600_QUEUE_POINTER];
65 /* TRD : first, check for a loop
67 both of which start at the dequeue end of the lfds600_queue
70 we advance one pointer by one element
73 we exit the loop when both pointers are NULL
74 (have reached the end of the lfds600_queue)
78 if we fast pointer 'sees' the slow pointer
79 which means we have a loop
85 qe_slow = qe_slow->next[LFDS600_QUEUE_POINTER];
88 qe_fast = qe_fast->next[LFDS600_QUEUE_POINTER];
91 qe_fast = qe_fast->next[LFDS600_QUEUE_POINTER];
93 while( qe_slow != NULL and qe_fast != qe_slow );
95 if( qe_fast != NULL and qe_slow != NULL and qe_fast == qe_slow )
96 *lfds600_queue_validity = VALIDITY_INVALID_LOOP;
98 /* TRD : now check for expected number of elements
99 vi can be NULL, in which case we do not check
100 we know we don't have a loop from our earlier check
103 if( *lfds600_queue_validity == VALIDITY_VALID and vi != NULL )
105 qe = (struct lfds600_queue_element *) qs->dequeue[LFDS600_QUEUE_POINTER];
110 qe = (struct lfds600_queue_element *) qe->next[LFDS600_QUEUE_POINTER];
113 /* TRD : remember there is a dummy element in the lfds600_queue */
116 if( element_count < vi->min_elements )
117 *lfds600_queue_validity = VALIDITY_INVALID_MISSING_ELEMENTS;
119 if( element_count > vi->max_elements )
120 *lfds600_queue_validity = VALIDITY_INVALID_ADDITIONAL_ELEMENTS;
123 /* TRD : now we validate the lfds600_freelist
125 we may be able to check for the expected number of
126 elements in the lfds600_freelist
128 if the caller has given us an expected min and max
129 number of elements in the lfds600_queue, then the total number
130 of elements in the lfds600_freelist, minus that min and max,
131 gives us the expected number of elements in the
137 lfds600_freelist_query( qs->fs, LFDS600_FREELIST_QUERY_ELEMENT_COUNT, NULL, (void *) &total_elements );
139 /* TRD : remember there is a dummy element in the lfds600_queue */
142 lfds600_freelist_vi.min_elements = total_elements - vi->max_elements;
143 lfds600_freelist_vi.max_elements = total_elements - vi->min_elements;
145 lfds600_freelist_query( qs->fs, LFDS600_FREELIST_QUERY_VALIDATE, (void *) &lfds600_freelist_vi, (void *) lfds600_freelist_validity );
149 lfds600_freelist_query( qs->fs, LFDS600_FREELIST_QUERY_VALIDATE, NULL, (void *) lfds600_freelist_validity );