7 struct lfds700_freelist_state
13 struct lfds700_freelist_element
20 /***** private prototypes *****/
21 static test_pal_thread_return_t TEST_PAL_CALLING_CONVENTION thread_popping( void *util_thread_starter_thread_state );
27 /****************************************************************************/
28 void test_lfds700_freelist_popping( struct lfds700_list_asu_state *list_of_logical_processors, lfds700_pal_uint_t memory_in_megabytes )
30 enum lfds700_misc_validity
31 dvs = LFDS700_MISC_VALIDITY_VALID;
36 number_logical_processors;
38 struct lfds700_list_asu_element
41 struct lfds700_freelist_state
44 struct lfds700_misc_prng_state
47 struct lfds700_misc_validation_info
50 struct test_pal_logical_processor
53 struct util_thread_starter_state
62 test_pal_thread_state_t
65 assert( list_of_logical_processors != NULL );
66 // TRD : memory_in_megabytes can be any value in its range
68 /* TRD : we create a freelist with 1,000,000 elements
70 the creation function runs in a single thread and creates
71 and pushes those elements onto the freelist
73 each element contains a void pointer to the container test element
75 we then run one thread per CPU
76 where each thread loops, popping as quickly as possible
77 each test element has a flag which indicates it has been popped
79 the threads run till the source freelist is empty
81 we then check the test elements
82 every element should have been popped
86 we have no extra code for CAS/GC as we're only popping
89 internal_display_test_name( "Popping" );
91 lfds700_list_asu_query( list_of_logical_processors, LFDS700_LIST_ASU_QUERY_GET_POTENTIALLY_INACCURATE_COUNT, NULL, (void **) &number_logical_processors );
93 lfds700_misc_prng_init( &ps );
95 lfds700_freelist_init_valid_on_current_logical_core( &fs, NULL );
97 number_elements = ( memory_in_megabytes * ONE_MEGABYTE_IN_BYTES ) / sizeof(struct test_element);
99 te_array = util_aligned_malloc( sizeof(struct test_element) * number_elements, LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES );
101 for( loop = 0 ; loop < number_elements ; loop++ )
103 (te_array+loop)->popped_flag = LOWERED;
104 LFDS700_FREELIST_SET_VALUE_IN_ELEMENT( (te_array+loop)->fe, te_array+loop );
105 lfds700_freelist_push( &fs, &(te_array+loop)->fe, &ps );
108 ts = util_aligned_malloc( sizeof(struct test_state) * number_logical_processors, LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES );
110 for( loop = 0 ; loop < number_logical_processors ; loop++ )
113 thread_handles = util_malloc_wrapper( sizeof(test_pal_thread_state_t) * number_logical_processors );
115 util_thread_starter_new( &tts, number_logical_processors );
117 LFDS700_MISC_BARRIER_STORE;
119 lfds700_misc_force_store();
124 while( LFDS700_LIST_ASU_GET_START_AND_THEN_NEXT(*list_of_logical_processors, lasue) )
126 lp = LFDS700_LIST_ASU_GET_VALUE_FROM_ELEMENT( *lasue );
127 util_thread_starter_start( tts, &thread_handles[loop], loop, lp, thread_popping, ts+loop );
131 util_thread_starter_run( tts );
133 for( loop = 0 ; loop < number_logical_processors ; loop++ )
134 test_pal_thread_wait( thread_handles[loop] );
136 util_thread_starter_delete( tts );
138 free( thread_handles );
140 LFDS700_MISC_BARRIER_LOAD;
142 lfds700_freelist_query( &fs, LFDS700_FREELIST_QUERY_SINGLETHREADED_VALIDATE, &vi, &dvs );
144 // TRD : now we check each element has popped_flag set to RAISED
145 for( loop = 0 ; loop < number_elements ; loop++ )
146 if( (te_array+loop)->popped_flag == LOWERED )
147 dvs = LFDS700_MISC_VALIDITY_INVALID_TEST_DATA;
150 lfds700_freelist_cleanup( &fs, NULL );
151 util_aligned_free( ts );
152 util_aligned_free( te_array );
154 // TRD : print the test result
155 internal_display_test_result( 1, "freelist", dvs );
164 /****************************************************************************/
165 static test_pal_thread_return_t TEST_PAL_CALLING_CONVENTION thread_popping( void *util_thread_starter_thread_state )
167 struct lfds700_freelist_element
170 struct lfds700_misc_prng_state
179 struct util_thread_starter_thread_state
182 LFDS700_MISC_MAKE_VALID_ON_CURRENT_LOGICAL_CORE_INITS_COMPLETED_BEFORE_NOW_ON_ANY_OTHER_LOGICAL_CORE;
184 assert( util_thread_starter_thread_state != NULL );
186 tsts = (struct util_thread_starter_thread_state *) util_thread_starter_thread_state;
187 ts = (struct test_state *) tsts->thread_user_state;
189 lfds700_misc_prng_init( &ps );
191 util_thread_starter_ready_and_wait( tsts );
193 while( lfds700_freelist_pop(ts->fs, &fe, &ps) )
195 te = LFDS700_FREELIST_GET_VALUE_FROM_ELEMENT( *fe );
196 te->popped_flag = RAISED;
199 LFDS700_MISC_BARRIER_STORE;
201 lfds700_misc_force_store();
203 return( (test_pal_thread_return_t) EXIT_SUCCESS );