2 #include "libtest_tests_internal.h"
5 struct libtest_tests_pal_atomic_dwcas_state
10 lfds710_pal_uint_t volatile
14 /***** private prototyps *****/
15 static libshared_pal_thread_return_t LIBSHARED_PAL_THREAD_CALLING_CONVENTION thread_dwcas( void *libtest_threadset_per_thread_state );
21 /****************************************************************************/
22 void libtest_tests_pal_atomic_dwcas( struct lfds710_list_asu_state *list_of_logical_processors, struct libshared_memory_state *ms, enum lfds710_misc_validity *dvs )
27 number_logical_processors;
29 lfds710_pal_uint_t volatile LFDS710_PAL_ALIGN(LFDS710_PAL_ATOMIC_ISOLATION_IN_BYTES)
30 shared_counter[2] = { 0, 0 };
32 struct lfds710_list_asu_element
35 struct libtest_logical_processor
38 struct libtest_threadset_per_thread_state
41 struct libtest_threadset_state
44 struct libtest_tests_pal_atomic_dwcas_state
47 LFDS710_PAL_ASSERT( list_of_logical_processors != NULL );
48 LFDS710_PAL_ASSERT( ms != NULL );
49 LFDS710_PAL_ASSERT( dvs != NULL );
51 /* TRD : here we test pal_dwcas
53 we run one thread per CPU
54 we use pal_dwcas() 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 lfds710_list_asu_query( list_of_logical_processors, LFDS710_LIST_ASU_QUERY_GET_POTENTIALLY_INACCURATE_COUNT, NULL, (void **) &number_logical_processors );
63 pts = libshared_memory_alloc_from_unknown_node( ms, sizeof(struct libtest_threadset_per_thread_state) * number_logical_processors, LFDS710_PAL_ATOMIC_ISOLATION_IN_BYTES );
64 atds = libshared_memory_alloc_from_unknown_node( ms, sizeof(struct libtest_tests_pal_atomic_dwcas_state) * number_logical_processors, LFDS710_PAL_ATOMIC_ISOLATION_IN_BYTES );
66 for( loop = 0 ; loop < number_logical_processors ; loop++ )
68 (atds+loop)->shared_counter = &shared_counter;
69 (atds+loop)->local_counter = 0;
72 libtest_threadset_init( &ts, NULL );
76 while( LFDS710_LIST_ASU_GET_START_AND_THEN_NEXT(*list_of_logical_processors, lasue) )
78 lp = LFDS710_LIST_ASU_GET_VALUE_FROM_ELEMENT( *lasue );
79 libtest_threadset_add_thread( &ts, &pts[loop], lp, thread_dwcas, atds+loop );
83 LFDS710_MISC_BARRIER_STORE;
85 lfds710_misc_force_store();
88 libtest_threadset_run( &ts );
90 libtest_threadset_cleanup( &ts );
93 LFDS710_MISC_BARRIER_LOAD;
95 for( loop = 0 ; loop < number_logical_processors ; loop++ )
96 local_total += (atds+loop)->local_counter;
98 if( local_total == shared_counter[0] )
99 *dvs = LFDS710_MISC_VALIDITY_VALID;
101 if( local_total != shared_counter[0] )
102 *dvs = LFDS710_MISC_VALIDITY_INVALID_TEST_DATA;
107 #pragma warning( disable : 4702 )
113 /****************************************************************************/
114 static libshared_pal_thread_return_t LIBSHARED_PAL_THREAD_CALLING_CONVENTION thread_dwcas( void *libtest_threadset_per_thread_state )
122 lfds710_pal_uint_t LFDS710_PAL_ALIGN(LFDS710_PAL_ALIGN_DOUBLE_POINTER)
126 struct libtest_tests_pal_atomic_dwcas_state
129 struct libtest_threadset_per_thread_state
132 LFDS710_PAL_ASSERT( libtest_threadset_per_thread_state != NULL );
134 pts = (struct libtest_threadset_per_thread_state *) libtest_threadset_per_thread_state;
135 atds = LIBTEST_THREADSET_GET_USER_STATE_FROM_PER_THREAD_STATE( *pts );
137 LFDS710_MISC_BARRIER_LOAD;
139 libtest_threadset_thread_ready_and_wait( pts );
141 while( loop++ < 10000000 )
143 compare[0] = (*atds->shared_counter)[0];
144 compare[1] = (*atds->shared_counter)[1];
148 exchange[0] = compare[0] + 1;
149 exchange[1] = compare[1];
150 LFDS710_PAL_ATOMIC_DWCAS( (*atds->shared_counter), compare, exchange, LFDS710_MISC_CAS_STRENGTH_WEAK, result );
152 while( result == 0 );
154 atds->local_counter++;
157 LFDS710_MISC_BARRIER_STORE;
159 lfds710_misc_force_store();
161 return LIBSHARED_PAL_THREAD_RETURN_CAST(RETURN_SUCCESS);