PAPI 7.1.0.0
Loading...
Searching...
No Matches
linux-io.c File Reference

io component This component provides access to the I/O statistics in the system file /proc/self/io. It typically contains 7 counters, but for robusness we read the file and create whatever events it contains. More...

Include dependency graph for linux-io.c:

Go to the source code of this file.

Data Structures

struct  IO_native_event_entry_t
 
struct  _io_control_state_t
 
struct  _io_context_t
 

Macros

#define FILE_LINE_SIZE   256
 
#define IO_COUNTERS   64
 
#define IO_FILENAME   "/proc/self/io"
 
#define HANDLE_STRING_ERROR   {fprintf(stderr,"%s:%i unexpected string function error.\n",__FILE__,__LINE__); exit(-1);}
 

Functions

static int io_count_events (_io_context_t *myCtx)
 
static int io_hardware_read (_io_context_t *ctx, _io_control_state_t *ctl)
 
static int _io_init_component (int cidx)
 
static int _io_init_thread (hwd_context_t *ctx)
 
static int _io_init_control_state (hwd_control_state_t *ctl)
 
static int _io_update_control_state (hwd_control_state_t *ctl, NativeInfo_t *native, int count, hwd_context_t *ctx)
 
static int _io_start (hwd_context_t *ctx, hwd_control_state_t *ctl)
 
static int _io_stop (hwd_context_t *ctx, hwd_control_state_t *ctl)
 
static int _io_read (hwd_context_t *ctx, hwd_control_state_t *ctl, long long **events, int flags)
 
static int _io_write (hwd_context_t *ctx, hwd_control_state_t *ctl, long long *events)
 
static int _io_reset (hwd_context_t *ctx, hwd_control_state_t *ctl)
 
static int _io_shutdown_component (void)
 
static int _io_shutdown_thread (hwd_context_t *ctx)
 
static int _io_ctl (hwd_context_t *ctx, int code, _papi_int_option_t *option)
 
static int _io_set_domain (hwd_control_state_t *cntrl, int domain)
 
static int _io_ntv_enum_events (unsigned int *EventCode, int modifier)
 
static int _io_ntv_code_to_name (unsigned int EventCode, char *name, int len)
 
static int _io_ntv_code_to_descr (unsigned int EventCode, char *descr, int len)
 

Variables

papi_vector_t _io_vector
 
static int gEventCount
 
static IO_native_event_entry_tio_native_table
 

Detailed Description

Author
Kevin A. Huck khuck.nosp@m.@uor.nosp@m.egon..nosp@m.edu

Definition in file linux-io.c.

Macro Definition Documentation

◆ FILE_LINE_SIZE

#define FILE_LINE_SIZE   256

Definition at line 31 of file linux-io.c.

◆ HANDLE_STRING_ERROR

#define HANDLE_STRING_ERROR   {fprintf(stderr,"%s:%i unexpected string function error.\n",__FILE__,__LINE__); exit(-1);}

Definition at line 41 of file linux-io.c.

◆ IO_COUNTERS

#define IO_COUNTERS   64

Definition at line 34 of file linux-io.c.

◆ IO_FILENAME

#define IO_FILENAME   "/proc/self/io"

Definition at line 36 of file linux-io.c.

Function Documentation

◆ _io_ctl()

static int _io_ctl ( hwd_context_t ctx,
int  code,
_papi_int_option_t option 
)
static

This function sets various options in the component

Parameters
[in]ctx– hardware context
[in]codevalid are PAPI_SET_DEFDOM, PAPI_SET_DOMAIN, PAPI_SETDEFGRN, PAPI_SET_GRANUL and PAPI_SET_INHERIT
[in]option– options to be set

Definition at line 431 of file linux-io.c.

432{
433 (void) ctx;
434 (void) code;
435 (void) option;
436 SUBDBG( "io_ctl..." );
437 return PAPI_OK;
438}
#define PAPI_OK
Definition: f90papi.h:73
#define SUBDBG(format, args...)
Definition: papi_debug.h:64

◆ _io_init_component()

static int _io_init_component ( int  cidx)
static

Initialize hardware counters, setup the function vector table and get hardware information, this routine is called when the PAPI process is initialized (IE PAPI_library_init)

Definition at line 170 of file linux-io.c.

171{
172 _io_context_t myCtx;
173 int ret, fileIdx;
174 SUBDBG( "_io_init_component..." );
175
176 ret = io_count_events(&myCtx);
177 if (ret != PAPI_OK) {
179 "Failed counting events.");
180 _io_vector.cmp_info.disabled_reason[PAPI_MAX_STR_LEN-1]=0; // force null termination.
182 goto fn_fail;
183 }
184
185 rewind(myCtx.pFile);
186
187 if (myCtx.EventCount > IO_COUNTERS) {
189 "File '%s' has %i events, exceeds counter limit of %i.", IO_FILENAME, myCtx.EventCount, IO_COUNTERS);
192 fclose(myCtx.pFile);
193 ret = PAPI_ENOSUPP;
194 goto fn_fail;
195 }
196
197 // Must be same for all threads, now.
198 gEventCount = myCtx.EventCount;
199 /* Allocate memory for the native event table */
203 if ( io_native_table == NULL ) {
205 "Failed to allocate %lu bytes for _io_native_table.", gEventCount*sizeof(IO_native_event_entry_t));
208 fclose(myCtx.pFile);
209 ret = PAPI_ENOMEM;
210 goto fn_fail;
211 }
212
213 for (fileIdx = 0; fileIdx < gEventCount; fileIdx++) {
214 (void) fgets(myCtx.line, FILE_LINE_SIZE, myCtx.pFile);
215 char name[FILE_LINE_SIZE] = {0};
216 long long tmplong = 0LL;
217 // No check for error here, we would have caught it in io_count_events().
218 (void) sscanf(myCtx.line, "%s %lld\n", name, &tmplong);
219 name[strlen(name)-1]=0; // null terminate over ':' we found.
220 strncpy(io_native_table[fileIdx].name, name, PAPI_MAX_STR_LEN-1);
221 io_native_table[fileIdx].fileIdx=fileIdx;
222 io_native_table[fileIdx].desc[0]=0; // flag for successful copy.
223 if (strcmp("rchar", name) == 0) {
224 strcpy(io_native_table[fileIdx].desc, "Characters read.");
225 }
226 if (strcmp("wchar", name) == 0) {
227 strcpy(io_native_table[fileIdx].desc, "Characters written.");
228 }
229 if (strcmp("syscr", name) == 0) {
230 strcpy(io_native_table[fileIdx].desc, "Characters read by system calls.");
231 }
232 if (strcmp("syscw", name) == 0) {
233 strcpy(io_native_table[fileIdx].desc, "Characters written by system calls.");
234 }
235 if (strcmp("read_bytes", name) == 0) {
236 strcpy(io_native_table[fileIdx].desc, "Binary bytes read.");
237 }
238 if (strcmp("write_bytes", name) == 0) {
239 strcpy(io_native_table[fileIdx].desc, "Binary bytes written.");
240 }
241 if (strcmp("cancelled_write_bytes", name) == 0) {
242 strcpy(io_native_table[fileIdx].desc, "Binary write bytes cancelled.");
243 }
244
245 // If none of the above found, generic description.
246 if (io_native_table[fileIdx].desc[0] == 0) {
247 strcpy(io_native_table[fileIdx].desc, "No description available.");
248 }
249 } // END READING.
250
251 fclose(myCtx.pFile);
252 // Export the total number of events available, at least on the init thread.
256
257 /* Export the component id */
259 fn_exit:
260 _papi_hwd[cidx]->cmp_info.disabled = ret;
261 return ret;
262 fn_fail:
263 goto fn_exit;
264} // END ROUTINE.
struct papi_vectors * _papi_hwd[]
#define PAPI_ENOSUPP
Definition: f90papi.h:244
#define PAPI_MAX_STR_LEN
Definition: f90papi.h:77
#define PAPI_ENOMEM
Definition: f90papi.h:16
papi_vector_t _io_vector
Definition: linux-io.c:28
#define IO_FILENAME
Definition: linux-io.c:36
static int gEventCount
Definition: linux-io.c:77
static IO_native_event_entry_t * io_native_table
Definition: linux-io.c:78
#define IO_COUNTERS
Definition: linux-io.c:34
static int io_count_events(_io_context_t *myCtx)
Definition: linux-io.c:82
#define FILE_LINE_SIZE
Definition: linux-io.c:31
#define HANDLE_STRING_ERROR
Definition: linux-io.c:41
int fclose(FILE *__stream)
#define papi_calloc(a, b)
Definition: papi_memory.h:37
static int cidx
const char * name
Definition: rocs.c:225
Definition: linux-io.c:45
int fileIdx
Definition: linux-io.c:48
char desc[PAPI_MAX_STR_LEN]
Definition: linux-io.c:47
char disabled_reason[PAPI_HUGE_STR_LEN]
Definition: papi.h:634
char line[FILE_LINE_SIZE]
Definition: linux-io.c:70
FILE * pFile
Definition: linux-io.c:69
int EventCount
Definition: linux-io.c:68
PAPI_component_info_t cmp_info
Definition: papi_vector.h:20
Here is the call graph for this function:

◆ _io_init_control_state()

static int _io_init_control_state ( hwd_control_state_t ctl)
static

Definition at line 292 of file linux-io.c.

293{
294 _io_control_state_t* control = ( _io_control_state_t* ) ctl;
295 memset(control, 0, sizeof(_io_control_state_t));
296 return PAPI_OK;
297} // END.

◆ _io_init_thread()

static int _io_init_thread ( hwd_context_t ctx)
static

Definition at line 271 of file linux-io.c.

272{
273 _io_context_t* myCtx = (_io_context_t*) ctx;
274 int ret;
275 ret = io_count_events(myCtx);
276 if (ret != PAPI_OK) return(ret);
277
278 // File mismatch on event count kills it.
279 if (gEventCount > 0 && myCtx->EventCount != gEventCount) {
280 fclose(myCtx->pFile);
281 myCtx->pFile = NULL;
282 return PAPI_ENOSUPP;
283 }
284
285 fclose(myCtx->pFile);
286 return PAPI_OK;
287} // END of init thread.
Here is the call graph for this function:

◆ _io_ntv_code_to_descr()

static int _io_ntv_code_to_descr ( unsigned int  EventCode,
char *  descr,
int  len 
)
static

Takes a native event code and passes back the event description

Parameters
EventCodeis the native event code
descris a pointer for the description to be copied to
lenis the size of the descr string

Definition at line 549 of file linux-io.c.

550{
551 int index;
552 index = EventCode;
553
554 /* make sure event is in range */
555 if (index >= 0 && index < gEventCount) {
556 strncpy( descr, io_native_table[index].desc, len );
557 return PAPI_OK;
558 }
559
560 return PAPI_ENOEVNT;
561}
#define PAPI_ENOEVNT
Definition: f90papi.h:139
char * descr

◆ _io_ntv_code_to_name()

static int _io_ntv_code_to_name ( unsigned int  EventCode,
char *  name,
int  len 
)
static

Takes a native event code and passes back the name

Parameters
EventCodeis the native event code
nameis a pointer for the name to be copied to
lenis the size of the name string

Definition at line 529 of file linux-io.c.

530{
531 int index;
532 index = EventCode;
533
534 /* Make sure we are in range */
535 if (index >= 0 && index < gEventCount) {
536 strncpy(name, io_native_table[index].name, len );
537 return PAPI_OK;
538 }
539
540 return PAPI_ENOEVNT;
541} // END ROUTINE.

◆ _io_ntv_enum_events()

static int _io_ntv_enum_events ( unsigned int EventCode,
int  modifier 
)
static

Enumerate Native Events

Parameters
EventCodeis the event of interest
modifieris one of PAPI_ENUM_FIRST, PAPI_ENUM_EVENTS If your component has attribute masks then these need to be handled here as well.

Definition at line 492 of file linux-io.c.

493{
494 int index;
495
496 switch ( modifier ) {
497
498 /* return EventCode of first event */
499 case PAPI_ENUM_FIRST:
500 *EventCode = 0;
501 return PAPI_OK;
502
503 /* return EventCode of next available event */
504 case PAPI_ENUM_EVENTS:
505 index = *EventCode;
506
507 /* Make sure we have at least 1 more event after us */
508 if ( index < (gEventCount-1) ) {
509 *EventCode = *EventCode + 1;
510 return PAPI_OK;
511 } else {
512 return PAPI_ENOEVNT;
513 }
514 break;
515
516 default:
517 return PAPI_EINVAL;
518 }
519
520 return PAPI_EINVAL;
521} // END ROUTINE
#define PAPI_ENUM_EVENTS
Definition: f90papi.h:224
#define PAPI_ENUM_FIRST
Definition: f90papi.h:85
#define PAPI_EINVAL
Definition: f90papi.h:115

◆ _io_read()

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

Definition at line 358 of file linux-io.c.

360{
361 // Prevent 'unused' warnings from compiler.
362 (void) flags;
363 _io_context_t *myCtx = (_io_context_t*) ctx;
365 int i;
366 SUBDBG( "io_read... %p %d", ctx, flags );
367
368 /* Read all counters into EventSetVal */
369 io_hardware_read(myCtx, myCtl);
370 for (i=0; i<myCtl->EventSetCount; i++) {
371 myCtl->EventSetReport[i]=myCtl->EventSetVal[myCtl->EventSetIdx[i]];
372 }
373
374 /* return pointer to the values we read */
375 *events = myCtl->EventSetReport;
376
377 return PAPI_OK;
378}
int i
char events[MAX_EVENTS][BUFSIZ]
static int io_hardware_read(_io_context_t *ctx, _io_control_state_t *ctl)
Definition: linux-io.c:135
long long EventSetReport[IO_COUNTERS]
Definition: linux-io.c:59
int EventSetIdx[IO_COUNTERS]
Definition: linux-io.c:60
long long EventSetVal[IO_COUNTERS]
Definition: linux-io.c:58
Here is the call graph for this function:

◆ _io_reset()

static int _io_reset ( hwd_context_t ctx,
hwd_control_state_t ctl 
)
static

Triggered by PAPI_reset() but only if the EventSet is currently running

Definition at line 399 of file linux-io.c.

400{
401 (void) ctx; // unused
402 (void) ctl;
403 SUBDBG( "io_reset...");
404 return PAPI_OK;
405}

◆ _io_set_domain()

static int _io_set_domain ( hwd_control_state_t cntrl,
int  domain 
)
static

This function has to set the bits needed to count different domains In particular: PAPI_DOM_USER, PAPI_DOM_KERNEL PAPI_DOM_OTHER By default return PAPI_EINVAL if none of those are specified and PAPI_OK with success PAPI_DOM_USER is only user context is counted PAPI_DOM_KERNEL is only the Kernel/OS context is counted PAPI_DOM_OTHER is Exception/transient mode (like user TLB misses) PAPI_DOM_ALL is all of the domains

Definition at line 450 of file linux-io.c.

451{
452 (void) cntrl;
453
454 int found = 0;
455 SUBDBG( "io_set_domain..." );
456
457 if ( PAPI_DOM_USER & domain ) {
458 SUBDBG( " PAPI_DOM_USER " );
459 found = 1;
460 }
461 if ( PAPI_DOM_KERNEL & domain ) {
462 SUBDBG( " PAPI_DOM_KERNEL " );
463 found = 1;
464 }
465 if ( PAPI_DOM_OTHER & domain ) {
466 SUBDBG( " PAPI_DOM_OTHER " );
467 found = 1;
468 }
469 if ( PAPI_DOM_ALL & domain ) {
470 SUBDBG( " PAPI_DOM_ALL " );
471 found = 1;
472 }
473 if ( !found )
474 return ( PAPI_EINVAL );
475
476 return PAPI_OK;
477}
#define PAPI_DOM_USER
Definition: f90papi.h:174
#define PAPI_DOM_OTHER
Definition: f90papi.h:21
#define PAPI_DOM_KERNEL
Definition: f90papi.h:254
#define PAPI_DOM_ALL
Definition: f90papi.h:261

◆ _io_shutdown_component()

static int _io_shutdown_component ( void  )
static

Definition at line 409 of file linux-io.c.

410{
411 SUBDBG( "io_shutdown_component..." );
412 return PAPI_OK;
413}

◆ _io_shutdown_thread()

static int _io_shutdown_thread ( hwd_context_t ctx)
static

Definition at line 417 of file linux-io.c.

418{
419 (void) ctx;
420 SUBDBG( "io_shutdown_thread... %p", ctx );
421 return PAPI_OK;
422}

◆ _io_start()

static int _io_start ( hwd_context_t ctx,
hwd_control_state_t ctl 
)
static

Triggered by PAPI_start()

Definition at line 332 of file linux-io.c.

333{
334 (void) ctl;
335 (void) ctx;
336 SUBDBG( "io_start %p %p...", ctx, ctl );
337 return PAPI_OK;
338}

◆ _io_stop()

static int _io_stop ( hwd_context_t ctx,
hwd_control_state_t ctl 
)
static

Triggered by PAPI_stop()

Definition at line 343 of file linux-io.c.

344{
345 (void) ctx;
346 (void) ctl;
347 SUBDBG( "io_stop %p %p...", ctx, ctl );
348 // Don't do anything, can't stop the counters.
349
350 return PAPI_OK;
351}

◆ _io_update_control_state()

static int _io_update_control_state ( hwd_control_state_t ctl,
NativeInfo_t native,
int  count,
hwd_context_t ctx 
)
static

Definition at line 303 of file linux-io.c.

307{
308 (void) ctx;
310
311 int i, index;
312
313 myCtl->EventSetCount = count;
314
315 /* if no events, return */
316 if (count==0) return PAPI_OK;
317
318 for( i = 0; i < count; i++ ) {
319 index = native[i].ni_event;
320 myCtl->EventSetIdx[i] = index;
321
322 /* We have no constraints on event position, so any event */
323 /* can be in any slot. */
324 native[i].ni_position = i;
325 }
326
327 return PAPI_OK;
328} // END ROUTINE.
static long count
static int native

◆ _io_write()

static int _io_write ( hwd_context_t ctx,
hwd_control_state_t ctl,
long long events 
)
static

Triggered by PAPI_write(), but only if the counters are running

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

385{
386 (void) ctx; // unused
387 (void) ctl; // unused
388 (void) events; // unused
389
390 return PAPI_OK;
391}

◆ io_count_events()

static int io_count_events ( _io_context_t myCtx)
static

Definition at line 82 of file linux-io.c.

83{
84 myCtx->EventCount = 0;
85 myCtx->pFile = fopen (IO_FILENAME,"r");
86 if (myCtx->pFile == NULL) {
88 "Failed to open target file '%s'.", IO_FILENAME);
91 return PAPI_ENOSUPP;
92 }
93
94 // Just count the lines, basic vetting for ability to parse.
95 while (1) {
96 char *res;
97 // fgets guarantees z-terminator, reads at most FILE_LINE_SIZE-1 bytes.
98 res = fgets(myCtx->line, FILE_LINE_SIZE, myCtx->pFile);
99 if (res == NULL) break;
100 // If the read filled the whole buffer, line is too long.
101 if (strlen(myCtx->line) == (FILE_LINE_SIZE-1)) {
102 fclose(myCtx->pFile);
104 "File '%s' line %i too long.", IO_FILENAME, myCtx->EventCount+1);
107 return PAPI_ENOSUPP;
108 }
109
110 char dummy[FILE_LINE_SIZE] = {0};
111 long long tmplong = 0LL;
112 int nf = sscanf( myCtx->line, "%s %lld\n", dummy, &tmplong);
113 if (nf != 2 || strlen(dummy)<2 || dummy[strlen(dummy)-1] != ':') {
114 fclose(myCtx->pFile);
116 "File '%s' line %i bad format.", IO_FILENAME, myCtx->EventCount+1);
119 return PAPI_ENOSUPP;
120 }
121
122 myCtx->EventCount++;
123 } // END READING.
124
125 // NOTE: We intentionally leave file open; up to caller to close
126 // or rewind and continue.
127 return PAPI_OK;
128} // END ROUTINE.
void dummy(void *array)
Definition: do_loops.c:306
Here is the call graph for this function:
Here is the caller graph for this function:

◆ io_hardware_read()

static int io_hardware_read ( _io_context_t ctx,
_io_control_state_t ctl 
)
static

Definition at line 135 of file linux-io.c.

136{
137 ctx->pFile = fopen(IO_FILENAME, "r");
138 if (ctx->pFile == NULL) return(PAPI_ENOCNTR); /* No counters */
139
140 /* Read each line */
141 int idx;
142 for (idx=0; idx<gEventCount; idx++) {
143 if (fgets(ctx->line, FILE_LINE_SIZE-1, ctx->pFile)) {
144 char dummy[FILE_LINE_SIZE] = {0};
145 long long tmplong = 0LL;
146 int nf = sscanf(ctx->line, "%s %lld\n", dummy, &tmplong);
147 if (nf != 2 || strlen(dummy)<2 || dummy[strlen(dummy)-1] != ':') {
148 return PAPI_ENOCNTR;
149 }
150
151 ctl->EventSetVal[idx] = tmplong;
152 } else { /* Did not read ALL counters. */
153 return(PAPI_EMISC);
154 }
155 }
156
157 fclose(ctx->pFile);
158 return(PAPI_OK);
159} // END FUNCTION.
#define PAPI_ENOCNTR
Definition: f90papi.h:215
#define PAPI_EMISC
Definition: f90papi.h:122
Here is the call graph for this function:
Here is the caller graph for this function:

Variable Documentation

◆ _io_vector

papi_vector_t _io_vector

Vector that points to entry points for our component

Definition at line 28 of file linux-io.c.

◆ gEventCount

int gEventCount
static

Definition at line 77 of file linux-io.c.

◆ io_native_table

IO_native_event_entry_t* io_native_table
static

Definition at line 78 of file linux-io.c.