|
Packit |
577717 |
/*
|
|
Packit |
577717 |
* File: multiplex3_pthreads.c
|
|
Packit |
577717 |
* Author: Philip Mucci
|
|
Packit |
577717 |
* mucci@cs.utk.edu
|
|
Packit |
577717 |
* Mods: John May
|
|
Packit |
577717 |
* johnmay@llnl.gov
|
|
Packit |
577717 |
*/
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* This file tests the multiplex functionality when there are
|
|
Packit |
577717 |
* threads in which the application isn't calling PAPI (and only
|
|
Packit |
577717 |
* one thread that is calling PAPI.)
|
|
Packit |
577717 |
*/
|
|
Packit |
577717 |
|
|
Packit |
577717 |
#include <stdio.h>
|
|
Packit |
577717 |
#include <stdlib.h>
|
|
Packit |
577717 |
#include <pthread.h>
|
|
Packit |
577717 |
|
|
Packit |
577717 |
#include "papi.h"
|
|
Packit |
577717 |
#include "papi_test.h"
|
|
Packit |
577717 |
|
|
Packit |
577717 |
#include "do_loops.h"
|
|
Packit |
577717 |
|
|
Packit |
577717 |
#define MAX_TO_ADD 5
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* A thread function that does nothing forever, while the other
|
|
Packit |
577717 |
* tests are running.
|
|
Packit |
577717 |
*/
|
|
Packit |
577717 |
void *
|
|
Packit |
577717 |
thread_fn( void *dummy )
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
( void ) dummy;
|
|
Packit |
577717 |
while ( 1 ) {
|
|
Packit |
577717 |
do_stuff( );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
return NULL;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* Runs a bunch of multiplexed events */
|
|
Packit |
577717 |
|
|
Packit |
577717 |
static void
|
|
Packit |
577717 |
mainloop( int arg )
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
int allvalid;
|
|
Packit |
577717 |
long long *values;
|
|
Packit |
577717 |
int EventSet = PAPI_NULL;
|
|
Packit |
577717 |
int retval, i, j = 2, skipped_counters=0;
|
|
Packit |
577717 |
PAPI_event_info_t pset;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
( void ) arg;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* Initialize the library */
|
|
Packit |
577717 |
|
|
Packit |
577717 |
retval = PAPI_library_init( PAPI_VER_CURRENT );
|
|
Packit |
577717 |
if ( retval != PAPI_VER_CURRENT ) {
|
|
Packit |
577717 |
test_fail( __FILE__, __LINE__, "PAPI_library_init", retval );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
retval = PAPI_multiplex_init( );
|
|
Packit |
577717 |
if ( retval != PAPI_OK ) {
|
|
Packit |
577717 |
test_fail( __FILE__, __LINE__, "PAPI multiplex init fail\n", retval );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
retval = PAPI_create_eventset( &EventSet );
|
|
Packit |
577717 |
if ( retval != PAPI_OK ) {
|
|
Packit |
577717 |
test_fail( __FILE__, __LINE__, "PAPI_create_eventset", retval );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* In Component PAPI, EventSets must be assigned a component index
|
|
Packit |
577717 |
before you can fiddle with their internals.
|
|
Packit |
577717 |
0 is always the cpu component */
|
|
Packit |
577717 |
retval = PAPI_assign_eventset_component( EventSet, 0 );
|
|
Packit |
577717 |
if ( retval != PAPI_OK ) {
|
|
Packit |
577717 |
test_fail( __FILE__, __LINE__, "PAPI_assign_eventset_component",
|
|
Packit |
577717 |
retval );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
retval = PAPI_set_multiplex( EventSet );
|
|
Packit |
577717 |
if ( retval == PAPI_ENOSUPP) {
|
|
Packit |
577717 |
test_skip(__FILE__, __LINE__, "Multiplex not supported", 1);
|
|
Packit |
577717 |
} else if ( retval != PAPI_OK ) {
|
|
Packit |
577717 |
test_fail( __FILE__, __LINE__, "PAPI_set_multiplex", retval );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
retval = PAPI_thread_init( ( unsigned long ( * )( void ) ) ( pthread_self ) );
|
|
Packit |
577717 |
if (retval != PAPI_OK ) {
|
|
Packit |
577717 |
if ( retval == PAPI_ECMP )
|
|
Packit |
577717 |
test_skip( __FILE__, __LINE__, "PAPI_thread_init", retval );
|
|
Packit |
577717 |
else
|
|
Packit |
577717 |
test_fail( __FILE__, __LINE__, "PAPI_thread_init", retval );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
retval = PAPI_add_event( EventSet, PAPI_TOT_INS );
|
|
Packit |
577717 |
if ( ( retval != PAPI_OK ) && ( retval != PAPI_ECNFLCT ) ) {
|
|
Packit |
577717 |
if (!TESTS_QUIET) printf("Trouble adding PAPI_TOT_INS\n");
|
|
Packit |
577717 |
test_skip( __FILE__, __LINE__, "PAPI_add_event", retval );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if ( !TESTS_QUIET ) {
|
|
Packit |
577717 |
printf( "Added %s\n", "PAPI_TOT_INS" );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
retval = PAPI_add_event( EventSet, PAPI_TOT_CYC );
|
|
Packit |
577717 |
if ( ( retval != PAPI_OK ) && ( retval != PAPI_ECNFLCT ) )
|
|
Packit |
577717 |
test_fail( __FILE__, __LINE__, "PAPI_add_event", retval );
|
|
Packit |
577717 |
if ( !TESTS_QUIET ) {
|
|
Packit |
577717 |
printf( "Added %s\n", "PAPI_TOT_CYC" );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
values = ( long long * ) malloc( MAX_TO_ADD * sizeof ( long long ) );
|
|
Packit |
577717 |
if ( values == NULL )
|
|
Packit |
577717 |
test_fail( __FILE__, __LINE__, "malloc", 0 );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
for ( i = 0; i < PAPI_MAX_PRESET_EVENTS; i++ ) {
|
|
Packit |
577717 |
retval = PAPI_get_event_info( i | PAPI_PRESET_MASK, &pset );
|
|
Packit |
577717 |
if ( retval != PAPI_OK )
|
|
Packit |
577717 |
test_fail( __FILE__, __LINE__, "PAPI_get_event_info", retval );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if ( pset.count ) {
|
|
Packit |
577717 |
if (!TESTS_QUIET) printf( "Adding %s\n", pset.symbol );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
retval = PAPI_add_event( EventSet, ( int ) pset.event_code );
|
|
Packit |
577717 |
if ( ( retval != PAPI_OK ) && ( retval != PAPI_ECNFLCT ) )
|
|
Packit |
577717 |
test_fail( __FILE__, __LINE__, "PAPI_add_event", retval );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if ( retval == PAPI_OK ) {
|
|
Packit |
577717 |
if (!TESTS_QUIET) printf( "Added %s\n", pset.symbol );
|
|
Packit |
577717 |
} else {
|
|
Packit |
577717 |
if (!TESTS_QUIET) printf( "Could not add %s\n", pset.symbol );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
do_stuff( );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if ( retval == PAPI_OK ) {
|
|
Packit |
577717 |
retval = PAPI_start( EventSet );
|
|
Packit |
577717 |
if ( retval != PAPI_OK )
|
|
Packit |
577717 |
test_fail( __FILE__, __LINE__, "PAPI_start", retval );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
do_stuff( );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
retval = PAPI_stop( EventSet, values );
|
|
Packit |
577717 |
if ( retval != PAPI_OK )
|
|
Packit |
577717 |
test_fail( __FILE__, __LINE__, "PAPI_stop", retval );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if ( values[j] ) {
|
|
Packit |
577717 |
if ( ++j >= MAX_TO_ADD )
|
|
Packit |
577717 |
break;
|
|
Packit |
577717 |
} else {
|
|
Packit |
577717 |
retval =
|
|
Packit |
577717 |
PAPI_remove_event( EventSet, ( int ) pset.event_code );
|
|
Packit |
577717 |
if ( retval == PAPI_OK )
|
|
Packit |
577717 |
if (!TESTS_QUIET) printf( "Removed %s\n", pset.symbol );
|
|
Packit |
577717 |
/* This added because the test */
|
|
Packit |
577717 |
/* can take a long time if mplexing */
|
|
Packit |
577717 |
/* is broken and all values are 0 */
|
|
Packit |
577717 |
skipped_counters++;
|
|
Packit |
577717 |
if (skipped_counters>MAX_TO_ADD) break;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
retval = PAPI_start( EventSet );
|
|
Packit |
577717 |
if ( retval != PAPI_OK )
|
|
Packit |
577717 |
test_fail( __FILE__, __LINE__, "PAPI_start", retval );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
do_stuff( );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
retval = PAPI_stop( EventSet, values );
|
|
Packit |
577717 |
if ( retval != PAPI_OK )
|
|
Packit |
577717 |
test_fail( __FILE__, __LINE__, "PAPI_stop", retval );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if (!TESTS_QUIET) {
|
|
Packit |
577717 |
test_print_event_header( "multiplex3_pthreads:\n", EventSet );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
allvalid = 0;
|
|
Packit |
577717 |
for ( i = 0; i < MAX_TO_ADD; i++ ) {
|
|
Packit |
577717 |
if (!TESTS_QUIET) printf( ONENUM, values[i] );
|
|
Packit |
577717 |
if ( values[i] != 0 )
|
|
Packit |
577717 |
allvalid++;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
if (!TESTS_QUIET) printf( "\n" );
|
|
Packit |
577717 |
if ( !allvalid )
|
|
Packit |
577717 |
test_fail( __FILE__, __LINE__, "all counter registered no counts", 1 );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
retval = PAPI_cleanup_eventset( EventSet ); /* JT */
|
|
Packit |
577717 |
if ( retval != PAPI_OK )
|
|
Packit |
577717 |
test_fail( __FILE__, __LINE__, "PAPI_cleanup_eventset", retval );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
retval = PAPI_destroy_eventset( &EventSet );
|
|
Packit |
577717 |
if ( retval != PAPI_OK )
|
|
Packit |
577717 |
test_fail( __FILE__, __LINE__, "PAPI_destroy_eventset", retval );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
free( values );
|
|
Packit |
577717 |
PAPI_shutdown( );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
int
|
|
Packit |
577717 |
main( int argc, char **argv )
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
int i, rc, retval;
|
|
Packit |
577717 |
pthread_t id[NUM_THREADS];
|
|
Packit |
577717 |
pthread_attr_t attr;
|
|
Packit |
577717 |
int quiet;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* Set TESTS_QUIET variable */
|
|
Packit |
577717 |
quiet = tests_quiet( argc, argv );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if (!quiet) {
|
|
Packit |
577717 |
printf( "%s: Using %d threads\n\n", argv[0], NUM_THREADS );
|
|
Packit |
577717 |
printf( "Does non-threaded multiplexing work "
|
|
Packit |
577717 |
"with extraneous threads present?\n" );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* Create a bunch of unused pthreads, to simulate threads created
|
|
Packit |
577717 |
* by the system that the user doesn't know about.
|
|
Packit |
577717 |
*/
|
|
Packit |
577717 |
pthread_attr_init( &attr );
|
|
Packit |
577717 |
#ifdef PTHREAD_CREATE_UNDETACHED
|
|
Packit |
577717 |
pthread_attr_setdetachstate( &attr, PTHREAD_CREATE_UNDETACHED );
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
#ifdef PTHREAD_SCOPE_SYSTEM
|
|
Packit |
577717 |
retval = pthread_attr_setscope( &attr, PTHREAD_SCOPE_SYSTEM );
|
|
Packit |
577717 |
if ( retval != 0 )
|
|
Packit |
577717 |
test_skip( __FILE__, __LINE__, "pthread_attr_setscope", retval );
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
|
|
Packit |
577717 |
#ifdef PPC64
|
|
Packit |
577717 |
sigset_t sigprof;
|
|
Packit |
577717 |
sigemptyset( &sigprof );
|
|
Packit |
577717 |
sigaddset( &sigprof, SIGPROF );
|
|
Packit |
577717 |
retval = sigprocmask( SIG_BLOCK, &sigprof, NULL );
|
|
Packit |
577717 |
if ( retval != 0 )
|
|
Packit |
577717 |
test_fail( __FILE__, __LINE__, "sigprocmask SIG_BLOCK", retval );
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
|
|
Packit |
577717 |
for ( i = 0; i < NUM_THREADS; i++ ) {
|
|
Packit |
577717 |
rc = pthread_create( &id[i], &attr, thread_fn, NULL );
|
|
Packit |
577717 |
if ( rc )
|
|
Packit |
577717 |
test_fail( __FILE__, __LINE__, "pthread_create", rc );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
pthread_attr_destroy( &attr );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
#ifdef PPC64
|
|
Packit |
577717 |
retval = sigprocmask( SIG_UNBLOCK, &sigprof, NULL );
|
|
Packit |
577717 |
if ( retval != 0 )
|
|
Packit |
577717 |
test_fail( __FILE__, __LINE__, "sigprocmask SIG_UNBLOCK", retval );
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
|
|
Packit |
577717 |
mainloop( NUM_ITERS );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
test_pass( __FILE__ );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
return 0;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
}
|