PAPI 7.1.0.0
Loading...
Searching...
No Matches
linux-stealtime.c
Go to the documentation of this file.
1
8#include <string.h>
9#include <sys/types.h>
10#include <sys/stat.h>
11#include <fcntl.h>
12#include <dirent.h>
13#include <stdint.h>
14#include <ctype.h>
15
16#include "papi.h"
17#include "papi_internal.h"
18#include "papi_vector.h"
19#include "papi_memory.h"
20
21struct counter_info
22{
23 char *name;
24 char *description;
25 char *units;
26 unsigned long long value;
27};
28
29typedef struct counter_info STEALTIME_register_t;
30typedef struct counter_info STEALTIME_native_event_entry_t;
31typedef struct counter_info STEALTIME_reg_alloc_t;
32
33
35{
36 long long *values;
39};
40
41
43{
44 long long *start_count;
45 long long *current_count;
46 long long *value;
47};
48
49
50static int num_events = 0;
51
52static struct counter_info *event_info=NULL;
53
54/* Advance declaration of buffer */
56
57/******************************************************************************
58 ******** BEGIN FUNCTIONS USED INTERNALLY SPECIFIC TO THIS COMPONENT ********
59 *****************************************************************************/
60
61struct statinfo {
62 long long user;
63 long long nice;
64 long long system;
65 long long idle;
66 long long iowait;
67 long long irq;
68 long long softirq;
69 long long steal;
70 long long guest;
71};
72
73static int
74read_stealtime( struct STEALTIME_context *context, int starting) {
75
76 FILE *fff;
77 char buffer[BUFSIZ],*result;
78 int i,count;
79 struct statinfo our_stat;
80
81 int hz=sysconf(_SC_CLK_TCK);
82
83
84 fff=fopen("/proc/stat","r");
85 if (fff==NULL) {
86 return PAPI_ESYS;
87 }
88
89 for(i=0;i<num_events;i++) {
90 result=fgets(buffer,BUFSIZ,fff);
91 if (result==NULL) break;
92
93 count=sscanf(buffer,"%*s %lld %lld %lld %lld %lld %lld %lld %lld %lld",
94 &our_stat.user,
95 &our_stat.nice,
96 &our_stat.system,
97 &our_stat.idle,
98 &our_stat.iowait,
99 &our_stat.irq,
100 &our_stat.softirq,
101 &our_stat.steal,
102 &our_stat.guest);
103 if (count<=7) {
104 fclose(fff);
105 return PAPI_ESYS;
106 }
107
108 if (starting) {
109 context->start_count[i]=our_stat.steal;
110 }
111 context->current_count[i]=our_stat.steal;
112
113 /* convert to us */
114 context->value[i]=(context->current_count[i]-context->start_count[i])*
115 (1000000/hz);
116 }
117
118
119 fclose(fff);
120
121 return PAPI_OK;
122
123}
124
125
126
127/*****************************************************************************
128 ******************* BEGIN PAPI's COMPONENT REQUIRED FUNCTIONS *************
129 *****************************************************************************/
130
131/*
132 * Component setup and shutdown
133 */
134static int _stealtime_shutdown_component( void ); // prototype for later routine.
135
136static int
138{
139 int retval = PAPI_OK;
140 (void)cidx;
141
142 FILE *fff;
143 char buffer[BUFSIZ],*result,string[BUFSIZ];
144 int i;
145
146 /* Make sure /proc/stat exists */
147 fff=fopen("/proc/stat","r");
148 if (fff==NULL) {
150 "Cannot open /proc/stat",PAPI_MAX_STR_LEN);
153 goto fn_fail;
154 }
155
156 num_events=0;
157 while(1) {
158 result=fgets(buffer,BUFSIZ,fff);
159 if (result==NULL) break;
160
161 /* /proc/stat line with cpu stats always starts with "cpu" */
162
163 if (!strncmp(buffer,"cpu",3)) {
164 num_events++;
165 }
166 else {
167 break;
168 }
169
170 }
171
172 fclose(fff);
173
174 if (num_events<1) {
176 "Cannot find enough CPU lines in /proc/stat",
180 goto fn_fail;
181 }
182
183 event_info=calloc(num_events,sizeof(struct counter_info));
184 if (event_info==NULL) {
187 goto fn_fail;
188 }
189
190
191 sysconf(_SC_CLK_TCK);
192 event_info[0].name=strdup("TOTAL");
193 event_info[0].description=strdup("Total amount of steal time");
194 event_info[0].units=strdup("us");
195
196 for(i=1;i<num_events;i++) {
197 sprintf(string,"CPU%d",i);
198 event_info[i].name=strdup(string);
199 sprintf(string,"Steal time for CPU %d",i);
200 event_info[i].description=strdup(string);
201 event_info[i].units=strdup("us");
202 }
203
204 // printf("Found %d CPUs\n",num_events-1);
205
209
210 fn_exit:
211 _papi_hwd[cidx]->cmp_info.disabled = retval;
212 return retval;
213 fn_fail:
214 goto fn_exit;
215}
216
217
218
219
220
221/*
222 * This is called whenever a thread is initialized
223 */
224static int
226{
227 struct STEALTIME_context *context=(struct STEALTIME_context *)ctx;
228
229 context->start_count=calloc(num_events,sizeof(long long));
230 if (context->start_count==NULL) return PAPI_ENOMEM;
231
232 context->current_count=calloc(num_events,sizeof(long long));
233 if (context->current_count==NULL) return PAPI_ENOMEM;
234
235 context->value=calloc(num_events,sizeof(long long));
236 if (context->value==NULL) return PAPI_ENOMEM;
237
238 return PAPI_OK;
239}
240
241
242/*
243 *
244 */
245static int
247{
248 int i;
250 if (event_info!=NULL) {
251 for (i=0; i<num_events; i++){
252 free(event_info[i].name);
253 free(event_info[i].description);
254 free(event_info[i].units);
255 }
256 free(event_info);
257 }
258
259 return PAPI_OK;
260}
261
262/*
263 *
264 */
265static int
267{
268
269 struct STEALTIME_context *context=(struct STEALTIME_context *)ctx;
270
271 if (context->start_count!=NULL) free(context->start_count);
272 if (context->current_count!=NULL) free(context->current_count);
273 if (context->value!=NULL) free(context->value);
274
275 return PAPI_OK;
276}
277
278
279
280/*
281 * Control of counters (Reading/Writing/Starting/Stopping/Setup) functions
282 */
283static int
285{
286
287 struct STEALTIME_control_state *control =
288 (struct STEALTIME_control_state *)ctl;
289
290 control->values=NULL;
291 control->which_counter=NULL;
292 control->num_events=0;
293
294 return PAPI_OK;
295}
296
297
298/*
299 *
300 */
301static int
304 int count,
305 hwd_context_t *ctx )
306{
307
308 struct STEALTIME_control_state *control;
309
310 ( void ) ctx;
311 int i, index;
312
313 control= (struct STEALTIME_control_state *)ctl;
314
315 if (count!=control->num_events) {
316 // printf("Resizing %d to %d\n",control->num_events,count);
317 control->which_counter=realloc(control->which_counter,
318 count*sizeof(int));
319 control->values=realloc(control->values,
320 count*sizeof(long long));
321
322 }
323
324
325 for ( i = 0; i < count; i++ ) {
326 index = native[i].ni_event;
327 control->which_counter[i]=index;
328 native[i].ni_position = i;
329 }
330
331 control->num_events=count;
332
333 return PAPI_OK;
334}
335
336
337/*
338 *
339 */
340static int
342{
343
344 (void)ctl;
345
346 // struct STEALTIME_control_state *control;
347 struct STEALTIME_context *context;
348
349 //control = (struct STEALTIME_control_state *)ctl;
350 context = (struct STEALTIME_context *)ctx;
351
352 read_stealtime( context, 1 );
353
354 /* no need to update control, as we assume only one EventSet */
355 /* is active at once, so starting things at the context level */
356 /* is fine, since stealtime is system-wide */
357
358 return PAPI_OK;
359}
360
361
362/*
363 *
364 */
365static int
367{
368
369 (void) ctl;
370
371 // struct STEALTIME_control_state *control;
372 struct STEALTIME_context *context;
373
374 //control = (struct STEALTIME_control_state *)ctl;
375 context = (struct STEALTIME_context *)ctx;
376
377 read_stealtime( context, 0 );
378
379 return PAPI_OK;
380
381}
382
383
384
385/*
386 *
387 */
388static int
390 long long **events, int flags )
391{
392 ( void ) flags;
393
394 struct STEALTIME_control_state *control;
395 struct STEALTIME_context *context;
396
397 int i;
398
399 control = (struct STEALTIME_control_state *)ctl;
400 context = (struct STEALTIME_context *)ctx;
401
402 read_stealtime( context, 0 );
403
404 for(i=0;i<control->num_events;i++) {
405 control->values[i]=
406 context->value[control->which_counter[i]];
407 }
408
409 *events = control->values;
410
411 return PAPI_OK;
412
413}
414
415
416
417
418/*
419 *
420 */
421static int
423{
424
425 /* re-initializes counter_start values to current */
426
427 _stealtime_start(ctx,ctrl);
428
429 return PAPI_OK;
430}
431
432
433/*
434 * Unused stealtime write function
435 */
436/* static int */
437/* _stealtime_write( hwd_context_t * ctx, hwd_control_state_t * ctrl, long long *from ) */
438/* { */
439/* ( void ) ctx; */
440/* ( void ) ctrl; */
441/* ( void ) from; */
442
443/* return PAPI_OK; */
444/* } */
445
446
447/*
448 * Functions for setting up various options
449 */
450
451/* This function sets various options in the component
452 * The valid codes being passed in are PAPI_SET_DEFDOM,
453 * PAPI_SET_DOMAIN, PAPI_SETDEFGRN, PAPI_SET_GRANUL * and PAPI_SET_INHERIT
454 */
455static int
457{
458 ( void ) ctx;
459 ( void ) code;
460 ( void ) option;
461
462 return PAPI_OK;
463}
464
465
466/*
467 * This function has to set the bits needed to count different domains
468 * In particular: PAPI_DOM_USER, PAPI_DOM_KERNEL PAPI_DOM_OTHER
469 * By default return PAPI_EINVAL if none of those are specified
470 * and PAPI_OK with success
471 * PAPI_DOM_USER is only user context is counted
472 * PAPI_DOM_KERNEL is only the Kernel/OS context is counted
473 * PAPI_DOM_OTHER is Exception/transient mode (like user TLB misses)
474 * PAPI_DOM_ALL is all of the domains
475 */
476static int
478{
479 ( void ) cntrl;
480 int found = 0;
481 if ( PAPI_DOM_USER & domain ) {
482 found = 1;
483 }
484 if ( PAPI_DOM_KERNEL & domain ) {
485 found = 1;
486 }
487 if ( PAPI_DOM_OTHER & domain ) {
488 found = 1;
489 }
490 if ( !found )
491 return PAPI_EINVAL;
492
493 return PAPI_OK;
494}
495
496
497/*
498 *
499 */
500static int
501_stealtime_ntv_code_to_name( unsigned int EventCode, char *name, int len )
502{
503
504 int event=EventCode;
505
506 if (event >=0 && event < num_events) {
507 strncpy( name, event_info[event].name, len );
508 return PAPI_OK;
509 }
510
511 return PAPI_ENOEVNT;
512}
513
514
515/*
516 *
517 */
518static int
519_stealtime_ntv_code_to_descr( unsigned int EventCode, char *name, int len )
520{
521
522 int event=EventCode;
523
524 if (event >=0 && event < num_events) {
525 strncpy( name, event_info[event].description, len );
526 return PAPI_OK;
527 }
528
529 return PAPI_ENOEVNT;
530}
531
532
533
534static int
535_stealtime_ntv_code_to_info(unsigned int EventCode, PAPI_event_info_t *info)
536{
537
538 int index = EventCode;
539
540 if ( ( index < 0) || (index >= num_events )) return PAPI_ENOEVNT;
541
542 strncpy( info->symbol, event_info[index].name,sizeof(info->symbol));
543 info->symbol[sizeof(info->symbol)-1] = '\0';
544
545 strncpy( info->long_descr, event_info[index].description,sizeof(info->symbol));
546 info->long_descr[sizeof(info->symbol)-1] = '\0';
547
548 strncpy( info->units, event_info[index].units,sizeof(info->units));
549 info->units[sizeof(info->units)-1] = '\0';
550
551 return PAPI_OK;
552
553}
554
555
556
557
558/*
559 *
560 */
561static int
562_stealtime_ntv_enum_events( unsigned int *EventCode, int modifier )
563{
564
565 if ( modifier == PAPI_ENUM_FIRST ) {
566 if (num_events==0) return PAPI_ENOEVNT;
567 *EventCode = 0;
568 return PAPI_OK;
569 }
570
571 if ( modifier == PAPI_ENUM_EVENTS ) {
572 int index;
573
574 index = *EventCode;
575
576 if ( (index+1) < num_events ) {
577 *EventCode = *EventCode + 1;
578 return PAPI_OK;
579 } else {
580 return PAPI_ENOEVNT;
581 }
582 }
583
584 return PAPI_EINVAL;
585}
586
587
588/*
589 *
590 */
592 .cmp_info = {
593 /* component information (unspecified values initialized to 0) */
594 .name = "stealtime",
595 .short_name="stealtime",
596 .version = "5.0",
597 .description = "Stealtime filesystem statistics",
598 .default_domain = PAPI_DOM_USER,
599 .default_granularity = PAPI_GRN_THR,
600 .available_granularities = PAPI_GRN_THR,
601 .hardware_intr_sig = PAPI_INT_SIGNAL,
602
603 /* component specific cmp_info initializations */
604 .fast_real_timer = 0,
605 .fast_virtual_timer = 0,
606 .attach = 0,
607 .attach_must_ptrace = 0,
608 .available_domains = PAPI_DOM_USER | PAPI_DOM_KERNEL,
609 },
610
611 /* sizes of framework-opaque component-private structures */
612 .size = {
613 .context = sizeof ( struct STEALTIME_context ),
614 .control_state = sizeof ( struct STEALTIME_control_state ),
615 .reg_value = sizeof ( STEALTIME_register_t ),
616 .reg_alloc = sizeof ( STEALTIME_reg_alloc_t ),
617 },
618
619 /* function pointers in this component */
620 .init_thread = _stealtime_init_thread,
621 .init_component = _stealtime_init_component,
622 .init_control_state = _stealtime_init_control_state,
623 .start = _stealtime_start,
624 .stop = _stealtime_stop,
625 .read = _stealtime_read,
626 .shutdown_thread = _stealtime_shutdown_thread,
627 .shutdown_component = _stealtime_shutdown_component,
628 .ctl = _stealtime_ctl,
629 .update_control_state = _stealtime_update_control_state,
630 .set_domain = _stealtime_set_domain,
631 .reset = _stealtime_reset,
632
633 .ntv_enum_events = _stealtime_ntv_enum_events,
634 .ntv_code_to_name = _stealtime_ntv_code_to_name,
635 .ntv_code_to_descr = _stealtime_ntv_code_to_descr,
636 .ntv_code_to_info = _stealtime_ntv_code_to_info,
637};
638
639
640
641
volatile int result
int i
static long count
struct papi_vectors * _papi_hwd[]
#define PAPI_DOM_USER
Definition: f90papi.h:174
#define PAPI_ENUM_EVENTS
Definition: f90papi.h:224
#define PAPI_DOM_OTHER
Definition: f90papi.h:21
#define PAPI_OK
Definition: f90papi.h:73
#define PAPI_ENUM_FIRST
Definition: f90papi.h:85
#define PAPI_DOM_KERNEL
Definition: f90papi.h:254
#define PAPI_ENOEVNT
Definition: f90papi.h:139
#define PAPI_EINVAL
Definition: f90papi.h:115
#define PAPI_MAX_STR_LEN
Definition: f90papi.h:77
#define PAPI_ESYS
Definition: f90papi.h:136
#define PAPI_ENOMEM
Definition: f90papi.h:16
#define PAPI_GRN_THR
Definition: f90papi.h:265
FILE * fff[MAX_EVENTS]
char events[MAX_EVENTS][BUFSIZ]
static int _stealtime_ntv_code_to_descr(unsigned int EventCode, char *name, int len)
static int _stealtime_set_domain(hwd_control_state_t *cntrl, int domain)
static int read_stealtime(struct STEALTIME_context *context, int starting)
static int _stealtime_shutdown_component(void)
static int num_events
papi_vector_t _stealtime_vector
static int _stealtime_ctl(hwd_context_t *ctx, int code, _papi_int_option_t *option)
static int _stealtime_init_control_state(hwd_control_state_t *ctl)
static struct counter_info * event_info
static int _stealtime_ntv_enum_events(unsigned int *EventCode, int modifier)
static int _stealtime_stop(hwd_context_t *ctx, hwd_control_state_t *ctl)
static int _stealtime_init_thread(hwd_context_t *ctx)
static int _stealtime_start(hwd_context_t *ctx, hwd_control_state_t *ctl)
static int _stealtime_read(hwd_context_t *ctx, hwd_control_state_t *ctl, long long **events, int flags)
static int _stealtime_update_control_state(hwd_control_state_t *ctl, NativeInfo_t *native, int count, hwd_context_t *ctx)
static int _stealtime_reset(hwd_context_t *ctx, hwd_control_state_t *ctrl)
static int _stealtime_init_component(int cidx)
static int _stealtime_ntv_code_to_info(unsigned int EventCode, PAPI_event_info_t *info)
static int _stealtime_shutdown_thread(hwd_context_t *ctx)
static int _stealtime_ntv_code_to_name(unsigned int EventCode, char *name, int len)
Return codes and api definitions.
int fclose(FILE *__stream)
#define PAPI_INT_SIGNAL
Definition: papi_internal.h:52
static int native
static int cidx
char units[MAX_EVENTS][BUFSIZ]
Definition: powercap_plot.c:15
const char * name
Definition: rocs.c:225
char name[PAPI_MAX_STR_LEN]
Definition: papi.h:627
char disabled_reason[PAPI_HUGE_STR_LEN]
Definition: papi.h:634
char units[PAPI_MIN_STR_LEN]
Definition: papi.h:969
char symbol[PAPI_HUGE_STR_LEN]
Definition: papi.h:960
char long_descr[PAPI_HUGE_STR_LEN]
Definition: papi.h:963
long long * start_count
long long * current_count
char * description
Definition: linux-lustre.c:34
unsigned long long value
Definition: linux-lustre.c:36
PAPI_component_info_t cmp_info
Definition: papi_vector.h:20
long long softirq
long long user
long long steal
long long guest
long long system
long long irq
long long nice
long long iowait
long long idle
int retval
Definition: zero_fork.c:53