PAPI  5.0.1.0
solaris-ultra.c File Reference
Include dependency graph for solaris-ultra.c:

Go to the source code of this file.

Data Structures

struct  ctr_info_t
struct  einfo_t

Defines

#define LASTULTRA3   CPC_ULTRA3_PLUS
#define MAX_ENAME   40

Functions

static void action (void *arg, int regno, const char *name, uint8_t bits)
static int build_tables (void)
static void add_preset (hwi_search_t *tab, int *np, einfo_t e)
static void dispatch_emt (int signal, siginfo_t *sip, void *arg)
static int scan_prtconf (char *cpuname, int len_cpuname, int *hz, int *ver)
int _ultra_set_domain (_niagara2_control_state_t *this_state, int domain)
static int set_granularity (_niagara2_control_state_t *this_state, int domain)
void print_walk_names (void *arg, int regno, const char *name, uint8_t bits)
static int srch_event (char *e1)
static int set_inherit (EventSetInfo_t *global, int arg)
static int set_default_domain (_niagara2_control_state_t *ctrl_state, int domain)
static int set_default_granularity (_niagara2_control_state_t *current_state, int granularity)
static void lock_init (void)
int _ultra_hwd_shutdown_component (void)
int _ultra_hwd_init_component (int cidx)
int _ultra_hwd_reset (_niagara2_context_t *ctx, _niagara2_control_state_t *ctrl)
int _ultra_hwd_read (_niagara2_context_t *ctx, _niagara2_control_state_t *ctrl, long long **events, int flags)
int _ultra_hwd_ctl (_niagara2_context_t *ctx, int code, _papi_int_option_t *option)
void _ultra_hwd_dispatch_timer (int signal, siginfo_t *si, void *context)
int _ultra_hwd_set_overflow (EventSetInfo_t *ESI, int EventIndex, int threshold)
 _ultra_shutdown (_niagara2_context_t *ctx)
void * _ultra_hwd_get_overflow_address (void *context)
int _ultra_hwd_start (_niagara2_context_t *ctx, _niagara2_control_state_t *ctrl)
int _ultra_hwd_stop (_niagara2_context_t *ctx, _niagara2_control_state_t *ctrl)
int _ultra_hwd_remove_event (hwd_register_map_t *chosen, unsigned int hardware_index, _niagara2_control_state_t *out)
int _ultra_hwd_encode_native (char *name, int *code)
int _ultra_hwd_ntv_enum_events (unsigned int *EventCode, int modifier)
int _ultra_hwd_ntv_code_to_name (unsigned int EventCode, char *ntv_name, int len)
int _ultra_hwd_ntv_code_to_descr (unsigned int EventCode, char *hwd_descr, int len)
static void copy_value (unsigned int val, char *nam, char *names, unsigned int *values, int len)
int _ultra_hwd_ntv_code_to_bits (unsigned int EventCode, _niagara2_register_t *bits)
int _ultra_hwd_init_control_state (_niagara2_control_state_t *ptr)
int _ultra_hwd_update_control_state (_niagara2_control_state_t *this_state, NativeInfo_t *native, int count, _niagara2_context_t *zero)

Variables

static einfo_t us3info []
static einfo_t us2info []
papi_vector_t _solaris_vector
static native_info_tnative_table
static hwi_search_tpreset_table
static struct ctr_info * ctrs
static int nctrs
static int cpuver
static int pcr_shift [2]
hwi_search_tpreset_search_map
rwlock_t lock [(9+0x2)]
papi_os_vector_t _papi_os_vector

Define Documentation

#define LASTULTRA3   CPC_ULTRA3_PLUS

Definition at line 33 of file solaris-ultra.c.

#define MAX_ENAME   40

Definition at line 36 of file solaris-ultra.c.


Function Documentation

int _ultra_hwd_ctl ( _niagara2_context_t ctx,
int  code,
_papi_int_option_t option 
)

< Domain for all new eventsets. Takes non-NULL option pointer.

< Domain for an eventset

< Granularity for all new eventsets

< Granularity for an eventset

< Invalid argument

Definition at line 719 of file solaris-ultra.c.

{

    switch ( code ) {
    case PAPI_DEFDOM:
        return ( set_default_domain
                 ( option->domain.ESI->ctl_state, option->domain.domain ) );
    case PAPI_DOMAIN:
        return ( _ultra_set_domain
                 ( option->domain.ESI->ctl_state, option->domain.domain ) );
    case PAPI_DEFGRN:
        return ( set_default_granularity
                 ( option->domain.ESI->ctl_state,
                   option->granularity.granularity ) );
    case PAPI_GRANUL:
        return ( set_granularity
                 ( option->granularity.ESI->ctl_state,
                   option->granularity.granularity ) );
    default:
        return ( PAPI_EINVAL );
    }
}

Here is the call graph for this function:

void _ultra_hwd_dispatch_timer ( int  signal,
siginfo_t si,
void *  context 
)

Definition at line 743 of file solaris-ultra.c.

{

  _papi_hwi_context_t ctx;
  ThreadInfo_t *master = NULL;
  int isHardware = 0;
  caddr_t address;
  int cidx = _solaris_vector.cmp_info.CmpIdx;

  ctx.si = si;
  ctx.ucontext = ( ucontext_t * ) context;

  address = GET_OVERFLOW_ADDRESS( ctx );
  _papi_hwi_dispatch_overflow_signal( ( void * ) &ctx, address, &isHardware,
                      0, 0, &master, _solaris_vector.cmp_info.CmpIdx );

  /* We are done, resume interrupting counters */
  if ( isHardware ) {
    //    errno = vperfctr_iresume( master->context[cidx]->perfctr );
    //if ( errno < 0 ) {
    //  PAPIERROR( "vperfctr_iresume errno %d", errno );
    //}
  }


#if 0
        EventSetInfo_t *ESI = NULL;
        ThreadInfo_t *thread = NULL;
        int overflow_vector = 0;
        hwd_control_state_t *ctrl = NULL;
        long_long results[MAX_COUNTERS];
        int i;
        _papi_hwi_context_t ctx;
    caddr_t address;
    int cidx = _solaris_vector.cmp_info.CmpIdx;

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

    thread = _papi_hwi_lookup_thread( 0 );

    if ( thread == NULL ) {
        PAPIERROR( "thread == NULL in _papi_hwd_dispatch_timer");
        return;
    }

        ESI = ( EventSetInfo_t * ) thread->running_eventset[cidx];


    if ( ESI == NULL || ESI->master != thread || ESI->ctl_state == NULL ||
         ( ( ESI->state & PAPI_OVERFLOWING ) == 0 ) ) {

      if ( ESI == NULL )
         PAPIERROR( "ESI is NULL\n");

      if ( ESI->master != thread )
         PAPIERROR( "Thread mismatch, ESI->master=%x thread=%x\n",
                ESI->master, thread );

      if ( ESI->ctl_state == NULL )
         PAPIERROR( "Counter state invalid\n");

      if ( ( ( ESI->state & PAPI_OVERFLOWING ) == 0 ) )
        PAPIERROR( "Overflow flag missing");
    }

    ctrl = ESI->ctl_state;

    if ( thread->running_eventset[cidx]->overflow.flags & PAPI_OVERFLOW_FORCE_SW ) {
        address = GET_OVERFLOW_ADDRESS( ctx );
        _papi_hwi_dispatch_overflow_signal( ( void * ) &ctx, address, NULL, 0,
                                            0, &thread, cidx );
       } else {
         PAPIERROR ( "Need to implement additional code in _papi_hwd_dispatch_timer!" );
       }
#endif
}

Here is the call graph for this function:

int _ultra_hwd_encode_native ( char *  name,
int *  code 
)

< No error

Definition at line 922 of file solaris-ultra.c.

{
    return ( PAPI_OK );
}
void* _ultra_hwd_get_overflow_address ( void *  context)

Definition at line 880 of file solaris-ultra.c.

{
    void *location;
    ucontext_t *info = ( ucontext_t * ) context;
    location = ( void * ) info->uc_mcontext.gregs[REG_PC];

    return ( location );
}
int _ultra_hwd_init_component ( int  cidx)

< No error

Definition at line 656 of file solaris-ultra.c.

{
    int retval;
 /* retval = _papi_hwi_setup_vector_table(vtable, _solaris_ultra_table);
    if ( retval != PAPI_OK ) return(retval); */

    /* Fill in what we can of the papi_system_info. */
    retval = _solaris_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 );


    lock_init(  );

    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 );

    return ( PAPI_OK );
}

Here is the call graph for this function:

< No error

Definition at line 1005 of file solaris-ultra.c.

{
    ptr->counter_cmd.flags = 0x0;
    ptr->counter_cmd.cmd.ce_cpuver = cpuver;
    ptr->counter_cmd.cmd.ce_pcr = 0x0;
    ptr->counter_cmd.cmd.ce_pic[0] = 0;
    ptr->counter_cmd.cmd.ce_pic[1] = 0;

    _ultra_set_domain( ptr, _solaris_vector.cmp_info.default_domain );
    set_granularity( ptr, _solaris_vector.cmp_info.default_granularity );

    return PAPI_OK;
}

Here is the call graph for this function:

int _ultra_hwd_ntv_code_to_bits ( unsigned int  EventCode,
_niagara2_register_t bits 
)

< Event does not exist

< Event does not exist

< Event does not exist

< No error

Definition at line 984 of file solaris-ultra.c.

{
    int index = EventCode & PAPI_NATIVE_AND_MASK;

    if ( cpuver <= CPC_ULTRA2 ) {
        if ( index >= MAX_NATIVE_EVENT_USII ) {
            return ( PAPI_ENOEVNT );
        }
    } else if ( cpuver <= LASTULTRA3 ) {
        if ( index >= MAX_NATIVE_EVENT ) {
            return ( PAPI_ENOEVNT );
        }
    } else
        return ( PAPI_ENOEVNT );

    bits->event[0] = native_table[index].encoding[0];
    bits->event[1] = native_table[index].encoding[1];
    return ( PAPI_OK );
}
int _ultra_hwd_ntv_code_to_descr ( unsigned int  EventCode,
char *  hwd_descr,
int  len 
)

Definition at line 969 of file solaris-ultra.c.

{
    return ( _ultra_hwd_ntv_code_to_name( EventCode, hwd_descr, len ) );
}

Here is the call graph for this function:

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

< No error

< Event does not exist

Definition at line 955 of file solaris-ultra.c.

{

        int event_code = EventCode & PAPI_NATIVE_AND_MASK;

    if ( event_code >= 0 && event_code < nctrs ) {
      strlcpy( ntv_name, native_table[event_code].name, len );
      return PAPI_OK;
    }
    return PAPI_ENOEVNT;
}

Here is the caller graph for this function:

int _ultra_hwd_ntv_enum_events ( unsigned int *  EventCode,
int  modifier 
)

< No error

< No error

< Event does not exist

< No error

< Event does not exist

< Event does not exist

Definition at line 928 of file solaris-ultra.c.

{
    int index = *EventCode & PAPI_NATIVE_AND_MASK;

    if ( modifier == PAPI_ENUM_FIRST ) {
       *EventCode = PAPI_NATIVE_MASK + 1;

       return PAPI_OK;
    }

    if ( cpuver <= CPC_ULTRA2 ) {
        if ( index < MAX_NATIVE_EVENT_USII - 1 ) {
            *EventCode = *EventCode + 1;
            return ( PAPI_OK );
        } else
            return ( PAPI_ENOEVNT );
    } else if ( cpuver <= LASTULTRA3 ) {
        if ( index < MAX_NATIVE_EVENT - 1 ) {
            *EventCode = *EventCode + 1;
            return ( PAPI_OK );
        } else
            return ( PAPI_ENOEVNT );
    };
    return ( PAPI_ENOEVNT );
}
int _ultra_hwd_read ( _niagara2_context_t ctx,
_niagara2_control_state_t ctrl,
long long **  events,
int  flags 
)

< A System/C library call failed

< No error

Definition at line 704 of file solaris-ultra.c.

{
    int retval;

    retval = cpc_take_sample( &ctrl->counter_cmd.cmd );
    if ( retval == -1 )
        return ( PAPI_ESYS );

    *events = ( long long * ) ctrl->counter_cmd.cmd.ce_pic;

    return PAPI_OK;
}
int _ultra_hwd_remove_event ( hwd_register_map_t chosen,
unsigned int  hardware_index,
_niagara2_control_state_t out 
)

< No error

Definition at line 915 of file solaris-ultra.c.

{
    return PAPI_OK;
}

< A System/C library call failed

< No error

Definition at line 687 of file solaris-ultra.c.

{
    int retval;

    /* reset the hardware counter */
    ctrl->counter_cmd.cmd.ce_pic[0] = 0;
    ctrl->counter_cmd.cmd.ce_pic[1] = 0;
    /* let's rock and roll */
    retval = cpc_bind_event( &ctrl->counter_cmd.cmd, ctrl->counter_cmd.flags );
    if ( retval == -1 )
        return ( PAPI_ESYS );

    return ( PAPI_OK );
}
int _ultra_hwd_set_overflow ( EventSetInfo_t ESI,
int  EventIndex,
int  threshold 
)

< A System/C library call failed

< A System/C library call failed

< No error

Definition at line 822 of file solaris-ultra.c.

{
    hwd_control_state_t *this_state = ESI->ctl_state;
    papi_cpc_event_t *arg = &this_state->counter_cmd;
    int hwcntr;

    if ( threshold == 0 ) {
        if ( this_state->overflow_num == 1 ) {
            arg->flags ^= CPC_BIND_EMT_OVF;
            if ( sigaction
                 ( _solaris_vector.cmp_info.hardware_intr_sig, NULL,
                   NULL ) == -1 )
                return ( PAPI_ESYS );
            this_state->overflow_num = 0;
        } else
            this_state->overflow_num--;

    } else {
        struct sigaction act;
        /* increase the counter for overflow events */
        this_state->overflow_num++;

        act.sa_sigaction = dispatch_emt;
        memset( &act.sa_mask, 0x0, sizeof ( act.sa_mask ) );
        act.sa_flags = SA_RESTART | SA_SIGINFO;
        if ( sigaction
             ( _solaris_vector.cmp_info.hardware_intr_sig, &act,
               NULL ) == -1 )
            return ( PAPI_ESYS );

        arg->flags |= CPC_BIND_EMT_OVF;
        hwcntr = ESI->EventInfoArray[EventIndex].pos[0];
        if ( hwcntr == 0 )
            arg->cmd.ce_pic[0] = UINT64_MAX - ( uint64_t ) threshold;
        else if ( hwcntr == 1 )
            arg->cmd.ce_pic[1] = UINT64_MAX - ( uint64_t ) threshold;
    }

    return ( PAPI_OK );
}

Here is the call graph for this function:

< No error

Definition at line 649 of file solaris-ultra.c.

{
    ( void ) cpc_rele(  );
    return ( PAPI_OK );
}

< A System/C library call failed

< No error

Definition at line 890 of file solaris-ultra.c.

{
    int retval;

    /* reset the hardware counter */
    if ( ctrl->overflow_num == 0 ) {
        ctrl->counter_cmd.cmd.ce_pic[0] = 0;
        ctrl->counter_cmd.cmd.ce_pic[1] = 0;
    }
    /* let's rock and roll */
    retval = cpc_bind_event( &ctrl->counter_cmd.cmd, ctrl->counter_cmd.flags );
    if ( retval == -1 )
        return ( PAPI_ESYS );

    return ( PAPI_OK );
}

< No error

Definition at line 908 of file solaris-ultra.c.

{
    cpc_bind_event( NULL, 0 );
    return PAPI_OK;
}
int _ultra_hwd_update_control_state ( _niagara2_control_state_t this_state,
NativeInfo_t native,
int  count,
_niagara2_context_t zero 
)

< No error

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

< No error

Definition at line 1020 of file solaris-ultra.c.

{
    int nidx1, nidx2, hwcntr;
    uint64_t tmp = 0;
    uint64_t pcr;
    int64_t cmd0, cmd1;

/* save the last three bits */
    pcr = this_state->counter_cmd.cmd.ce_pcr & 0x7;

/* clear the control register */
    this_state->counter_cmd.cmd.ce_pcr = pcr;

/* no native events left */
    if ( count == 0 )
        return ( PAPI_OK );

    cmd0 = -1;
    cmd1 = -1;
/* one native event */
    if ( count == 1 ) {
        nidx1 = native[0].ni_event & PAPI_NATIVE_AND_MASK;
        hwcntr = 0;
        cmd0 = native_table[nidx1].encoding[0];
        native[0].ni_position = 0;
        if ( cmd0 == -1 ) {
            cmd1 = native_table[nidx1].encoding[1];
            native[0].ni_position = 1;
        }
    }

/* two native events */
    if ( count == 2 ) {
        int avail1, avail2;

        avail1 = 0;
        avail2 = 0;
        nidx1 = native[0].ni_event & PAPI_NATIVE_AND_MASK;
        nidx2 = native[1].ni_event & PAPI_NATIVE_AND_MASK;
        if ( native_table[nidx1].encoding[0] != -1 )
            avail1 = 0x1;
        if ( native_table[nidx1].encoding[1] != -1 )
            avail1 += 0x2;
        if ( native_table[nidx2].encoding[0] != -1 )
            avail2 = 0x1;
        if ( native_table[nidx2].encoding[1] != -1 )
            avail2 += 0x2;
        if ( ( avail1 | avail2 ) != 0x3 )
            return ( PAPI_ECNFLCT );
        if ( avail1 == 0x3 ) {
            if ( avail2 == 0x1 ) {
                cmd0 = native_table[nidx2].encoding[0];
                cmd1 = native_table[nidx1].encoding[1];
                native[0].ni_position = 1;
                native[1].ni_position = 0;
            } else {
                cmd1 = native_table[nidx2].encoding[1];
                cmd0 = native_table[nidx1].encoding[0];
                native[0].ni_position = 0;
                native[1].ni_position = 1;
            }
        } else {
            if ( avail1 == 0x1 ) {
                cmd0 = native_table[nidx1].encoding[0];
                cmd1 = native_table[nidx2].encoding[1];
                native[0].ni_position = 0;
                native[1].ni_position = 1;
            } else {
                cmd0 = native_table[nidx2].encoding[0];
                cmd1 = native_table[nidx1].encoding[1];
                native[0].ni_position = 1;
                native[1].ni_position = 0;
            }
        }
    }

/* set the control register */
    if ( cmd0 != -1 ) {
        tmp = ( ( uint64_t ) cmd0 << pcr_shift[0] );
    }
    if ( cmd1 != -1 ) {
        tmp = tmp | ( ( uint64_t ) cmd1 << pcr_shift[1] );
    }
    this_state->counter_cmd.cmd.ce_pcr = tmp | pcr;
#if DEBUG
    dump_cmd( &this_state->counter_cmd );
#endif

    return ( PAPI_OK );
}
int _ultra_set_domain ( _niagara2_control_state_t this_state,
int  domain 
)

< User context counted

< Kernel/OS context counted

< Invalid argument

< No error

Definition at line 333 of file solaris-ultra.c.

{
    papi_cpc_event_t *command = &this_state->counter_cmd;
    cpc_event_t *event = &command->cmd;
    uint64_t pcr = event->ce_pcr;
    int did = 0;

    pcr = pcr | 0x7;
    pcr = pcr ^ 0x7;

    if ( domain & PAPI_DOM_USER ) {
        pcr = pcr | 1 << CPC_ULTRA_PCR_USR;
        did = 1;
    }
    if ( domain & PAPI_DOM_KERNEL ) {
        pcr = pcr | 1 << CPC_ULTRA_PCR_SYS;
        did = 1;
    }
    /* DOMAIN ERROR */
    if ( !did ) {
        return ( PAPI_EINVAL );
    }

    event->ce_pcr = pcr;

    return ( PAPI_OK );
}

Here is the caller graph for this function:

< No error

Definition at line 864 of file solaris-ultra.c.

{

  return PAPI_OK;
}
void action ( void *  arg,
int  regno,
const char *  name,
uint8_t  bits 
) [static]

Definition at line 571 of file solaris-ultra.c.

{
    int i;

    if ( arg == 0 ) {
        ++nctrs;
        return;
    }
    assert( regno == 0 || regno == 1 );
    for ( i = 0; i < nctrs; ++i ) {
        if ( strcmp( ctrs[i].name, name ) == 0 ) {
            ctrs[i].bits[regno] = bits;
            ctrs[i].bitmask |= ( 1 << regno );
            return;
        }
    }
    memset( &ctrs[i], 0, sizeof ( ctrs[i] ) );
    ctrs[i].name = papi_strdup( name );
    ctrs[i].bits[regno] = bits;
    ctrs[i].bitmask = ( 1 << regno );
    ++nctrs;
}

Here is the caller graph for this function:

static void add_preset ( hwi_search_t tab,
int *  np,
einfo_t  e 
) [static]

<A nonexistent hardware event used as a placeholder

< Sub all counters from counter with operand_index

< Add counters

<A nonexistent hardware event used as a placeholder

Definition at line 495 of file solaris-ultra.c.

{
    /* Parse the event info string and build the PAPI preset.
     * If parse fails, just return, otherwise increment the table
     * size. We assume that the table is big enough.
     */
    char *p;
    char *q;
    char op;
    char e1[MAX_ENAME], e2[MAX_ENAME];
    int i;
    int ne;
    int ne2;

    p = e.event_str;
    /* Assume p is the name of a native event, the sum of two
     * native events, or the difference of two native events.
     * This could be extended with a real parser (hint).
     */
    while ( isspace( *p ) )
        ++p;
    q = p;
    i = 0;
    while ( isalnum( *p ) || ( *p == '_' ) ) {
        if ( i >= MAX_ENAME - 1 )
            break;
        e1[i] = *p++;
        ++i;
    }
    e1[i] = 0;
    if ( *p == '+' || *p == '-' )
        op = *p++;
    else
        op = 0;
    while ( isspace( *p ) )
        ++p;
    q = p;
    i = 0;
    while ( isalnum( *p ) || ( *p == '_' ) ) {
        if ( i >= MAX_ENAME - 1 )
            break;
        e2[i] = *p++;
        ++i;
    }
    e2[i] = 0;

    if ( e2[0] == 0 && e1[0] == 0 ) {
        return;
    }
    if ( e2[0] == 0 || op == 0 ) {
        ne = srch_event( e1 );
        if ( ne == -1 )
            return;
        tab[*np].event_code = e.papi_event;
        tab[*np].data.derived = 0;
        tab[*np].data.native[0] = PAPI_NATIVE_MASK | ne;
        tab[*np].data.native[1] = PAPI_NULL;
        memset( tab[*np].data.operation, 0,
                sizeof ( tab[*np].data.operation ) );
        ++*np;
        return;
    }
    ne = srch_event( e1 );
    ne2 = srch_event( e2 );
    if ( ne == -1 || ne2 == -1 )
        return;
    tab[*np].event_code = e.papi_event;
    tab[*np].data.derived = ( op == '-' ) ? DERIVED_SUB : DERIVED_ADD;
    tab[*np].data.native[0] = PAPI_NATIVE_MASK | ne;
    tab[*np].data.native[1] = PAPI_NATIVE_MASK | ne2;
    tab[*np].data.native[2] = PAPI_NULL;
    memset( tab[*np].data.operation, 0, sizeof ( tab[*np].data.operation ) );
    ++*np;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int build_tables ( void  ) [static]

< Insufficient memory

< Insufficient memory

< Not supported by component

< No error

Definition at line 389 of file solaris-ultra.c.

{
    int i;
    int regno;
    int npic;
    einfo_t *ep;
    int n;
    int npresets;
    npic = cpc_getnpic( cpuver );
    nctrs = 0;
    for ( regno = 0; regno < npic; ++regno ) {
        cpc_walk_names( cpuver, regno, 0, action );
    }
    SUBDBG( "%d counters\n", nctrs );
    if ( ( ctrs = papi_malloc( nctrs * sizeof ( struct ctr_info ) ) ) == 0 ) {
        return PAPI_ENOMEM;
    }
    nctrs = 0;
    for ( regno = 0; regno < npic; ++regno ) {
        cpc_walk_names( cpuver, regno, ( void * ) 1, action );
    }
    SUBDBG( "%d counters\n", nctrs );
#if DEBUG
    if ( ISLEVEL( DEBUG_SUBSTRATE ) ) {
        for ( i = 0; i < nctrs; ++i ) {
            SUBDBG( "%s: bits (%x,%x) pics %x\n", ctrs[i].name, ctrs[i].bits[0],
                    ctrs[i].bits[1], ctrs[i].bitmask );
        }
    }
#endif
    /* Build the native event table */
    if ( ( native_table =
           papi_malloc( nctrs * sizeof ( native_info_t ) ) ) == 0 ) {
        papi_free( ctrs );
        return PAPI_ENOMEM;
    }
    for ( i = 0; i < nctrs; ++i ) {
        native_table[i].name[39] = 0;
        strncpy( native_table[i].name, ctrs[i].name, 39 );
        if ( ctrs[i].bitmask & 1 )
            native_table[i].encoding[0] = ctrs[i].bits[0];
        else
            native_table[i].encoding[0] = -1;
        if ( ctrs[i].bitmask & 2 )
            native_table[i].encoding[1] = ctrs[i].bits[1];
        else
            native_table[i].encoding[1] = -1;
    }
    papi_free( ctrs );

    /* Build the preset table */
    if ( cpuver <= CPC_ULTRA2 ) {
        n = sizeof ( us2info ) / sizeof ( einfo_t );
        ep = us2info;
    } else if ( cpuver <= LASTULTRA3 ) {
        n = sizeof ( us3info ) / sizeof ( einfo_t );
        ep = us3info;
    } else
        return PAPI_ECMP;
    preset_table = papi_malloc( ( n + 1 ) * sizeof ( hwi_search_t ) );
    npresets = 0;
    for ( i = 0; i < n; ++i ) {
        add_preset( preset_table, &npresets, ep[i] );
    }
    memset( &preset_table[npresets], 0, sizeof ( hwi_search_t ) );

#ifdef DEBUG
    if ( ISLEVEL( DEBUG_SUBSTRATE ) ) {
        SUBDBG( "Native table: %d\n", nctrs );
        for ( i = 0; i < nctrs; ++i ) {
            SUBDBG( "%40s: %8x %8x\n", native_table[i].name,
                    native_table[i].encoding[0], native_table[i].encoding[1] );
        }
        SUBDBG( "\nPreset table: %d\n", npresets );
        for ( i = 0; preset_table[i].event_code != 0; ++i ) {
            SUBDBG( "%8x: op %2d e0 %8x e1 %8x\n",
                    preset_table[i].event_code,
                    preset_table[i].data.derived,
                    preset_table[i].data.native[0],
                    preset_table[i].data.native[1] );
        }
    }
#endif

    _solaris_vector.cmp_info.num_native_events = nctrs;

    return PAPI_OK;
}

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 975 of file solaris-ultra.c.

{
    *values = val;
    strncpy( names, nam, len );
    names[len - 1] = 0;
}
static void dispatch_emt ( int  signal,
siginfo_t sip,
void *  arg 
) [static]

< EventSet has overflowing enabled

< Force using Software

Definition at line 132 of file solaris-ultra.c.

{
    int event_counter;
    _papi_hwi_context_t ctx;
    caddr_t address;
    ctx.si = sip;
    ctx.ucontext = arg;
    SUBDBG( "%d, %p, %p\n", signal, sip, arg );

    if ( sip->si_code == EMT_CPCOVF ) {
        papi_cpc_event_t *sample;
        EventSetInfo_t *ESI;
        ThreadInfo_t *thread = NULL;
        int t, overflow_vector, readvalue;

        thread = _papi_hwi_lookup_thread( 0 );
        ESI = ( EventSetInfo_t * ) thread->running_eventset;
        int cidx = ESI->CmpIdx;

        if ( ( ESI == NULL ) || ( ( ESI->state & PAPI_OVERFLOWING ) == 0 ) ) {
            OVFDBG( "Either no eventset or eventset not set to overflow.\n" );
            return;
        }

        if ( ESI->master != thread ) {
            PAPIERROR
                ( "eventset->thread 0x%lx vs. current thread 0x%lx mismatch",
                  ESI->master, thread );
            return;
        }

        event_counter = ESI->overflow.event_counter;
        sample = &( ESI->ctl_state->counter_cmd );

        /* GROSS! This is a hack to 'push' the correct values 
           back into the hardware, such that when PAPI handles
           the overflow and reads the values, it gets the correct ones.
         */

        /* Find which HW counter overflowed */

        if ( ESI->EventInfoArray[ESI->overflow.EventIndex[0]].pos[0] == 0 )
            t = 0;
        else
            t = 1;

        if ( cpc_take_sample( &sample->cmd ) == -1 )
            return;
        if ( event_counter == 1 ) {
            /* only one event is set to be the overflow monitor */

            /* generate the overflow vector */
            overflow_vector = 1 << t;
            /* reset the threshold */
            sample->cmd.ce_pic[t] = UINT64_MAX - ESI->overflow.threshold[0];
        } else {
            /* two events are set to be the overflow monitors */
            overflow_vector = 0;
            readvalue = sample->cmd.ce_pic[0];
            if ( readvalue >= 0 ) {
                /* the first counter overflowed */

                /* generate the overflow vector */
                overflow_vector = 1;
                /* reset the threshold */
                if ( t == 0 )
                    sample->cmd.ce_pic[0] =
                        UINT64_MAX - ESI->overflow.threshold[0];
                else
                    sample->cmd.ce_pic[0] =
                        UINT64_MAX - ESI->overflow.threshold[1];
            }
            readvalue = sample->cmd.ce_pic[1];
            if ( readvalue >= 0 ) {
                /* the second counter overflowed */

                /* generate the overflow vector */
                overflow_vector ^= 1 << 1;
                /* reset the threshold */
                if ( t == 0 )
                    sample->cmd.ce_pic[1] =
                        UINT64_MAX - ESI->overflow.threshold[1];
                else
                    sample->cmd.ce_pic[1] =
                        UINT64_MAX - ESI->overflow.threshold[0];
            }
            SUBDBG( "overflow_vector, = %d\n", overflow_vector );
            /* something is wrong here */
            if ( overflow_vector == 0 ) {
                PAPIERROR( "BUG! overflow_vector is 0, dropping interrupt" );
                return;
            }
        }

        /* Call the regular overflow function in extras.c */
        if ( thread->running_eventset[cidx]->overflow.
             flags & PAPI_OVERFLOW_FORCE_SW ) {
            address = GET_OVERFLOW_ADDRESS(ctx);
            _papi_hwi_dispatch_overflow_signal( ( void * ) &ctx, address, NULL,
                                                overflow_vector, 0, &thread,
                                                cidx );
        } else {
            PAPIERROR( "Additional implementation needed in dispatch_emt!" );
        }

#if DEBUG
        dump_cmd( sample );
#endif
        /* push back the correct values and start counting again */
        if ( cpc_bind_event( &sample->cmd, sample->flags ) == -1 )
            return;
    } else {
        SUBDBG( "dispatch_emt() dropped, si_code = %d\n", sip->si_code );
        return;
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void lock_init ( void  ) [static]

< Used with setting up array

Definition at line 643 of file solaris-ultra.c.

{
    memset( lock, 0x0, sizeof ( rwlock_t ) * PAPI_MAX_LOCK );
}

Here is the caller graph for this function:

void print_walk_names ( void *  arg,
int  regno,
const char *  name,
uint8_t  bits 
)

Definition at line 382 of file solaris-ultra.c.

{
    SUBDBG( arg, regno, name, bits );
}

Here is the caller graph for this function:

static int scan_prtconf ( char *  cpuname,
int  len_cpuname,
int *  hz,
int *  ver 
) [static]

Definition at line 250 of file solaris-ultra.c.

{
    /* This code courtesy of our friends in Germany. Thanks Rudolph Berrendorf! */
    /* See the PCL home page for the German version of PAPI. */
    /* Modified by Nils Smeds, all new bugs are my fault */
    /*    The routine now looks for the first "Node" with the following: */
    /*           "device_type"     = 'cpu'                    */
    /*           "name"            = (Any value)              */
    /*           "sparc-version"   = (Any value)              */
    /*           "clock-frequency" = (Any value)              */
    int ihz, version;
    char line[256], cmd[80], name[256];
    FILE *f = NULL;
    char cmd_line[PAPI_HUGE_STR_LEN + PAPI_HUGE_STR_LEN], fname[L_tmpnam];
    unsigned int matched;

    /*??? system call takes very long */
    /* get system configuration and put output into file */

    tmpnam( fname );
    SUBDBG( "Temporary name %s\n", fname );

    sprintf( cmd_line, "/usr/sbin/prtconf -vp > %s", fname );
    SUBDBG( "Executing %s\n", cmd_line );
    if ( system( cmd_line ) == -1 ) {
        remove( fname );
        return -1;
    }

    f = fopen( fname, "r" );
    /* open output file */
    if ( f == NULL ) {
        remove( fname );
        return -1;
    }

    /* ignore all lines until we reach something with a sparc line */
    matched = 0x0;
    ihz = -1;
    while ( fgets( line, 256, f ) != NULL ) {
        /*SUBDBG(">>> %s",line); */
        if ( ( sscanf( line, "%s", cmd ) == 1 )
             && strstr( line, "Node 0x" ) ) {
            matched = 0x0;
            /*SUBDBG("Found 'Node' -- search reset. (0x%2.2x)\n",matched); */
        } else {
            if ( strstr( cmd, "device_type:" ) && strstr( line, "'cpu'" ) ) {
                matched |= 0x1;
                SUBDBG( "Found 'cpu'. (0x%2.2x)\n", matched );
            } else if ( !strcmp( cmd, "sparc-version:" ) &&
                        ( sscanf( line, "%s %x", cmd, &version ) == 2 ) ) {
                matched |= 0x2;
                SUBDBG( "Found version=%d. (0x%2.2x)\n", version, matched );
            } else if ( !strcmp( cmd, "clock-frequency:" ) &&
                        ( sscanf( line, "%s %x", cmd, &ihz ) == 2 ) ) {
                matched |= 0x4;
                SUBDBG( "Found ihz=%d. (0x%2.2x)\n", ihz, matched );
            } else if ( !strcmp( cmd, "name:" ) &&
                        ( sscanf( line, "%s %s", cmd, name ) == 2 ) ) {
                matched |= 0x8;
                SUBDBG( "Found name: %s. (0x%2.2x)\n", name, matched );
            }
        }
        if ( ( matched & 0xF ) == 0xF )
            break;
    }
    SUBDBG( "Parsing found name=%s, speed=%dHz, version=%d\n", name, ihz,
            version );

    if ( matched ^ 0x0F )
        ihz = -1;
    else {
        *hz = ( float ) ihz;
        *ver = version;
        strncpy( cpuname, name, len_cpuname );
    }

    return ihz;

    /* End stolen code */
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int set_default_domain ( _niagara2_control_state_t ctrl_state,
int  domain 
) [static]

< Exception/transient mode (like user TLB misses )

< Invalid argument

Definition at line 624 of file solaris-ultra.c.

{
    /* This doesn't exist on this platform */

    if ( domain == PAPI_DOM_OTHER )
        return ( PAPI_EINVAL );

    return ( _ultra_set_domain( ctrl_state, domain ) );
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int set_default_granularity ( _niagara2_control_state_t current_state,
int  granularity 
) [static]

Definition at line 635 of file solaris-ultra.c.

{
    return ( set_granularity( current_state, granularity ) );
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int set_granularity ( _niagara2_control_state_t this_state,
int  domain 
) [static]

< PAPI counters for each individual process group

< PAPI counters for the current CPU, are you bound?

< PAPI counters for all CPUs individually

< PAPI counters for each individual process

< Not supported by component

< PAPI counters for each individual thread

< Invalid argument

< No error

Definition at line 362 of file solaris-ultra.c.

{
    switch ( domain ) {
    case PAPI_GRN_PROCG:
    case PAPI_GRN_SYS:
    case PAPI_GRN_SYS_CPU:
    case PAPI_GRN_PROC:
        return PAPI_ECMP;
    case PAPI_GRN_THR:
        break;
    default:
        return ( PAPI_EINVAL );
    }
    return ( PAPI_OK );
}

Here is the caller graph for this function:

static int set_inherit ( EventSetInfo_t global,
int  arg 
) [static]

< Not supported by component

Definition at line 599 of file solaris-ultra.c.

{
    return PAPI_ECMP;

/*
  hwd_control_state_t *machdep = (hwd_control_state_t *)global->machdep;
  papi_cpc_event_t *command= &machdep->counter_cmd;

  return(PAPI_EINVAL);
*/

#if 0
    if ( arg == 0 ) {
        if ( command->flags & CPC_BIND_LWP_INHERIT )
            command->flags = command->flags ^ CPC_BIND_LWP_INHERIT;
    } else if ( arg == 1 ) {
        command->flags = command->flags | CPC_BIND_LWP_INHERIT;
    } else
        return ( PAPI_EINVAL );

    return ( PAPI_OK );
#endif
}
static int srch_event ( char *  e1) [static]

Definition at line 479 of file solaris-ultra.c.

{
    int i;

    for ( i = 0; i < nctrs; ++i ) {
        if ( strcmp( e1, native_table[i].name ) == 0 )
            break;
    }
    if ( i >= nctrs )
        return -1;
    return i;
}

Here is the caller graph for this function:


Variable Documentation

Initial value:
 {

    
        .get_memory_info =    _solaris_get_memory_info,
        .get_dmem_info =      _solaris_get_dmem_info,
    .update_shlib_info =  _solaris_update_shlib_info,
    .get_system_info =    _solaris_get_system_info,
    .get_real_usec =      _solaris_get_real_usec,
    .get_real_cycles =    _solaris_get_real_cycles,
    .get_virt_usec =      _solaris_get_virt_usec,
}

Definition at line 1169 of file solaris-ultra.c.

Definition at line 100 of file solaris-ultra.c.

int cpuver [static]

Definition at line 113 of file solaris-ultra.c.

struct ctr_info* ctrs [static]

Definition at line 105 of file solaris-ultra.c.

rwlock_t lock[(9+0x2)]

Definition at line 640 of file solaris-ultra.c.

Definition at line 102 of file solaris-ultra.c.

int nctrs [static]

Definition at line 106 of file solaris-ultra.c.

int pcr_shift[2] [static]

Definition at line 114 of file solaris-ultra.c.

Definition at line 116 of file solaris-ultra.c.

Definition at line 103 of file solaris-ultra.c.

einfo_t us2info[] [static]
Initial value:
 {
    { (PAPI_L1_ICM_idx |  ((int)0x80000000) )  , "IC_ref-IC_hit"},
    { (PAPI_L2_TCM_idx |  ((int)0x80000000) )  , "EC_ref-EC_hit"},
    { (PAPI_CA_SNP_idx |  ((int)0x80000000) )  , "EC_snoop_cb"},
    { (PAPI_CA_INV_idx |  ((int)0x80000000) )  , "EC_snoop_inv"},
    { (PAPI_L1_LDM_idx |  ((int)0x80000000) )  , "DC_rd-DC_rd_hit"},
    { (PAPI_L1_STM_idx |  ((int)0x80000000) )  , "DC_wr-DC_wr_hit"},
    { (PAPI_L2_LDM_idx |  ((int)0x80000000) )  , "EC_rd_miss"},
    { (PAPI_BR_MSP_idx |  ((int)0x80000000) )  , "Dispatch0_mispred"},
    { (PAPI_TOT_IIS_idx |  ((int)0x80000000) )  , "Instr_cnt"},
    { (PAPI_TOT_INS_idx |  ((int)0x80000000) )  , "Instr_cnt"},
    { (PAPI_LD_INS_idx |  ((int)0x80000000) )  , "DC_rd"},
    { (PAPI_SR_INS_idx |  ((int)0x80000000) )  , "DC_wr"},
    { (PAPI_TOT_CYC_idx |  ((int)0x80000000) )  , "Cycle_cnt"},
    { (PAPI_L1_DCR_idx |  ((int)0x80000000) )  , "DC_rd"},
    { (PAPI_L1_DCW_idx |  ((int)0x80000000) )  , "DC_wr"},
    { (PAPI_L1_ICH_idx |  ((int)0x80000000) )  , "IC_hit"},
    { (PAPI_L2_ICH_idx |  ((int)0x80000000) )  , "EC_ic_hit"},
    { (PAPI_L1_ICA_idx |  ((int)0x80000000) )  , "IC_ref"},
    { (PAPI_L2_TCH_idx |  ((int)0x80000000) )  , "EC_hit"},
    { (PAPI_L2_TCA_idx |  ((int)0x80000000) )  , "EC_ref"},
}

Definition at line 77 of file solaris-ultra.c.

einfo_t us3info[] [static]
Initial value:
 {
    { (PAPI_FP_INS_idx |  ((int)0x80000000) )  , "FA_pipe_completion+FM_pipe_completion"},
    { (PAPI_FAD_INS_idx |  ((int)0x80000000) )  , "FA_pipe_completion"},
    { (PAPI_FML_INS_idx |  ((int)0x80000000) )  , "FM_pipe_completion"},
    { (PAPI_TLB_IM_idx |  ((int)0x80000000) )  , "ITLB_miss"},
    { (PAPI_TLB_DM_idx |  ((int)0x80000000) )  , "DTLB_miss"},
    { (PAPI_TOT_CYC_idx |  ((int)0x80000000) )  , "Cycle_cnt"},
    { (PAPI_TOT_IIS_idx |  ((int)0x80000000) )  , "Instr_cnt"},
    { (PAPI_TOT_INS_idx |  ((int)0x80000000) )  , "Instr_cnt"},
    { (PAPI_L2_TCM_idx |  ((int)0x80000000) )  , "EC_misses"},
    { (PAPI_L2_ICM_idx |  ((int)0x80000000) )  , "EC_ic_miss"},
    { (PAPI_L1_ICM_idx |  ((int)0x80000000) )  , "IC_miss"},
    { (PAPI_L1_LDM_idx |  ((int)0x80000000) )  , "DC_rd_miss"},
    { (PAPI_L1_STM_idx |  ((int)0x80000000) )  , "DC_wr_miss"},
    { (PAPI_L2_LDM_idx |  ((int)0x80000000) )  , "EC_rd_miss"},
    { (PAPI_BR_MSP_idx |  ((int)0x80000000) )  , "IU_Stat_Br_miss_taken+IU_Stat_Br_miss_untaken"},
    { (PAPI_L1_DCR_idx |  ((int)0x80000000) )  , "DC_rd"},
    { (PAPI_L1_DCW_idx |  ((int)0x80000000) )  , "DC_wr"},
    { (PAPI_L1_ICH_idx |  ((int)0x80000000) )  , "IC_ref-IC_miss"}, 
    { (PAPI_L1_ICA_idx |  ((int)0x80000000) )  , "IC_ref"}, 
    { (PAPI_L2_TCH_idx |  ((int)0x80000000) )  , "EC_ref-EC_misses"},
    { (PAPI_L2_TCA_idx |  ((int)0x80000000) )  , "EC_ref"},
}

Definition at line 53 of file solaris-ultra.c.

 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines