|
Packit Service |
a1973e |
/*
|
|
Packit Service |
a1973e |
* Test PAPI with multiple threads.
|
|
Packit Service |
a1973e |
*/
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#define MAX_THREADS 256
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#include <stdio.h>
|
|
Packit Service |
a1973e |
#include <stdlib.h>
|
|
Packit Service |
a1973e |
#include <pthread.h>
|
|
Packit Service |
a1973e |
#include <sys/time.h>
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#include "papi.h"
|
|
Packit Service |
a1973e |
#include "papi_test.h"
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
#define EVENT PAPI_TOT_CYC
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
static int program_time = 5;
|
|
Packit Service |
a1973e |
static int threshold = 20000000;
|
|
Packit Service |
a1973e |
static int num_threads = 3;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
static long count[MAX_THREADS];
|
|
Packit Service |
a1973e |
static long iter[MAX_THREADS];
|
|
Packit Service |
a1973e |
static struct timeval last[MAX_THREADS];
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
static pthread_key_t key;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
static struct timeval start;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
static void
|
|
Packit Service |
a1973e |
my_handler( int EventSet, void *pc, long long ovec, void *context )
|
|
Packit Service |
a1973e |
{
|
|
Packit Service |
a1973e |
( void ) EventSet;
|
|
Packit Service |
a1973e |
( void ) pc;
|
|
Packit Service |
a1973e |
( void ) ovec;
|
|
Packit Service |
a1973e |
( void ) context;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
long num = ( long ) pthread_getspecific( key );
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
if ( num < 0 || num > num_threads )
|
|
Packit Service |
a1973e |
test_fail( __FILE__, __LINE__, "getspecific failed", 1 );
|
|
Packit Service |
a1973e |
count[num]++;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
static void
|
|
Packit Service |
a1973e |
print_rate( long num )
|
|
Packit Service |
a1973e |
{
|
|
Packit Service |
a1973e |
struct timeval now;
|
|
Packit Service |
a1973e |
long st_secs;
|
|
Packit Service |
a1973e |
double last_secs;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
gettimeofday( &now, NULL );
|
|
Packit Service |
a1973e |
st_secs = now.tv_sec - start.tv_sec;
|
|
Packit Service |
a1973e |
last_secs = ( double ) ( now.tv_sec - last[num].tv_sec )
|
|
Packit Service |
a1973e |
+ ( ( double ) ( now.tv_usec - last[num].tv_usec ) ) / 1000000.0;
|
|
Packit Service |
a1973e |
if ( last_secs <= 0.001 )
|
|
Packit Service |
a1973e |
last_secs = 0.001;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
if (!TESTS_QUIET) {
|
|
Packit Service |
a1973e |
printf( "[%ld] time = %ld, count = %ld, iter = %ld, "
|
|
Packit Service |
a1973e |
"rate = %.1f/Kiter\n",
|
|
Packit Service |
a1973e |
num, st_secs, count[num], iter[num],
|
|
Packit Service |
a1973e |
( 1000.0 * ( double ) count[num] ) / ( double ) iter[num] );
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
count[num] = 0;
|
|
Packit Service |
a1973e |
iter[num] = 0;
|
|
Packit Service |
a1973e |
last[num] = now;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
static void
|
|
Packit Service |
a1973e |
do_cycles( long num, int len )
|
|
Packit Service |
a1973e |
{
|
|
Packit Service |
a1973e |
struct timeval start, now;
|
|
Packit Service |
a1973e |
double x, sum;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
gettimeofday( &start, NULL );
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
for ( ;; ) {
|
|
Packit Service |
a1973e |
sum = 1.0;
|
|
Packit Service |
a1973e |
for ( x = 1.0; x < 250000.0; x += 1.0 )
|
|
Packit Service |
a1973e |
sum += x;
|
|
Packit Service |
a1973e |
if ( sum < 0.0 )
|
|
Packit Service |
a1973e |
printf( "==>> SUM IS NEGATIVE !! <<==\n" );
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
iter[num]++;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
gettimeofday( &now, NULL );
|
|
Packit Service |
a1973e |
if ( now.tv_sec >= start.tv_sec + len )
|
|
Packit Service |
a1973e |
break;
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
static void *
|
|
Packit Service |
a1973e |
my_thread( void *v )
|
|
Packit Service |
a1973e |
{
|
|
Packit Service |
a1973e |
long num = ( long ) v;
|
|
Packit Service |
a1973e |
int n;
|
|
Packit Service |
a1973e |
int EventSet = PAPI_NULL;
|
|
Packit Service |
a1973e |
long long value;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
int retval;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
retval = PAPI_register_thread( );
|
|
Packit Service |
a1973e |
if ( retval != PAPI_OK ) {
|
|
Packit Service |
a1973e |
test_fail( __FILE__, __LINE__, "PAPI_register_thread", retval );
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
pthread_setspecific( key, v );
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
count[num] = 0;
|
|
Packit Service |
a1973e |
iter[num] = 0;
|
|
Packit Service |
a1973e |
last[num] = start;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
retval = PAPI_create_eventset( &EventSet );
|
|
Packit Service |
a1973e |
if ( retval != PAPI_OK ) {
|
|
Packit Service |
a1973e |
test_fail( __FILE__, __LINE__, "PAPI_create_eventset failed", retval );
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
retval = PAPI_add_event( EventSet, EVENT );
|
|
Packit Service |
a1973e |
if (retval != PAPI_OK ) {
|
|
Packit Service |
a1973e |
if (!TESTS_QUIET) printf("Trouble adding event\n");
|
|
Packit Service |
a1973e |
test_fail( __FILE__, __LINE__, "PAPI_add_event failed", retval );
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
if ( PAPI_overflow( EventSet, EVENT, threshold, 0, my_handler ) != PAPI_OK )
|
|
Packit Service |
a1973e |
test_fail( __FILE__, __LINE__, "PAPI_overflow failed", 1 );
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
if ( PAPI_start( EventSet ) != PAPI_OK )
|
|
Packit Service |
a1973e |
test_fail( __FILE__, __LINE__, "PAPI_start failed", 1 );
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
if (!TESTS_QUIET) printf( "launched timer in thread %ld\n", num );
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
for ( n = 1; n <= program_time; n++ ) {
|
|
Packit Service |
a1973e |
do_cycles( num, 1 );
|
|
Packit Service |
a1973e |
print_rate( num );
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
PAPI_stop( EventSet, &value );
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
retval = PAPI_overflow( EventSet, EVENT, 0, 0, my_handler);
|
|
Packit Service |
a1973e |
if ( retval != PAPI_OK )
|
|
Packit Service |
a1973e |
test_fail( __FILE__, __LINE__, "PAPI_overflow failed to reset the overflow handler", retval );
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
if ( PAPI_remove_event( EventSet, EVENT ) != PAPI_OK )
|
|
Packit Service |
a1973e |
test_fail( __FILE__, __LINE__, "PAPI_remove_event", 1 );
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
if ( PAPI_destroy_eventset( &EventSet ) != PAPI_OK )
|
|
Packit Service |
a1973e |
test_fail( __FILE__, __LINE__, "PAPI_destroy_eventset", 1 );
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
if ( PAPI_unregister_thread( ) != PAPI_OK )
|
|
Packit Service |
a1973e |
test_fail( __FILE__, __LINE__, "PAPI_unregister_thread", 1 );
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
return ( NULL );
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
int
|
|
Packit Service |
a1973e |
main( int argc, char **argv )
|
|
Packit Service |
a1973e |
{
|
|
Packit Service |
a1973e |
pthread_t *td = NULL;
|
|
Packit Service |
a1973e |
long n;
|
|
Packit Service |
a1973e |
int quiet,retval;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/* Set TESTS_QUIET variable */
|
|
Packit Service |
a1973e |
quiet=tests_quiet( argc, argv );
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
if ( argc < 2 || sscanf( argv[1], "%d", &program_time ) < 1 )
|
|
Packit Service |
a1973e |
program_time = 6;
|
|
Packit Service |
a1973e |
if ( argc < 3 || sscanf( argv[2], "%d", &threshold ) < 1 )
|
|
Packit Service |
a1973e |
threshold = 20000000;
|
|
Packit Service |
a1973e |
if ( argc < 4 || sscanf( argv[3], "%d", &num_threads ) < 1 )
|
|
Packit Service |
a1973e |
num_threads = 3;
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
td = malloc((num_threads+1) * sizeof(pthread_t));
|
|
Packit Service |
a1973e |
if (!td) {
|
|
Packit Service |
a1973e |
test_fail( __FILE__, __LINE__, "td malloc failed", 1 );
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
if (!quiet) {
|
|
Packit Service |
a1973e |
printf( "program_time = %d, threshold = %d, num_threads = %d\n\n",
|
|
Packit Service |
a1973e |
program_time, threshold, num_threads );
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
if ( PAPI_library_init( PAPI_VER_CURRENT ) != PAPI_VER_CURRENT )
|
|
Packit Service |
a1973e |
test_fail( __FILE__, __LINE__, "PAPI_library_init failed", 1 );
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/* Test to be sure we can add events */
|
|
Packit Service |
a1973e |
retval = PAPI_query_event( EVENT );
|
|
Packit Service |
a1973e |
if (retval!=PAPI_OK) {
|
|
Packit Service |
a1973e |
if (!quiet) printf("Trouble finding event\n");
|
|
Packit Service |
a1973e |
test_skip(__FILE__,__LINE__,"Event not available",1);
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
if ( PAPI_thread_init( ( unsigned long ( * )( void ) ) ( pthread_self ) ) !=
|
|
Packit Service |
a1973e |
PAPI_OK )
|
|
Packit Service |
a1973e |
test_fail( __FILE__, __LINE__, "PAPI_thread_init failed", 1 );
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
if ( pthread_key_create( &key, NULL ) != 0 )
|
|
Packit Service |
a1973e |
test_fail( __FILE__, __LINE__, "pthread key create failed", 1 );
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
gettimeofday( &start, NULL );
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
for ( n = 1; n <= num_threads; n++ ) {
|
|
Packit Service |
a1973e |
if ( pthread_create( &(td[n]), NULL, my_thread, ( void * ) n ) != 0 )
|
|
Packit Service |
a1973e |
test_fail( __FILE__, __LINE__, "pthread create failed", 1 );
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
my_thread( ( void * ) 0 );
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
/* wait for all the threads */
|
|
Packit Service |
a1973e |
for ( n = 1; n <= num_threads; n++ ) {
|
|
Packit Service |
a1973e |
if ( pthread_join( td[n], NULL))
|
|
Packit Service |
a1973e |
test_fail( __FILE__, __LINE__, "pthread join failed", 1 );
|
|
Packit Service |
a1973e |
}
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
free(td);
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
if (!quiet) printf( "done\n" );
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
test_pass( __FILE__ );
|
|
Packit Service |
a1973e |
|
|
Packit Service |
a1973e |
return 0;
|
|
Packit Service |
a1973e |
}
|