2 #include "lfds710_queue_bounded_manyproducer_manyconsumer_internal.h"
4 /***** private prototypes *****/
5 static void lfds710_queue_bmm_internal_validate( struct lfds710_queue_bmm_state *qbmms,
6 struct lfds710_misc_validation_info *vi,
7 enum lfds710_misc_validity *lfds710_validity );
13 /****************************************************************************/
14 void lfds710_queue_bmm_query( struct lfds710_queue_bmm_state *qbmms,
15 enum lfds710_queue_bmm_query query_type,
19 LFDS710_PAL_ASSERT( qbmms != NULL );
20 // TRD : query_type can be any value in its range
24 case LFDS710_QUEUE_BMM_QUERY_GET_POTENTIALLY_INACCURATE_COUNT:
30 LFDS710_PAL_ASSERT( query_input == NULL );
31 LFDS710_PAL_ASSERT( query_output != NULL );
33 LFDS710_MISC_BARRIER_LOAD;
35 local_read_index = qbmms->read_index;
36 local_write_index = qbmms->write_index;
38 *(lfds710_pal_uint_t *) query_output = +( local_write_index - local_read_index );
40 if( local_read_index > local_write_index )
41 *(lfds710_pal_uint_t *) query_output = ((lfds710_pal_uint_t) -1) - *(lfds710_pal_uint_t *) query_output;
45 case LFDS710_QUEUE_BMM_QUERY_SINGLETHREADED_VALIDATE:
46 // TRD : query_input can be NULL
47 LFDS710_PAL_ASSERT( query_output != NULL );
49 lfds710_queue_bmm_internal_validate( qbmms, (struct lfds710_misc_validation_info *) query_input, (enum lfds710_misc_validity *) query_output );
60 /****************************************************************************/
61 static void lfds710_queue_bmm_internal_validate( struct lfds710_queue_bmm_state *qbmms,
62 struct lfds710_misc_validation_info *vi,
63 enum lfds710_misc_validity *lfds710_validity )
66 expected_sequence_number,
71 LFDS710_PAL_ASSERT( qbmms != NULL );
72 // TRD : vi can be NULL
73 LFDS710_PAL_ASSERT( lfds710_validity != NULL );
75 *lfds710_validity = LFDS710_MISC_VALIDITY_VALID;
77 /* TRD : starting from the read_index, we should find number_elements of incrementing sequence numbers
78 we then perform a second scan from the write_index onwards, which should have (max elements in queue - number_elements) incrementing sequence numbers
81 lfds710_queue_bmm_query( qbmms, LFDS710_QUEUE_BMM_QUERY_GET_POTENTIALLY_INACCURATE_COUNT, NULL, (void *) &number_elements );
83 expected_sequence_number = qbmms->element_array[ qbmms->read_index & qbmms->mask ].sequence_number;
85 for( loop = 0 ; loop < number_elements ; loop++ )
87 sequence_number = qbmms->element_array[ (qbmms->read_index + loop) & qbmms->mask ].sequence_number;
89 if( sequence_number != expected_sequence_number )
90 *lfds710_validity = LFDS710_MISC_VALIDITY_INVALID_ORDER;
92 if( sequence_number == expected_sequence_number )
93 expected_sequence_number = sequence_number + 1;
96 // TRD : now the write_index onwards
98 expected_sequence_number = qbmms->element_array[ qbmms->write_index & qbmms->mask ].sequence_number;
100 for( loop = 0 ; loop < qbmms->number_elements - number_elements ; loop++ )
102 sequence_number = qbmms->element_array[ (qbmms->write_index + loop) & qbmms->mask ].sequence_number;
104 if( sequence_number != expected_sequence_number )
105 *lfds710_validity = LFDS710_MISC_VALIDITY_INVALID_ORDER;
107 if( sequence_number == expected_sequence_number )
108 expected_sequence_number = sequence_number + 1;
111 // TRD : now check against the expected number of elements
113 if( *lfds710_validity == LFDS710_MISC_VALIDITY_VALID and vi != NULL )
118 lfds710_queue_bmm_query( qbmms, LFDS710_QUEUE_BMM_QUERY_GET_POTENTIALLY_INACCURATE_COUNT, NULL, (void *) &number_elements );
120 if( number_elements < vi->min_elements )
121 *lfds710_validity = LFDS710_MISC_VALIDITY_INVALID_MISSING_ELEMENTS;
123 if( number_elements > vi->max_elements )
124 *lfds710_validity = LFDS710_MISC_VALIDITY_INVALID_ADDITIONAL_ELEMENTS;