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