2 #include "libtest_tests_internal.h"
5 struct test_per_thread_state
7 struct lfds710_stack_state
13 struct lfds710_stack_element
20 /***** private prototypes *****/
21 static libshared_pal_thread_return_t LIBSHARED_PAL_THREAD_CALLING_CONVENTION thread_rapid_popping_and_pushing( void *libtest_threadset_per_thread_state );
27 /****************************************************************************/
28 void libtest_tests_stack_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_stack_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 stack is valid and don't leak memory
74 and here, this test now is one of those 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 stack and then run one thread
79 per CPU, where each thread simply pushes and then immediately
82 the test runs for ten seconds
84 after the test is done, the only check we do is to traverse
85 the stack, checking for loops and ensuring the number of
90 lfds710_list_asu_query( list_of_logical_processors, LFDS710_LIST_ASU_QUERY_GET_POTENTIALLY_INACCURATE_COUNT, NULL, (void **) &number_logical_processors );
91 tpts = libshared_memory_alloc_from_unknown_node( ms, sizeof(struct test_per_thread_state) * number_logical_processors, LFDS710_PAL_ATOMIC_ISOLATION_IN_BYTES );
92 pts = libshared_memory_alloc_from_unknown_node( ms, sizeof(struct libtest_threadset_per_thread_state) * number_logical_processors, LFDS710_PAL_ATOMIC_ISOLATION_IN_BYTES );
93 te_array = libshared_memory_alloc_from_unknown_node( ms, sizeof(struct test_element) * number_logical_processors, LFDS710_PAL_ATOMIC_ISOLATION_IN_BYTES );
95 lfds710_stack_init_valid_on_current_logical_core( &ss, NULL );
97 for( loop = 0 ; loop < number_logical_processors ; loop++ )
100 for( loop = 0 ; loop < number_logical_processors ; loop++ )
102 LFDS710_STACK_SET_VALUE_IN_ELEMENT( te_array[loop].se, &te_array[loop] );
103 lfds710_stack_push( &ss, &te_array[loop].se );
106 // TRD : get the threads ready
107 libtest_threadset_init( &ts, NULL );
109 while( LFDS710_LIST_ASU_GET_START_AND_THEN_NEXT(*list_of_logical_processors,lasue) )
111 lp = LFDS710_LIST_ASU_GET_VALUE_FROM_ELEMENT( *lasue );
112 libtest_threadset_add_thread( &ts, &pts[index], lp, thread_rapid_popping_and_pushing, &tpts[index] );
116 // TRD : run the test
117 libtest_threadset_run( &ts );
119 libtest_threadset_cleanup( &ts );
122 LFDS710_MISC_BARRIER_LOAD;
124 vi.min_elements = vi.max_elements = number_logical_processors;
126 lfds710_stack_query( &ss, LFDS710_STACK_QUERY_SINGLETHREADED_VALIDATE, &vi, dvs );
128 lfds710_stack_cleanup( &ss, NULL );
137 /****************************************************************************/
138 static libshared_pal_thread_return_t LIBSHARED_PAL_THREAD_CALLING_CONVENTION thread_rapid_popping_and_pushing( void *libtest_threadset_per_thread_state )
143 struct lfds710_stack_element
146 struct libtest_threadset_per_thread_state
149 struct test_per_thread_state
156 LFDS710_MISC_MAKE_VALID_ON_CURRENT_LOGICAL_CORE_INITS_COMPLETED_BEFORE_NOW_ON_ANY_OTHER_LOGICAL_CORE;
158 LFDS710_PAL_ASSERT( libtest_threadset_per_thread_state != NULL );
160 pts = (struct libtest_threadset_per_thread_state *) libtest_threadset_per_thread_state;
161 tpts = LIBTEST_THREADSET_GET_USER_STATE_FROM_PER_THREAD_STATE( *pts );
163 libtest_threadset_thread_ready_and_wait( pts );
165 current_time = start_time = time( NULL );
167 while( current_time < start_time + TEST_DURATION_IN_SECONDS )
169 lfds710_stack_pop( tpts->ss, &se );
170 lfds710_stack_push( tpts->ss, se );
172 if( time_loop++ == TIME_LOOP_COUNT )
175 time( ¤t_time );
179 LFDS710_MISC_BARRIER_STORE;
181 lfds710_misc_force_store();
183 return LIBSHARED_PAL_THREAD_RETURN_CAST(RETURN_SUCCESS);