void *pthread_main(void *arg)
{
#if 0
   struct vperfctr *ptr = vperfctr_open();
   long long *lcyca;
   int i, iters = atoi(getenv("ITERS"));
   lcyca = (long long *) malloc(sizeof(long long) * iters);

   for (i = 0; i < iters; i++) {
      lcyca[i] = vperfctr_read_tsc(ptr);
   }

   for (i = 1; i < iters; i++)
      if (lcyca[i] - lcyca[i - 1] < 0)
         abort();
#endif
#if 0
   long long *lcyca;
   int i, iters = atoi(getenv("ITERS"));
   lcyca = (long long *) malloc(sizeof(long long) * iters);

   for (i = 0; i < iters; i++) {
      lcyca[i] = gethrvtime();
   }

   for (i = 1; i < iters; i++)
      if (lcyca[i] - lcyca[i - 1] < 0)
         abort();
#endif
   clockcore();
   return (NULL);
}
Example #2
0
static int hipe_perfctr_open(unsigned int user)
{
    struct perfctr_info info;

    if (!vperfctr) {
	vperfctr = vperfctr_open();
	if (!vperfctr)
	    return -1;
	if (vperfctr_info(vperfctr, &info) >= 0) {
	    tsc_to_ms = (double)(info.tsc_to_cpu_mult ? : 1) / (double)info.cpu_khz;
	    have_rdtsc = (info.cpu_features & PERFCTR_FEATURE_RDTSC) ? 1 : 0;
	}
Example #3
0
int
_perfctr_init( hwd_context_t * ctx )
{
	struct vperfctr_control tmp;
	int error;

	/* Initialize our thread/process pointer. */
	if ( ( ctx->perfctr = vperfctr_open(  ) ) == NULL ) {
#ifdef VPERFCTR_OPEN_CREAT_EXCL
		/* New versions of perfctr have this, which allows us to
		   get a previously created context, i.e. one created after
		   a fork and now we're inside a new process that has been exec'd */
		if ( errno ) {
			if ( ( ctx->perfctr = vperfctr_open_mode( 0 ) ) == NULL ) {
				PAPIERROR( VOPEN_ERROR );
				return ( PAPI_ESYS );
			}
		} else {
			PAPIERROR( VOPEN_ERROR );
			return ( PAPI_ESYS );
		}
#else
		PAPIERROR( VOPEN_ERROR );
		return ( PAPI_ESYS );
#endif
	}
	SUBDBG( "_papi_hwd_init vperfctr_open() = %p\n", ctx->perfctr );

	/* Initialize the per thread/process virtualized TSC */
	memset( &tmp, 0x0, sizeof ( tmp ) );
	tmp.cpu_control.tsc_on = 1;

#ifdef VPERFCTR_CONTROL_CLOEXEC
	tmp.flags = VPERFCTR_CONTROL_CLOEXEC;
	SUBDBG( "close on exec\t\t\t%u\n", tmp.flags );
#endif

	/* Start the per thread/process virtualized TSC */
	error = vperfctr_control( ctx->perfctr, &tmp );
	if ( error < 0 ) {
		SUBDBG( "starting virtualized TSC; vperfctr_control returns %d\n",
				error );
		PAPIERROR( VCNTRL_ERROR );
		return ( PAPI_ESYS );
	}

	return ( PAPI_OK );
}
Example #4
0
int
_perfctr_init_component( int cidx )
{
	int retval;
	struct perfctr_info info;
	char abiv[PAPI_MIN_STR_LEN];

#if defined(PERFCTR26)
	int fd;
#else
	struct vperfctr *dev;
#endif

#if defined(PERFCTR26)
	/* Get info from the kernel */
	/* Use lower level calls per Mikael to get the perfctr info
	   without actually creating a new kernel-side state.
	   Also, close the fd immediately after retrieving the info.
	   This is much lighter weight and doesn't reserve the counter
	   resources. Also compatible with perfctr 2.6.14.
	 */
	fd = _vperfctr_open( 0 );
	if ( fd < 0 ) {
	   strncpy(_perfctr_vector.cmp_info.disabled_reason,
		  VOPEN_ERROR,PAPI_MAX_STR_LEN);
	   return PAPI_ESYS;
	}
	retval = perfctr_info( fd, &info );
	close( fd );
	if ( retval < 0 ) {
	   strncpy(_perfctr_vector.cmp_info.disabled_reason,
		  VINFO_ERROR,PAPI_MAX_STR_LEN);
	   return PAPI_ESYS;
	}

	/* copy tsc multiplier to local variable        */
	/* this field appears in perfctr 2.6 and higher */
	tb_scale_factor = ( long long ) info.tsc_to_cpu_mult;
#else
	/* Opened once for all threads. */
	if ( ( dev = vperfctr_open(  ) ) == NULL ) {
	   strncpy(_perfctr_vector.cmp_info.disabled_reason,
		  VOPEN_ERROR,PAPI_MAX_STR_LEN);
	   return PAPI_ESYS;
	}
	SUBDBG( "_perfctr_init_component vperfctr_open = %p\n", dev );

	/* Get info from the kernel */
	retval = vperfctr_info( dev, &info );
	if ( retval < 0 ) {
	   strncpy(_perfctr_vector.cmp_info.disabled_reason,
		  VINFO_ERROR,PAPI_MAX_STR_LEN);
		return ( PAPI_ESYS );
	}
	vperfctr_close( dev );
#endif

	/* Fill in what we can of the papi_system_info. */
	retval = _papi_os_vector.get_system_info( &_papi_hwi_system_info );
	if ( retval != PAPI_OK )
		return ( retval );

	/* Setup memory info */
	retval = _papi_os_vector.get_memory_info( &_papi_hwi_system_info.hw_info,
						   ( int ) info.cpu_type );
	if ( retval )
		return ( retval );

	strcpy( _perfctr_vector.cmp_info.name,"perfctr.c" );
	strcpy( _perfctr_vector.cmp_info.version, "$Revision$" );
	sprintf( abiv, "0x%08X", info.abi_version );
	strcpy( _perfctr_vector.cmp_info.support_version, abiv );
	strcpy( _perfctr_vector.cmp_info.kernel_version, info.driver_version );
	_perfctr_vector.cmp_info.CmpIdx = cidx;
	_perfctr_vector.cmp_info.num_cntrs = ( int ) PERFCTR_CPU_NRCTRS( &info );
        _perfctr_vector.cmp_info.num_mpx_cntrs=_perfctr_vector.cmp_info.num_cntrs;
	if ( info.cpu_features & PERFCTR_FEATURE_RDPMC )
		_perfctr_vector.cmp_info.fast_counter_read = 1;
	else
		_perfctr_vector.cmp_info.fast_counter_read = 0;
	_perfctr_vector.cmp_info.fast_real_timer = 1;
	_perfctr_vector.cmp_info.fast_virtual_timer = 1;
	_perfctr_vector.cmp_info.attach = 1;
	_perfctr_vector.cmp_info.attach_must_ptrace = 1;
	_perfctr_vector.cmp_info.default_domain = PAPI_DOM_USER;
#if !defined(PPC64)
	/* AMD and Intel ia386 processors all support unit mask bits */
	_perfctr_vector.cmp_info.cntr_umasks = 1;
#endif
#if defined(PPC64)
	_perfctr_vector.cmp_info.available_domains =
		PAPI_DOM_USER | PAPI_DOM_KERNEL | PAPI_DOM_SUPERVISOR;
#else
	_perfctr_vector.cmp_info.available_domains = PAPI_DOM_USER | PAPI_DOM_KERNEL;
#endif
	_perfctr_vector.cmp_info.default_granularity = PAPI_GRN_THR;
	_perfctr_vector.cmp_info.available_granularities = PAPI_GRN_THR;
	if ( info.cpu_features & PERFCTR_FEATURE_PCINT )
		_perfctr_vector.cmp_info.hardware_intr = 1;
	else
		_perfctr_vector.cmp_info.hardware_intr = 0;
	SUBDBG( "Hardware/OS %s support counter generated interrupts\n",
			_perfctr_vector.cmp_info.hardware_intr ? "does" : "does not" );

	strcpy( _papi_hwi_system_info.hw_info.model_string,
			PERFCTR_CPU_NAME( &info ) );
	_papi_hwi_system_info.hw_info.model = ( int ) info.cpu_type;
#if defined(PPC64)
	_papi_hwi_system_info.hw_info.vendor = PAPI_VENDOR_IBM;
	if ( strlen( _papi_hwi_system_info.hw_info.vendor_string ) == 0 )
		strcpy( _papi_hwi_system_info.hw_info.vendor_string, "IBM" );
#else
	_papi_hwi_system_info.hw_info.vendor =
		xlate_cpu_type_to_vendor( info.cpu_type );
#endif

	/* Setup presets last. Some platforms depend on earlier info */
#if !defined(PPC64)
//     retval = setup_p3_vector_table(vtable);
		if ( !retval )
			retval = setup_x86_presets( ( int ) info.cpu_type );
#else
	/* Setup native and preset events */
//  retval = ppc64_setup_vector_table(vtable);
	if ( !retval )
		retval = perfctr_ppc64_setup_native_table(  );
	if ( !retval )
		retval = setup_ppc64_presets( info.cpu_type );
#endif
	if ( retval )
		return ( retval );

	return ( PAPI_OK );
}
Example #5
0
static void init_perfctr() {
    unsigned int tsc_on = 1;
    unsigned int nractrs = 1;
    unsigned int pmc_map0 = 0;
    unsigned int evntsel0 = 0;

    self = vperfctr_open();
    clock_perfctr = self;
    if( !self ) {
      char *str = "vperfctr_open() failed!!\n";
      syscall(SYS_write, 2, str, strlen(str));
      exit(1);
    }
    if( vperfctr_info(clock_perfctr, &info) < 0 ) {
      char *str = "vperfctr_info() failed!!\n";
      syscall(SYS_write, 2, str, strlen(str));
      exit(1);
    }

    memset(&control, 0, sizeof control);

    /* Attempt to set up control to count clocks via the TSC
       and retired instructions via PMC0. */
    switch( info.cpu_type ) {
      case PERFCTR_X86_GENERIC:
        nractrs = 0;            /* no PMCs available */
        break;
      case PERFCTR_X86_INTEL_P5:
      case PERFCTR_X86_INTEL_P5MMX:
      case PERFCTR_X86_CYRIX_MII:
        /* event 0x16 (INSTRUCTIONS_EXECUTED), count at CPL 3 */
        evntsel0 = 0x16 | (2 << 6);
        break;
      case PERFCTR_X86_INTEL_P6:
      case PERFCTR_X86_INTEL_PII:
      case PERFCTR_X86_INTEL_PIII:
      case PERFCTR_X86_AMD_K7:
      case PERFCTR_X86_AMD_K8:
        /* event 0xC0 (INST_RETIRED), count at CPL > 0, Enable */
        evntsel0 = 0xC0 | (1 << 16) | (1 << 22);
        break;
      case PERFCTR_X86_WINCHIP_C6:
        tsc_on = 0;             /* no working TSC available */
        evntsel0 = 0x02;        /* X86_INSTRUCTIONS */
        break;
      case PERFCTR_X86_WINCHIP_2:
        tsc_on = 0;             /* no working TSC available */
        evntsel0 = 0x16;        /* INSTRUCTIONS_EXECUTED */
        break;
      case PERFCTR_X86_VIA_C3:
        pmc_map0 = 1;           /* redirect PMC0 to PERFCTR1 */
        evntsel0 = 0xC0;        /* INSTRUCTIONS_EXECUTED */  
        break;
      case PERFCTR_X86_INTEL_P4:
      case PERFCTR_X86_INTEL_P4M2:
        /* PMC0: IQ_COUNTER0 with fast RDPMC */
        pmc_map0 = 0x0C | (1 << 31);
        /* IQ_CCCR0: required flags, ESCR 4 (CRU_ESCR0), Enable */
        evntsel0 = (0x3 << 16) | (4 << 13) | (1 << 12);
        /* CRU_ESCR0: event 2 (instr_retired), NBOGUSNTAG, CPL>0 */
        control.cpu_control.p4.escr[0] = (2 << 25) | (1 << 9) | (1 << 2);
        break;
    default: {
          char *str = "cpu type not supported - perfctr init failed!!\n";
          syscall(SYS_write, 2, str, strlen(str));
          exit(1);
        }
    }
    control.cpu_control.tsc_on = tsc_on;
    control.cpu_control.nractrs = nractrs;
    control.cpu_control.pmc_map[0] = pmc_map0;
    control.cpu_control.evntsel[0] = evntsel0;

    if (!nractrs) {
      //output("error: your CPU (%s) doesn't support PMC timing\n", perfctr_info_cpu_name(&info));
      char *str = "error: your CPU doesn't support PMC timing\n";
      syscall(SYS_write, 2, str, strlen(str));
      exit(1);
    }

    // start the perfctr
    if( vperfctr_control(clock_perfctr, &control) < 0 ) {
      char *str = "vperfctr_control failed!!!\n";
      syscall(SYS_write, 2, str, strlen(str));
      exit(1);
    }
}