Blame src/ctests/zero_pthreads.c

Packit 577717
/* This file performs the following test: start, stop and timer
Packit 577717
functionality for 2 slave pthreads
Packit 577717
Packit 577717
   - It attempts to use the following two counters. It may use less
Packit 577717
depending on hardware counter resource limitations. These are counted
Packit 577717
in the default counting domain and default granularity, depending on
Packit 577717
the platform. Usually this is the user domain (PAPI_DOM_USER) and
Packit 577717
thread context (PAPI_GRN_THR).
Packit 577717
Packit 577717
     + PAPI_FP_INS
Packit 577717
     + PAPI_TOT_CYC
Packit 577717
Packit 577717
Each of 2 slave pthreads:
Packit 577717
   - Get cyc.
Packit 577717
   - Get us.
Packit 577717
   - Start counters
Packit 577717
   - Do flops
Packit 577717
   - Stop and read counters
Packit 577717
   - Get us.
Packit 577717
   - Get cyc.
Packit 577717
Packit 577717
Master pthread:
Packit 577717
   - Get us.
Packit 577717
   - Get cyc.
Packit 577717
   - Fork threads
Packit 577717
   - Wait for threads to exit
Packit 577717
   - Get us.
Packit 577717
   - Get cyc.
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
void *
Packit 577717
Thread( void *arg )
Packit 577717
{
Packit 577717
	int retval, num_tests = 1;
Packit 577717
	int EventSet1 = PAPI_NULL;
Packit 577717
	int PAPI_event, mask1;
Packit 577717
	int num_events1;
Packit 577717
	long long **values;
Packit 577717
	long long elapsed_us, elapsed_cyc;
Packit 577717
	char event_name[PAPI_MAX_STR_LEN];
Packit 577717
Packit 577717
	retval = PAPI_register_thread(  );
Packit 577717
	if ( retval != PAPI_OK ) {
Packit 577717
	   test_fail( __FILE__, __LINE__, "PAPI_register_thread", retval );
Packit 577717
	}
Packit 577717
Packit 577717
	if (!TESTS_QUIET) {
Packit 577717
		printf( "Thread %#x started\n", ( int ) pthread_self(  ) );
Packit 577717
	}
Packit 577717
Packit 577717
	/* add PAPI_TOT_CYC and one of the events in
Packit 577717
	   PAPI_FP_INS, PAPI_FP_OPS or PAPI_TOT_INS,
Packit 577717
	   depending on the availability of the event
Packit 577717
	   on the platform                              */
Packit 577717
	EventSet1 = add_two_events( &num_events1, &PAPI_event, &mask1 );
Packit 577717
	if (!TESTS_QUIET) {
Packit 577717
		printf("Events %d\n",num_events1);
Packit 577717
	}
Packit 577717
	if (num_events1<2) {
Packit 577717
	   test_fail( __FILE__, __LINE__, "Not enough events", retval );
Packit 577717
	}
Packit 577717
Packit 577717
	retval = PAPI_event_code_to_name( PAPI_event, event_name );
Packit 577717
	if ( retval != PAPI_OK ) {
Packit 577717
	   test_fail( __FILE__, __LINE__, "PAPI_event_code_to_name", retval );
Packit 577717
	}
Packit 577717
Packit 577717
	values = allocate_test_space( num_tests, num_events1 );
Packit 577717
Packit 577717
	elapsed_us = PAPI_get_real_usec(  );
Packit 577717
	elapsed_cyc = PAPI_get_real_cyc(  );
Packit 577717
Packit 577717
	retval = PAPI_start( EventSet1 );
Packit 577717
	if ( retval != PAPI_OK ) {
Packit 577717
		test_fail( __FILE__, __LINE__, "PAPI_start", retval );
Packit 577717
	}
Packit 577717
Packit 577717
	do_flops( *( int * ) arg );
Packit 577717
Packit 577717
	retval = PAPI_stop( EventSet1, values[0] );
Packit 577717
	if ( retval != PAPI_OK ) {
Packit 577717
		test_fail( __FILE__, __LINE__, "PAPI_stop", retval );
Packit 577717
	}
Packit 577717
Packit 577717
	elapsed_us = PAPI_get_real_usec(  ) - elapsed_us;
Packit 577717
	elapsed_cyc = PAPI_get_real_cyc(  ) - elapsed_cyc;
Packit 577717
Packit 577717
	remove_test_events( &EventSet1, mask1 );
Packit 577717
Packit 577717
	if ( !TESTS_QUIET ) {
Packit 577717
	   printf( "Thread %#x %-12s : \t%lld\n", ( int ) pthread_self(  ),
Packit 577717
				event_name, values[0][1] );
Packit 577717
	   printf( "Thread %#x PAPI_TOT_CYC : \t%lld\n", (int) pthread_self(),
Packit 577717
				values[0][0] );
Packit 577717
	   printf( "Thread %#x Real usec    : \t%lld\n",
Packit 577717
			( int ) pthread_self(  ),
Packit 577717
				elapsed_us );
Packit 577717
	   printf( "Thread %#x Real cycles  : \t%lld\n", (int) pthread_self(),
Packit 577717
				elapsed_cyc );
Packit 577717
	}
Packit 577717
Packit 577717
	free_test_space( values, num_tests );
Packit 577717
Packit 577717
	retval = PAPI_unregister_thread(  );
Packit 577717
	if ( retval != PAPI_OK )
Packit 577717
		test_fail( __FILE__, __LINE__, "PAPI_unregister_thread", retval );
Packit 577717
	return NULL;
Packit 577717
}
Packit 577717
Packit 577717
int
Packit 577717
main( int argc, char **argv )
Packit 577717
{
Packit 577717
	pthread_t e_th, f_th, g_th, h_th;
Packit 577717
	int flops1, flops2, flops3, flops4;
Packit 577717
	int retval, rc;
Packit 577717
	pthread_attr_t attr;
Packit 577717
	long long elapsed_us, elapsed_cyc;
Packit 577717
	int quiet;
Packit 577717
Packit 577717
	/* Set TESTS_QUIET variable */
Packit 577717
	quiet = tests_quiet( argc, argv );
Packit 577717
Packit 577717
	/* Init PAPI library */
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
	if (PAPI_query_event(PAPI_TOT_INS)!=PAPI_OK) {
Packit 577717
		if (!quiet) printf("Can't find PAPI_TOT_INS\n");
Packit 577717
		test_skip(__FILE__,__LINE__,"Event missing",1);
Packit 577717
	}
Packit 577717
Packit 577717
	if (PAPI_query_event(PAPI_TOT_CYC)!=PAPI_OK) {
Packit 577717
		if (!quiet) printf("Can't find PAPI_TOT_CYC\n");
Packit 577717
		test_skip(__FILE__,__LINE__,"Event missing",1);
Packit 577717
	}
Packit 577717
Packit 577717
	retval = PAPI_thread_init( ( unsigned long ( * )( void ) )
Packit 577717
				   ( pthread_self ) );
Packit 577717
Packit 577717
	if ( retval != PAPI_OK ) {
Packit 577717
		if ( retval == PAPI_ECMP ) {
Packit 577717
			test_skip( __FILE__, __LINE__, "PAPI_thread_init", retval );
Packit 577717
		}
Packit 577717
		else {
Packit 577717
			test_fail( __FILE__, __LINE__, "PAPI_thread_init", retval );
Packit 577717
		}
Packit 577717
	}
Packit 577717
Packit 577717
	elapsed_us = PAPI_get_real_usec(  );
Packit 577717
Packit 577717
	elapsed_cyc = PAPI_get_real_cyc(  );
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
	flops1 = 1000000;
Packit 577717
	rc = pthread_create( &e_th, &attr, Thread, ( void * ) &flops1 );
Packit 577717
	if ( rc ) {
Packit 577717
		retval = PAPI_ESYS;
Packit 577717
		test_fail( __FILE__, __LINE__, "pthread_create", retval );
Packit 577717
	}
Packit 577717
	flops2 = 2000000;
Packit 577717
	rc = pthread_create( &f_th, &attr, Thread, ( void * ) &flops2 );
Packit 577717
	if ( rc ) {
Packit 577717
		retval = PAPI_ESYS;
Packit 577717
		test_fail( __FILE__, __LINE__, "pthread_create", retval );
Packit 577717
	}
Packit 577717
Packit 577717
	flops3 = 4000000;
Packit 577717
	rc = pthread_create( &g_th, &attr, Thread, ( void * ) &flops3 );
Packit 577717
	if ( rc ) {
Packit 577717
		retval = PAPI_ESYS;
Packit 577717
		test_fail( __FILE__, __LINE__, "pthread_create", retval );
Packit 577717
	}
Packit 577717
Packit 577717
	flops4 = 8000000;
Packit 577717
	rc = pthread_create( &h_th, &attr, Thread, ( void * ) &flops4 );
Packit 577717
	if ( rc ) {
Packit 577717
		retval = PAPI_ESYS;
Packit 577717
		test_fail( __FILE__, __LINE__, "pthread_create", retval );
Packit 577717
	}
Packit 577717
Packit 577717
	pthread_attr_destroy( &attr );
Packit 577717
	flops1 = 500000;
Packit 577717
	Thread( &flops1 );
Packit 577717
	pthread_join( h_th, NULL );
Packit 577717
	pthread_join( g_th, NULL );
Packit 577717
	pthread_join( f_th, NULL );
Packit 577717
	pthread_join( e_th, NULL );
Packit 577717
Packit 577717
	elapsed_cyc = PAPI_get_real_cyc(  ) - elapsed_cyc;
Packit 577717
	elapsed_us = PAPI_get_real_usec(  ) - elapsed_us;
Packit 577717
Packit 577717
	if ( !quiet ) {
Packit 577717
		printf( "Master real usec   : \t%lld\n", elapsed_us );
Packit 577717
		printf( "Master real cycles : \t%lld\n", elapsed_cyc );
Packit 577717
	}
Packit 577717
Packit 577717
	test_pass( __FILE__ );
Packit 577717
Packit 577717
	pthread_exit( NULL );
Packit 577717
Packit 577717
	return 0;
Packit 577717
}