PAPI  5.0.1.0
solaris-common.h File Reference
Include dependency graph for solaris-common.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Defines

#define _papi_hwd_lock(lck)   rw_wrlock(&lock[lck]);
#define _papi_hwd_unlock(lck)   rw_unlock(&lock[lck]);

Functions

int _solaris_update_shlib_info (papi_mdi_t *mdi)
int _solaris_get_system_info (papi_mdi_t *mdi)
long long _solaris_get_real_usec (void)
long long _solaris_get_real_cycles (void)
long long _solaris_get_virt_usec (void)
void cpu_sync (void)

Variables

caddr_t _start
caddr_t _end
caddr_t _etext
caddr_t _edata
rwlock_t lock [PAPI_MAX_LOCK]

Define Documentation

#define _papi_hwd_lock (   lck)    rw_wrlock(&lock[lck]);

Definition at line 23 of file solaris-common.h.

#define _papi_hwd_unlock (   lck)    rw_unlock(&lock[lck]);

Definition at line 25 of file solaris-common.h.


Function Documentation

long long _solaris_get_real_cycles ( void  )

Definition at line 769 of file solaris-common.c.

{
    return ( _ultra_hwd_get_real_usec(  ) *
             ( long long ) _papi_hwi_system_info.hw_info.cpu_max_mhz );
}
long long _solaris_get_real_usec ( void  )

Definition at line 763 of file solaris-common.c.

{
    return ( ( long long ) gethrtime(  ) / ( long long ) 1000 );
}

< Not supported by component

< Not supported by component

< Not supported by component

< No error

< Not supported by component

< A System/C library call failed

< A System/C library call failed

< A System/C library call failed

< A System/C library call failed

< Not supported by component

< Not supported by component

< User context counted

< User context counted

< Kernel/OS context counted

< No error

Definition at line 584 of file solaris-common.c.

{
    int retval;
    pid_t pid;
    char maxargs[PAPI_MAX_STR_LEN] = "<none>";
    psinfo_t psi;
    int fd;
    int hz, version;
    char cpuname[PAPI_MAX_STR_LEN], pname[PAPI_HUGE_STR_LEN];

    /* Check counter access */

    if ( cpc_version( CPC_VER_CURRENT ) != CPC_VER_CURRENT )
        return PAPI_ECMP;
    SUBDBG( "CPC version %d successfully opened\n", CPC_VER_CURRENT );

    if ( cpc_access(  ) == -1 )
        return PAPI_ECMP;

    /* Global variable cpuver */

    cpuver = cpc_getcpuver(  );
    SUBDBG( "Got %d from cpc_getcpuver()\n", cpuver );
    if ( cpuver == -1 )
        return PAPI_ECMP;

#ifdef DEBUG
    {
        if ( ISLEVEL( DEBUG_SUBSTRATE ) ) {
            const char *name;
            int i;

            name = cpc_getcpuref( cpuver );
            if ( name ) {
                SUBDBG( "CPC CPU reference: %s\n", name );
            }
            else {
                SUBDBG( "Could not get a CPC CPU reference\n" );
            }

            for ( i = 0; i < cpc_getnpic( cpuver ); i++ ) {
                SUBDBG( "\n%6s %-40s %8s\n", "Reg", "Symbolic name", "Code" );
                cpc_walk_names( cpuver, i, "%6d %-40s %02x\n",
                                print_walk_names );
            }
            SUBDBG( "\n" );
        }
    }
#endif


    /* Initialize other globals */

    if ( ( retval = build_tables(  ) ) != PAPI_OK )
        return retval;

    preset_search_map = preset_table;
    if ( cpuver <= CPC_ULTRA2 ) {
        SUBDBG( "cpuver (==%d) <= CPC_ULTRA2 (==%d)\n", cpuver, CPC_ULTRA2 );
        pcr_shift[0] = CPC_ULTRA_PCR_PIC0_SHIFT;
        pcr_shift[1] = CPC_ULTRA_PCR_PIC1_SHIFT;
    } else if ( cpuver <= LASTULTRA3 ) {
        SUBDBG( "cpuver (==%d) <= CPC_ULTRA3x (==%d)\n", cpuver, LASTULTRA3 );
        pcr_shift[0] = CPC_ULTRA_PCR_PIC0_SHIFT;
        pcr_shift[1] = CPC_ULTRA_PCR_PIC1_SHIFT;
        _solaris_vector.cmp_info.hardware_intr = 1;
        _solaris_vector.cmp_info.hardware_intr_sig = SIGEMT;
    } else
        return PAPI_ECMP;

    /* Path and args */

    pid = getpid(  );
    if ( pid == -1 )
        return ( PAPI_ESYS );

    /* Turn on microstate accounting for this process and any LWPs. */

    sprintf( maxargs, "/proc/%d/ctl", ( int ) pid );
    if ( ( fd = open( maxargs, O_WRONLY ) ) == -1 )
        return ( PAPI_ESYS );
    {
        int retval;
        struct
        {
            long cmd;
            long flags;
        } cmd;
        cmd.cmd = PCSET;
        cmd.flags = PR_MSACCT | PR_MSFORK;
        retval = write( fd, &cmd, sizeof ( cmd ) );
        close( fd );
        SUBDBG( "Write PCSET returned %d\n", retval );
        if ( retval != sizeof ( cmd ) )
            return ( PAPI_ESYS );
    }

    /* Get executable info */

    sprintf( maxargs, "/proc/%d/psinfo", ( int ) pid );
    if ( ( fd = open( maxargs, O_RDONLY ) ) == -1 )
        return ( PAPI_ESYS );
    read( fd, &psi, sizeof ( psi ) );
    close( fd );

    /* Cut off any arguments to exe */
    {
        char *tmp;
        tmp = strchr( psi.pr_psargs, ' ' );
        if ( tmp != NULL )
            *tmp = '\0';
    }

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

    /* please don't use pr_fname here, because it can only store less that 
       16 characters */
    strcpy( _papi_hwi_system_info.exe_info.address_info.name,
            basename( _papi_hwi_system_info.exe_info.fullname ) );

    SUBDBG( "Full Executable is %s\n",
            _papi_hwi_system_info.exe_info.fullname );

    /* Executable regions, reading /proc/pid/maps file */
    retval = _ultra_hwd_update_shlib_info( &_papi_hwi_system_info );

    /* Hardware info */

    _papi_hwi_system_info.hw_info.ncpu = sysconf( _SC_NPROCESSORS_ONLN );
    _papi_hwi_system_info.hw_info.nnodes = 1;
    _papi_hwi_system_info.hw_info.totalcpus = sysconf( _SC_NPROCESSORS_CONF );

    retval = scan_prtconf( cpuname, PAPI_MAX_STR_LEN, &hz, &version );
    if ( retval == -1 )
        return PAPI_ECMP;

    strcpy( _papi_hwi_system_info.hw_info.model_string,
            cpc_getcciname( cpuver ) );
    _papi_hwi_system_info.hw_info.model = cpuver;
    strcpy( _papi_hwi_system_info.hw_info.vendor_string, "SUN" );
    _papi_hwi_system_info.hw_info.vendor = PAPI_VENDOR_SUN;
    _papi_hwi_system_info.hw_info.revision = version;

    _papi_hwi_system_info.hw_info.mhz = ( ( float ) hz / 1.0e6 );
    SUBDBG( "hw_info.mhz = %f\n", _papi_hwi_system_info.hw_info.mhz );

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


    /* Number of PMCs */

    retval = cpc_getnpic( cpuver );
    if ( retval < 0 )
        return PAPI_ECMP;

    _solaris_vector.cmp_info.num_cntrs = retval;
    _solaris_vector.cmp_info.fast_real_timer = 1;
    _solaris_vector.cmp_info.fast_virtual_timer = 1;
    _solaris_vector.cmp_info.default_domain = PAPI_DOM_USER;
    _solaris_vector.cmp_info.available_domains =
        PAPI_DOM_USER | PAPI_DOM_KERNEL;

    /* Setup presets */

    retval = _papi_hwi_setup_all_presets( preset_search_map, NULL );
    if ( retval )
        return ( retval );

    return ( PAPI_OK );
}

Here is the call graph for this function:

Here is the caller graph for this function:

long long _solaris_get_virt_usec ( void  )

Definition at line 776 of file solaris-common.c.

{
    return ( ( long long ) gethrvtime(  ) / ( long long ) 1000 );
}

< A System/C library call failed

< A System/C library call failed

< No error

Definition at line 277 of file solaris-common.c.

{
    char *file = "/proc/self/map";
    char *resolve_pattern = "/proc/self/path/%s";

    char lastobject[PRMAPSZ];
    char link[PAPI_HUGE_STR_LEN];
    char path[PAPI_HUGE_STR_LEN];

    prmap_t mapping;

    int fd, count = 0, total = 0, position = -1, first = 1;
    caddr_t t_min, t_max, d_min, d_max;

    PAPI_address_map_t *pam, *cur;

#ifdef DEBUG
    SUBDBG( "ENTERING FUNCTION  >>%s<< at %s:%d\n", __func__, __FILE__,
            __LINE__ );
#endif

    fd = open( file, O_RDONLY );

    if ( fd == -1 ) {
        return PAPI_ESYS;
    }

    memset( lastobject, 0, PRMAPSZ );

#ifdef DEBUG
    SUBDBG( " -> %s: Preprocessing memory maps from procfs\n", __func__ );
#endif

    /* Search through the list of mappings in order to identify a) how many
       mappings are available and b) how many unique mappings are available. */
    while ( read( fd, &mapping, sizeof ( prmap_t ) ) > 0 ) {
#ifdef DEBUG
        SUBDBG( " -> %s: Found a new memory map entry\n", __func__ );
#endif
        /* Another entry found, just the total count of entries. */
        total++;

        /* Is the mapping accessible and not anonymous? */
        if ( mapping.pr_mflags & ( MA_READ | MA_WRITE | MA_EXEC ) &&
             !( mapping.pr_mflags & MA_ANON ) ) {
            /* Test if a new library has been found. If a new library has been
               found a new entry needs to be counted. */
            if ( strcmp( lastobject, mapping.pr_mapname ) != 0 ) {
                strncpy( lastobject, mapping.pr_mapname, PRMAPSZ );
                count++;

#ifdef DEBUG
                SUBDBG( " -> %s: Memory mapping entry valid for %s\n", __func__,
                        mapping.pr_mapname );
#endif
            }
        }
    }
#ifdef DEBUG
    SUBDBG( " -> %s: Preprocessing done, starting to analyze\n", __func__ );
#endif


    /* Start from the beginning, now fill in the found mappings */
    if ( lseek( fd, 0, SEEK_SET ) == -1 ) {
        return PAPI_ESYS;
    }

    memset( lastobject, 0, PRMAPSZ );

    /* Allocate memory */
    pam =
        ( PAPI_address_map_t * ) papi_calloc( count,
                                              sizeof ( PAPI_address_map_t ) );

    while ( read( fd, &mapping, sizeof ( prmap_t ) ) > 0 ) {

        if ( mapping.pr_mflags & MA_ANON ) {
#ifdef DEBUG
            SUBDBG
                ( " -> %s: Anonymous mapping (MA_ANON) found for %s, skipping\n",
                  __func__, mapping.pr_mapname );
#endif
            continue;
        }

        /* Check for a new entry */
        if ( strcmp( mapping.pr_mapname, lastobject ) != 0 ) {
#ifdef DEBUG
            SUBDBG( " -> %s: Analyzing mapping for %s\n", __func__,
                    mapping.pr_mapname );
#endif
            cur = &( pam[++position] );
            strncpy( lastobject, mapping.pr_mapname, PRMAPSZ );
            snprintf( link, PAPI_HUGE_STR_LEN, resolve_pattern, lastobject );
            memset( path, 0, PAPI_HUGE_STR_LEN );
            readlink( link, path, PAPI_HUGE_STR_LEN );
            strncpy( cur->name, path, PAPI_HUGE_STR_LEN );
#ifdef DEBUG
            SUBDBG( " -> %s: Resolved name for %s: %s\n", __func__,
                    mapping.pr_mapname, cur->name );
#endif
        }

        if ( mapping.pr_mflags & MA_READ ) {
            /* Data (MA_WRITE) or text (MA_READ) segment? */
            if ( mapping.pr_mflags & MA_WRITE ) {
                cur->data_start = ( caddr_t ) mapping.pr_vaddr;
                cur->data_end =
                    ( caddr_t ) ( mapping.pr_vaddr + mapping.pr_size );

                if ( strcmp
                     ( cur->name,
                       _papi_hwi_system_info.exe_info.fullname ) == 0 ) {
                    _papi_hwi_system_info.exe_info.address_info.data_start =
                        cur->data_start;
                    _papi_hwi_system_info.exe_info.address_info.data_end =
                        cur->data_end;
                }

                if ( first )
                    d_min = cur->data_start;
                if ( first )
                    d_max = cur->data_end;

                if ( cur->data_start < d_min ) {
                    d_min = cur->data_start;
                }

                if ( cur->data_end > d_max ) {
                    d_max = cur->data_end;
                }
            } else if ( mapping.pr_mflags & MA_EXEC ) {
                cur->text_start = ( caddr_t ) mapping.pr_vaddr;
                cur->text_end =
                    ( caddr_t ) ( mapping.pr_vaddr + mapping.pr_size );

                if ( strcmp
                     ( cur->name,
                       _papi_hwi_system_info.exe_info.fullname ) == 0 ) {
                    _papi_hwi_system_info.exe_info.address_info.text_start =
                        cur->text_start;
                    _papi_hwi_system_info.exe_info.address_info.text_end =
                        cur->text_end;
                }

                if ( first )
                    t_min = cur->text_start;
                if ( first )
                    t_max = cur->text_end;

                if ( cur->text_start < t_min ) {
                    t_min = cur->text_start;
                }

                if ( cur->text_end > t_max ) {
                    t_max = cur->text_end;
                }
            }
        }

        first = 0;
    }

    close( fd );

    /* During the walk of shared objects the upper and lower bound of the
       segments could be discovered. The bounds are stored in the PAPI info
       structure. The information is important for the profiling functions of
       PAPI. */

/* This variant would pass the addresses of all text and data segments 
  _papi_hwi_system_info.exe_info.address_info.text_start = t_min;
  _papi_hwi_system_info.exe_info.address_info.text_end = t_max;
  _papi_hwi_system_info.exe_info.address_info.data_start = d_min;
  _papi_hwi_system_info.exe_info.address_info.data_end = d_max;
*/

#ifdef DEBUG
    SUBDBG( " -> %s: Analysis of memory maps done, results:\n", __func__ );
    SUBDBG( " -> %s: text_start=%x, text_end=%x, text_size=%lld\n", __func__,
            _papi_hwi_system_info.exe_info.address_info.text_start,
            _papi_hwi_system_info.exe_info.address_info.text_end,
            _papi_hwi_system_info.exe_info.address_info.text_end
            - _papi_hwi_system_info.exe_info.address_info.text_start );
    SUBDBG( " -> %s: data_start=%x, data_end=%x, data_size=%lld\n", __func__,
            _papi_hwi_system_info.exe_info.address_info.data_start,
            _papi_hwi_system_info.exe_info.address_info.data_end,
            _papi_hwi_system_info.exe_info.address_info.data_end
            - _papi_hwi_system_info.exe_info.address_info.data_start );
#endif

    /* Store the map read and the total count of shlibs found */
    _papi_hwi_system_info.shlib_info.map = pam;
    _papi_hwi_system_info.shlib_info.count = count;

#ifdef DEBUG
    SUBDBG( "LEAVING FUNCTION  >>%s<< at %s:%d\n", __func__, __FILE__,
            __LINE__ );
#endif

    return PAPI_OK;
}

Here is the call graph for this function:

void cpu_sync ( void  )

Variable Documentation

caddr_t _edata
caddr_t _end
caddr_t _etext
caddr_t _start
rwlock_t lock[PAPI_MAX_LOCK]

Definition at line 25 of file aix.c.

 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines