Blame src/ctests/multiplex3_pthreads.c

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
}