2 #include "libtest_tests_internal.h"
5 struct libtest_tests_pal_atomic_cas_state
10 lfds710_pal_uint_t volatile
14 /***** private prototyps *****/
15 static libshared_pal_thread_return_t LIBSHARED_PAL_THREAD_CALLING_CONVENTION thread_cas( void *libtest_threadset_per_thread_state );
21 /****************************************************************************/
22 void libtest_tests_pal_atomic_cas( struct lfds710_list_asu_state *list_of_logical_processors, struct libshared_memory_state *ms, enum lfds710_misc_validity *dvs )
24 lfds710_pal_uint_t volatile LFDS710_PAL_ALIGN(LFDS710_PAL_ATOMIC_ISOLATION_IN_BYTES)
32 number_logical_processors;
34 struct lfds710_list_asu_element
37 struct libtest_logical_processor
40 struct libtest_threadset_per_thread_state
43 struct libtest_threadset_state
46 struct libtest_tests_pal_atomic_cas_state
49 LFDS710_PAL_ASSERT( list_of_logical_processors != NULL );
50 LFDS710_PAL_ASSERT( ms != NULL );
51 LFDS710_PAL_ASSERT( dvs != NULL );
53 /* TRD : here we test pal_cas
55 we run one thread per CPU
56 we use pal_cas() to increment a shared counter
57 every time a thread successfully increments the counter,
58 it increments a thread local counter
59 the threads run for ten seconds
60 after the threads finish, we total the local counters
61 they should equal the shared counter
65 lfds710_list_asu_query( list_of_logical_processors, LFDS710_LIST_ASU_QUERY_GET_POTENTIALLY_INACCURATE_COUNT, NULL, (void **) &number_logical_processors );
66 pts = libshared_memory_alloc_from_unknown_node( ms, sizeof(struct libtest_threadset_per_thread_state) * number_logical_processors, LFDS710_PAL_ATOMIC_ISOLATION_IN_BYTES );
67 atcs = libshared_memory_alloc_from_unknown_node( ms, sizeof(struct libtest_tests_pal_atomic_cas_state) * number_logical_processors, LFDS710_PAL_ATOMIC_ISOLATION_IN_BYTES );
71 for( loop = 0 ; loop < number_logical_processors ; loop++ )
73 (atcs+loop)->shared_counter = &shared_counter;
74 (atcs+loop)->local_counter = 0;
77 libtest_threadset_init( &ts, NULL );
81 while( LFDS710_LIST_ASU_GET_START_AND_THEN_NEXT(*list_of_logical_processors,lasue) )
83 lp = LFDS710_LIST_ASU_GET_VALUE_FROM_ELEMENT( *lasue );
84 libtest_threadset_add_thread( &ts, &pts[loop], lp, thread_cas, atcs+loop );
88 LFDS710_MISC_BARRIER_STORE;
90 lfds710_misc_force_store();
93 libtest_threadset_run( &ts );
95 libtest_threadset_cleanup( &ts );
98 LFDS710_MISC_BARRIER_LOAD;
100 for( loop = 0 ; loop < number_logical_processors ; loop++ )
101 local_total += (atcs+loop)->local_counter;
103 if( local_total == shared_counter )
104 *dvs = LFDS710_MISC_VALIDITY_VALID;
106 if( local_total != shared_counter )
107 *dvs = LFDS710_MISC_VALIDITY_INVALID_TEST_DATA;
116 /****************************************************************************/
117 static libshared_pal_thread_return_t LIBSHARED_PAL_THREAD_CALLING_CONVENTION thread_cas( void *libtest_threadset_per_thread_state )
125 lfds710_pal_uint_t LFDS710_PAL_ALIGN(LFDS710_PAL_ALIGN_SINGLE_POINTER)
129 struct libtest_tests_pal_atomic_cas_state
132 struct libtest_threadset_per_thread_state
135 LFDS710_MISC_BARRIER_LOAD;
137 LFDS710_PAL_ASSERT( libtest_threadset_per_thread_state != NULL );
139 pts = (struct libtest_threadset_per_thread_state *) libtest_threadset_per_thread_state;
140 atcs = LIBTEST_THREADSET_GET_USER_STATE_FROM_PER_THREAD_STATE( *pts );
142 LFDS710_MISC_BARRIER_LOAD;
144 libtest_threadset_thread_ready_and_wait( pts );
146 while( loop++ < 10000000 )
148 compare = *atcs->shared_counter;
152 exchange = compare + 1;
153 LFDS710_PAL_ATOMIC_CAS( atcs->shared_counter, &compare, exchange, LFDS710_MISC_CAS_STRENGTH_WEAK, result );
155 while( result == 0 );
157 atcs->local_counter++;
160 LFDS710_MISC_BARRIER_STORE;
162 lfds710_misc_force_store();
164 return LIBSHARED_PAL_THREAD_RETURN_CAST(RETURN_SUCCESS);