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 = NULL
static int num_events = 0
static int is_initialized = 0
static long long _net_register_start [NET_MAX_COUNTERS]
static long long _net_register_current [NET_MAX_COUNTERS]
static struct temp_eventroot = NULL
static struct net_counters _net_counter_info [NET_INTERFACE_COUNTERS]

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 469 of file linux-net.c.

00470 {
00471     ( void ) ctx;
00472     ( void ) code;
00473     ( void ) option;
00474 
00475     return PAPI_OK;
00476 }

int _net_init_component ( int  cidx  ) 

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

00300 {
00301     int i = 0;
00302     struct temp_event *t, *last;
00303 
00304     if ( is_initialized )
00305         return PAPI_OK;
00306 
00307     memset(_net_register_start, 0,
00308             NET_MAX_COUNTERS*sizeof(_net_register_start[0]));
00309     memset(_net_register_current, 0, 
00310             NET_MAX_COUNTERS*sizeof(_net_register_current[0]));
00311 
00312     is_initialized = 1;
00313 
00314     /* The network interfaces are listed in /proc/net/dev */
00315     num_events = generateNetEventList();
00316 
00317     if ( num_events < 0 )  /* PAPI errors */
00318         return num_events;
00319 
00320     if ( num_events == 0 )  /* No network interfaces found */
00321         return PAPI_OK;
00322 
00323     t = root;
00324     _net_native_events = (NET_native_event_entry_t*)
00325         papi_malloc(sizeof(NET_native_event_entry_t) * num_events);
00326     do {
00327         strncpy(_net_native_events[i].name, t->name, PAPI_MAX_STR_LEN-1);
00328         _net_native_events[i].name[PAPI_MAX_STR_LEN-1] = '\0';
00329         strncpy(_net_native_events[i].description, t->description, PAPI_MAX_STR_LEN-1);
00330         _net_native_events[i].description[PAPI_MAX_STR_LEN-1] = '\0';
00331         _net_native_events[i].resources.selector = i + 1;
00332         last    = t;
00333         t       = t->next;
00334         papi_free(last);
00335         i++;
00336     } while (t != NULL);
00337     root = NULL;
00338 
00339     /* Export the total number of events available */
00340     _net_vector.cmp_info.num_native_events = num_events;
00341 
00342     /* Export the component id */
00343     _net_vector.cmp_info.CmpIdx = cidx;
00344 
00345     return PAPI_OK;
00346 }

Here is the call graph for this function:

int _net_init_control_state ( hwd_control_state_t ctl  ) 

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

00355 {
00356     ( void ) ctl;
00357 
00358     return PAPI_OK;
00359 }

int _net_init_thread ( hwd_context_t ctx  ) 

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

00287 {
00288     ( void ) ctx;
00289 
00290     return PAPI_OK;
00291 }

int _net_ntv_code_to_bits ( unsigned int  EventCode,
hwd_register_t bits 
)

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

00622 {
00623     int index = EventCode;
00624 
00625     if ( index >= 0 && index < num_events ) {
00626         memcpy( ( NET_register_t * ) bits,
00627                 &( _net_native_events[index].resources ),
00628                 sizeof ( NET_register_t ) );
00629         return PAPI_OK;
00630     }
00631 
00632     return PAPI_ENOEVNT;
00633 }

int _net_ntv_code_to_descr ( unsigned int  EventCode,
char *  name,
int  len 
)

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

00605 {
00606     int index = EventCode;
00607 
00608     if ( index >= 0 && index < num_events ) {
00609         strncpy( name, _net_native_events[index].description, len );
00610         return PAPI_OK;
00611     }
00612 
00613     return PAPI_ENOEVNT;
00614 }

int _net_ntv_code_to_name ( unsigned int  EventCode,
char *  name,
int  len 
)

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

00588 {
00589     int index = EventCode;
00590 
00591     if ( index >= 0 && index < num_events ) {
00592         strncpy( name, _net_native_events[index].name, len );
00593         return PAPI_OK;
00594     }
00595 
00596     return PAPI_ENOEVNT;
00597 }

int _net_ntv_enum_events ( unsigned int *  EventCode,
int  modifier 
)

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

00533 {
00534     int index;
00535 
00536     switch ( modifier ) {
00537         case PAPI_ENUM_FIRST:
00538             if (num_events==0) {
00539                 return PAPI_ENOEVNT;
00540             }
00541             *EventCode = 0;
00542             return PAPI_OK;
00543             break;
00544 
00545         case PAPI_ENUM_EVENTS:
00546             index = *EventCode;
00547             if ( index < num_events - 1 ) {
00548                 *EventCode = *EventCode + 1;
00549                 return PAPI_OK;
00550             } else {
00551                 return PAPI_ENOEVNT;
00552             }
00553             break;
00554 
00555         default:
00556             return PAPI_EINVAL;
00557             break;
00558     }
00559     return PAPI_EINVAL;
00560 }

int _net_ntv_name_to_code ( char *  name,
unsigned int *  EventCode 
)

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

00568 {
00569     int i;
00570 
00571     for ( i=0; i<num_events; i++) {
00572         if (strcmp(name, _net_native_events[i].name) == 0) {
00573        *EventCode = i;
00574 
00575             return PAPI_OK;
00576         }
00577     }
00578 
00579     return PAPI_ENOEVNT;
00580 }

int _net_read ( hwd_context_t ctx,
hwd_control_state_t ctl,
long long **  events,
int  flags 
)

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

00387 {
00388     (void) flags;
00389     (void) ctx;
00390 
00391     NET_control_state_t *net_ctl = (NET_control_state_t *) ctl;
00392     long long now = PAPI_get_real_usec();
00393     int i;
00394 
00395     /* Caching
00396      * Only read new values from /proc if enough time has passed
00397      * since the last read.
00398      */
00399     if ( now - net_ctl->lastupdate > NET_REFRESH_LATENCY ) {
00400         read_net_counters(_net_register_current);
00401         for ( i=0; i<NET_MAX_COUNTERS; i++ ) {
00402             net_ctl->values[i] = _net_register_current[i] - _net_register_start[i];
00403         }
00404         net_ctl->lastupdate = now;
00405     }
00406     *events = net_ctl->values;
00407 
00408     return PAPI_OK;
00409 }

Here is the call graph for this function:

int _net_reset ( hwd_context_t ctx,
hwd_control_state_t ctl 
)

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

00520 {
00521     ( void ) ctx;
00522     ( void ) ctl;
00523 
00524     return PAPI_OK;
00525 }

int _net_set_domain ( hwd_control_state_t ctl,
int  domain 
)

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

00509 {
00510     ( void ) ctl;
00511     if ( PAPI_DOM_ALL != domain )
00512         return PAPI_EINVAL;
00513 
00514     return PAPI_OK;
00515 }

int _net_shutdown_component ( void   ) 

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

00448 {
00449     if ( is_initialized )
00450     {
00451       is_initialized = 0;
00452       if (_net_native_events != NULL)
00453       {
00454          papi_free(_net_native_events);
00455          _net_native_events = NULL;
00456       }
00457     }
00458 
00459     return PAPI_OK;
00460 }

int _net_shutdown_thread ( hwd_context_t ctx  ) 

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

00436 {
00437     ( void ) ctx;
00438 
00439     return PAPI_OK;
00440 }

int _net_start ( hwd_context_t ctx,
hwd_control_state_t ctl 
)

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

00364 {
00365     ( void ) ctx;
00366 
00367     NET_control_state_t *net_ctl = (NET_control_state_t *) ctl;
00368     long long now = PAPI_get_real_usec();
00369 
00370     read_net_counters(_net_register_start);
00371     memcpy(_net_register_current, _net_register_start,
00372             NET_MAX_COUNTERS * sizeof(_net_register_start[0]));
00373 
00374     /* set initial values to 0 */
00375     memset(net_ctl->values, 0, NET_MAX_COUNTERS*sizeof(net_ctl->values[0]));
00376     
00377     /* Set last access time for caching purposes */
00378     net_ctl->lastupdate = now;
00379 
00380     return PAPI_OK;
00381 }

Here is the call graph for this function:

int _net_stop ( hwd_context_t ctx,
hwd_control_state_t ctl 
)

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

00414 {
00415     (void) ctx;
00416 
00417     NET_control_state_t *net_ctl = (NET_control_state_t *) ctl;
00418     long long now = PAPI_get_real_usec();
00419     int i;
00420 
00421     read_net_counters(_net_register_current);
00422     for ( i=0; i<NET_MAX_COUNTERS; i++ ) {
00423         net_ctl->values[i] = _net_register_current[i] - _net_register_start[i];
00424     }
00425     net_ctl->lastupdate = now;
00426 
00427     return PAPI_OK;
00428 }

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 480 of file linux-net.c.

00482 {
00483     ( void ) ctx;
00484     ( void ) ctl;
00485 
00486     int i, index;
00487 
00488     for ( i = 0; i < count; i++ ) {
00489         index = native[i].ni_event;
00490         native[i].ni_position = _net_native_events[index].resources.selector - 1;
00491     }
00492 
00493     return PAPI_OK;
00494 }

static int generateNetEventList ( void   )  [static]

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

00107 {
00108     FILE *fin;
00109     char line[NET_PROC_MAX_LINE];
00110     char *retval, *ifname;
00111     int count = 0;
00112     struct temp_event *temp;
00113     struct temp_event *last = NULL;
00114     int i, j;
00115 
00116     fin = fopen(NET_PROC_FILE, "r");
00117     if (fin == NULL) {
00118         SUBDBG("Can't find %s, are you sure the /proc file-system is mounted?\n",
00119            NET_PROC_FILE);
00120         return 0;
00121     }
00122 
00123     /* skip the 2 header lines */
00124     for (i=0; i<2; i++) {
00125         retval = fgets (line, NET_PROC_MAX_LINE, fin);
00126         if (retval == NULL) {
00127             fclose(fin);
00128             SUBDBG("Not enough lines in %s\n", NET_PROC_FILE);
00129             return 0;
00130         }
00131     }
00132 
00133     while ((fgets (line, NET_PROC_MAX_LINE, fin)) == line) {
00134 
00135         /* split the interface name from the 16 counters */
00136         retval = strstr(line, ":");
00137         if (retval == NULL) {
00138             SUBDBG("Wrong line format <%s>\n", line);
00139             continue;
00140         }
00141 
00142         *retval = '\0';
00143         ifname = line;
00144         while (isspace(*ifname)) { ifname++; }
00145 
00146         for (j=0; j<NET_INTERFACE_COUNTERS; j++) {
00147 
00148             /* keep the interface name around */
00149             temp = (struct temp_event *)papi_malloc(sizeof(struct temp_event));
00150             if (!temp) {
00151                 PAPIERROR("out of memory!");
00152                 fclose(fin);
00153                 return PAPI_ENOMEM;
00154             }
00155             temp->next = NULL;
00156 
00157             if (root == NULL) {
00158                 root = temp;
00159             } else if (last) {
00160                 last->next = temp;
00161             } else {
00162                 free(temp);
00163                 fclose(fin);
00164                 PAPIERROR("This shouldn't be possible\n");
00165                 return PAPI_ECMP;
00166             }
00167             last = temp;
00168 
00169             snprintf(temp->name, PAPI_MAX_STR_LEN, "%s:%s",
00170                     ifname, _net_counter_info[j].name);
00171             snprintf(temp->description, PAPI_MAX_STR_LEN, "%s %s",
00172                     ifname, _net_counter_info[j].description);
00173 
00174             count++;
00175         }
00176     }
00177 
00178     fclose(fin);
00179 
00180     return count;
00181 }

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.

00186 {
00187     int i;
00188 
00189     for ( i=0; i<num_events; i+=NET_INTERFACE_COUNTERS ) {
00190         if (strncmp(_net_native_events[i].name, ifname, strlen(ifname)) == 0) {
00191             return i;
00192         }
00193     }
00194 
00195     return -1;  /* Not found */
00196 }

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.

00201 {
00202     FILE *fin;
00203     char line[NET_PROC_MAX_LINE];
00204     char *retval, *ifname, *data;
00205     int i, nf, if_bidx;
00206 
00207     fin = fopen(NET_PROC_FILE, "r");
00208     if (fin == NULL) {
00209         SUBDBG("Can't find %s, are you sure the /proc file-system is mounted?\n",
00210            NET_PROC_FILE);
00211         return NET_INVALID_RESULT;
00212     }
00213 
00214     /* skip the 2 header lines */
00215     for (i=0; i<2; i++) {
00216         retval = fgets (line, NET_PROC_MAX_LINE, fin);
00217         if (retval == NULL) {
00218             SUBDBG("Not enough lines in %s\n", NET_PROC_FILE);
00219             fclose(fin);
00220             return 0;
00221         }
00222     }
00223 
00224     while ((fgets (line, NET_PROC_MAX_LINE, fin)) == line) {
00225 
00226         /* split the interface name from its 16 counters */
00227         retval = strstr(line, ":");
00228         if (retval == NULL) {
00229             SUBDBG("Wrong line format <%s>\n", line);
00230             continue;
00231         }
00232 
00233         *retval = '\0';
00234         data = retval + 1;
00235         ifname = line;
00236         while (isspace(*ifname)) { ifname++; }
00237 
00238         if_bidx = getInterfaceBaseIndex(ifname);
00239         if (if_bidx < 0) {
00240             SUBDBG("Interface <%s> not found\n", ifname);
00241         } else {
00242             nf = sscanf( data,
00243                 "%lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld\n",
00244                 &values[if_bidx + 0],  &values[if_bidx + 1],
00245                 &values[if_bidx + 2],  &values[if_bidx + 3],
00246                 &values[if_bidx + 4],  &values[if_bidx + 5],
00247                 &values[if_bidx + 6],  &values[if_bidx + 7],
00248                 &values[if_bidx + 8],  &values[if_bidx + 9],
00249                 &values[if_bidx + 10], &values[if_bidx + 11],
00250                 &values[if_bidx + 12], &values[if_bidx + 13],
00251                 &values[if_bidx + 14], &values[if_bidx + 15]);
00252 
00253             SUBDBG("\nRead "
00254                 "%lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld\n",
00255                 values[if_bidx + 0],  values[if_bidx + 1],
00256                 values[if_bidx + 2],  values[if_bidx + 3],
00257                 values[if_bidx + 4],  values[if_bidx + 5],
00258                 values[if_bidx + 6],  values[if_bidx + 7],
00259                 values[if_bidx + 8],  values[if_bidx + 9],
00260                 values[if_bidx + 10], values[if_bidx + 11],
00261                 values[if_bidx + 12], values[if_bidx + 13],
00262                 values[if_bidx + 14], values[if_bidx + 15]);
00263 
00264             if ( nf != NET_INTERFACE_COUNTERS ) {
00265                 /* This shouldn't happen */
00266                 SUBDBG("/proc line with wrong number of fields\n");
00267             }
00268         }
00269 
00270     }
00271 
00272     fclose(fin);
00273 
00274     return 0;
00275 }

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

struct net_counters _net_counter_info[NET_INTERFACE_COUNTERS] [static]

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

long long _net_register_current[NET_MAX_COUNTERS] [static]

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

long long _net_register_start[NET_MAX_COUNTERS] [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.


Generated on 26 Jan 2016 for PAPI by  doxygen 1.6.1