5 struct test_lfds700_pal_atomic_cas_state
10 lfds700_pal_atom_t volatile
14 /***** private prototyps *****/
15 static test_pal_thread_return_t TEST_PAL_CALLING_CONVENTION thread_cas( void *util_thread_starter_thread_state );
21 /****************************************************************************/
22 void test_lfds700_pal_atomic_cas( struct lfds700_list_asu_state *list_of_logical_processors )
24 lfds700_pal_atom_t volatile LFDS700_PAL_ALIGN(LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES)
32 number_logical_processors;
34 struct lfds700_list_asu_element
37 struct test_pal_logical_processor
40 struct util_thread_starter_state
43 struct test_lfds700_pal_atomic_cas_state
46 test_pal_thread_state_t
49 assert( list_of_logical_processors != NULL );
51 /* TRD : here we test pal_cas
53 we run one thread per CPU
54 we use pal_cas() to increment a shared counter
55 every time a thread successfully increments the counter,
56 it increments a thread local counter
57 the threads run for ten seconds
58 after the threads finish, we total the local counters
59 they should equal the shared counter
62 internal_display_test_name( "Atomic CAS" );
64 lfds700_list_asu_query( list_of_logical_processors, LFDS700_LIST_ASU_QUERY_GET_POTENTIALLY_INACCURATE_COUNT, NULL, (void **) &number_logical_processors );
68 atcs = util_malloc_wrapper( sizeof(struct test_lfds700_pal_atomic_cas_state) * number_logical_processors );
70 for( loop = 0 ; loop < number_logical_processors ; loop++ )
72 (atcs+loop)->shared_counter = &shared_counter;
73 (atcs+loop)->local_counter = 0;
76 thread_handles = util_malloc_wrapper( sizeof(test_pal_thread_state_t) * number_logical_processors );
78 util_thread_starter_new( &tts, number_logical_processors );
80 LFDS700_MISC_BARRIER_STORE;
82 lfds700_misc_force_store();
87 while( LFDS700_LIST_ASU_GET_START_AND_THEN_NEXT(*list_of_logical_processors, lasue) )
89 lp = LFDS700_LIST_ASU_GET_VALUE_FROM_ELEMENT( *lasue );
90 util_thread_starter_start( tts, &thread_handles[loop], loop, lp, thread_cas, atcs+loop );
94 util_thread_starter_run( tts );
96 for( loop = 0 ; loop < number_logical_processors ; loop++ )
97 test_pal_thread_wait( thread_handles[loop] );
99 util_thread_starter_delete( tts );
101 free( thread_handles );
104 LFDS700_MISC_BARRIER_LOAD;
106 for( loop = 0 ; loop < number_logical_processors ; loop++ )
107 local_total += (atcs+loop)->local_counter;
109 if( local_total == shared_counter )
112 if( local_total != shared_counter )
115 exit( EXIT_FAILURE );
128 /****************************************************************************/
129 static test_pal_thread_return_t TEST_PAL_CALLING_CONVENTION thread_cas( void *util_thread_starter_thread_state )
137 lfds700_pal_atom_t LFDS700_PAL_ALIGN(LFDS700_PAL_ALIGN_SINGLE_POINTER)
141 struct test_lfds700_pal_atomic_cas_state
144 struct util_thread_starter_thread_state
147 LFDS700_MISC_BARRIER_LOAD;
149 assert( util_thread_starter_thread_state != NULL );
151 tsts = (struct util_thread_starter_thread_state *) util_thread_starter_thread_state;
152 atcs = (struct test_lfds700_pal_atomic_cas_state *) tsts->thread_user_state;
154 util_thread_starter_ready_and_wait( tsts );
156 while( loop++ < 10000000 )
158 compare = *atcs->shared_counter;
162 exchange = compare + 1;
163 LFDS700_PAL_ATOMIC_CAS( atcs->shared_counter, &compare, exchange, LFDS700_MISC_CAS_STRENGTH_WEAK, result );
165 while( result == 0 );
167 atcs->local_counter++;
170 LFDS700_MISC_BARRIER_STORE;
172 lfds700_misc_force_store();
174 return( (test_pal_thread_return_t) EXIT_SUCCESS );