PAPI  5.6.0.0
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
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 
21 struct counter_info
22 {
23  char *name;
24  char *description;
25  char *units;
26  unsigned long long value;
27 };
28 
29 typedef struct counter_info STEALTIME_register_t;
30 typedef struct counter_info STEALTIME_native_event_entry_t;
31 typedef 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 
50 static int num_events = 0;
51 
52 static 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 
61 struct 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 
73 static int
74 read_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  */
134 
135 static int
137 {
138 
139  (void)cidx;
140 
141  FILE *fff;
142  char buffer[BUFSIZ],*result,string[BUFSIZ];
143  int i;
144 
145  /* Make sure /proc/stat exists */
146  fff=fopen("/proc/stat","r");
147  if (fff==NULL) {
148  strncpy(_stealtime_vector.cmp_info.disabled_reason,
149  "Cannot open /proc/stat",PAPI_MAX_STR_LEN);
150  return PAPI_ESYS;
151  }
152 
153  num_events=0;
154  while(1) {
155  result=fgets(buffer,BUFSIZ,fff);
156  if (result==NULL) break;
157 
158  /* /proc/stat line with cpu stats always starts with "cpu" */
159 
160  if (!strncmp(buffer,"cpu",3)) {
161  num_events++;
162  }
163  else {
164  break;
165  }
166 
167  }
168 
169  fclose(fff);
170 
171  if (num_events<1) {
172  strncpy(_stealtime_vector.cmp_info.disabled_reason,
173  "Cannot find enough CPU lines in /proc/stat",
175  return PAPI_ESYS;
176  }
177 
178  event_info=calloc(num_events,sizeof(struct counter_info));
179  if (event_info==NULL) {
180  return PAPI_ENOMEM;
181  }
182 
183 
184  sysconf(_SC_CLK_TCK);
185  event_info[0].name=strdup("TOTAL");
186  event_info[0].description=strdup("Total amount of steal time");
187  event_info[0].units=strdup("us");
188 
189  for(i=1;i<num_events;i++) {
190  sprintf(string,"CPU%d",i);
191  event_info[i].name=strdup(string);
192  sprintf(string,"Steal time for CPU %d",i);
193  event_info[i].description=strdup(string);
194  event_info[i].units=strdup("us");
195  }
196 
197  // printf("Found %d CPUs\n",num_events-1);
198 
199  _stealtime_vector.cmp_info.num_native_events=num_events;
200  _stealtime_vector.cmp_info.num_cntrs=num_events;
201  _stealtime_vector.cmp_info.num_mpx_cntrs=num_events;
202 
203  return PAPI_OK;
204 }
205 
206 
207 
208 
209 
210 /*
211  * This is called whenever a thread is initialized
212  */
213 static int
215 {
216  struct STEALTIME_context *context=(struct STEALTIME_context *)ctx;
217 
218  context->start_count=calloc(num_events,sizeof(long long));
219  if (context->start_count==NULL) return PAPI_ENOMEM;
220 
221  context->current_count=calloc(num_events,sizeof(long long));
222  if (context->current_count==NULL) return PAPI_ENOMEM;
223 
224  context->value=calloc(num_events,sizeof(long long));
225  if (context->value==NULL) return PAPI_ENOMEM;
226 
227  return PAPI_OK;
228 }
229 
230 
231 /*
232  *
233  */
234 static int
236 {
237  int i;
238  int num_events = _stealtime_vector.cmp_info.num_native_events;
239  if (event_info!=NULL) {
240  for (i=0; i<num_events; i++){
241  free(event_info[i].name);
242  free(event_info[i].description);
243  free(event_info[i].units);
244  }
245  free(event_info);
246  }
247 
248  return PAPI_OK;
249 }
250 
251 /*
252  *
253  */
254 static int
256 {
257 
258  struct STEALTIME_context *context=(struct STEALTIME_context *)ctx;
259 
260  if (context->start_count!=NULL) free(context->start_count);
261  if (context->current_count!=NULL) free(context->current_count);
262  if (context->value!=NULL) free(context->value);
263 
264  return PAPI_OK;
265 }
266 
267 
268 
269 /*
270  * Control of counters (Reading/Writing/Starting/Stopping/Setup) functions
271  */
272 static int
274 {
275 
276  struct STEALTIME_control_state *control =
277  (struct STEALTIME_control_state *)ctl;
278 
279  control->values=NULL;
280  control->which_counter=NULL;
281  control->num_events=0;
282 
283  return PAPI_OK;
284 }
285 
286 
287 /*
288  *
289  */
290 static int
293  int count,
294  hwd_context_t *ctx )
295 {
296 
297  struct STEALTIME_control_state *control;
298 
299  ( void ) ctx;
300  int i, index;
301 
302  control= (struct STEALTIME_control_state *)ctl;
303 
304  if (count!=control->num_events) {
305  // printf("Resizing %d to %d\n",control->num_events,count);
306  control->which_counter=realloc(control->which_counter,
307  count*sizeof(int));
308  control->values=realloc(control->values,
309  count*sizeof(long long));
310 
311  }
312 
313 
314  for ( i = 0; i < count; i++ ) {
315  index = native[i].ni_event;
316  control->which_counter[i]=index;
317  native[i].ni_position = i;
318  }
319 
320  control->num_events=count;
321 
322  return PAPI_OK;
323 }
324 
325 
326 /*
327  *
328  */
329 static int
331 {
332 
333  (void)ctl;
334 
335  // struct STEALTIME_control_state *control;
336  struct STEALTIME_context *context;
337 
338  //control = (struct STEALTIME_control_state *)ctl;
339  context = (struct STEALTIME_context *)ctx;
340 
341  read_stealtime( context, 1 );
342 
343  /* no need to update control, as we assume only one EventSet */
344  /* is active at once, so starting things at the context level */
345  /* is fine, since stealtime is system-wide */
346 
347  return PAPI_OK;
348 }
349 
350 
351 /*
352  *
353  */
354 static int
356 {
357 
358  (void) ctl;
359 
360  // struct STEALTIME_control_state *control;
361  struct STEALTIME_context *context;
362 
363  //control = (struct STEALTIME_control_state *)ctl;
364  context = (struct STEALTIME_context *)ctx;
365 
366  read_stealtime( context, 0 );
367 
368  return PAPI_OK;
369 
370 }
371 
372 
373 
374 /*
375  *
376  */
377 static int
379  long long **events, int flags )
380 {
381  ( void ) flags;
382 
383  struct STEALTIME_control_state *control;
384  struct STEALTIME_context *context;
385 
386  int i;
387 
388  control = (struct STEALTIME_control_state *)ctl;
389  context = (struct STEALTIME_context *)ctx;
390 
391  read_stealtime( context, 0 );
392 
393  for(i=0;i<control->num_events;i++) {
394  control->values[i]=
395  context->value[control->which_counter[i]];
396  }
397 
398  *events = control->values;
399 
400  return PAPI_OK;
401 
402 }
403 
404 
405 
406 
407 /*
408  *
409  */
410 static int
412 {
413 
414  /* re-initializes counter_start values to current */
415 
416  _stealtime_start(ctx,ctrl);
417 
418  return PAPI_OK;
419 }
420 
421 
422 /*
423  * Unused stealtime write function
424  */
425 /* static int */
426 /* _stealtime_write( hwd_context_t * ctx, hwd_control_state_t * ctrl, long long *from ) */
427 /* { */
428 /* ( void ) ctx; */
429 /* ( void ) ctrl; */
430 /* ( void ) from; */
431 
432 /* return PAPI_OK; */
433 /* } */
434 
435 
436 /*
437  * Functions for setting up various options
438  */
439 
440 /* This function sets various options in the component
441  * The valid codes being passed in are PAPI_SET_DEFDOM,
442  * PAPI_SET_DOMAIN, PAPI_SETDEFGRN, PAPI_SET_GRANUL * and PAPI_SET_INHERIT
443  */
444 static int
445 _stealtime_ctl( hwd_context_t * ctx, int code, _papi_int_option_t * option )
446 {
447  ( void ) ctx;
448  ( void ) code;
449  ( void ) option;
450 
451  return PAPI_OK;
452 }
453 
454 
455 /*
456  * This function has to set the bits needed to count different domains
457  * In particular: PAPI_DOM_USER, PAPI_DOM_KERNEL PAPI_DOM_OTHER
458  * By default return PAPI_EINVAL if none of those are specified
459  * and PAPI_OK with success
460  * PAPI_DOM_USER is only user context is counted
461  * PAPI_DOM_KERNEL is only the Kernel/OS context is counted
462  * PAPI_DOM_OTHER is Exception/transient mode (like user TLB misses)
463  * PAPI_DOM_ALL is all of the domains
464  */
465 static int
467 {
468  ( void ) cntrl;
469  int found = 0;
470  if ( PAPI_DOM_USER & domain ) {
471  found = 1;
472  }
473  if ( PAPI_DOM_KERNEL & domain ) {
474  found = 1;
475  }
476  if ( PAPI_DOM_OTHER & domain ) {
477  found = 1;
478  }
479  if ( !found )
480  return PAPI_EINVAL;
481 
482  return PAPI_OK;
483 }
484 
485 
486 /*
487  *
488  */
489 static int
490 _stealtime_ntv_code_to_name( unsigned int EventCode, char *name, int len )
491 {
492 
493  int event=EventCode;
494 
495  if (event >=0 && event < num_events) {
496  strncpy( name, event_info[event].name, len );
497  return PAPI_OK;
498  }
499 
500  return PAPI_ENOEVNT;
501 }
502 
503 
504 /*
505  *
506  */
507 static int
508 _stealtime_ntv_code_to_descr( unsigned int EventCode, char *name, int len )
509 {
510 
511  int event=EventCode;
512 
513  if (event >=0 && event < num_events) {
514  strncpy( name, event_info[event].description, len );
515  return PAPI_OK;
516  }
517 
518  return PAPI_ENOEVNT;
519 }
520 
521 
522 
523 static int
524 _stealtime_ntv_code_to_info(unsigned int EventCode, PAPI_event_info_t *info)
525 {
526 
527  int index = EventCode;
528 
529  if ( ( index < 0) || (index >= num_events )) return PAPI_ENOEVNT;
530 
531  strncpy( info->symbol, event_info[index].name,sizeof(info->symbol));
532  info->symbol[sizeof(info->symbol)-1] = '\0';
533 
534  strncpy( info->long_descr, event_info[index].description,sizeof(info->symbol));
535  info->long_descr[sizeof(info->symbol)-1] = '\0';
536 
537  strncpy( info->units, event_info[index].units,sizeof(info->units));
538  info->units[sizeof(info->units)-1] = '\0';
539 
540  return PAPI_OK;
541 
542 }
543 
544 
545 
546 
547 /*
548  *
549  */
550 static int
551 _stealtime_ntv_enum_events( unsigned int *EventCode, int modifier )
552 {
553 
554  if ( modifier == PAPI_ENUM_FIRST ) {
555  if (num_events==0) return PAPI_ENOEVNT;
556  *EventCode = 0;
557  return PAPI_OK;
558  }
559 
560  if ( modifier == PAPI_ENUM_EVENTS ) {
561  int index;
562 
563  index = *EventCode;
564 
565  if ( (index+1) < num_events ) {
566  *EventCode = *EventCode + 1;
567  return PAPI_OK;
568  } else {
569  return PAPI_ENOEVNT;
570  }
571  }
572 
573  return PAPI_EINVAL;
574 }
575 
576 
577 /*
578  *
579  */
580 papi_vector_t _stealtime_vector = {
581  .cmp_info = {
582  /* component information (unspecified values initialized to 0) */
583  .name = "stealtime",
584  .short_name="stealtime",
585  .version = "5.0",
586  .description = "Stealtime filesystem statistics",
587  .default_domain = PAPI_DOM_USER,
588  .default_granularity = PAPI_GRN_THR,
589  .available_granularities = PAPI_GRN_THR,
590  .hardware_intr_sig = PAPI_INT_SIGNAL,
591 
592  /* component specific cmp_info initializations */
593  .fast_real_timer = 0,
594  .fast_virtual_timer = 0,
595  .attach = 0,
596  .attach_must_ptrace = 0,
597  .available_domains = PAPI_DOM_USER | PAPI_DOM_KERNEL,
598  },
599 
600  /* sizes of framework-opaque component-private structures */
601  .size = {
602  .context = sizeof ( struct STEALTIME_context ),
603  .control_state = sizeof ( struct STEALTIME_control_state ),
604  .reg_value = sizeof ( STEALTIME_register_t ),
605  .reg_alloc = sizeof ( STEALTIME_reg_alloc_t ),
606  },
607 
608  /* function pointers in this component */
609  .init_thread = _stealtime_init_thread,
610  .init_component = _stealtime_init_component,
611  .init_control_state = _stealtime_init_control_state,
612  .start = _stealtime_start,
613  .stop = _stealtime_stop,
614  .read = _stealtime_read,
615  .shutdown_thread = _stealtime_shutdown_thread,
616  .shutdown_component = _stealtime_shutdown_component,
617  .ctl = _stealtime_ctl,
618  .update_control_state = _stealtime_update_control_state,
619  .set_domain = _stealtime_set_domain,
620  .reset = _stealtime_reset,
621 
622  .ntv_enum_events = _stealtime_ntv_enum_events,
623  .ntv_code_to_name = _stealtime_ntv_code_to_name,
624  .ntv_code_to_descr = _stealtime_ntv_code_to_descr,
625  .ntv_code_to_info = _stealtime_ntv_code_to_info,
626 };
627 
628 
629 
630 
char name[PAPI_MAX_STR_LEN]
Definition: papi.h:629
#define PAPI_ENOEVNT
Definition: papi.h:260
sprintf(splash[splash_line++],"\tIozone: Performance Test of File I/O\n")
static int _stealtime_shutdown_component(void)
long long nice
long long flags
Definition: iozone.c:12330
long long guest
static int _stealtime_reset(hwd_context_t *ctx, hwd_control_state_t *ctrl)
static int _stealtime_shutdown_thread(hwd_context_t *ctx)
#define PAPI_DOM_KERNEL
Definition: papi.h:300
char long_descr[PAPI_HUGE_STR_LEN]
Definition: papi.h:969
static int _stealtime_ntv_code_to_info(unsigned int EventCode, PAPI_event_info_t *info)
long long system
static int read_stealtime(struct STEALTIME_context *context, int starting)
char symbol[PAPI_HUGE_STR_LEN]
Definition: papi.h:966
return PAPI_OK
Definition: linux-nvml.c:497
int count
Definition: iozone.c:22422
static int _stealtime_read(hwd_context_t *ctx, hwd_control_state_t *ctl, long long **events, int flags)
fclose(thread_wqfd)
#define PAPI_DOM_USER
Definition: papi.h:298
void
Definition: iozone.c:18627
char units[MAX_EVENTS][BUFSIZ]
Definition: powercap_plot.c:15
return PAPI_EINVAL
Definition: linux-nvml.c:436
PAPI_component_info_t cmp_info
Definition: papi_vector.h:20
long long idle
static int _stealtime_ntv_enum_events(unsigned int *EventCode, int modifier)
Return codes and api definitions.
FILE * fff[MAX_EVENTS]
char events[MAX_EVENTS][BUFSIZ]
static struct counter_info * event_info
static int cidx
char disabled_reason[PAPI_MAX_STR_LEN]
Definition: papi.h:636
int i
Definition: fileop.c:140
long long irq
long long found
Definition: libasync.c:735
free(dummyfile[xx])
long long softirq
#define PAPI_ESYS
Definition: papi.h:255
static int native
long long * current_count
static int _stealtime_init_thread(hwd_context_t *ctx)
static int num_events
#define PAPI_INT_SIGNAL
Definition: papi_internal.h:53
#define PAPI_GRN_THR
Definition: papi.h:362
static int _stealtime_start(hwd_context_t *ctx, hwd_control_state_t *ctl)
static int _stealtime_stop(hwd_context_t *ctx, hwd_control_state_t *ctl)
#define PAPI_ENOMEM
Definition: papi.h:254
static int _stealtime_update_control_state(hwd_control_state_t *ctl, NativeInfo_t *native, int count, hwd_context_t *ctx)
char * buffer
Definition: iozone.c:1366
static int _stealtime_set_domain(hwd_control_state_t *cntrl, int domain)
long long iowait
long long user
sscanf(mnc->m_child_port,"%d",&mc.m_child_port)
char * name
Definition: iozone.c:23648
papi_vector_t _stealtime_vector
#define PAPI_MAX_STR_LEN
Definition: papi.h:465
static int _stealtime_init_control_state(hwd_control_state_t *ctl)
#define PAPI_DOM_OTHER
Definition: papi.h:301
static int _stealtime_ctl(hwd_context_t *ctx, int code, _papi_int_option_t *option)
static int _stealtime_init_component(int cidx)
static int _stealtime_ntv_code_to_name(unsigned int EventCode, char *name, int len)
long long * start_count
char units[PAPI_MIN_STR_LEN]
Definition: papi.h:975
static int _stealtime_ntv_code_to_descr(unsigned int EventCode, char *name, int len)
long long steal