PAPI  5.0.1.0
linux-net.c File Reference

net component This file contains the source code for a component that enables PAPI-C to access network statistics through the /proc file system. This component will dynamically create a native events table for all the interfaces listed in /proc/net/dev (16 entries for each interface). More...

Include dependency graph for linux-net.c:

Go to the source code of this file.

Data Structures

struct  temp_event
struct  net_counters

Defines

#define NET_REFRESH_LATENCY   1000000
#define NET_PROC_FILE   "/proc/net/dev"
#define NET_PROC_MAX_LINE   (IFNAMSIZ + 16 * (20 + 1) + 16)
#define NET_INVALID_RESULT   -1
#define NET_INTERFACE_COUNTERS   16

Functions

static int generateNetEventList (void)
static int getInterfaceBaseIndex (const char *ifname)
static int read_net_counters (long long *values)
int _net_init_thread (hwd_context_t *ctx)
int _net_init_component (int cidx)
int _net_init_control_state (hwd_control_state_t *ctl)
int _net_start (hwd_context_t *ctx, hwd_control_state_t *ctl)
int _net_read (hwd_context_t *ctx, hwd_control_state_t *ctl, long long **events, int flags)
int _net_stop (hwd_context_t *ctx, hwd_control_state_t *ctl)
int _net_shutdown_thread (hwd_context_t *ctx)
int _net_shutdown_component (void)
int _net_ctl (hwd_context_t *ctx, int code, _papi_int_option_t *option)
int _net_update_control_state (hwd_control_state_t *ctl, NativeInfo_t *native, int count, hwd_context_t *ctx)
int _net_set_domain (hwd_control_state_t *ctl, int domain)
int _net_reset (hwd_context_t *ctx, hwd_control_state_t *ctl)
int _net_ntv_enum_events (unsigned int *EventCode, int modifier)
int _net_ntv_name_to_code (char *name, unsigned int *EventCode)
int _net_ntv_code_to_name (unsigned int EventCode, char *name, int len)
int _net_ntv_code_to_descr (unsigned int EventCode, char *name, int len)
int _net_ntv_code_to_bits (unsigned int EventCode, hwd_register_t *bits)

Variables

papi_vector_t _net_vector
static NET_native_event_entry_t_net_native_events
static int num_events = 0
static int is_initialized = 0
static long long _net_register_start [320]
static long long _net_register_current [320]
static struct temp_eventroot = NULL
static struct net_counters _net_counter_info [16]

Detailed Description

Author:
Haihang You you@cs.utk.edu
Jose Pedro Oliveira jpo@di.uminho.pt

Definition in file linux-net.c.


Define Documentation

#define NET_INTERFACE_COUNTERS   16

Definition at line 71 of file linux-net.c.

#define NET_INVALID_RESULT   -1

Definition at line 51 of file linux-net.c.

#define NET_PROC_FILE   "/proc/net/dev"

Definition at line 44 of file linux-net.c.

#define NET_PROC_MAX_LINE   (IFNAMSIZ + 16 * (20 + 1) + 16)

Definition at line 49 of file linux-net.c.

#define NET_REFRESH_LATENCY   1000000

Definition at line 42 of file linux-net.c.


Function Documentation

int _net_ctl ( hwd_context_t ctx,
int  code,
_papi_int_option_t option 
)

Definition at line 463 of file linux-net.c.

{
    ( void ) ctx;
    ( void ) code;
    ( void ) option;

    return PAPI_OK;
}
int _net_init_component ( int  cidx)

Definition at line 299 of file linux-net.c.

{
    int i = 0;
    struct temp_event *t, *last;

    if ( is_initialized )
        return PAPI_OK;

    memset(_net_register_start, 0,
            NET_MAX_COUNTERS*sizeof(_net_register_start[0]));
    memset(_net_register_current, 0, 
            NET_MAX_COUNTERS*sizeof(_net_register_current[0]));

    is_initialized = 1;

    /* The network interfaces are listed in /proc/net/dev */
    num_events = generateNetEventList();

    if ( num_events < 0 )  /* PAPI errors */
        return num_events;

    if ( num_events == 0 )  /* No network interfaces found */
        return PAPI_OK;

    t = root;
    _net_native_events = (NET_native_event_entry_t*)
        papi_malloc(sizeof(NET_native_event_entry_t) * num_events);
    do {
        strncpy(_net_native_events[i].name, t->name, PAPI_MAX_STR_LEN);
        strncpy(_net_native_events[i].description, t->description, PAPI_MAX_STR_LEN);
        _net_native_events[i].resources.selector = i + 1;
        last    = t;
        t       = t->next;
        papi_free(last);
        i++;
    } while (t != NULL);
    root = NULL;

    /* Export the total number of events available */
    _net_vector.cmp_info.num_native_events = num_events;

    /* Export the component id */
    _net_vector.cmp_info.CmpIdx = cidx;

    return PAPI_OK;
}

Here is the call graph for this function:

Definition at line 352 of file linux-net.c.

{
    ( void ) ctl;

    return PAPI_OK;
}

Definition at line 286 of file linux-net.c.

{
    ( void ) ctx;

    return PAPI_OK;
}
int _net_ntv_code_to_bits ( unsigned int  EventCode,
hwd_register_t bits 
)

Definition at line 622 of file linux-net.c.

{
    int index = EventCode;

    if ( index >= 0 && index < num_events ) {
        memcpy( ( NET_register_t * ) bits,
                &( _net_native_events[index].resources ),
                sizeof ( NET_register_t ) );
        return PAPI_OK;
    }

    return PAPI_ENOEVNT;
}
int _net_ntv_code_to_descr ( unsigned int  EventCode,
char *  name,
int  len 
)

Definition at line 605 of file linux-net.c.

{
    int index = EventCode;

    if ( index >= 0 && index < num_events ) {
        strncpy( name, _net_native_events[index].description, len );
        return PAPI_OK;
    }

    return PAPI_ENOEVNT;
}
int _net_ntv_code_to_name ( unsigned int  EventCode,
char *  name,
int  len 
)

Definition at line 588 of file linux-net.c.

{
    int index = EventCode;

    if ( index >= 0 && index < num_events ) {
        strncpy( name, _net_native_events[index].name, len );
        return PAPI_OK;
    }

    return PAPI_ENOEVNT;
}
int _net_ntv_enum_events ( unsigned int *  EventCode,
int  modifier 
)

Definition at line 533 of file linux-net.c.

{
    int index;

    switch ( modifier ) {
        case PAPI_ENUM_FIRST:
            if (num_events==0) {
                return PAPI_ENOEVNT;
            }
            *EventCode = 0;
            return PAPI_OK;
            break;

        case PAPI_ENUM_EVENTS:
            index = *EventCode;
            if ( index < num_events - 1 ) {
                *EventCode = *EventCode + 1;
                return PAPI_OK;
            } else {
                return PAPI_ENOEVNT;
            }
            break;

        default:
            return PAPI_EINVAL;
            break;
    }
    return PAPI_EINVAL;
}
int _net_ntv_name_to_code ( char *  name,
unsigned int *  EventCode 
)

Definition at line 568 of file linux-net.c.

{
    int i;

    for ( i=0; i<num_events; i++) {
        if (strcmp(name, _net_native_events[i].name) == 0) {
       *EventCode = i;

            return PAPI_OK;
        }
    }

    return PAPI_ENOEVNT;
}
int _net_read ( hwd_context_t ctx,
hwd_control_state_t ctl,
long long **  events,
int  flags 
)

Definition at line 383 of file linux-net.c.

{
    (void) flags;
    (void) ctx;

    NET_control_state_t *net_ctl = (NET_control_state_t *) ctl;
    long long now = PAPI_get_real_usec();
    int i;

    /* Caching
     * Only read new values from /proc if enough time has passed
     * since the last read.
     */
    if ( now - net_ctl->lastupdate > NET_REFRESH_LATENCY ) {
        read_net_counters(_net_register_current);
        for ( i=0; i<NET_MAX_COUNTERS; i++ ) {
            net_ctl->values[i] = _net_register_current[i] - _net_register_start[i];
        }
        net_ctl->lastupdate = now;
    }
    *events = net_ctl->values;

    return PAPI_OK;
}

Here is the call graph for this function:

int _net_reset ( hwd_context_t ctx,
hwd_control_state_t ctl 
)

Definition at line 520 of file linux-net.c.

{
    ( void ) ctx;
    ( void ) ctl;

    return PAPI_OK;
}
int _net_set_domain ( hwd_control_state_t ctl,
int  domain 
)

Definition at line 502 of file linux-net.c.

{
    ( void ) ctl;

    int found = 0;

    if ( PAPI_DOM_USER & domain )   found = 1;
    if ( PAPI_DOM_KERNEL & domain ) found = 1;
    if ( PAPI_DOM_OTHER & domain )  found = 1;

    if ( !found )
        return PAPI_EINVAL;

    return PAPI_OK;
}
int _net_shutdown_component ( void  )

Definition at line 445 of file linux-net.c.

Definition at line 433 of file linux-net.c.

{
    ( void ) ctx;

    return PAPI_OK;
}
int _net_start ( hwd_context_t ctx,
hwd_control_state_t ctl 
)

Definition at line 361 of file linux-net.c.

{
    ( void ) ctx;

    NET_control_state_t *net_ctl = (NET_control_state_t *) ctl;
    long long now = PAPI_get_real_usec();

    read_net_counters(_net_register_start);
    memcpy(_net_register_current, _net_register_start,
            NET_MAX_COUNTERS * sizeof(_net_register_start[0]));

    /* set initial values to 0 */
    memset(net_ctl->values, 0, NET_MAX_COUNTERS*sizeof(net_ctl->values[0]));
    
    /* Set last access time for caching purposes */
    net_ctl->lastupdate = now;

    return PAPI_OK;
}

Here is the call graph for this function:

int _net_stop ( hwd_context_t ctx,
hwd_control_state_t ctl 
)

Definition at line 411 of file linux-net.c.

{
    (void) ctx;

    NET_control_state_t *net_ctl = (NET_control_state_t *) ctl;
    long long now = PAPI_get_real_usec();
    int i;

    read_net_counters(_net_register_current);
    for ( i=0; i<NET_MAX_COUNTERS; i++ ) {
        net_ctl->values[i] = _net_register_current[i] - _net_register_start[i];
    }
    net_ctl->lastupdate = now;

    return PAPI_OK;
}

Here is the call graph for this function:

int _net_update_control_state ( hwd_control_state_t ctl,
NativeInfo_t native,
int  count,
hwd_context_t ctx 
)

Definition at line 474 of file linux-net.c.

{
    ( void ) ctx;
    ( void ) ctl;

    int i, index;

    for ( i = 0; i < count; i++ ) {
        index = native[i].ni_event;
        native[i].ni_position = _net_native_events[index].resources.selector - 1;
    }

    return PAPI_OK;
}
static int generateNetEventList ( void  ) [static]

Definition at line 106 of file linux-net.c.

{
    FILE *fin;
    char line[NET_PROC_MAX_LINE];
    char *retval, *ifname;
    int count = 0;
    struct temp_event *temp;
    struct temp_event *last = NULL;
    int i, j;

    fin = fopen(NET_PROC_FILE, "r");
    if (fin == NULL) {
        SUBDBG("Can't find %s, are you sure the /proc file-system is mounted?\n",
           NET_PROC_FILE);
        return 0;
    }

    /* skip the 2 header lines */
    for (i=0; i<2; i++) {
        retval = fgets (line, NET_PROC_MAX_LINE, fin);
        if (retval == NULL) {
            fclose(fin);
            SUBDBG("Not enough lines in %s\n", NET_PROC_FILE);
            return 0;
        }
    }

    while ((fgets (line, NET_PROC_MAX_LINE, fin)) == line) {

        /* split the interface name from the 16 counters */
        retval = strstr(line, ":");
        if (retval == NULL) {
            SUBDBG("Wrong line format <%s>\n", line);
            continue;
        }

        *retval = '\0';
        ifname = line;
        while (isspace(*ifname)) { ifname++; }

        for (j=0; j<NET_INTERFACE_COUNTERS; j++) {

            /* keep the interface name around */
            temp = (struct temp_event *)papi_malloc(sizeof(struct temp_event));
            if (!temp) {
                PAPIERROR("out of memory!");
                fclose(fin);
                return PAPI_ENOMEM;
            }
            temp->next = NULL;

            if (root == NULL) {
                root = temp;
            } else if (last) {
                last->next = temp;
            } else {
                free(temp);
                fclose(fin);
                PAPIERROR("This shouldn't be possible\n");
                return PAPI_ECMP;
            }
            last = temp;

            snprintf(temp->name, PAPI_MAX_STR_LEN, "%s:%s",
                    ifname, _net_counter_info[j].name);
            snprintf(temp->description, PAPI_MAX_STR_LEN, "%s %s",
                    ifname, _net_counter_info[j].description);

            count++;
        }
    }

    fclose(fin);

    return count;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int getInterfaceBaseIndex ( const char *  ifname) [static]

Definition at line 185 of file linux-net.c.

{
    int i;

    for ( i=0; i<num_events; i+=NET_INTERFACE_COUNTERS ) {
        if (strncmp(_net_native_events[i].name, ifname, strlen(ifname)) == 0) {
            return i;
        }
    }

    return -1;  /* Not found */
}

Here is the caller graph for this function:

static int read_net_counters ( long long *  values) [static]

Definition at line 200 of file linux-net.c.

{
    FILE *fin;
    char line[NET_PROC_MAX_LINE];
    char *retval, *ifname, *data;
    int i, nf, if_bidx;

    fin = fopen(NET_PROC_FILE, "r");
    if (fin == NULL) {
        SUBDBG("Can't find %s, are you sure the /proc file-system is mounted?\n",
           NET_PROC_FILE);
        return NET_INVALID_RESULT;
    }

    /* skip the 2 header lines */
    for (i=0; i<2; i++) {
        retval = fgets (line, NET_PROC_MAX_LINE, fin);
        if (retval == NULL) {
            SUBDBG("Not enough lines in %s\n", NET_PROC_FILE);
            fclose(fin);
            return 0;
        }
    }

    while ((fgets (line, NET_PROC_MAX_LINE, fin)) == line) {

        /* split the interface name from its 16 counters */
        retval = strstr(line, ":");
        if (retval == NULL) {
            SUBDBG("Wrong line format <%s>\n", line);
            continue;
        }

        *retval = '\0';
        data = retval + 1;
        ifname = line;
        while (isspace(*ifname)) { ifname++; }

        if_bidx = getInterfaceBaseIndex(ifname);
        if (if_bidx < 0) {
            SUBDBG("Interface <%s> not found\n", ifname);
        } else {
            nf = sscanf( data,
                "%llu %llu %llu %llu %llu %llu %llu %llu %llu %llu %llu %llu %llu %llu %llu %llu\n",
                &values[if_bidx + 0],  &values[if_bidx + 1],
                &values[if_bidx + 2],  &values[if_bidx + 3],
                &values[if_bidx + 4],  &values[if_bidx + 5],
                &values[if_bidx + 6],  &values[if_bidx + 7],
                &values[if_bidx + 8],  &values[if_bidx + 9],
                &values[if_bidx + 10], &values[if_bidx + 11],
                &values[if_bidx + 12], &values[if_bidx + 13],
                &values[if_bidx + 14], &values[if_bidx + 15]);

            SUBDBG("\nRead "
                "%llu %llu %llu %llu %llu %llu %llu %llu %llu %llu %llu %llu %llu %llu %llu %llu\n",
                values[if_bidx + 0],  values[if_bidx + 1],
                values[if_bidx + 2],  values[if_bidx + 3],
                values[if_bidx + 4],  values[if_bidx + 5],
                values[if_bidx + 6],  values[if_bidx + 7],
                values[if_bidx + 8],  values[if_bidx + 9],
                values[if_bidx + 10], values[if_bidx + 11],
                values[if_bidx + 12], values[if_bidx + 13],
                values[if_bidx + 14], values[if_bidx + 15]);

            if ( nf != NET_INTERFACE_COUNTERS ) {
                /* This shouldn't happen */
                SUBDBG("/proc line with wrong number of fields\n");
            }
        }

    }

    fclose(fin);

    return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

struct net_counters _net_counter_info[ 16 ] [static]

Definition at line 54 of file linux-net.c.

long long _net_register_current[320] [static]

Definition at line 60 of file linux-net.c.

long long _net_register_start[320] [static]

Definition at line 59 of file linux-net.c.

Definition at line 35 of file linux-net.c.

int is_initialized = 0 [static]

Definition at line 57 of file linux-net.c.

int num_events = 0 [static]

Definition at line 56 of file linux-net.c.

struct temp_event* root = NULL [static]

Definition at line 68 of file linux-net.c.

 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines