Files
openairinterface5g/openair2/UTIL/LFDS/liblfds7.0.0/test/src/util_thread_starter.c
T

152 lines
3.7 KiB
C

/***** includes *****/
#include "internal.h"
/****************************************************************************/
void util_thread_starter_new( struct util_thread_starter_state **tts, lfds700_pal_uint_t number_threads )
{
lfds700_pal_uint_t
loop;
assert( tts != NULL );
// TRD : number_threads cam be any value in its range
*tts = util_malloc_wrapper( sizeof(struct util_thread_starter_state) );
(*tts)->tsts = util_malloc_wrapper( sizeof(struct util_thread_starter_thread_state) * number_threads );
(*tts)->thread_start_flag = LOWERED;
(*tts)->number_thread_states = number_threads;
for( loop = 0 ; loop < number_threads ; loop++ )
{
((*tts)->tsts+loop)->thread_ready_flag = LOWERED;
((*tts)->tsts+loop)->thread_start_flag = &(*tts)->thread_start_flag;
}
LFDS700_MISC_BARRIER_STORE;
lfds700_misc_force_store();
return;
}
/****************************************************************************/
void util_thread_starter_start( struct util_thread_starter_state *tts,
test_pal_thread_state_t *thread_state,
lfds700_pal_uint_t thread_number,
struct test_pal_logical_processor *lp,
test_pal_thread_return_t (TEST_PAL_CALLING_CONVENTION *thread_function)( void *thread_user_state ),
void *thread_user_state )
{
assert( tts != NULL );
assert( thread_state != NULL );
assert( lp != NULL );
assert( thread_function != NULL );
// TRD : thread_user_state can be NULL
(tts->tsts+thread_number)->thread_user_state = thread_user_state;
util_thread_start_wrapper( thread_state, lp, thread_function, tts->tsts+thread_number );
// TRD : wait for the thread to indicate it is ready and waiting
while( (tts->tsts+thread_number)->thread_ready_flag == LOWERED );
return;
}
/****************************************************************************/
void util_thread_starter_ready_and_wait( struct util_thread_starter_thread_state *tsts )
{
assert( tsts != NULL );
tsts->thread_ready_flag = RAISED;
LFDS700_MISC_BARRIER_FULL;
// TRD : threads here are all looping, so we don't need to force a store
while( *tsts->thread_start_flag == LOWERED )
LFDS700_MISC_BARRIER_LOAD;
return;
}
/****************************************************************************/
void util_thread_starter_run( struct util_thread_starter_state *tts )
{
assert( tts != NULL );
/* TRD : all threads at this point are ready to go
as we wait for their ready flag immediately after their spawn
*/
tts->thread_start_flag = RAISED;
LFDS700_MISC_BARRIER_STORE;
lfds700_misc_force_store();
return;
}
/****************************************************************************/
void util_thread_starter_delete( struct util_thread_starter_state *tts )
{
assert( tts != NULL );
free( tts->tsts );
free( tts );
return;
}
/****************************************************************************/
void util_thread_start_wrapper( test_pal_thread_state_t *thread_state,
struct test_pal_logical_processor *lp,
test_pal_thread_return_t (TEST_PAL_CALLING_CONVENTION *thread_function)(void *thread_user_state),
void *thread_user_state )
{
int
rv;
assert( thread_state != NULL );
assert( lp != NULL );
assert( thread_function != NULL );
// TRD : thread_user_state can be NULL
rv = test_pal_thread_start( thread_state, lp, thread_function, thread_user_state );
if( rv == 0 )
{
puts( "test_pal_thread_start() failed." );
exit( EXIT_FAILURE );
}
return;
}