10 struct lfds700_queue_bss_state
14 /***** private prototypes *****/
15 static test_pal_thread_return_t TEST_PAL_CALLING_CONVENTION thread_enqueuer( void *util_thread_starter_thread_state );
16 static test_pal_thread_return_t TEST_PAL_CALLING_CONVENTION thread_dequeuer( void *util_thread_starter_thread_state );
22 /****************************************************************************/
23 void test_lfds700_queue_bss_enqueuing_and_dequeuing( struct lfds700_list_asu_state *list_of_logical_processors )
25 enum lfds700_misc_validity
26 dvs = LFDS700_MISC_VALIDITY_VALID;
30 number_logical_processors,
33 struct lfds700_list_asu_element
36 struct lfds700_queue_bss_element
39 struct lfds700_queue_bss_state
42 struct test_pal_logical_processor
46 struct util_thread_starter_state
52 test_pal_thread_state_t
55 assert( list_of_logical_processors != NULL );
57 /* TRD : so, this is the real test
58 problem is, because we use memory barriers only
59 and we only support one producer and one consumer
60 we need to ensure these threads are on different physical cores
61 if they're on the same core, the code would work even without memory barriers
63 problem is, in the test application, we only know the *number* of logical cores
64 obtaining topology information adds a great deal of complexity to the test app
65 and makes porting much harder
67 so, we know how many logical cores there are; my thought is to partially
68 permutate over them - we always run the producer on core 0, but we iterate
69 over the other logical cores, running the test once each time, with the
70 consumer being run on core 0, then core 1, then core 2, etc
72 (we run on core 0 for the single-cpu case; it's redundent, since a single
73 logical core running both producer and consumer will work, but otherwise
74 we have to skip the test, which is confusing for the user)
76 the test is one thread enqueuing and one thread dequeuing for two seconds
79 lfds700_list_asu_query( list_of_logical_processors, LFDS700_LIST_ASU_QUERY_GET_POTENTIALLY_INACCURATE_COUNT, NULL, (void **) &number_logical_processors );
81 internal_display_test_name( "Enqueuing and dequeuing (%d seconds)", number_logical_processors * 2 );
83 ts = util_malloc_wrapper( sizeof(struct test_state) * 2 );
85 for( loop = 0 ; loop < 2 ; loop++ )
88 (ts+loop)->error_flag = LOWERED;
91 thread_handles = util_malloc_wrapper( sizeof(test_pal_thread_state_t) * 2 );
93 /* TRD : producer always on core 0
94 iterate over the other cores with consumer
97 lasue = LFDS700_LIST_ASU_GET_START( *list_of_logical_processors );
98 lp_first = LFDS700_LIST_ASU_GET_VALUE_FROM_ELEMENT( *lasue );
100 while( lasue != NULL )
102 lp = LFDS700_LIST_ASU_GET_VALUE_FROM_ELEMENT( *lasue );
104 lfds700_queue_bss_init_valid_on_current_logical_core( &qs, element_array, 4, NULL );
106 util_thread_starter_new( &tts, 2 );
108 LFDS700_MISC_BARRIER_STORE;
110 lfds700_misc_force_store();
112 util_thread_starter_start( tts, &thread_handles[0], 0, lp_first, thread_enqueuer, ts );
113 util_thread_starter_start( tts, &thread_handles[1], 1, lp, thread_dequeuer, ts+1 );
115 util_thread_starter_run( tts );
117 for( subloop = 0 ; subloop < 2 ; subloop++ )
118 test_pal_thread_wait( thread_handles[subloop] );
120 util_thread_starter_delete( tts );
122 LFDS700_MISC_BARRIER_LOAD;
124 lfds700_queue_bss_cleanup( &qs, NULL );
126 lasue = LFDS700_LIST_ASU_GET_NEXT( *lasue );
129 if( (ts+1)->error_flag == RAISED )
130 dvs = LFDS700_MISC_VALIDITY_INVALID_TEST_DATA;
132 free( thread_handles );
136 internal_display_test_result( 1, "queue_bss", dvs );
145 /****************************************************************************/
146 static test_pal_thread_return_t TEST_PAL_CALLING_CONVENTION thread_enqueuer( void *util_thread_starter_thread_state )
158 struct util_thread_starter_thread_state
165 LFDS700_MISC_MAKE_VALID_ON_CURRENT_LOGICAL_CORE_INITS_COMPLETED_BEFORE_NOW_ON_ANY_OTHER_LOGICAL_CORE;
167 assert( util_thread_starter_thread_state != NULL );
169 tsts = (struct util_thread_starter_thread_state *) util_thread_starter_thread_state;
170 ts = (struct test_state *) tsts->thread_user_state;
172 util_thread_starter_ready_and_wait( tsts );
174 current_time = start_time = time( NULL );
176 while( current_time < start_time + 2 )
178 rv = lfds700_queue_bss_enqueue( ts->qs, NULL, (void *) datum );
184 if( time_loop++ == TIME_LOOP_COUNT )
187 time( ¤t_time );
191 LFDS700_MISC_BARRIER_STORE;
193 lfds700_misc_force_store();
195 return( (test_pal_thread_return_t) EXIT_SUCCESS );
202 /****************************************************************************/
203 static test_pal_thread_return_t TEST_PAL_CALLING_CONVENTION thread_dequeuer( void *util_thread_starter_thread_state )
216 struct util_thread_starter_thread_state
223 LFDS700_MISC_BARRIER_LOAD;
225 assert( util_thread_starter_thread_state != NULL );
227 tsts = (struct util_thread_starter_thread_state *) util_thread_starter_thread_state;
228 ts = (struct test_state *) tsts->thread_user_state;
230 util_thread_starter_ready_and_wait( tsts );
232 current_time = start_time = time( NULL );
234 while( current_time < start_time + 2 )
236 rv = lfds700_queue_bss_dequeue( ts->qs, NULL, (void *) &datum );
240 if( datum != expected_datum )
241 ts->error_flag = RAISED;
243 if( ++expected_datum == 4 )
247 if( time_loop++ == TIME_LOOP_COUNT )
250 time( ¤t_time );
254 LFDS700_MISC_BARRIER_STORE;
256 lfds700_misc_force_store();
258 return( (test_pal_thread_return_t) EXIT_SUCCESS );