Exemple #1
0
static int
_x86_start( hwd_context_t * ctx, hwd_control_state_t * state )
{
	int error;
#ifdef DEBUG
	print_control( &state->control.cpu_control );
#endif

	if ( state->rvperfctr != NULL ) {
		if ( ( error =
			   rvperfctr_control( state->rvperfctr, &state->control ) ) < 0 ) {
			SUBDBG( "rvperfctr_control returns: %d\n", error );
			PAPIERROR( RCNTRL_ERROR );
			return ( PAPI_ESYS );
		}
		return ( PAPI_OK );
	}

	if ( ( error = vperfctr_control( ctx->perfctr, &state->control ) ) < 0 ) {
		SUBDBG( "vperfctr_control returns: %d\n", error );
		PAPIERROR( VCNTRL_ERROR );
		return ( PAPI_ESYS );
	}
	return ( PAPI_OK );
}
Exemple #2
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 );
}
Exemple #3
0
int
_papi_hwd_start( hwd_context_t * ctx, hwd_control_state_t * state )
{
	int error;
/*   clear_unused_pmcsel_bits(this_state);   moved to update_control_state */
#ifdef DEBUG
	print_control( &state->control.cpu_control );
#endif
	if ( state->rvperfctr != NULL ) {
		if ( ( error =
			   rvperfctr_control( state->rvperfctr, &state->control ) ) < 0 ) {
			SUBDBG( "rvperfctr_control returns: %d\n", error );
			PAPIERROR( RCNTRL_ERROR );
			return ( PAPI_ESYS );
		}
		return ( PAPI_OK );
	}
	if ( ( error = vperfctr_control( ctx->perfctr, &state->control ) ) < 0 ) {
		SUBDBG( "vperfctr_control returns: %d\n", error );
		PAPIERROR( VCNTRL_ERROR );
		return ( PAPI_ESYS );
	}
	return ( PAPI_OK );
}
Exemple #4
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);
    }
}