PAPI  5.0.1.0
aix.c File Reference
Include dependency graph for aix.c:

Go to the source code of this file.

Defines

#define START_OF_TEXT   &_text
#define END_OF_TEXT   &_etext
#define START_OF_DATA   &_data
#define END_OF_DATA   &_edata
#define START_OF_BSS   &_edata
#define END_OF_BSS   &_end

Functions

void aix_initialize_native_table ()
static void aix_ppc64_setup_gps (int total)
int aix_ppc64_setup_native_table ()
static void copy_value (unsigned int val, char *nam, char *names, unsigned int *values, int len)
static int do_counter_allocation (ppc64_reg_alloc_t *event_list, int size)
int _aix_allocate_registers (EventSetInfo_t *ESI)
int _aix_init_control_state (void *ptr)
int _aix_update_control_state (void *this_state, NativeInfo_t *native, int count, void *context)
static char * trim_string (char *in)
int _aix_ntv_code_to_name (unsigned int EventCode, char *ntv_name, int len)
int _aix_ntv_code_to_descr (unsigned int EventCode, char *ntv_descr, int len)
int _aix_ntv_code_to_bits (unsigned int EventCode, void *bits)
int _aix_ntv_enum_events (unsigned int *EventCode, int modifier)
static void set_config (void *ptr, int arg1, int arg2)
static void unset_config (void *ptr, int arg1)
int init_domain ()
static int _aix_set_domain (void *this_state, int domain)
int _aix_set_granularity (void *this_state, int domain)
static int set_default_domain (EventSetInfo_t *zero, int domain)
static int set_default_granularity (EventSetInfo_t *zero, int granularity)
int _aix_mdi_init ()
static int _aix_get_system_info (papi_mdi_t *mdi)
long long _aix_get_real_usec (void)
long long _aix_get_real_cycles (void)
long long _aix_get_virt_usec (void)
static void _aix_lock_init (void)
int _aix_shutdown_thread (void *ctx)
int _aix_init_component (int cidx)
int _aix_init_thread (void *context)
static int get_avail_hwcntr_bits (int cntr_avail_bits)
static void set_hwcntr_codes (int selector, unsigned char *from, int *to)
int _aix_reset (void *ESI, void *zero)
int _aix_read (void *ctx, void *spc, long long **vals, int flags)
static int round_requested_ns (int ns)
int _aix_ctl (void *ctx, int code, _papi_int_option_t *option)
void _aix_dispatch_timer (int signal, siginfo_t *si, void *i)
int _aix_set_overflow (EventSetInfo_t *ESI, int EventIndex, int threshold)
void * _aix_get_overflow_address (void *context)
int _aix_start (void *ctx, void *cntrl)
int _aix_stop (void *ctx, void *cntrl)
int _aix_update_shlib_info (papi_mdi_t *mdi)
int _aix_ntv_name_to_code (char *name, unsigned int *evtcode)
int _papi_hwi_init_os (void)

Variables

papi_vector_t _aix_vector
volatile int lock_var [(9+0x2)] = { 0 }
atomic_p lock [(9+0x2)]
static int maxgroups = 0
struct utsname AixVer
native_event_entry_t native_table [1024]
hwd_pminfo_t pminfo
pm_groups_info_t pmgroups
PPC64_native_map_t native_name_map [1024]
hwd_groups_t group_map [(8 *32)] = { 0 }
PAPI_os_info_t _papi_os_info
papi_os_vector_t _papi_os_vector

Define Documentation

#define END_OF_BSS   &_end

Definition at line 36 of file aix.c.

#define END_OF_DATA   &_edata

Definition at line 34 of file aix.c.

#define END_OF_TEXT   &_etext

Definition at line 32 of file aix.c.

#define START_OF_BSS   &_edata

Definition at line 35 of file aix.c.

#define START_OF_DATA   &_data

Definition at line 33 of file aix.c.

#define START_OF_TEXT   &_text

Definition at line 31 of file aix.c.


Function Documentation

< Event exists, but cannot be counted due to counter resource limitations

< Event exists, but cannot be counted due to counter resource limitations

< No error

< Event exists, but cannot be counted due to counter resource limitations

Definition at line 201 of file aix.c.

{
    hwd_control_state_t *this_state = ESI->ctl_state;
    unsigned char selector;
    int i, j, natNum, index;
    ppc64_reg_alloc_t event_list[MAX_COUNTERS];
    int position, group;


    /* not yet successfully mapped, but have enough slots for events */

    /* Initialize the local structure needed 
       for counter allocation and optimization. */
    natNum = ESI->NativeCount;
    for ( i = 0; i < natNum; i++ ) {
        /* CAUTION: Since this is in the hardware layer, it's ok 
           to access the native table directly, but in general this is a bad idea */
        event_list[i].ra_position = -1;
        /* calculate native event rank, which is number of counters it can live on, this is power3 specific */
        for ( j = 0; j < MAX_COUNTERS; j++ ) {
            if ( ( index =
                   native_name_map[ESI->NativeInfoArray[i].
                                   ni_event & PAPI_NATIVE_AND_MASK].index ) <
                 0 )
                return PAPI_ECNFLCT;
            event_list[i].ra_counter_cmd[j] =
                native_table[index].resources.counter_cmd[j];
        }
        for ( j = 0; j < GROUP_INTS; j++ ) {
            if ( ( index =
                   native_name_map[ESI->NativeInfoArray[i].
                                   ni_event & PAPI_NATIVE_AND_MASK].index ) <
                 0 )
                return PAPI_ECNFLCT;
            event_list[i].ra_group[j] = native_table[index].resources.group[j];
        }
        /*event_list[i].ra_mod = -1; */
    }

    if ( ( group = do_counter_allocation( event_list, natNum ) ) >= 0 ) {   /* successfully mapped */
        /* copy counter allocations info back into NativeInfoArray */
        this_state->group_id = group;
        for ( i = 0; i < natNum; i++ )
            ESI->NativeInfoArray[i].ni_position = event_list[i].ra_position;
        /* update the control structure based on the NativeInfoArray */
      /*_papi_hwd_update_control_state(this_state, ESI->NativeInfoArray, natNum);*/
        return PAPI_OK;
    } else {
        return PAPI_ECNFLCT;
    }
}

Here is the call graph for this function:

int _aix_ctl ( void *  ctx,
int  code,
_papi_int_option_t option 
)

< Domain for an eventset

< Granularity for an eventset

< Option to set the type of itimer used in both software multiplexing, overflowing and profiling

< Invalid argument

< Invalid argument

< Invalid argument

< No error

< Multiplexing/overflowing interval in ns, same as PAPI_DEF_ITIMER_NS

< No error

< Multiplexing/overflowing interval in ns, same as PAPI_DEF_MPX_NS

< No error

< Not supported

Definition at line 874 of file aix.c.

{
    switch ( code ) {
/* I don't understand what it means to set the default domain 
    case PAPI_DEFDOM:
      return(set_default_domain(zero, option->domain.domain));
*/
    case PAPI_DOMAIN:
        return ( _aix_set_domain
                 ( option->domain.ESI->ctl_state, option->domain.domain ) );
/* I don't understand what it means to set the default granularity 
    case PAPI_DEFGRN:
      return(set_default_granularity(zero, option->granularity.granularity));
*/
    case PAPI_GRANUL:
        return ( _aix_set_granularity
                 ( option->domain.ESI->ctl_state,
                   option->granularity.granularity ) );
#if 0
    case PAPI_INHERIT:
        return ( set_inherit( option->inherit.inherit ) );
#endif
    case PAPI_DEF_ITIMER:
    {
        /* flags are currently ignored, eventually the flags will be able
           to specify whether or not we use POSIX itimers (clock_gettimer) */
        if ( ( option->itimer.itimer_num == ITIMER_REAL ) &&
             ( option->itimer.itimer_sig != SIGALRM ) )
            return PAPI_EINVAL;
        if ( ( option->itimer.itimer_num == ITIMER_VIRTUAL ) &&
             ( option->itimer.itimer_sig != SIGVTALRM ) )
            return PAPI_EINVAL;
        if ( ( option->itimer.itimer_num == ITIMER_PROF ) &&
             ( option->itimer.itimer_sig != SIGPROF ) )
            return PAPI_EINVAL;
        if ( option->itimer.ns > 0 )
            option->itimer.ns = round_requested_ns( option->itimer.ns );
        /* At this point, we assume the user knows what he or
           she is doing, they maybe doing something arch specific */
        return PAPI_OK;
    }
    case PAPI_DEF_MPX_NS:
    {
        option->multiplex.ns = round_requested_ns( option->multiplex.ns );
        return ( PAPI_OK );
    }
    case PAPI_DEF_ITIMER_NS:
    {
        option->itimer.ns = round_requested_ns( option->itimer.ns );
        return ( PAPI_OK );
    }
    default:
        return ( PAPI_ENOSUPP );
    }
}

Here is the call graph for this function:

void _aix_dispatch_timer ( int  signal,
siginfo_t si,
void *  i 
)

Definition at line 931 of file aix.c.

{
    _papi_hwi_context_t ctx;
    ThreadInfo_t *t = NULL;
    caddr_t address;

    ctx.si = si;
    ctx.ucontext = ( hwd_ucontext_t * ) i;

    address = ( caddr_t ) GET_OVERFLOW_ADDRESS( ( &ctx ) );
    _papi_hwi_dispatch_overflow_signal( ( void * ) &ctx, address, NULL, 0, 0,
                        &t, _aix_vector.cmp_info.CmpIdx );
}

Here is the call graph for this function:

void* _aix_get_overflow_address ( void *  context)

Definition at line 954 of file aix.c.

{
    void *location;
    struct sigcontext *info = ( struct sigcontext * ) context;
    location = ( void * ) info->sc_jmpbuf.jmp_context.iar;

    return ( location );
}
long long _aix_get_real_cycles ( void  )

Definition at line 666 of file aix.c.

{
    return ( _aix_get_real_usec(  ) *
             ( long long ) _papi_hwi_system_info.hw_info.cpu_max_mhz );
}

Here is the call graph for this function:

long long _aix_get_real_usec ( void  )

Definition at line 654 of file aix.c.

{
    timebasestruct_t t;
    long long retval;

    read_real_time( &t, TIMEBASE_SZ );
    time_base_to_time( &t, TIMEBASE_SZ );
    retval = ( t.tb_high * 1000000 ) + t.tb_low / 1000;
    return ( retval );
}

Here is the caller graph for this function:

static int _aix_get_system_info ( papi_mdi_t mdi) [static]

< A System/C library call failed

< A System/C library call failed

< PAPI counters for each individual thread

< No error

Definition at line 560 of file aix.c.

{
    int retval;
    /* pm_info_t pminfo; */
    struct procsinfo psi = { 0 };
    pid_t pid;
    char maxargs[PAPI_HUGE_STR_LEN];
    char pname[PAPI_HUGE_STR_LEN];

    pid = getpid(  );
    if ( pid == -1 )
        return ( PAPI_ESYS );
    _papi_hwi_system_info.pid = pid;
    psi.pi_pid = pid;
    retval = getargs( &psi, sizeof ( psi ), maxargs, PAPI_HUGE_STR_LEN );
    if ( retval == -1 )
        return ( PAPI_ESYS );

    if ( realpath( maxargs, pname ) )
        strncpy( _papi_hwi_system_info.exe_info.fullname, pname,
                 PAPI_HUGE_STR_LEN );
    else
        strncpy( _papi_hwi_system_info.exe_info.fullname, maxargs,
                 PAPI_HUGE_STR_LEN );

    strcpy( _papi_hwi_system_info.exe_info.address_info.name,
            basename( maxargs ) );

#ifdef _POWER7
    /* we pass PM_POWER7 for the same reasons as below (power6 case) */
    retval = pm_initialize( PM_INIT_FLAGS , &pminfo, &pmgroups, PM_POWER7); 
#elif defined(_POWER6)
    /* problem with pm_initialize(): it cannot be called multiple times with 
       PM_CURRENT; use instead the actual proc type - here PM_POWER6 - 
       and multiple invocations are no longer a problem */ 
    retval = pm_initialize( PM_INIT_FLAGS, &pminfo, &pmgroups, PM_POWER6 );
#else
#ifdef _AIXVERSION_510
#ifdef PM_INITIALIZE
    SUBDBG( "Calling AIX 5 version of pm_initialize...\n" );
/*#if defined(_POWER5)
    retval = pm_initialize(PM_INIT_FLAGS, &pminfo, &pmgroups, PM_POWER5);
#endif*/
    retval = pm_initialize( PM_INIT_FLAGS, &pminfo, &pmgroups, PM_CURRENT );
#else
    SUBDBG( "Calling AIX 5 version of pm_init...\n" );
    retval = pm_init( PM_INIT_FLAGS, &pminfo, &pmgroups );
#endif

#else
    SUBDBG( "Calling AIX 4 version of pm_init...\n" );
    retval = pm_init( PM_INIT_FLAGS, &pminfo );
#endif
#endif
    SUBDBG( "...Back from pm_init\n" );

    if ( retval > 0 )
        return ( retval );

    _aix_mdi_init(  );

    _papi_hwi_system_info.hw_info.nnodes = 1;
    _papi_hwi_system_info.hw_info.ncpu = _system_configuration.ncpus;
    _papi_hwi_system_info.hw_info.totalcpus =
        _papi_hwi_system_info.hw_info.ncpu *
        _papi_hwi_system_info.hw_info.nnodes;
    _papi_hwi_system_info.hw_info.vendor = -1;
    strcpy( _papi_hwi_system_info.hw_info.vendor_string, "IBM" );
    _papi_hwi_system_info.hw_info.model = _system_configuration.implementation;
    strcpy( _papi_hwi_system_info.hw_info.model_string, pminfo.proc_name );
    _papi_hwi_system_info.hw_info.revision =
        ( float ) _system_configuration.version;
    _papi_hwi_system_info.hw_info.mhz = ( float ) ( pm_cycles(  ) / 1000000.0 );
    _papi_hwi_system_info.hw_info.cpu_max_mhz=_papi_hwi_system_info.hw_info.mhz;
    _papi_hwi_system_info.hw_info.cpu_min_mhz=_papi_hwi_system_info.hw_info.mhz;

/*   _papi_hwi_system_info.num_gp_cntrs = pminfo.maxpmcs;*/
    _aix_vector.cmp_info.num_cntrs = pminfo.maxpmcs;
    _aix_vector.cmp_info.num_mpx_cntrs = MAX_MPX_COUNTERS;   // pminfo.maxpmcs,

    _aix_vector.cmp_info.available_granularities = PAPI_GRN_THR;
/* This field doesn't appear to exist in the PAPI 3.0 structure 
  _papi_hwi_system_info.cpunum = mycpu(); 
*/
    _aix_vector.cmp_info.available_domains = init_domain(  );
    return PAPI_OK;
}

Here is the call graph for this function:

long long _aix_get_virt_usec ( void  )

Definition at line 673 of file aix.c.

{
    long long retval;
    struct tms buffer;

    times( &buffer );
    SUBDBG( "user %d system %d\n", ( int ) buffer.tms_utime,
            ( int ) buffer.tms_stime );
    retval =
        ( long long ) ( ( buffer.tms_utime + buffer.tms_stime ) *
                        ( 1000000 / CLK_TCK ) );
    return ( retval );
}
int _aix_init_component ( int  cidx)

< No error

< Not implemented

Definition at line 702 of file aix.c.

{
    int retval = PAPI_OK, procidx;

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

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

    SUBDBG( "Found %d %s %s CPUs at %d Mhz.\n",
            _papi_hwi_system_info.hw_info.totalcpus,
            _papi_hwi_system_info.hw_info.vendor_string,
            _papi_hwi_system_info.hw_info.model_string,
            _papi_hwi_system_info.hw_info.cpu_max_mhz );

    _aix_vector.cmp_info.CmpIdx = cidx;
    _aix_vector.cmp_info.num_native_events = aix_ppc64_setup_native_table(  );

    procidx = pm_get_procindex(  );
    switch ( procidx ) {
    case PM_POWER5:
      _papi_load_preset_table( "POWER5", 0, cidx );
        break;
    case PM_POWER5_II:
      _papi_load_preset_table( "POWER5+", 0, cidx );
        break;
    case PM_POWER6:
      _papi_load_preset_table( "POWER6", 0, cidx );
        break;
    case PM_PowerPC970:
      _papi_load_preset_table( "PPC970", 0, cidx );
        break;
    case PM_POWER7:
      _papi_load_preset_table( "POWER7", 0, cidx );
        break;
    default:
        fprintf( stderr, "%s is not supported!\n", pminfo.proc_name );
        return PAPI_ENOIMPL;
    }

    _aix_lock_init(  );

    return ( retval );
}

Here is the call graph for this function:

int _aix_init_control_state ( void *  ptr)

< No error

Definition at line 254 of file aix.c.

{
    int i;

    for ( i = 0; i < _aix_vector.cmp_info.num_cntrs; i++ ) {
        ptr->counter_cmd.events[i] = COUNT_NOTHING;
    }
    ptr->counter_cmd.mode.b.is_group = 1;

    _aix_vector.set_domain( ptr, _aix_vector.cmp_info.default_domain );
    _aix_set_granularity( ptr, _aix_vector.cmp_info.default_granularity );
    /*setup_native_table(); */
    return ( PAPI_OK );
}

Here is the call graph for this function:

Here is the caller graph for this function:

int _aix_init_thread ( void *  context)

Definition at line 754 of file aix.c.

{
    int retval;
    /* Initialize our global control state. */

    _aix_init_control_state( &context->cntrl );
}

Here is the call graph for this function:

static void _aix_lock_init ( void  ) [static]

< Used with setting up array

Definition at line 688 of file aix.c.

{
    int i;
    for ( i = 0; i < PAPI_MAX_LOCK; i++ )
        lock[i] = ( int * ) ( lock_var + i );
}

Here is the caller graph for this function:

int _aix_mdi_init ( )

< A System/C library call failed

< No error

Definition at line 526 of file aix.c.

{
    int retval;

    if ( ( retval = uname( &AixVer ) ) < 0 )
        return ( PAPI_ESYS );
    if ( AixVer.version[0] == '4' ) {
        _papi_hwi_system_info.exe_info.address_info.text_start =
            ( caddr_t ) START_OF_TEXT;
        _papi_hwi_system_info.exe_info.address_info.text_end =
            ( caddr_t ) END_OF_TEXT;
        _papi_hwi_system_info.exe_info.address_info.data_start =
            ( caddr_t ) START_OF_DATA;
        _papi_hwi_system_info.exe_info.address_info.data_end =
            ( caddr_t ) END_OF_DATA;
        _papi_hwi_system_info.exe_info.address_info.bss_start =
            ( caddr_t ) START_OF_BSS;
        _papi_hwi_system_info.exe_info.address_info.bss_end =
            ( caddr_t ) END_OF_BSS;
    } else {
        _aix_update_shlib_info( &_papi_hwi_system_info );
    }

/*   _papi_hwi_system_info.supports_64bit_counters = 1;
   _papi_hwi_system_info.supports_real_usec = 1;
   _papi_hwi_system_info.sub_info.fast_real_timer = 1;
   _papi_hwi_system_info.sub_info->available_domains = init_domain();*/


    return ( PAPI_OK );
}

Here is the call graph for this function:

Here is the caller graph for this function:

int _aix_ntv_code_to_bits ( unsigned int  EventCode,
void *  bits 
)

< No error

Definition at line 348 of file aix.c.

{
    bits = &native_table[EventCode & PAPI_NATIVE_AND_MASK].resources;   /* it is not right, different type */
    return ( PAPI_OK );
}
int _aix_ntv_code_to_descr ( unsigned int  EventCode,
char *  ntv_descr,
int  len 
)

< Event does not exist

< Buffer size exceeded

< No error

Definition at line 330 of file aix.c.

{
    if ( ( EventCode & PAPI_NATIVE_AND_MASK ) >=
         _aix_vector.cmp_info.num_native_events )
        return ( PAPI_ENOEVNT );
    strncpy( ntv_descr,
             native_table[native_name_map[EventCode & PAPI_NATIVE_AND_MASK].
                          index].description, len );
    trim_string( ntv_descr );
    if ( strlen
         ( native_table
           [native_name_map[EventCode & PAPI_NATIVE_AND_MASK].index].
           description ) > len - 1 )
        return ( PAPI_EBUF );
    return ( PAPI_OK );
}

Here is the call graph for this function:

int _aix_ntv_code_to_name ( unsigned int  EventCode,
char *  ntv_name,
int  len 
)

< Event does not exist

< Buffer size exceeded

< No error

Definition at line 315 of file aix.c.

{
    if ( ( EventCode & PAPI_NATIVE_AND_MASK ) >=
         _aix_vector.cmp_info.num_native_events )
        return ( PAPI_ENOEVNT );
    strncpy( ntv_name,
             native_name_map[EventCode & PAPI_NATIVE_AND_MASK].name, len );
    trim_string( ntv_name );
    if ( strlen( native_name_map[EventCode & PAPI_NATIVE_AND_MASK].name ) >
         len - 1 )
        return ( PAPI_EBUF );
    return ( PAPI_OK );
}

Here is the call graph for this function:

int _aix_ntv_enum_events ( unsigned int *  EventCode,
int  modifier 
)

< No error

< No error

< Event does not exist

< Event does not exist

< Invalid argument

Definition at line 366 of file aix.c.

{
    if ( modifier == PAPI_ENUM_FIRST ) {
        *EventCode = PAPI_NATIVE_MASK;
        return ( PAPI_OK );
    }
    if ( modifier == PAPI_ENUM_EVENTS ) {
        int index = *EventCode & PAPI_NATIVE_AND_MASK;

        if ( native_table[index + 1].resources.selector ) {
            *EventCode = *EventCode + 1;
            return ( PAPI_OK );
        } else
            return ( PAPI_ENOEVNT );
    } else if ( modifier == PAPI_NTV_ENUM_GROUPS ) {
#if defined(_POWER5) || defined(_POWER6)
        unsigned int group =
            ( *EventCode & PAPI_NTV_GROUP_AND_MASK ) >> PAPI_NTV_GROUP_SHIFT;
        int index = *EventCode & 0x000000FF;
        int i;
        unsigned int tmpg;

        *EventCode = *EventCode & ( ~PAPI_NTV_GROUP_SHIFT );
        for ( i = 0; i < GROUP_INTS; i++ ) {
            tmpg = native_table[index].resources.group[i];
            if ( group != 0 ) {
                while ( ( ffs( tmpg ) + i * 32 ) <= group && tmpg != 0 )
                    tmpg = tmpg ^ ( 1 << ( ffs( tmpg ) - 1 ) );
            }
            if ( tmpg != 0 ) {
                group = ffs( tmpg ) + i * 32;
                *EventCode = *EventCode | ( group << PAPI_NTV_GROUP_SHIFT );
                return ( PAPI_OK );
            }
        }
#endif
        return ( PAPI_ENOEVNT );
    } else
        return ( PAPI_EINVAL );
}
int _aix_ntv_name_to_code ( char *  name,
unsigned int *  evtcode 
)

< No error

< Event does not exist

Definition at line 1196 of file aix.c.

{
       int i;

       for ( i = 0; i < PAPI_MAX_NATIVE_EVENTS; i++ )
               if ( strcmp( name, native_name_map[i].name ) == 0 ) {
                       *evtcode = native_name_map[i].index | PAPI_NATIVE_MASK;
                       return PAPI_OK;
               }

       return PAPI_ENOEVNT;
}
int _aix_read ( void *  ctx,
void *  spc,
long long **  vals,
int  flags 
)

< Option to turn off automatic reporting of return codes < 0 to stderr.

< No error

Definition at line 840 of file aix.c.

{
    int retval;

    retval = pm_get_data_mythread( &spc->state );
    if ( retval > 0 ) {
        if ( _papi_hwi_error_level != PAPI_QUIET )
            pm_error( "PAPI Error: pm_get_data_mythread", retval );
        return ( retval );
    }

    *vals = spc->state.accu;

#ifdef DEBUG
    if ( ISLEVEL( DEBUG_SUBSTRATE ) )
        dump_data( *vals );
#endif

    return ( PAPI_OK );
}
int _aix_reset ( void *  ESI,
void *  zero 
)

< Option to turn off automatic reporting of return codes < 0 to stderr.

< No error

Definition at line 827 of file aix.c.

{
    int retval = pm_reset_data_mythread(  );
    if ( retval > 0 ) {
        if ( _papi_hwi_error_level != PAPI_QUIET )
            pm_error( "PAPI Error: pm_reset_data_mythread", retval );
        return ( retval );
    }
    return ( PAPI_OK );
}
static int _aix_set_domain ( void *  this_state,
int  domain 
) [static]

< User context counted

< Kernel/OS context counted

< No error

< Invalid argument

Definition at line 436 of file aix.c.

{
    pm_mode_t *mode = &( this_state->counter_cmd.mode );
    int did = 0;

    mode->b.user = 0;
    mode->b.kernel = 0;
    if ( domain & PAPI_DOM_USER ) {
        did++;
        mode->b.user = 1;
    }
    if ( domain & PAPI_DOM_KERNEL ) {
        did++;
        mode->b.kernel = 1;
    }
#ifdef PM_INITIALIZE
#ifdef _AIXVERSION_510
    if ( ( domain & PAPI_DOM_SUPERVISOR ) && pminfo.proc_feature.b.hypervisor ) {
        did++;
        mode->b.hypervisor = 1;
    }
#endif
#endif
    if ( did )
        return ( PAPI_OK );
    else
        return ( PAPI_EINVAL );
/*
  switch (domain)
    {
    case PAPI_DOM_USER:
      mode->b.user = 1;
      mode->b.kernel = 0;
      break;
    case PAPI_DOM_KERNEL:
      mode->b.user = 0;
      mode->b.kernel = 1;
      break;
    case PAPI_DOM_ALL:
      mode->b.user = 1;
      mode->b.kernel = 1;
      break;
    default:
      return(PAPI_EINVAL);
    }
  return(PAPI_OK);
*/
}

Here is the caller graph for this function:

int _aix_set_granularity ( void *  this_state,
int  domain 
)

< PAPI counters for each individual thread

< Invalid argument

< No error

Definition at line 486 of file aix.c.

{
    pm_mode_t *mode = &( this_state->counter_cmd.mode );

    switch ( domain ) {
    case PAPI_GRN_THR:
        mode->b.process = 0;
        mode->b.proctree = 0;
        break;
        /* case PAPI_GRN_PROC:
           mode->b.process = 1;
           mode->b.proctree = 0;
           break;
           case PAPI_GRN_PROCG:
           mode->b.process = 0;
           mode->b.proctree = 1;
           break; */
    default:
        return ( PAPI_EINVAL );
    }
    return ( PAPI_OK );
}

Here is the caller graph for this function:

int _aix_set_overflow ( EventSetInfo_t ESI,
int  EventIndex,
int  threshold 
)

< No error

Definition at line 946 of file aix.c.

{
    hwd_control_state_t *this_state = ESI->ctl_state;

    return ( PAPI_OK );
}
int _aix_shutdown_thread ( void *  ctx)

< No error

Definition at line 696 of file aix.c.

{
    return ( PAPI_OK );
}
int _aix_start ( void *  ctx,
void *  cntrl 
)

< Option to turn off automatic reporting of return codes < 0 to stderr.

< Option to turn off automatic reporting of return codes < 0 to stderr.

< Option to turn off automatic reporting of return codes < 0 to stderr.

< Option to turn off automatic reporting of return codes < 0 to stderr.

< No error

Definition at line 967 of file aix.c.

{
    int i, retval;
    hwd_control_state_t *current_state = &ctx->cntrl;

    /* If we are nested, merge the global counter structure
       with the current eventset */

    SUBDBG( "Start\n" );

    /* Copy the global counter structure to the current eventset */

    SUBDBG( "Copying states\n" );
    memcpy( current_state, cntrl, sizeof ( hwd_control_state_t ) );

    retval = pm_set_program_mythread( &current_state->counter_cmd );
    if ( retval > 0 ) {
        if ( retval == 13 ) {
            retval = pm_delete_program_mythread(  );
            if ( retval > 0 ) {
                if ( _papi_hwi_error_level != PAPI_QUIET )
                    pm_error( "PAPI Error: pm_delete_program_mythread",
                              retval );
                return ( retval );
            }
            retval = pm_set_program_mythread( &current_state->counter_cmd );
            if ( retval > 0 ) {
                if ( _papi_hwi_error_level != PAPI_QUIET )
                    pm_error( "PAPI Error: pm_set_program_mythread", retval );
                return ( retval );
            }
        } else {
            if ( _papi_hwi_error_level != PAPI_QUIET )
                pm_error( "PAPI Error: pm_set_program_mythread", retval );
            return ( retval );
        }
    }

    /* Set up the new merged control structure */

#if 0
    dump_cmd( &current_state->counter_cmd );
#endif

    /* Start the counters */

    retval = pm_start_mythread(  );
    if ( retval > 0 ) {
        if ( _papi_hwi_error_level != PAPI_QUIET )
            pm_error( "pm_start_mythread()", retval );
        return ( retval );
    }

    return ( PAPI_OK );
}
int _aix_stop ( void *  ctx,
void *  cntrl 
)

< Option to turn off automatic reporting of return codes < 0 to stderr.

< Option to turn off automatic reporting of return codes < 0 to stderr.

< No error

Definition at line 1024 of file aix.c.

{
    int retval;

    retval = pm_stop_mythread(  );
    if ( retval > 0 ) {
        if ( _papi_hwi_error_level != PAPI_QUIET )
            pm_error( "pm_stop_mythread()", retval );
        return ( retval );
    }

    retval = pm_delete_program_mythread(  );
    if ( retval > 0 ) {
        if ( _papi_hwi_error_level != PAPI_QUIET )
            pm_error( "pm_delete_program_mythread()", retval );
        return ( retval );
    }

    return ( PAPI_OK );
}
int _aix_update_control_state ( void *  this_state,
NativeInfo_t native,
int  count,
void *  context 
)

< No error

Definition at line 273 of file aix.c.

{

    this_state->counter_cmd.events[0] = this_state->group_id;
    return PAPI_OK;
}

< Not implemented

Definition at line 1046 of file aix.c.

{
#if ( ( defined( _AIXVERSION_510) || defined(_AIXVERSION_520)))
    struct ma_msg_s
    {
        long flag;
        char *name;
    } ma_msgs[] = {
        {
        MA_MAINEXEC, "MAINEXEC"}, {
        MA_KERNTEXT, "KERNTEXT"}, {
        MA_READ, "READ"}, {
        MA_WRITE, "WRITE"}, {
        MA_EXEC, "EXEC"}, {
        MA_SHARED, "SHARED"}, {
        MA_BREAK, "BREAK"}, {
    MA_STACK, "STACK"},};

    char fname[80], name[PAPI_HUGE_STR_LEN];
    prmap_t newp;
    int count, t_index, retval, i, j, not_first_flag_bit;
    FILE *map_f;
    void *vaddr;
    prmap_t *tmp1 = NULL;
    PAPI_address_map_t *tmp2 = NULL;

    sprintf( fname, "/proc/%d/map", getpid(  ) );
    map_f = fopen( fname, "r" );
    if ( !map_f ) {
        PAPIERROR( "fopen(%s) returned < 0", fname );
        return ( PAPI_OK );
    }

    /* count the entries we need */
    count = 0;
    t_index = 0;
    while ( ( retval = fread( &newp, sizeof ( prmap_t ), 1, map_f ) ) > 0 ) {
        if ( newp.pr_pathoff > 0 && newp.pr_mapname[0] != '\0' ) {
            if ( newp.pr_mflags & MA_STACK )
                continue;

            count++;
            SUBDBG( "count=%d offset=%ld map=%s\n", count,
                    newp.pr_pathoff, newp.pr_mapname );

            if ( ( newp.pr_mflags & MA_READ ) && ( newp.pr_mflags & MA_EXEC ) )
                t_index++;
        }
    }
    rewind( map_f );
    tmp1 = ( prmap_t * ) papi_calloc( ( count + 1 ), sizeof ( prmap_t ) );
    if ( tmp1 == NULL )
        return ( PAPI_ENOMEM );

    tmp2 =
        ( PAPI_address_map_t * ) papi_calloc( t_index,
                                              sizeof ( PAPI_address_map_t ) );
    if ( tmp2 == NULL )
        return ( PAPI_ENOMEM );

    i = 0;
    t_index = -1;
    while ( ( retval = fread( &tmp1[i], sizeof ( prmap_t ), 1, map_f ) ) > 0 ) {
        if ( tmp1[i].pr_pathoff > 0 && tmp1[i].pr_mapname[0] != '\0' )
            if ( !( tmp1[i].pr_mflags & MA_STACK ) )
                i++;
    }
    for ( i = 0; i < count; i++ ) {
        char c;
        int cc = 0;

        retval = fseek( map_f, tmp1[i].pr_pathoff, SEEK_SET );
        if ( retval != 0 )
            return ( PAPI_ESYS );
        while ( fscanf( map_f, "%c", &c ) != EOF ) {
            name[cc] = c;
            /* how many char are hold in /proc/xxxx/map */
            cc++;
            if ( c == '\0' )
                break;
        }


        /* currently /proc/xxxx/map file holds only 33 char per line (incl NULL char);
         * if executable name > 32 char, compare first 32 char only */
        if ( strncmp( _papi_hwi_system_info.exe_info.address_info.name,
                      basename( name ), cc - 1 ) == 0 ) {
            if ( strlen( _papi_hwi_system_info.exe_info.address_info.name ) !=
                 cc - 1 )
                PAPIERROR
                    ( "executable name too long (%d char). Match of first %d char only",
                      strlen( _papi_hwi_system_info.exe_info.address_info.
                              name ), cc - 1 );

            if ( tmp1[i].pr_mflags & MA_READ ) {
                if ( tmp1[i].pr_mflags & MA_EXEC ) {
                    _papi_hwi_system_info.exe_info.address_info.
                        text_start = ( caddr_t ) tmp1[i].pr_vaddr;
                    _papi_hwi_system_info.exe_info.address_info.
                        text_end =
                        ( caddr_t ) ( tmp1[i].pr_vaddr + tmp1[i].pr_size );
                } else if ( tmp1[i].pr_mflags & MA_WRITE ) {
                    _papi_hwi_system_info.exe_info.address_info.
                        data_start = ( caddr_t ) tmp1[i].pr_vaddr;
                    _papi_hwi_system_info.exe_info.address_info.
                        data_end =
                        ( caddr_t ) ( tmp1[i].pr_vaddr + tmp1[i].pr_size );
                }
            }

        } else {
            if ( ( _papi_hwi_system_info.exe_info.address_info.text_start == 0 )
                 && ( _papi_hwi_system_info.exe_info.address_info.text_end ==
                      0 ) &&
                 ( _papi_hwi_system_info.exe_info.address_info.data_start == 0 )
                 && ( _papi_hwi_system_info.exe_info.address_info.data_end ==
                      0 ) )
                PAPIERROR( "executable name not recognized" );

            if ( tmp1[i].pr_mflags & MA_READ ) {
                if ( tmp1[i].pr_mflags & MA_EXEC ) {
                    t_index++;
                    tmp2[t_index].text_start = ( caddr_t ) tmp1[i].pr_vaddr;
                    tmp2[t_index].text_end =
                        ( caddr_t ) ( tmp1[i].pr_vaddr + tmp1[i].pr_size );
                    strncpy( tmp2[t_index].name, name, PAPI_MAX_STR_LEN );
                } else if ( tmp1[i].pr_mflags & MA_WRITE ) {
                    tmp2[t_index].data_start = ( caddr_t ) tmp1[i].pr_vaddr;
                    tmp2[t_index].data_end =
                        ( caddr_t ) ( tmp1[i].pr_vaddr + tmp1[i].pr_size );
                }
            }

        }
    }
    fclose( map_f );

    if ( _papi_hwi_system_info.shlib_info.map )
        papi_free( _papi_hwi_system_info.shlib_info.map );
    _papi_hwi_system_info.shlib_info.map = tmp2;
    _papi_hwi_system_info.shlib_info.count = t_index + 1;
    papi_free( tmp1 );

    return PAPI_OK;
#else
    return PAPI_ENOIMPL;
#endif
}

Here is the call graph for this function:

Here is the caller graph for this function:

int _papi_hwi_init_os ( void  )

< No error

Definition at line 1213 of file aix.c.

                        {
  
   struct utsname uname_buffer;

   uname(&uname_buffer);

   strncpy(_papi_os_info.name,uname_buffer.sysname,PAPI_MAX_STR_LEN);

   strncpy(_papi_os_info.version,uname_buffer.release,PAPI_MAX_STR_LEN);
   
   _papi_os_info.itimer_sig = PAPI_INT_MPX_SIGNAL;
   _papi_os_info.itimer_num = PAPI_INT_ITIMER;
   _papi_os_info.itimer_res_ns = 1;
   _papi_os_info.itimer_ns = 1000 * PAPI_INT_MPX_DEF_US;

   return PAPI_OK;

}

Here is the caller graph for this function:

Definition at line 51 of file aix.c.

{
    int i, j;

    memset( native_table, 0,
            PAPI_MAX_NATIVE_EVENTS * sizeof ( native_event_entry_t ) );
    memset( native_name_map, 0,
            PAPI_MAX_NATIVE_EVENTS * sizeof ( PPC64_native_map_t ) );
    for ( i = 0; i < PAPI_MAX_NATIVE_EVENTS; i++ ) {
        native_name_map[i].index = -1;
        for ( j = 0; j < MAX_COUNTERS; j++ )
            native_table[i].resources.counter_cmd[j] = -1;
    }
}

Here is the caller graph for this function:

static void aix_ppc64_setup_gps ( int  total) [static]

Definition at line 68 of file aix.c.

{
    int i, j, gnum;

    for ( i = 0; i < total; i++ ) {
        for ( j = 0; j < MAX_COUNTERS; j++ ) {
            /*      native_table[i].resources.rgg[j]=-1; */
            if ( native_table[i].resources.selector & ( 1 << j ) ) {
                for ( gnum = 0; gnum < pmgroups.maxgroups; gnum++ ) {
                    if ( native_table[i].resources.counter_cmd[j] ==
                         pmgroups.event_groups[gnum].events[j] ) {
                        /* could use gnum instead of pmgroups.event_groups[gnum].group_id */
                        native_table[i].resources.group[pmgroups.
                                                        event_groups[gnum].
                                                        group_id / 32] |=
                            1 << ( pmgroups.event_groups[gnum].group_id % 32 );
                    }
                }
            }
        }
    }

    for ( gnum = 0; gnum < pmgroups.maxgroups; gnum++ ) {
        for ( i = 0; i < MAX_COUNTERS; i++ ) {
            /*group_map[gnum].counter_cmd[i] = pmgroups.event_groups[gnum].events[i]; */
            if (pmgroups.event_groups[gnum].group_id >=MAX_GROUPS) {
               fprintf(stderr,"ERROR, group number trying to go past MAX GROUPS\n");
               continue;
            } 

            group_map[pmgroups.event_groups[gnum].group_id].counter_cmd[i] =
                pmgroups.event_groups[gnum].events[i];
        }
    }
}

Here is the caller graph for this function:

Definition at line 106 of file aix.c.

{
    hwd_pmevents_t *wevp;
    hwd_pminfo_t *info;
    int pmc, ev, i, j, index;

    info = &pminfo;
    index = 0;
    aix_initialize_native_table(  );
    for ( pmc = 0; pmc < info->maxpmcs; pmc++ ) {
        wevp = info->list_events[pmc];
        for ( ev = 0; ev < info->maxevents[pmc]; ev++, wevp++ ) {
            for ( i = 0; i < index; i++ ) {
                if ( strcmp( wevp->short_name, native_table[i].name ) == 0 ) {
                    native_table[i].resources.selector |= 1 << pmc;
                    native_table[i].resources.counter_cmd[pmc] = wevp->event_id;
                    break;
                }
            }
            if ( i == index ) {
                /*native_table[i].index=i; */
                native_table[i].resources.selector |= 1 << pmc;
                native_table[i].resources.counter_cmd[pmc] = wevp->event_id;
                native_table[i].name = wevp->short_name;
                native_table[i].description = wevp->description;
                native_name_map[i].name = native_table[i].name;
                native_name_map[i].index = i;
                index++;
            }
        }
    }
    aix_ppc64_setup_gps( index );

    return index;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void copy_value ( unsigned int  val,
char *  nam,
char *  names,
unsigned int *  values,
int  len 
) [static]

Definition at line 146 of file aix.c.

{
    *values = val;
    strncpy( names, nam, len );
    names[len - 1] = '\0';
}
static int do_counter_allocation ( ppc64_reg_alloc_t event_list,
int  size 
) [static]

Definition at line 160 of file aix.c.

{
    int i, j, group = -1;
    unsigned int map[GROUP_INTS];

    for ( i = 0; i < GROUP_INTS; i++ )
        map[i] = event_list[0].ra_group[i];

    for ( i = 1; i < size; i++ ) {
        for ( j = 0; j < GROUP_INTS; j++ )
            map[j] &= event_list[i].ra_group[j];
    }

    for ( i = 0; i < GROUP_INTS; i++ ) {
        if ( map[i] ) {
            group = ffs( map[i] ) - 1 + i * 32;
            break;
        }
    }

    if ( group < 0 )
        return group;        /* allocation fail */
    else {
        for ( i = 0; i < size; i++ ) {
            for ( j = 0; j < MAX_COUNTERS; j++ ) {
                if ( event_list[i].ra_counter_cmd[j] >= 0
                     && event_list[i].ra_counter_cmd[j] ==
                     group_map[group].counter_cmd[j] )
                    event_list[i].ra_position = j;
            }
        }
        return group;
    }
}

Here is the caller graph for this function:

static int get_avail_hwcntr_bits ( int  cntr_avail_bits) [static]

Definition at line 766 of file aix.c.

{
    int tmp = 0, i = 1 << ( POWER_MAX_COUNTERS - 1 );

    while ( i ) {
        tmp = i & cntr_avail_bits;
        if ( tmp )
            return ( tmp );
        i = i >> 1;
    }
    return ( 0 );
}
int init_domain ( )

< User context counted

< Kernel/OS context counted

< Exception/transient mode (like user TLB misses )

Definition at line 420 of file aix.c.

{
    int domain = 0;

    domain = PAPI_DOM_USER | PAPI_DOM_KERNEL | PAPI_DOM_OTHER;
#ifdef PM_INITIALIZE
#ifdef _AIXVERSION_510
    if ( pminfo.proc_feature.b.hypervisor ) {
        domain |= PAPI_DOM_SUPERVISOR;
    }
#endif
#endif
    return ( domain );
}

Here is the caller graph for this function:

static int round_requested_ns ( int  ns) [static]

Definition at line 863 of file aix.c.

{
    if ( ns <= _papi_os_info.itimer_res_ns ) {
        return _papi_os_info.itimer_res_ns;
    } else {
        int leftover_ns = ns % _papi_os_info.itimer_res_ns;
        return ( ns - leftover_ns + _papi_os_info.itimer_res_ns );
    }
}

Here is the caller graph for this function:

static void set_config ( void *  ptr,
int  arg1,
int  arg2 
) [static]

Definition at line 408 of file aix.c.

{
    ptr->counter_cmd.events[arg1] = arg2;
}
static int set_default_domain ( EventSetInfo_t zero,
int  domain 
) [static]

Definition at line 510 of file aix.c.

{
    hwd_control_state_t *current_state = zero->ctl_state;
    return ( _aix_set_domain( current_state, domain ) );
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int set_default_granularity ( EventSetInfo_t zero,
int  granularity 
) [static]

Definition at line 517 of file aix.c.

{
    hwd_control_state_t *current_state = zero->ctl_state;
    return ( _aix_set_granularity( current_state, granularity ) );
}

Here is the call graph for this function:

static void set_hwcntr_codes ( int  selector,
unsigned char *  from,
int *  to 
) [static]

Definition at line 780 of file aix.c.

{
    int useme, i;

    for ( i = 0; i < _aix_vector.cmp_info.num_cntrs; i++ ) {
        useme = ( 1 << i ) & selector;
        if ( useme ) {
            to[i] = from[i];
        }
    }
}
static char* trim_string ( char *  in) [static]

Definition at line 289 of file aix.c.

{
    int len, i = 0;
    char *start = in;

    if ( in == NULL )
        return ( in );
    len = strlen( in );
    if ( len == 0 )
        return ( in );
    /* Trim right */
    i = strlen( start ) - 1;
    while ( i >= 0 ) {
        if ( isblank( start[i] ) || ( start[i] == '\r' ) ||
             ( start[i] == '\n' ) )
            start[i] = '\0';
        else
            break;
        i--;
    }
    return ( start );
}

Here is the caller graph for this function:

static void unset_config ( void *  ptr,
int  arg1 
) [static]

Definition at line 414 of file aix.c.

{
    ptr->counter_cmd.events[arg1] = 0;
}

Variable Documentation

Definition at line 21 of file aix.c.

Definition at line 1210 of file aix.c.

Initial value:
 {
    .get_memory_info = _aix_get_memory_info,
    .get_dmem_info = _aix_get_dmem_info,
    .get_real_usec = _aix_get_real_usec,
    .get_real_cycles = _aix_get_real_cycles,
        .get_virt_usec = _aix_get_virt_usec,
        .update_shlib_info = _aix_update_shlib_info,
    .get_system_info = _aix_get_system_info,
}

Definition at line 1288 of file aix.c.

struct utsname AixVer

Definition at line 39 of file aix.c.

hwd_groups_t group_map[(8 *32)] = { 0 }

Definition at line 47 of file aix.c.

atomic_p lock[(9+0x2)]

Definition at line 25 of file aix.c.

volatile int lock_var[(9+0x2)] = { 0 }

Definition at line 24 of file aix.c.

int maxgroups = 0 [static]

Definition at line 38 of file aix.c.

Definition at line 46 of file aix.c.

Definition at line 41 of file aix.c.

pm_groups_info_t pmgroups

Definition at line 44 of file aix.c.

Definition at line 43 of file aix.c.

 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines