Blame src/ctests/attach3.c

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