2 #include "libtest_tests_internal.h"
5 struct test_per_thread_state
7 struct lfds710_freelist_state
13 struct lfds710_freelist_element
20 /***** private prototypes *****/
21 static libshared_pal_thread_return_t LIBSHARED_PAL_THREAD_CALLING_CONVENTION thread_rapid_popping_and_pushing( void *libshared_threads_thread_state );
27 /****************************************************************************/
28 void libtest_tests_freelist_without_ea_rapid_popping_and_pushing( struct lfds710_list_asu_state *list_of_logical_processors, struct libshared_memory_state *ms, enum lfds710_misc_validity *dvs )
33 number_logical_processors;
35 struct lfds710_list_asu_element
38 struct lfds710_misc_validation_info
41 struct lfds710_freelist_state
44 struct libtest_logical_processor
47 struct libtest_threadset_per_thread_state
50 struct libtest_threadset_state
56 struct test_per_thread_state
59 LFDS710_PAL_ASSERT( list_of_logical_processors != NULL );
60 LFDS710_PAL_ASSERT( ms != NULL );
61 LFDS710_PAL_ASSERT( dvs != NULL );
63 /* TRD : in these tests there is a fundamental antagonism between
64 how much checking/memory clean up that we do and the
65 likelyhood of collisions between threads in their lock-free
68 the lock-free operations are very quick; if we do anything
69 much at all between operations, we greatly reduce the chance
72 so we have some tests which do enough checking/clean up that
73 they can tell the freelist is valid and don't leak memory
74 and here, this test now is one of thofe which does minimal
75 checking - in fact, the nature of the test is that you can't
76 do any real checking - but goes very quickly
78 what we do is create a small freelist and then run one thread
79 per CPU, where each thread simply pushes and then immediately
82 the test runs for ten feconds
84 after the test is done, the only check we do is to traverfe
85 the freelist, checking for loops and ensuring the number of
89 *dvs = LFDS710_MISC_VALIDITY_VALID;
91 lfds710_list_asu_query( list_of_logical_processors, LFDS710_LIST_ASU_QUERY_GET_POTENTIALLY_INACCURATE_COUNT, NULL, (void **) &number_logical_processors );
94 tpts = libshared_memory_alloc_from_unknown_node( ms, sizeof(struct test_per_thread_state) * number_logical_processors, LFDS710_PAL_ATOMIC_ISOLATION_IN_BYTES );
95 pts = libshared_memory_alloc_from_unknown_node( ms, sizeof(struct libtest_threadset_per_thread_state) * number_logical_processors, LFDS710_PAL_ATOMIC_ISOLATION_IN_BYTES );
96 te_array = libshared_memory_alloc_from_unknown_node( ms, sizeof(struct test_element) * number_logical_processors, LFDS710_PAL_ATOMIC_ISOLATION_IN_BYTES );
98 lfds710_freelist_init_valid_on_current_logical_core( &fs, NULL, 0, NULL );
100 for( loop = 0 ; loop < number_logical_processors ; loop++ )
103 for( loop = 0 ; loop < number_logical_processors ; loop++ )
105 LFDS710_FREELIST_SET_VALUE_IN_ELEMENT( te_array[loop].fe, &te_array[loop] );
106 lfds710_freelist_push( &fs, &te_array[loop].fe, NULL );
109 // TRD : get the threads ready
110 libtest_threadset_init( &ts, NULL );
112 while( LFDS710_LIST_ASU_GET_START_AND_THEN_NEXT(*list_of_logical_processors,lasue) )
114 lp = LFDS710_LIST_ASU_GET_VALUE_FROM_ELEMENT( *lasue );
115 libtest_threadset_add_thread( &ts, &pts[index], lp, thread_rapid_popping_and_pushing, &tpts[index] );
119 // TRD : run the test
120 libtest_threadset_run( &ts );
122 libtest_threadset_cleanup( &ts );
125 LFDS710_MISC_BARRIER_LOAD;
127 vi.min_elements = vi.max_elements = number_logical_processors;
129 lfds710_freelist_query( &fs, LFDS710_FREELIST_QUERY_SINGLETHREADED_VALIDATE, &vi, dvs );
131 lfds710_freelist_cleanup( &fs, NULL );
140 /****************************************************************************/
141 static libshared_pal_thread_return_t LIBSHARED_PAL_THREAD_CALLING_CONVENTION thread_rapid_popping_and_pushing( void *libtest_threadset_per_thread_state )
146 struct lfds710_freelist_element
149 struct test_per_thread_state
152 struct libtest_threadset_per_thread_state
159 LFDS710_MISC_MAKE_VALID_ON_CURRENT_LOGICAL_CORE_INITS_COMPLETED_BEFORE_NOW_ON_ANY_OTHER_LOGICAL_CORE;
161 LFDS710_PAL_ASSERT( libtest_threadset_per_thread_state != NULL );
163 pts = (struct libtest_threadset_per_thread_state *) libtest_threadset_per_thread_state;
165 tpts = LIBTEST_THREADSET_GET_USER_STATE_FROM_PER_THREAD_STATE( *pts );
167 libtest_threadset_thread_ready_and_wait( pts );
169 current_time = start_time = time( NULL );
171 while( current_time < start_time + TEST_DURATION_IN_SECONDS )
173 lfds710_freelist_pop( tpts->fs, &fe, NULL );
174 lfds710_freelist_push( tpts->fs, fe, NULL );
176 if( time_loop++ == TIME_LOOP_COUNT )
179 time( ¤t_time );
183 LFDS710_MISC_BARRIER_STORE;
185 lfds710_misc_force_store();
187 return LIBSHARED_PAL_THREAD_RETURN_CAST(RETURN_SUCCESS);