5 struct test_lfds700_pal_atomic_dwcas_state
10 lfds700_pal_atom_t volatile
14 /***** private prototyps *****/
15 static test_pal_thread_return_t TEST_PAL_CALLING_CONVENTION thread_dwcas( void *util_thread_starter_thread_state );
21 /****************************************************************************/
22 void test_lfds700_pal_atomic_dwcas( struct lfds700_list_asu_state *list_of_logical_processors )
27 number_logical_processors;
29 lfds700_pal_atom_t volatile LFDS700_PAL_ALIGN(LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES)
30 shared_counter[2] = { 0, 0 };
32 struct lfds700_list_asu_element
35 struct test_pal_logical_processor
38 struct util_thread_starter_state
41 struct test_lfds700_pal_atomic_dwcas_state
44 test_pal_thread_state_t
47 assert( list_of_logical_processors != NULL );
49 /* TRD : here we test pal_dwcas
51 we run one thread per CPU
52 we use pal_dwcas() to increment a shared counter
53 every time a thread successfully increments the counter,
54 it increments a thread local counter
55 the threads run for ten seconds
56 after the threads finish, we total the local counters
57 they should equal the shared counter
60 internal_display_test_name( "Atomic DWCAS" );
62 lfds700_list_asu_query( list_of_logical_processors, LFDS700_LIST_ASU_QUERY_GET_POTENTIALLY_INACCURATE_COUNT, NULL, (void **) &number_logical_processors );
64 atds = util_malloc_wrapper( sizeof(struct test_lfds700_pal_atomic_dwcas_state) * number_logical_processors );
66 for( loop = 0 ; loop < number_logical_processors ; loop++ )
68 (atds+loop)->shared_counter = &shared_counter;
69 (atds+loop)->local_counter = 0;
72 thread_handles = util_malloc_wrapper( sizeof(test_pal_thread_state_t) * number_logical_processors );
74 util_thread_starter_new( &tts, number_logical_processors );
76 LFDS700_MISC_BARRIER_STORE;
78 lfds700_misc_force_store();
83 while( LFDS700_LIST_ASU_GET_START_AND_THEN_NEXT(*list_of_logical_processors, lasue) )
85 lp = LFDS700_LIST_ASU_GET_VALUE_FROM_ELEMENT( *lasue );
86 util_thread_starter_start( tts, &thread_handles[loop], loop, lp, thread_dwcas, atds+loop );
90 util_thread_starter_run( tts );
92 for( loop = 0 ; loop < number_logical_processors ; loop++ )
93 test_pal_thread_wait( thread_handles[loop] );
95 util_thread_starter_delete( tts );
97 free( thread_handles );
100 LFDS700_MISC_BARRIER_LOAD;
102 for( loop = 0 ; loop < number_logical_processors ; loop++ )
103 local_total += (atds+loop)->local_counter;
105 if( local_total == shared_counter[0] )
108 if( local_total != shared_counter[0] )
110 printf( "%llu != %llu\n", (int long long unsigned) local_total, (int long long unsigned) shared_counter[0] );
112 exit( EXIT_FAILURE );
121 #pragma warning( disable : 4702 )
127 /****************************************************************************/
128 static test_pal_thread_return_t TEST_PAL_CALLING_CONVENTION thread_dwcas( void *util_thread_starter_thread_state )
136 lfds700_pal_atom_t LFDS700_PAL_ALIGN(LFDS700_PAL_ALIGN_DOUBLE_POINTER)
140 struct test_lfds700_pal_atomic_dwcas_state
143 struct util_thread_starter_thread_state
146 assert( util_thread_starter_thread_state != NULL );
148 tsts = (struct util_thread_starter_thread_state *) util_thread_starter_thread_state;
149 atds = (struct test_lfds700_pal_atomic_dwcas_state *) tsts->thread_user_state;
151 LFDS700_MISC_BARRIER_LOAD;
153 util_thread_starter_ready_and_wait( tsts );
155 while( loop++ < 10000000 )
157 compare[0] = (*atds->shared_counter)[0];
158 compare[1] = (*atds->shared_counter)[1];
162 exchange[0] = compare[0] + 1;
163 exchange[1] = compare[1];
164 LFDS700_PAL_ATOMIC_DWCAS( atds->shared_counter, compare, exchange, LFDS700_MISC_CAS_STRENGTH_WEAK, result );
166 while( result == 0 );
168 atds->local_counter++;
171 LFDS700_MISC_BARRIER_STORE;
173 lfds700_misc_force_store();
175 return( (test_pal_thread_return_t) EXIT_SUCCESS );