Blame src/ctests/attach3.c

Packit 577717
/* This file performs the following test: start, stop and timer functionality for
Packit 577717
   attached processes.
Packit 577717
Packit 577717
   - It attempts to use the following two counters. It may use less depending on
Packit 577717
     hardware counter resource limitations. These are counted in the default counting
Packit 577717
     domain and default granularity, depending on the platform. Usually this is 
Packit 577717
     the user domain (PAPI_DOM_USER) and thread context (PAPI_GRN_THR).
Packit 577717
     + PAPI_FP_INS
Packit 577717
     + PAPI_TOT_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
*/
Packit 577717
Packit 577717
#include <stdio.h>
Packit 577717
#include <stdlib.h>
Packit 577717
#include <unistd.h>
Packit 577717
#include <string.h>
Packit 577717
Packit 577717
#include <limits.h>
Packit 577717
#include <sys/ptrace.h>
Packit 577717
#include <sys/wait.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
Packit 577717
#ifdef _AIX
Packit 577717
#define _LINUX_SOURCE_COMPAT
Packit 577717
#endif
Packit 577717
Packit 577717
#if defined(__FreeBSD__)
Packit 577717
# define PTRACE_ATTACH PT_ATTACH
Packit 577717
# define PTRACE_TRACEME PT_TRACE_ME
Packit 577717
#endif
Packit 577717
Packit 577717
static int
Packit 577717
wait_for_attach_and_loop( void )
Packit 577717
{
Packit 577717
  char *path;
Packit 577717
  char newpath[PATH_MAX];
Packit 577717
  path = getenv("PATH");
Packit 577717
Packit 577717
  sprintf(newpath, "PATH=./:%s", (path)?path:"\0" );
Packit 577717
  putenv(newpath);
Packit 577717
Packit 577717
  if (ptrace(PTRACE_TRACEME, 0, 0, 0) == 0) {
Packit 577717
    execlp("attach_target","attach_target","100000000",NULL);
Packit 577717
    perror("execl(attach_target) failed");
Packit 577717
  }
Packit 577717
  perror("PTRACE_TRACEME");
Packit 577717
  return ( 1 );
Packit 577717
}
Packit 577717
Packit 577717
int
Packit 577717
main( int argc, char **argv )
Packit 577717
{
Packit 577717
	int status, retval, tmp;
Packit 577717
	int EventSet1 = PAPI_NULL;
Packit 577717
	long long **values;
Packit 577717
	long long elapsed_us, elapsed_cyc, elapsed_virt_us, elapsed_virt_cyc;
Packit 577717
	char event_name[PAPI_MAX_STR_LEN];;
Packit 577717
	const PAPI_hw_info_t *hw_info;
Packit 577717
	const PAPI_component_info_t *cmpinfo;
Packit 577717
	pid_t pid;
Packit 577717
	int quiet;
Packit 577717
Packit 577717
	/* Fork before doing anything with the PMU */
Packit 577717
Packit 577717
	setbuf(stdout,NULL);
Packit 577717
	pid = fork(  );
Packit 577717
	if ( pid < 0 )
Packit 577717
		test_fail( __FILE__, __LINE__, "fork()", PAPI_ESYS );
Packit 577717
	if ( pid == 0 )
Packit 577717
		exit( wait_for_attach_and_loop(  ) );
Packit 577717
Packit 577717
	/* Set TESTS_QUIET variable */
Packit 577717
	quiet=tests_quiet( argc, argv );
Packit 577717
Packit 577717
Packit 577717
	/* Master only process below here */
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
	if ( ( cmpinfo = PAPI_get_component_info( 0 ) ) == NULL )
Packit 577717
		test_fail( __FILE__, __LINE__, "PAPI_get_component_info", 0 );
Packit 577717
Packit 577717
	if ( cmpinfo->attach == 0 )
Packit 577717
		test_skip( __FILE__, __LINE__, "Platform does not support attaching",
Packit 577717
				   0 );
Packit 577717
Packit 577717
	hw_info = PAPI_get_hardware_info(  );
Packit 577717
	if ( hw_info == NULL )
Packit 577717
		test_fail( __FILE__, __LINE__, "PAPI_get_hardware_info", 0 );
Packit 577717
Packit 577717
	/* add PAPI_TOT_CYC and one of the events in PAPI_FP_INS, PAPI_FP_OPS or
Packit 577717
	   PAPI_TOT_INS, depending on the availability of the event on the
Packit 577717
	   platform */
Packit 577717
	retval = PAPI_create_eventset(&EventSet1);
Packit 577717
	if ( retval != PAPI_OK )
Packit 577717
		test_fail( __FILE__, __LINE__, "PAPI_attach", retval );
Packit 577717
Packit 577717
	/* Force addition of component */
Packit 577717
Packit 577717
	retval = PAPI_assign_eventset_component( EventSet1, 0 );
Packit 577717
	if ( retval != PAPI_OK )
Packit 577717
		test_fail( __FILE__, __LINE__, "PAPI_assign_eventset_component",
Packit 577717
				   retval );
Packit 577717
Packit 577717
	/* The following call causes this test to fail for perf_events */
Packit 577717
Packit 577717
	retval = PAPI_attach( EventSet1, ( unsigned long ) pid );
Packit 577717
	if ( retval != PAPI_OK )
Packit 577717
		test_fail( __FILE__, __LINE__, "PAPI_attach", retval );
Packit 577717
Packit 577717
Packit 577717
Packit 577717
	retval = PAPI_add_event(EventSet1, PAPI_TOT_CYC);
Packit 577717
	if ( retval != PAPI_OK ) {
Packit 577717
		if (!quiet) printf("Could not add PAPI_TOT_CYC\n");
Packit 577717
		test_skip( __FILE__, __LINE__, "PAPI_add_event", retval );
Packit 577717
	}
Packit 577717
Packit 577717
	strcpy(event_name,"PAPI_FP_INS");
Packit 577717
	retval = PAPI_add_named_event(EventSet1, event_name);
Packit 577717
	if ( retval == PAPI_ENOEVNT ) {
Packit 577717
		strcpy(event_name,"PAPI_TOT_INS");
Packit 577717
		retval = PAPI_add_named_event(EventSet1, event_name);
Packit 577717
	}
Packit 577717
Packit 577717
	if ( retval != PAPI_OK ) {
Packit 577717
		test_fail( __FILE__, __LINE__, "PAPI_add_event", retval );
Packit 577717
	}
Packit 577717
Packit 577717
	values = allocate_test_space( 1, 2);
Packit 577717
Packit 577717
	elapsed_us = PAPI_get_real_usec(  );
Packit 577717
Packit 577717
	elapsed_cyc = PAPI_get_real_cyc(  );
Packit 577717
Packit 577717
	elapsed_virt_us = PAPI_get_virt_usec(  );
Packit 577717
Packit 577717
	elapsed_virt_cyc = PAPI_get_virt_cyc(  );
Packit 577717
Packit 577717
	if (!quiet) printf("must_ptrace is %d\n",cmpinfo->attach_must_ptrace);
Packit 577717
	pid_t  child = wait( &status );
Packit 577717
	if (!quiet) printf( "Debugger exited wait() with %d\n",child );
Packit 577717
	  if (WIFSTOPPED( status ))
Packit 577717
	    {
Packit 577717
	      if (!quiet) printf( "Child has stopped due to signal %d (%s)\n",
Packit 577717
		      WSTOPSIG( status ), strsignal(WSTOPSIG( status )) );
Packit 577717
	    }
Packit 577717
	  if (WIFSIGNALED( status ))
Packit 577717
	    {
Packit 577717
	      if (!quiet) printf( "Child %ld received signal %d (%s)\n",
Packit 577717
		      (long)child,
Packit 577717
		      WTERMSIG(status) , strsignal(WTERMSIG( status )) );
Packit 577717
	    }
Packit 577717
	if (!quiet) printf("After %d\n",retval);
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
	if (!quiet) printf("Continuing\n");
Packit 577717
#if defined(__FreeBSD__)
Packit 577717
	if ( ptrace( PT_CONTINUE, pid, (caddr_t) 1, 0 ) == -1 ) {
Packit 577717
#else
Packit 577717
	if ( ptrace( PTRACE_CONT, pid, NULL, NULL ) == -1 ) {
Packit 577717
#endif
Packit 577717
	  perror( "ptrace(PTRACE_CONT)" );
Packit 577717
	  return 1;
Packit 577717
	}
Packit 577717
Packit 577717
Packit 577717
	do {
Packit 577717
	  child = wait( &status );
Packit 577717
	  if (!quiet) printf( "Debugger exited wait() with %d\n", child);
Packit 577717
	  if (WIFSTOPPED( status ))
Packit 577717
	    {
Packit 577717
	      if (!quiet) printf( "Child has stopped due to signal %d (%s)\n",
Packit 577717
		      WSTOPSIG( status ), strsignal(WSTOPSIG( status )) );
Packit 577717
	    }
Packit 577717
	  if (WIFSIGNALED( status ))
Packit 577717
	    {
Packit 577717
	      if (!quiet) printf( "Child %ld received signal %d (%s)\n",
Packit 577717
		      (long)child,
Packit 577717
		      WTERMSIG(status) , strsignal(WTERMSIG( status )) );
Packit 577717
	    }
Packit 577717
	} while (!WIFEXITED( status ));
Packit 577717
Packit 577717
	if (!quiet) printf("Child exited with value %d\n",WEXITSTATUS(status));
Packit 577717
	if (WEXITSTATUS(status) != 0) {
Packit 577717
	  test_fail( __FILE__, __LINE__, "Exit status of child to attach to", PAPI_EMISC);
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
	elapsed_virt_us = PAPI_get_virt_usec(  ) - elapsed_virt_us;
Packit 577717
Packit 577717
	elapsed_virt_cyc = PAPI_get_virt_cyc(  ) - elapsed_virt_cyc;
Packit 577717
Packit 577717
	elapsed_us = PAPI_get_real_usec(  ) - elapsed_us;
Packit 577717
Packit 577717
	elapsed_cyc = PAPI_get_real_cyc(  ) - elapsed_cyc;
Packit 577717
Packit 577717
	retval = PAPI_cleanup_eventset(EventSet1);
Packit 577717
	if (retval != PAPI_OK)
Packit 577717
	  test_fail( __FILE__, __LINE__, "PAPI_cleanup_eventset", retval );
Packit 577717
Packit 577717
	retval = PAPI_destroy_eventset(&EventSet1);
Packit 577717
	if (retval != PAPI_OK)
Packit 577717
	  test_fail( __FILE__, __LINE__, "PAPI_destroy_eventset", retval );
Packit 577717
Packit 577717
	if (!quiet) {
Packit 577717
	printf( "Test case: 3rd party attach start, stop.\n" );
Packit 577717
	printf( "-----------------------------------------------\n" );
Packit 577717
	tmp = PAPI_get_opt( PAPI_DEFDOM, NULL );
Packit 577717
	printf( "Default domain is: %d (%s)\n", tmp, stringify_all_domains( tmp ) );
Packit 577717
	tmp = PAPI_get_opt( PAPI_DEFGRN, NULL );
Packit 577717
	printf( "Default granularity is: %d (%s)\n", tmp,
Packit 577717
			stringify_granularity( tmp ) );
Packit 577717
	printf( "Using %d iterations of c += a*b\n", NUM_FLOPS );
Packit 577717
	printf( "-------------------------------------------------------------------------\n" );
Packit 577717
Packit 577717
	printf( "Test type    : \t           1\n" );
Packit 577717
Packit 577717
	printf( TAB1, "PAPI_TOT_CYC : \t", ( values[0] )[0] );
Packit 577717
	printf( "%s : \t %12lld\n", event_name, ( values[0] )[1] );
Packit 577717
	printf( TAB1, "Real usec    : \t", elapsed_us );
Packit 577717
	printf( TAB1, "Real cycles  : \t", elapsed_cyc );
Packit 577717
	printf( TAB1, "Virt usec    : \t", elapsed_virt_us );
Packit 577717
	printf( TAB1, "Virt cycles  : \t", elapsed_virt_cyc );
Packit 577717
Packit 577717
	printf( "-------------------------------------------------------------------------\n" );
Packit 577717
Packit 577717
	printf( "Verification: none\n" );
Packit 577717
	}
Packit 577717
	test_pass( __FILE__ );
Packit 577717
Packit 577717
	return 0;
Packit 577717
Packit 577717
}