PAPI 7.1.0.0
Loading...
Searching...
No Matches
papi.c
Go to the documentation of this file.
1/****************************/
2/* THIS IS OPEN SOURCE CODE */
3/****************************/
4
26#include <stdio.h>
27#include <string.h>
28#include <stdlib.h>
29#include <unistd.h>
30#include <stdbool.h>
31#include <pthread.h>
32
33#include "papi.h"
34#include "papi_internal.h"
35#include "papi_vector.h"
36#include "papi_memory.h"
37#include "papi_preset.h"
38
39#include "cpus.h"
40#include "extras.h"
41#include "sw_multiplex.h"
42
43
44/* simplified papi functions for event rates */
45
46/* For dynamic linking to libpapi */
47/* Weak symbol for pthread_once to avoid additional linking
48 * against libpthread when not used. */
49#pragma weak pthread_once
50
51#define STOP 0
52#define FLIP 1
53#define FLOP 2
54#define IPC 3
55#define EPC 4
56
60typedef struct _RateInfo
61{
63 int event_0;
64 short int running;
65 long long last_real_time;
66 long long last_proc_time;
67} RateInfo;
68
71
72static void _internal_papi_init(void);
73static void _internal_onetime_papi_init(void);
74static int _start_new_rate_call(float *real_time, float *proc_time, int *events,
75 int num_events, long long *ins, float *rate);
76static int _rate_calls( float *real_time, float *proc_time, int *events,
77 long long *values, long long *ins, float *rate, int mode );
79
80
81static void _internal_papi_init(void)
82{
83 /* This function is only called by the first thread! */
84 int retval;
85
86 /* check if user has already initialzed PAPI with thread support */
89 fprintf( stderr, "PAPI Error: PAPI_library_init failed with return value %d.\n", retval);
90 } else {
91
93 fprintf( stderr, "PAPI Error: PAPI_thread_init failed with return value %d.\n", retval);
94 fprintf( stderr, "PAPI Error: PAPI could not be initiated!\n");
95 } else {
97 }
98 }
99 } else {
101 }
102}
103
105{
106 static pthread_once_t library_is_initialized = PTHREAD_ONCE_INIT;
107 if ( pthread_once ) {
108 /* we assume that this function was called from a parallel region */
109 pthread_once(&library_is_initialized, _internal_papi_init);
110 /* wait until first thread has finished */
111 int i = 0;
112 /* give it 5 seconds in case PAPI_thread_init crashes */
113 while ( !_papi_rate_initiated && (i++) < 500000 )
114 usleep(10);
115 } else {
116 /* we assume that this function was called from a serial application
117 * that was not linked against libpthread */
119 }
120}
121
122static int
124{
125 /* check if PAPI is initialized for rate functions */
126 if ( _papi_rate_initiated == false ) {
128
129 if ( _papi_rate_initiated == false )
130 return ( PAPI_EINVAL );
131 }
132
133 if ( _rate_state== NULL ) {
134 _rate_state= ( RateInfo* ) papi_malloc( sizeof ( RateInfo ) );
135 if ( _rate_state== NULL )
136 return ( PAPI_ENOMEM );
137
138 memset( _rate_state, 0, sizeof ( RateInfo ) );
140 }
141 return ( PAPI_OK );
142}
143
184int
185PAPI_flips_rate( int event, float *rtime, float *ptime, long long *flpins, float *mflips )
186{
187 int retval;
188
189 /* check event first */
190 if ( event == PAPI_FP_INS || event == PAPI_VEC_DP || event == PAPI_VEC_SP ) {
191
192 int events[1] = {event};
193 long long values = 0;
194
195 if ( rtime == NULL || ptime == NULL ||
196 flpins == NULL || mflips == NULL ) {
197 return PAPI_EINVAL;
198 }
199
200 retval = _rate_calls( rtime, ptime, events,
201 &values, flpins, mflips, FLIP );
202
203 return ( retval );
204 }
205 return ( PAPI_ENOEVNT );
206}
207
249int
250PAPI_flops_rate( int event, float *rtime, float *ptime, long long *flpops, float *mflops )
251{
252 int retval;
253
254 /* check event first */
255 if ( event == PAPI_FP_OPS || event == PAPI_SP_OPS || event == PAPI_DP_OPS ) {
256
257 int events[1] = {event};
258 long long values = 0;
259
260 if ( rtime == NULL || ptime == NULL ||
261 flpops == NULL || mflops == NULL ) {
262 return PAPI_EINVAL;
263 }
264
265 retval = _rate_calls( rtime, ptime, events,
266 &values, flpops, mflops, FLOP );
267
268 return ( retval );
269 }
270 return ( PAPI_ENOEVNT );
271}
272
312int
313PAPI_ipc( float *rtime, float *ptime, long long *ins, float *ipc )
314{
315 long long values[2] = { 0, 0 };
316 int events[2] = {PAPI_TOT_INS, PAPI_TOT_CYC};
317 int retval = 0;
318
319 if ( rtime == NULL || ptime == NULL || ins == NULL || ipc == NULL )
320 return PAPI_EINVAL;
321
322 retval = _rate_calls( rtime, ptime, events, values, ins, ipc, IPC );
323 return ( retval );
324}
325
376int
377PAPI_epc( int event, float *rtime, float *ptime, long long *ref, long long *core, long long *evt, float *epc )
378{
379 long long values[3] = { 0, 0, 0 };
381 int retval = 0;
382
383 if ( rtime == NULL || ptime == NULL || ref == NULL ||core == NULL || evt == NULL || epc == NULL )
384 return PAPI_EINVAL;
385
386 // if an event is provided, use it; otherwise use TOT_INS
387 if (event != 0 ) events[0] = event;
388
389 retval = _rate_calls( rtime, ptime, events, values, evt, epc, EPC );
390 *ref = values[2];
391 *core = values[1];
392 return ( retval );
393}
394
414int
416{
417 int retval;
418 long long tmp_values[3];
419
420 if ( _papi_rate_events_running == 1 ) {
421 if ( _rate_state!= NULL ) {
422 if ( _rate_state->running > STOP ) {
423 retval = PAPI_stop( _rate_state->EventSet, tmp_values );
424 if ( retval == PAPI_OK ) {
427 }
429 return retval;
430 }
431 }
432 }
433 return ( PAPI_ENOEVNT );
434}
435
436static int
437_start_new_rate_call(float *real_time, float *proc_time, int *events,
438 int num_events, long long *ins, float *rate)
439{
440 int retval;
441 _rate_state->EventSet = -1;
442
444 return ( retval );
445
447 return retval;
448
449 /* remember the event for subsequent calls of PAPI_flips_rate and PAPI_flops_rate */
451 *real_time = 0.0;
452 *proc_time = 0.0;
453 *rate = 0.0;
454 *ins = 0;
455
458
459 if ( ( retval = PAPI_start( _rate_state->EventSet ) ) != PAPI_OK ) {
460 return retval;
461 }
462
463 return ( PAPI_OK );
464}
465
466static int
467_rate_calls( float *real_time, float *proc_time, int *events,
468 long long *values, long long *ins, float *rate, int mode )
469{
470
471 // printf("_rate_calls event %d, mode %d\n", events[0], mode);
472
473 long long rt, pt; // current elapsed real and process times in usec
474 int num_events = 2;
475 int retval = 0;
476
477 /* if a high-level event set is running stop it */
478 if ( _papi_hl_events_running == 1 ) {
479 if ( ( retval = PAPI_hl_stop() ) != PAPI_OK )
480 return ( retval );
481 }
482
483 if ( ( retval = _internal_check_rate_state() ) != PAPI_OK ) {
484 return ( retval );
485 }
486
487
488 switch (mode) {
489 case FLOP:
490 case FLIP:
491 if ( (retval = PAPI_query_event(events[0])) != PAPI_OK)
492 return retval;
493 num_events = 1;
494 break;
495 case IPC:
496 break;
497 case EPC:
498 if ( (retval = PAPI_query_event(events[0])) != PAPI_OK)
499 return retval;
500 if ( (retval = PAPI_query_event(events[2])) == PAPI_OK)
501 num_events = 3;
502 break;
503 default:
504 return PAPI_EINVAL;
505 }
506
507 /* STOP means the first call of a rate function */
508 if ( _rate_state->running == STOP ) {
509
510 if ( ( retval = _start_new_rate_call(real_time, proc_time, events, num_events, ins, rate)) != PAPI_OK )
511 return retval;
512 _rate_state->running = mode;
513
514 } else {
515 // check last mode
516 // printf("current mode: %d, last mode: %d\n", mode, _rate_state->running);
517 // printf("current event: %d, last event: %d\n", events[0], _rate_state->event_0);
518
519 if ( mode != _rate_state->running || events[0] != _rate_state->event_0 ) {
520
521 long long tmp_values[3];
522 retval = PAPI_stop( _rate_state->EventSet, tmp_values );
523 if ( retval == PAPI_OK ) {
525 } else {
526 return retval;
527 }
528
529 if ( ( retval = _start_new_rate_call(real_time, proc_time, events, num_events, ins, rate)) != PAPI_OK )
530 return retval;
531 _rate_state->running = mode;
533 return ( PAPI_OK );
534 }
535
536 if ( ( retval = PAPI_stop( _rate_state->EventSet, values ) ) != PAPI_OK ) {
538 return retval;
539 }
540
541 /* Read elapsed real and process times */
542 rt = PAPI_get_real_usec();
543 pt = PAPI_get_virt_usec();
544
545 /* Convert to seconds with multiplication because it is much faster */
546 *real_time = ((float)( rt - _rate_state->last_real_time )) * .000001;
547 *proc_time = ((float)( pt - _rate_state->last_proc_time )) * .000001;
548
549 *ins = values[0];
550
551 switch (mode) {
552 case FLOP:
553 case FLIP:
554 /* Calculate MFLOP and MFLIP rates */
555 if ( pt > 0 ) {
556 *rate = (float)values[0] / (pt - _rate_state->last_proc_time);
557 } else *rate = 0;
558 break;
559 case IPC:
560 case EPC:
561 /* Calculate IPC */
562 if (values[1]!=0) {
563 *rate = (float) ((float)values[0] / (float) ( values[1]));
564 }
565 break;
566 default:
567 return PAPI_EINVAL;
568 }
571
572 if ( ( retval = PAPI_start( _rate_state->EventSet ) ) != PAPI_OK ) {
574 return retval;
575 }
576 }
578 return PAPI_OK;
579}
580
581
582/*******************************/
583/* BEGIN EXTERNAL DECLARATIONS */
584/*******************************/
585
586
589
590
591#ifdef DEBUG
592#define papi_return(a) do { \
593 int b = a; \
594 if (b != PAPI_OK) {\
595 _papi_hwi_errno = b;\
596 } \
597 APIDBG("EXIT: return: %d\n", b);\
598 return((_papi_hwi_debug_handler ? _papi_hwi_debug_handler(b) : b)); \
599} while (0)
600#else
601#define papi_return(a) do { \
602 int b = a; \
603 if (b != PAPI_OK) {\
604 _papi_hwi_errno = b;\
605 } \
606 APIDBG("EXIT: return: %d\n", b);\
607 return(b);\
608} while(0)
609#endif
610
611
612/*
613#ifdef DEBUG
614#define papi_return(a) return((_papi_hwi_debug_handler ? _papi_hwi_debug_handler(a) : a))
615#else
616#define papi_return(a) return(a)
617#endif
618*/
619
620#ifdef DEBUG
622#endif
623
624
626
629{
631 return ( PAPI_ENOCMP );
632 return ( cidx );
633}
634
637{
638 return ( valid_component( ESI->CmpIdx ) );
639}
640
664int
665PAPI_thread_init( unsigned long int ( *id_fn ) ( void ) )
666{
667 /* Thread support not implemented on Alpha/OSF because the OSF pfm
668 * counter device driver does not support per-thread counters.
669 * When this is updated, we can remove this if statement
670 */
673
676
679}
680
703unsigned long
705{
706 if ( _papi_hwi_thread_id_fn != NULL )
707 return ( ( *_papi_hwi_thread_id_fn ) ( ) );
708 else
709#ifdef DEBUG
711 return ( unsigned long ) _papi_hwi_debug_handler( PAPI_EMISC );
712#endif
713 return ( unsigned long ) PAPI_EMISC;
714}
715
716/* Thread Functions */
717
718/*
719 * Notify PAPI that a thread has 'appeared'
720 * We lookup the thread, if it does not exist we create it
721 */
722
749int
751{
753
757}
758
759/*
760 * Notify PAPI that a thread has 'disappeared'
761 * We lookup the thread, if it does not exist we return an error
762 */
785int
787{
789
790 if ( thread )
792
794}
795
827int
829{
831 int retval;
832
833 /* If tids == NULL, then just count the threads, don't gather a list. */
834 /* If tids != NULL, then we need the length of the tids array in num. */
835
836 if ( ( number == NULL ) || ( tids && ( *number <= 0 ) ) )
838
839 memset( &tmp, 0x0, sizeof ( tmp ) );
840
841 /* data == NULL, since we don't want the thread specific pointers. */
842 /* tids may be NULL, if the user doesn't want the thread IDs. */
843
844 tmp.num = *number;
845 tmp.id = tids;
846 tmp.data = NULL;
847
849 if ( retval == PAPI_OK )
850 *number = tmp.num;
851
853}
854
903int
904PAPI_get_thr_specific( int tag, void **ptr )
905{
907 int doall = 0, retval = PAPI_OK;
908
911 if ( tag & PAPI_TLS_ALL_THREADS ) {
912 tag = tag ^ PAPI_TLS_ALL_THREADS;
913 doall = 1;
914 }
915 if ( ( tag < 0 ) || ( tag > PAPI_TLS_NUM ) )
917
918 if ( doall )
920 ( tag, ( PAPI_all_thr_spec_t * ) ptr ) );
921
923 if ( retval == PAPI_OK )
924 *ptr = thread->thread_storage[tag];
925 else
927
928 return ( PAPI_OK );
929}
930
979int
980PAPI_set_thr_specific( int tag, void *ptr )
981{
983 int retval = PAPI_OK;
984
987 if ( ( tag < 0 ) || ( tag > PAPI_NUM_TLS ) )
989
991 if ( retval == PAPI_OK ) {
993 thread->thread_storage[tag] = ptr;
995 }
996 else
997 return ( retval );
998
999 return ( PAPI_OK );
1000}
1001
1002
1041int
1043{
1044 APIDBG( "Entry: version: %#x\n", version);
1045
1046 int tmp = 0;
1047
1048 /* This is a poor attempt at a lock.
1049 For 3.1 this should be replaced with a
1050 true UNIX semaphore. We cannot use PAPI
1051 locks here because they are not initialized yet */
1052 static int _in_papi_library_init_cnt = 0;
1053#ifdef DEBUG
1054 char *var;
1055#endif
1057
1058 if ( version != PAPI_VER_CURRENT )
1060
1061 ++_in_papi_library_init_cnt;
1062 while ( _in_papi_library_init_cnt > 1 ) {
1063 PAPIERROR( "Multiple callers of PAPI_library_init" );
1064 sleep( 1 );
1065 }
1066
1067 /* This checks to see if we have forked or called init more than once.
1068 If we have forked, then we continue to init. If we have not forked,
1069 we check to see the status of initialization. */
1070
1071 APIDBG( "Initializing library: current PID %d, old PID %d\n",
1072 getpid( ), _papi_hwi_system_info.pid );
1073
1074 if ( _papi_hwi_system_info.pid == getpid( ) ) {
1075 /* If the magic environment variable PAPI_ALLOW_STOLEN is set,
1076 we call shutdown if PAPI has been initialized. This allows
1077 tools that use LD_PRELOAD to run on applications that use PAPI.
1078 In this circumstance, PAPI_ALLOW_STOLEN will be set to 'stolen'
1079 so the tool can check for this case. */
1080
1081 if ( getenv( "PAPI_ALLOW_STOLEN" ) ) {
1082 char buf[PAPI_HUGE_STR_LEN];
1083 if ( init_level != PAPI_NOT_INITED )
1084 PAPI_shutdown( );
1085 sprintf( buf, "%s=%s", "PAPI_ALLOW_STOLEN", "stolen" );
1086 putenv( buf );
1087 }
1088
1089 /* If the library has been successfully initialized *OR*
1090 the library attempted initialization but failed. */
1091
1092 else if ( ( init_level != PAPI_NOT_INITED ) ||
1093 ( init_retval != DEADBEEF ) ) {
1094 _in_papi_library_init_cnt--;
1095 if ( init_retval < PAPI_OK )
1097 else
1098 return ( init_retval );
1099 }
1100
1101 APIDBG( "system_info was initialized, but init did not succeed\n" );
1102 }
1103#ifdef DEBUG
1104 var = ( char * ) getenv( "PAPI_DEBUG" );
1105 _papi_hwi_debug = 0;
1106
1107 if ( var != NULL ) {
1108 if ( strlen( var ) != 0 ) {
1109 if ( strstr( var, "SUBSTRATE" ) )
1111 if ( strstr( var, "API" ) )
1113 if ( strstr( var, "INTERNAL" ) )
1115 if ( strstr( var, "THREADS" ) )
1117 if ( strstr( var, "MULTIPLEX" ) )
1119 if ( strstr( var, "OVERFLOW" ) )
1121 if ( strstr( var, "PROFILE" ) )
1123 if ( strstr( var, "MEMORY" ) )
1125 if ( strstr( var, "LEAK" ) )
1127 if ( strstr( var, "HIGHLEVEL" ) )
1129 if ( strstr( var, "ALL" ) )
1131 }
1132
1133 if ( _papi_hwi_debug == 0 )
1135 }
1136#endif
1137
1138
1139 /* Initialize internal globals */
1141 _in_papi_library_init_cnt--;
1143 }
1144
1145 /* Initialize OS */
1147 if ( tmp ) {
1148 init_retval = tmp;
1150 _in_papi_library_init_cnt--;
1152 }
1153
1154 /* Initialize component globals EXCEPT for perf_event, perf_event_uncore.
1155 * To avoid race conditions, these components use the thread local storage
1156 * construct initialized by _papi_hwi_init_global_threads(), from within
1157 * their init_component(). So these must have init_component() run AFTER
1158 * _papi_hwi_init_global_threads. Other components demand that init threads
1159 * run AFTER init_component(), which sets up globals they need.
1160 */
1161
1162 tmp = _papi_hwi_init_global( 0 ); /* Selector 0 to skip perf_event, perf_event_uncore */
1163 if ( tmp ) {
1164 init_retval = tmp;
1166 _in_papi_library_init_cnt--;
1168 }
1169
1170 /* Initialize thread globals, including the main threads */
1171
1173 if ( tmp ) {
1174 init_retval = tmp;
1176 _in_papi_library_init_cnt--;
1178 }
1179
1180 /* Initialize perf_event, perf_event_uncore components */
1181
1182 tmp = _papi_hwi_init_global( 1 ); /* Selector 1 for only perf_event, perf_event_uncore */
1183 if ( tmp ) {
1184 init_retval = tmp;
1186 _in_papi_library_init_cnt--;
1188 }
1189
1191 _in_papi_library_init_cnt--;
1192
1193 return ( init_retval = PAPI_VER_CURRENT );
1194}
1195
1237int
1238PAPI_query_event( int EventCode )
1239{
1240 APIDBG( "Entry: EventCode: %#x\n", EventCode);
1241 if ( IS_PRESET(EventCode) ) {
1242 EventCode &= PAPI_PRESET_AND_MASK;
1243 if ( EventCode < 0 || EventCode >= PAPI_MAX_PRESET_EVENTS )
1245
1246 if ( _papi_hwi_presets[EventCode].count )
1248 else
1249 return PAPI_ENOEVNT;
1250 }
1251
1252 if ( IS_NATIVE(EventCode) ) {
1254 ( ( unsigned int ) EventCode ) );
1255 }
1256
1257 if ( IS_USER_DEFINED(EventCode) ) {
1258 EventCode &= PAPI_UE_AND_MASK;
1259 if ( EventCode < 0 || EventCode >= PAPI_MAX_USER_EVENTS)
1261
1262 if ( user_defined_events[EventCode].count )
1264 else
1266 }
1267
1269}
1270
1309int
1310PAPI_query_named_event( const char *EventName )
1311{
1312 int ret, code;
1313
1314 ret = PAPI_event_name_to_code( EventName, &code );
1315 if ( ret == PAPI_OK ) ret = PAPI_query_event( code );
1316 papi_return( ret);
1317}
1318
1319
1351{
1352 APIDBG( "Entry: Component Index %d\n", cidx);
1353 if ( _papi_hwi_invalid_cmp( cidx ) )
1354 return ( NULL );
1355 else
1356 return ( &( _papi_hwd[cidx]->cmp_info ) );
1357}
1358
1359/* PAPI_get_event_info:
1360 tests input EventCode and returns a filled in PAPI_event_info_t
1361 structure containing descriptive strings and values for the
1362 specified event. Handles both preset and native events by
1363 calling either _papi_hwi_get_event_info or
1364 _papi_hwi_get_native_event_info.
1365*/
1388int
1390{
1391 APIDBG( "Entry: EventCode: 0x%x, info: %p\n", EventCode, info);
1392 int i;
1393
1394 if ( info == NULL )
1396
1397 if ( IS_PRESET(EventCode) ) {
1398 i = EventCode & PAPI_PRESET_AND_MASK;
1399 if ( i >= PAPI_MAX_PRESET_EVENTS )
1401 papi_return( _papi_hwi_get_preset_event_info( EventCode, info ) );
1402 }
1403
1404 if ( IS_NATIVE(EventCode) ) {
1406 ( ( unsigned int ) EventCode, info ) );
1407 }
1408
1409 if ( IS_USER_DEFINED(EventCode) ) {
1410 papi_return( _papi_hwi_get_user_event_info( EventCode, info ));
1411 }
1413}
1414
1415
1468int
1469PAPI_event_code_to_name( int EventCode, char *out )
1470{
1471 APIDBG( "Entry: EventCode: %#x, out: %p\n", EventCode, out);
1472 if ( out == NULL )
1474
1475 if ( IS_PRESET(EventCode) ) {
1476 EventCode &= PAPI_PRESET_AND_MASK;
1477 if ( EventCode < 0 || EventCode >= PAPI_MAX_PRESET_EVENTS )
1479
1480 if (_papi_hwi_presets[EventCode].symbol == NULL )
1482
1483 strncpy( out, _papi_hwi_presets[EventCode].symbol, PAPI_MAX_STR_LEN-1 );
1484 out[PAPI_MAX_STR_LEN-1] = '\0';
1486 }
1487
1488 if ( IS_NATIVE(EventCode) ) {
1490 ( ( unsigned int ) EventCode, out, PAPI_MAX_STR_LEN ) );
1491 }
1492
1493 if ( IS_USER_DEFINED(EventCode) ) {
1494 EventCode &= PAPI_UE_AND_MASK;
1495
1496 if ( EventCode < 0 || EventCode >= user_defined_events_count )
1498
1499 if (user_defined_events[EventCode].symbol == NULL )
1501
1502 strncpy( out, user_defined_events[EventCode].symbol, PAPI_MAX_STR_LEN-1);
1503 out[PAPI_MAX_STR_LEN-1] = '\0';
1505 }
1506
1508}
1509
1557int
1558PAPI_event_name_to_code( const char *in, int *out )
1559{
1560 APIDBG("Entry: in: %p, name: %s, out: %p\n", in, in, out);
1561 int i;
1562
1563 if ( ( in == NULL ) || ( out == NULL ) )
1565
1566 if ( init_level == PAPI_NOT_INITED )
1568
1569 /* All presets start with "PAPI_" so no need to */
1570 /* do an exhaustive search if that's not there */
1571 if (strncmp(in, "PAPI_", 5) == 0) {
1572 for(i = 0; i < PAPI_MAX_PRESET_EVENTS; i++ ) {
1573 if ( ( _papi_hwi_presets[i].symbol )
1574 && ( strcasecmp( _papi_hwi_presets[i].symbol, in ) == 0) ) {
1575 *out = ( int ) ( i | PAPI_PRESET_MASK );
1577 }
1578 }
1579 }
1580
1581 // check to see if it is a user defined event
1582 for ( i=0; i < user_defined_events_count ; i++ ) {
1583 APIDBG("&user_defined_events[%d]: %p, user_defined_events[%d].symbol: %s, user_defined_events[%d].count: %d\n",
1585 if (user_defined_events[i].symbol == NULL)
1586 break;
1587 if (user_defined_events[i].count == 0)
1588 break;
1589 if ( strcasecmp( user_defined_events[i].symbol, in ) == 0 ) {
1590 *out = (int) ( i | PAPI_UE_MASK );
1592 }
1593 }
1594
1595 // go look for native events defined by one of the components
1597}
1598
1599/* Updates EventCode to next valid value, or returns error;
1600 modifier can specify {all / available} for presets, or other values for native tables
1601 and may be platform specific (Major groups / all mask bits; P / M / E chip, etc) */
1602
1705int
1706PAPI_enum_event( int *EventCode, int modifier )
1707{
1708 APIDBG( "Entry: EventCode: %#x, modifier: %d\n", *EventCode, modifier);
1709 int i = *EventCode;
1710 int retval;
1711 int cidx;
1712 int event_code;
1713 char *evt_name;
1714
1715 cidx = _papi_hwi_component_index( *EventCode );
1716 if (cidx < 0) return PAPI_ENOCMP;
1717
1718 /* Do we handle presets in componets other than CPU? */
1719 /* if (( IS_PRESET(i) ) && cidx > 0 )) return PAPI_ENOCMP; */
1720
1721 if ( IS_PRESET(i) ) {
1722 if ( modifier == PAPI_ENUM_FIRST ) {
1723 *EventCode = ( int ) PAPI_PRESET_MASK;
1724 APIDBG("EXIT: *EventCode: %#x\n", *EventCode);
1725 return ( PAPI_OK );
1726 }
1728 while ( ++i < PAPI_MAX_PRESET_EVENTS ) {
1729 if ( _papi_hwi_presets[i].symbol == NULL ) {
1730 APIDBG("EXIT: PAPI_ENOEVNT\n");
1731 return ( PAPI_ENOEVNT ); /* NULL pointer terminates list */
1732 }
1733 if ( modifier & PAPI_PRESET_ENUM_AVAIL ) {
1734 if ( _papi_hwi_presets[i].count == 0 )
1735 continue;
1736 }
1737 *EventCode = ( int ) ( i | PAPI_PRESET_MASK );
1738 APIDBG("EXIT: *EventCode: %#x\n", *EventCode);
1739 return ( PAPI_OK );
1740 }
1742 }
1743
1744 if ( IS_NATIVE(i) ) {
1745 // save event code so components can get it with call to: _papi_hwi_get_papi_event_code()
1746 _papi_hwi_set_papi_event_code(*EventCode, 0);
1747
1748 /* Should check against num native events here */
1749
1750 event_code=_papi_hwi_eventcode_to_native((int)*EventCode);
1751 retval = _papi_hwd[cidx]->ntv_enum_events((unsigned int *)&event_code, modifier );
1752
1753 if (retval!=PAPI_OK) {
1754 APIDBG("VMW: retval=%d\n",retval);
1755 return PAPI_EINVAL;
1756 }
1757
1759 *EventCode = _papi_hwi_native_to_eventcode(cidx, event_code, -1, evt_name);
1761
1762 APIDBG("EXIT: *EventCode: %#x\n", *EventCode);
1763 return retval;
1764 }
1765
1766 if ( IS_USER_DEFINED(i) ) {
1767 if (user_defined_events_count == 0) {
1768 APIDBG("EXIT: PAPI_ENOEVNT\n");
1769 return PAPI_ENOEVNT;
1770 }
1771 if ( modifier == PAPI_ENUM_FIRST ) {
1772 *EventCode = (int) (0 | PAPI_UE_MASK);
1773 APIDBG("EXIT: *EventCode: %#x\n", *EventCode);
1774 return ( PAPI_OK );
1775 }
1776
1778 ++i;
1779
1780 if ( i <= 0 || i >= user_defined_events_count ) {
1781 APIDBG("EXIT: PAPI_ENOEVNT\n");
1782 return ( PAPI_ENOEVNT );
1783 }
1784
1785 // if next entry does not have an event name, we are done
1786 if (user_defined_events[i].symbol == NULL) {
1787 APIDBG("EXIT: PAPI_ENOEVNT\n");
1788 return ( PAPI_ENOEVNT );
1789 }
1790
1791 // if next entry does not map to any other events, we are done
1792 if (user_defined_events[i].count == 0) {
1793 APIDBG("EXIT: PAPI_ENOEVNT\n");
1794 return ( PAPI_ENOEVNT );
1795 }
1796
1797 *EventCode = (int) (i | PAPI_UE_MASK);
1798 APIDBG("EXIT: *EventCode: %#x\n", *EventCode);
1799 return ( PAPI_OK );
1800 }
1801
1803}
1804
1805
1910int
1911PAPI_enum_cmp_event( int *EventCode, int modifier, int cidx )
1912{
1913 APIDBG( "Entry: EventCode: %#x, modifier: %d, cidx: %d\n", *EventCode, modifier, cidx);
1914 int i = *EventCode;
1915 int retval;
1916 int event_code;
1917 char *evt_name;
1918
1919 if ( _papi_hwi_invalid_cmp(cidx) || ( (IS_PRESET(i)) && cidx > 0 ) ) {
1920 return PAPI_ENOCMP;
1921 }
1922
1923 if (_papi_hwd[cidx]->cmp_info.disabled &&
1924 _papi_hwd[cidx]->cmp_info.disabled != PAPI_EDELAY_INIT) {
1925 return PAPI_ENOCMP;
1926 }
1927
1928 if ( IS_PRESET(i) ) {
1929 if ( modifier == PAPI_ENUM_FIRST ) {
1930 *EventCode = ( int ) PAPI_PRESET_MASK;
1931 APIDBG("EXIT: *EventCode: %#x\n", *EventCode);
1932 return PAPI_OK;
1933 }
1935 while ( ++i < PAPI_MAX_PRESET_EVENTS ) {
1936 if ( _papi_hwi_presets[i].symbol == NULL ) {
1937 APIDBG("EXIT: PAPI_ENOEVNT\n");
1938 return ( PAPI_ENOEVNT ); /* NULL pointer terminates list */
1939 }
1940 if ( modifier & PAPI_PRESET_ENUM_AVAIL ) {
1941 if ( _papi_hwi_presets[i].count == 0 )
1942 continue;
1943 }
1944 *EventCode = ( int ) ( i | PAPI_PRESET_MASK );
1945 APIDBG("EXIT: *EventCode: %#x\n", *EventCode);
1946 return PAPI_OK;
1947 }
1949 }
1950
1951 if ( IS_NATIVE(i) ) {
1952 // save event code so components can get it with call to: _papi_hwi_get_papi_event_code()
1953 _papi_hwi_set_papi_event_code(*EventCode, 0);
1954
1955 /* Should we check against num native events here? */
1956 event_code=_papi_hwi_eventcode_to_native(*EventCode);
1957 retval = _papi_hwd[cidx]->ntv_enum_events((unsigned int *)&event_code, modifier );
1958
1959 if (retval!=PAPI_OK) {
1960 APIDBG("EXIT: PAPI_EINVAL retval=%d\n",retval);
1961 return PAPI_EINVAL;
1962 }
1963
1965 *EventCode = _papi_hwi_native_to_eventcode(cidx, event_code, -1, evt_name);
1967
1968 APIDBG("EXIT: *EventCode: %#x\n", *EventCode);
1969 return retval;
1970 }
1971
1973}
1974
2018int
2020{
2021 APIDBG("Entry: EventSet: %p\n", EventSet);
2022
2023 ThreadInfo_t *master;
2024 int retval;
2025
2026 if ( init_level == PAPI_NOT_INITED )
2029 if ( retval )
2031
2033}
2034
2080int
2082{
2083 EventSetInfo_t *ESI;
2084 int retval;
2085
2087 if ( ESI == NULL )
2089
2090/* validate cidx */
2092 if ( retval < 0 )
2094
2095/* cowardly refuse to reassign eventsets */
2096 if ( ESI->CmpIdx >= 0 )
2097 return PAPI_EINVAL;
2098
2099 return ( _papi_hwi_assign_eventset( ESI, cidx ) );
2100}
2101
2123int
2125{
2126 EventSetInfo_t *ESI;
2127 int retval;
2128
2129/* validate eventset */
2131 if ( ESI == NULL )
2133
2134/* check if a component has been assigned */
2135 if ( ESI->CmpIdx < 0 )
2137
2138/* validate CmpIdx */
2139 retval = valid_component( ESI->CmpIdx );
2140 if ( retval < 0 )
2142
2143/* return the index */
2144 return ( ESI->CmpIdx );
2145}
2146
2147
2219int
2220PAPI_add_event( int EventSet, int EventCode )
2221{
2222 APIDBG("Entry: EventSet: %d, EventCode: %#x\n", EventSet, EventCode);
2223 EventSetInfo_t *ESI;
2224
2225 /* Is the EventSet already in existence? */
2226
2228 if ( ESI == NULL )
2230
2231 /* Check argument for validity */
2232
2233 if ( ( ( EventCode & PAPI_PRESET_MASK ) == 0 ) &&
2234 ( EventCode & PAPI_NATIVE_MASK ) == 0 )
2236
2237 /* Of course, it must be stopped in order to modify it. */
2238
2239 if ( ESI->state & PAPI_RUNNING )
2241
2242 /* Now do the magic. */
2243 int retval = _papi_hwi_add_event( ESI, EventCode );
2245}
2246
2314int
2315PAPI_remove_event( int EventSet, int EventCode )
2316{
2317 APIDBG("Entry: EventSet: %d, EventCode: %#x\n", EventSet, EventCode);
2318 EventSetInfo_t *ESI;
2319 int i,retval;
2320
2321 /* check for pre-existing ESI */
2322
2324 if ( ESI == NULL )
2326
2327 /* Check argument for validity */
2328
2329 if ( ( !IS_PRESET(EventCode) ) &&
2330 ( !IS_NATIVE(EventCode) ) &&
2331 ( !IS_USER_DEFINED(EventCode) ))
2333
2334 /* Of course, it must be stopped in order to modify it. */
2335
2336 if ( !( ESI->state & PAPI_STOPPED ) )
2338
2339 /* if the state is PAPI_OVERFLOWING, you must first call
2340 PAPI_overflow with threshold=0 to remove the overflow flag */
2341
2342 /* Turn off the event that is overflowing */
2343 if ( ESI->state & PAPI_OVERFLOWING ) {
2344 for ( i = 0; i < ESI->overflow.event_counter; i++ ) {
2345 if ( ESI->overflow.EventCode[i] == EventCode ) {
2346 retval = PAPI_overflow( EventSet, EventCode, 0, 0,
2347 ESI->overflow.handler );
2348 if (retval!=PAPI_OK) return retval;
2349 break;
2350 }
2351 }
2352 }
2353
2354 /* force the user to call PAPI_profil to clear the PAPI_PROFILING flag */
2355 if ( ESI->state & PAPI_PROFILING ) {
2356 for ( i = 0; i < ESI->profile.event_counter; i++ ) {
2357 if ( ESI->profile.EventCode[i] == EventCode ) {
2358 PAPI_sprofil( NULL, 0, EventSet, EventCode, 0, 0 );
2359 break;
2360 }
2361 }
2362 }
2363
2364 /* Now do the magic. */
2365
2366 papi_return( _papi_hwi_remove_event( ESI, EventCode ) );
2367}
2368
2434int
2435PAPI_add_named_event( int EventSet, const char *EventName )
2436{
2437 APIDBG("Entry: EventSet: %d, EventName: %s\n", EventSet, EventName);
2438
2439 int ret, code;
2440
2441 ret = PAPI_event_name_to_code( EventName, &code );
2442 if ( ret != PAPI_OK ) {
2443 APIDBG("EXIT: return: %d\n", ret);
2444 return ret; // do not use papi_return here because if there was an error PAPI_event_name_to_code already reported it
2445 }
2446
2447 ret = PAPI_add_event( EventSet, code );
2448 APIDBG("EXIT: return: %d\n", ret);
2449 return ret; // do not use papi_return here because if there was an error PAPI_add_event already reported it
2450}
2451
2519int
2520PAPI_remove_named_event( int EventSet, const char *EventName )
2521{
2522 APIDBG("Entry: EventSet: %d, EventName: %s\n", EventSet, EventName);
2523 int ret, code;
2524
2525 ret = PAPI_event_name_to_code( EventName, &code );
2526 if ( ret == PAPI_OK ) ret = PAPI_remove_event( EventSet, code );
2527 papi_return( ret );
2528
2529}
2530
2572int
2574{
2575 APIDBG("Entry: EventSet: %p, *EventSet: %d\n", EventSet, *EventSet);
2576
2577 EventSetInfo_t *ESI;
2578
2579 /* check for pre-existing ESI */
2580
2581 if ( EventSet == NULL )
2583
2585 if ( ESI == NULL )
2587
2588 if ( !( ESI->state & PAPI_STOPPED ) )
2590
2591 if ( ESI->NumberOfEvents )
2593
2596
2597 return PAPI_OK;
2598}
2599
2600/* simply checks for valid EventSet, calls component start() call */
2654int
2656{
2657 APIDBG("Entry: EventSet: %d\n", EventSet);
2658
2659 int is_dirty=0;
2660 int i,retval;
2661 EventSetInfo_t *ESI;
2662 ThreadInfo_t *thread = NULL;
2663 CpuInfo_t *cpu = NULL;
2664 hwd_context_t *context;
2665 int cidx;
2666
2668 if ( ESI == NULL ) {
2670 }
2671
2672 APIDBG("EventSet: %p\n", ESI);
2673
2674 cidx = valid_ESI_component( ESI );
2675 if ( cidx < 0 ) {
2676 papi_return( cidx );
2677 }
2678
2679 /* only one event set per thread can be running at any time, */
2680 /* so if another event set is running, the user must stop that */
2681 /* event set explicitly */
2682
2683 /* We used to check and not let multiple events be attached */
2684 /* to the same CPU, but this was unnecessary? */
2685
2686 thread = ESI->master;
2687 cpu = ESI->CpuInfo;
2688
2689 if ( thread->running_eventset[cidx] ) {
2690 APIDBG("Thread Running already (Only one active Eventset per component)\n");
2692 }
2693
2694 /* Check that there are added events */
2695 if ( ESI->NumberOfEvents < 1 ) {
2697 }
2698
2699 /* If multiplexing is enabled for this eventset,
2700 call John May's code. */
2701
2702 if ( _papi_hwi_is_sw_multiplex( ESI ) ) {
2704 if ( retval != PAPI_OK ) {
2706 }
2707
2708 /* Update the state of this EventSet */
2709 ESI->state ^= PAPI_STOPPED;
2710 ESI->state |= PAPI_RUNNING;
2711
2712 return PAPI_OK;
2713 }
2714
2715 /* get the context we should use for this event set */
2716 context = _papi_hwi_get_context( ESI, &is_dirty );
2717 if (is_dirty) {
2718 /* we need to reset the context state because it was last used */
2719 /* for some other event set and does not contain the information */
2720 /* for our events. */
2721 retval = _papi_hwd[ESI->CmpIdx]->update_control_state(
2722 ESI->ctl_state,
2723 ESI->NativeInfoArray,
2724 ESI->NativeCount,
2725 context);
2726 if ( retval != PAPI_OK ) {
2728 }
2729
2730 //update_control_state disturbs the overflow settings so set
2731 //it to initial values again
2732 if ( ESI->overflow.flags & PAPI_OVERFLOW_HARDWARE ) {
2733 for( i = 0; i < ESI->overflow.event_counter; i++ ) {
2734 retval = _papi_hwd[ESI->CmpIdx]->set_overflow( ESI,
2735 ESI->overflow.EventIndex[i],
2736 ESI->overflow.threshold[i] );
2737 if ( retval != PAPI_OK ) {
2738 break;
2739 }
2740 }
2741 }
2742
2743 /* now that the context contains this event sets information, */
2744 /* make sure the position array in the EventInfoArray is correct */
2745
2746 /* We have to do this because ->update_control_state() can */
2747 /* in theory re-order the native events out from under us. */
2749
2750 }
2751
2752 /* If overflowing is enabled, turn it on */
2753 if ( ( ESI->state & PAPI_OVERFLOWING ) &&
2754 !( ESI->overflow.flags & PAPI_OVERFLOW_HARDWARE ) ) {
2756 NEED_CONTEXT, cidx );
2757 if ( retval != PAPI_OK ) {
2759 }
2760
2761 /* Update the state of this EventSet and thread */
2762 /* before to avoid races */
2763 ESI->state ^= PAPI_STOPPED;
2764 ESI->state |= PAPI_RUNNING;
2765 /* can not be attached to thread or cpu if overflowing */
2766 thread->running_eventset[cidx] = ESI;
2767
2768 retval = _papi_hwd[cidx]->start( context, ESI->ctl_state );
2769 if ( retval != PAPI_OK ) {
2771 ESI->state ^= PAPI_RUNNING;
2772 ESI->state |= PAPI_STOPPED;
2773 thread->running_eventset[cidx] = NULL;
2775 }
2776
2780 if ( retval != PAPI_OK ) {
2782 _papi_hwd[cidx]->stop( context, ESI->ctl_state );
2783 ESI->state ^= PAPI_RUNNING;
2784 ESI->state |= PAPI_STOPPED;
2785 thread->running_eventset[cidx] = NULL;
2787 }
2788 } else {
2789 /* Update the state of this EventSet and thread before */
2790 /* to avoid races */
2791 ESI->state ^= PAPI_STOPPED;
2792 ESI->state |= PAPI_RUNNING;
2793
2794 /* if not attached to cpu or another process */
2795 if ( !(ESI->state & PAPI_CPU_ATTACHED) ) {
2796 if ( !( ESI->state & PAPI_ATTACHED ) ) {
2797 thread->running_eventset[cidx] = ESI;
2798 }
2799 } else {
2800 cpu->running_eventset[cidx] = ESI;
2801 }
2802
2803 retval = _papi_hwd[cidx]->start( context, ESI->ctl_state );
2804 if ( retval != PAPI_OK ) {
2805 _papi_hwd[cidx]->stop( context, ESI->ctl_state );
2806 ESI->state ^= PAPI_RUNNING;
2807 ESI->state |= PAPI_STOPPED;
2808 if ( !(ESI->state & PAPI_CPU_ATTACHED) ) {
2809 if ( !( ESI->state & PAPI_ATTACHED ) )
2810 thread->running_eventset[cidx] = NULL;
2811 } else {
2812 cpu->running_eventset[cidx] = NULL;
2813 }
2815 }
2816 }
2817
2818 return retval;
2819}
2820
2821/* checks for valid EventSet, calls component stop() function. */
2872int
2873PAPI_stop( int EventSet, long long *values )
2874{
2875 APIDBG("Entry: EventSet: %d, values: %p\n", EventSet, values);
2876 EventSetInfo_t *ESI;
2877 hwd_context_t *context;
2878 int cidx, retval;
2879
2881 if ( ESI == NULL )
2883
2884 cidx = valid_ESI_component( ESI );
2885 if ( cidx < 0 )
2886 papi_return( cidx );
2887
2888 if ( !( ESI->state & PAPI_RUNNING ) )
2890
2891 /* If multiplexing is enabled for this eventset, turn if off */
2892
2893 if ( _papi_hwi_is_sw_multiplex( ESI ) ) {
2895 if ( retval != PAPI_OK )
2897
2898 /* Update the state of this EventSet */
2899
2900 ESI->state ^= PAPI_RUNNING;
2901 ESI->state |= PAPI_STOPPED;
2902
2903 return ( PAPI_OK );
2904 }
2905
2906 /* get the context we should use for this event set */
2907 context = _papi_hwi_get_context( ESI, NULL );
2908 /* Read the current counter values into the EventSet */
2909 retval = _papi_hwi_read( context, ESI, ESI->sw_stop );
2910 if ( retval != PAPI_OK )
2912
2913 /* Remove the control bits from the active counter config. */
2914 retval = _papi_hwd[cidx]->stop( context, ESI->ctl_state );
2915 if ( retval != PAPI_OK )
2917 if ( values )
2918 memcpy( values, ESI->sw_stop,
2919 ( size_t ) ESI->NumberOfEvents * sizeof ( long long ) );
2920
2921 /* If kernel profiling is in use, flush and process the kernel buffer */
2922
2923 if ( ESI->state & PAPI_PROFILING ) {
2924 if ( _papi_hwd[cidx]->cmp_info.kernel_profile &&
2925 !( ESI->profile.flags & PAPI_PROFIL_FORCE_SW ) ) {
2926 retval = _papi_hwd[cidx]->stop_profiling( ESI->master, ESI );
2927 if ( retval < PAPI_OK )
2929 }
2930 }
2931
2932 /* If overflowing is enabled, turn it off */
2933
2934 if ( ESI->state & PAPI_OVERFLOWING ) {
2935 if ( !( ESI->overflow.flags & PAPI_OVERFLOW_HARDWARE ) ) {
2938 if ( retval != PAPI_OK )
2941 }
2942 }
2943
2944 /* Update the state of this EventSet */
2945
2946 ESI->state ^= PAPI_RUNNING;
2947 ESI->state |= PAPI_STOPPED;
2948
2949 /* Update the running event set for this thread */
2950 if ( !(ESI->state & PAPI_CPU_ATTACHED) ) {
2951 if ( !( ESI->state & PAPI_ATTACHED ))
2952 ESI->master->running_eventset[cidx] = NULL;
2953 } else {
2954 ESI->CpuInfo->running_eventset[cidx] = NULL;
2955 }
2956
2957#if defined(DEBUG)
2958 if ( _papi_hwi_debug & DEBUG_API ) {
2959 int i;
2960 for ( i = 0; i < ESI->NumberOfEvents; i++ ) {
2961 APIDBG( "PAPI_stop ESI->sw_stop[%d]:\t%llu\n", i, ESI->sw_stop[i] );
2962 }
2963 }
2964#endif
2965
2966 return ( PAPI_OK );
2967}
2968
3017int
3019{
3020 APIDBG("Entry: EventSet: %d\n", EventSet);
3021 int retval = PAPI_OK;
3022 EventSetInfo_t *ESI;
3023 hwd_context_t *context;
3024 int cidx;
3025
3027 if ( ESI == NULL )
3029
3030 cidx = valid_ESI_component( ESI );
3031 if ( cidx < 0 )
3032 papi_return( cidx );
3033
3034 if ( ESI->state & PAPI_RUNNING ) {
3035 if ( _papi_hwi_is_sw_multiplex( ESI ) ) {
3037 } else {
3038 /* If we're not the only one running, then just
3039 read the current values into the ESI->start
3040 array. This holds the starting value for counters
3041 that are shared. */
3042 /* get the context we should use for this event set */
3043 context = _papi_hwi_get_context( ESI, NULL );
3044 retval = _papi_hwd[cidx]->reset( context, ESI->ctl_state );
3045 }
3046 } else {
3047#ifdef __bgp__
3048 // For BG/P, we always want to reset the 'real' hardware counters. The counters
3049 // can be controlled via multiple interfaces, and we need to ensure that the values
3050 // are truly zero...
3051 /* get the context we should use for this event set */
3052 context = _papi_hwi_get_context( ESI, NULL );
3053 retval = _papi_hwd[cidx]->reset( context, ESI->ctl_state );
3054#endif
3055 memset( ESI->sw_stop, 0x00,
3056 ( size_t ) ESI->NumberOfEvents * sizeof ( long long ) );
3057 }
3058
3059 APIDBG( "EXIT: retval %d\n", retval );
3061}
3062
3117int
3118PAPI_read( int EventSet, long long *values )
3119{
3120 APIDBG( "Entry: EventSet: %d, values: %p\n", EventSet, values);
3121 EventSetInfo_t *ESI;
3122 hwd_context_t *context;
3123 int cidx, retval = PAPI_OK;
3124
3126 if ( ESI == NULL )
3128
3129 cidx = valid_ESI_component( ESI );
3130 if ( cidx < 0 )
3131 papi_return( cidx );
3132
3133 if ( values == NULL )
3135
3136 if ( ESI->state & PAPI_RUNNING ) {
3137 if ( _papi_hwi_is_sw_multiplex( ESI ) ) {
3139 } else {
3140 /* get the context we should use for this event set */
3141 context = _papi_hwi_get_context( ESI, NULL );
3142 retval = _papi_hwi_read( context, ESI, values );
3143 }
3144 if ( retval != PAPI_OK )
3146 } else {
3147 memcpy( values, ESI->sw_stop,
3148 ( size_t ) ESI->NumberOfEvents * sizeof ( long long ) );
3149 }
3150
3151#if defined(DEBUG)
3152 if ( ISLEVEL( DEBUG_API ) ) {
3153 int i;
3154 for ( i = 0; i < ESI->NumberOfEvents; i++ ) {
3155 APIDBG( "PAPI_read values[%d]:\t%lld\n", i, values[i] );
3156 }
3157 }
3158#endif
3159
3160 APIDBG( "PAPI_read returns %d\n", retval );
3161 return ( PAPI_OK );
3162}
3163
3206int
3207PAPI_read_ts( int EventSet, long long *values, long long *cycles )
3208{
3209 APIDBG( "Entry: EventSet: %d, values: %p, cycles: %p\n", EventSet, values, cycles);
3210 EventSetInfo_t *ESI;
3211 hwd_context_t *context;
3212 int cidx, retval = PAPI_OK;
3213
3215 if ( ESI == NULL )
3217
3218 cidx = valid_ESI_component( ESI );
3219 if ( cidx < 0 )
3220 papi_return( cidx );
3221
3222 if ( values == NULL )
3224
3225 if ( ESI->state & PAPI_RUNNING ) {
3226 if ( _papi_hwi_is_sw_multiplex( ESI ) ) {
3228 } else {
3229 /* get the context we should use for this event set */
3230 context = _papi_hwi_get_context( ESI, NULL );
3231 retval = _papi_hwi_read( context, ESI, values );
3232 }
3233 if ( retval != PAPI_OK )
3235 } else {
3236 memcpy( values, ESI->sw_stop,
3237 ( size_t ) ESI->NumberOfEvents * sizeof ( long long ) );
3238 }
3239
3240 *cycles = _papi_os_vector.get_real_cycles( );
3241
3242#if defined(DEBUG)
3243 if ( ISLEVEL( DEBUG_API ) ) {
3244 int i;
3245 for ( i = 0; i < ESI->NumberOfEvents; i++ ) {
3246 APIDBG( "PAPI_read values[%d]:\t%lld\n", i, values[i] );
3247 }
3248 }
3249#endif
3250
3251 APIDBG( "PAPI_read_ts returns %d\n", retval );
3252 return PAPI_OK;
3253}
3254
3303int
3304PAPI_accum( int EventSet, long long *values )
3305{
3306 APIDBG("Entry: EventSet: %d, values: %p\n", EventSet, values);
3307 EventSetInfo_t *ESI;
3308 hwd_context_t *context;
3309 int i, cidx, retval;
3310 long long a, b, c;
3311
3313 if ( ESI == NULL )
3315
3316 cidx = valid_ESI_component( ESI );
3317 if ( cidx < 0 )
3318 papi_return( cidx );
3319
3320 if ( values == NULL )
3322
3323 if ( ESI->state & PAPI_RUNNING ) {
3324 if ( _papi_hwi_is_sw_multiplex( ESI ) ) {
3325 retval = MPX_read( ESI->multiplex.mpx_evset, ESI->sw_stop, 0 );
3326 } else {
3327 /* get the context we should use for this event set */
3328 context = _papi_hwi_get_context( ESI, NULL );
3329 retval = _papi_hwi_read( context, ESI, ESI->sw_stop );
3330 }
3331 if ( retval != PAPI_OK )
3333 }
3334
3335 for ( i = 0; i < ESI->NumberOfEvents; i++ ) {
3336 a = ESI->sw_stop[i];
3337 b = values[i];
3338 c = a + b;
3339 values[i] = c;
3340 }
3341
3343}
3344
3371int
3372PAPI_write( int EventSet, long long *values )
3373{
3374 APIDBG("Entry: EventSet: %d, values: %p\n", EventSet, values);
3375
3376 int cidx, retval = PAPI_OK;
3377 EventSetInfo_t *ESI;
3378 hwd_context_t *context;
3379
3381 if ( ESI == NULL )
3383
3384 cidx = valid_ESI_component( ESI );
3385 if ( cidx < 0 )
3386 papi_return( cidx );
3387
3388 if ( values == NULL )
3390
3391 if ( ESI->state & PAPI_RUNNING ) {
3392 /* get the context we should use for this event set */
3393 context = _papi_hwi_get_context( ESI, NULL );
3394 retval = _papi_hwd[cidx]->write( context, ESI->ctl_state, values );
3395 if ( retval != PAPI_OK )
3396 return ( retval );
3397 }
3398
3399 memcpy( ESI->hw_start, values,
3400 ( size_t ) _papi_hwd[cidx]->cmp_info.num_cntrs *
3401 sizeof ( long long ) );
3402
3403 return ( retval );
3404}
3405
3448int
3450{
3451 APIDBG("Entry: EventSet: %d\n",EventSet);
3452
3453 EventSetInfo_t *ESI;
3454 int i, cidx, total, retval;
3455
3456 /* Is the EventSet already in existence? */
3457
3459 if ( ESI == NULL )
3461
3462 /* if the eventset has no index and no events, return OK
3463 otherwise return NOCMP */
3464 cidx = valid_ESI_component( ESI );
3465 if ( cidx < 0 ) {
3466 if ( ESI->NumberOfEvents )
3467 papi_return( cidx );
3469 }
3470
3471 /* Of course, it must be stopped in order to modify it. */
3472
3473 if ( ESI->state & PAPI_RUNNING )
3475
3476 /* clear overflow flag and turn off hardware overflow handler */
3477 if ( ESI->state & PAPI_OVERFLOWING ) {
3479 for ( i = 0; i < total; i++ ) {
3481 ESI->overflow.EventCode[0], 0, 0, NULL );
3482 if ( retval != PAPI_OK )
3484 }
3485 }
3486
3487 /* clear profile flag and turn off hardware profile handler */
3488 if ( ( ESI->state & PAPI_PROFILING ) &&
3489 _papi_hwd[cidx]->cmp_info.hardware_intr &&
3490 !( ESI->profile.flags & PAPI_PROFIL_FORCE_SW ) ) {
3492 for ( i = 0; i < total; i++ ) {
3493 retval =
3494 PAPI_sprofil( NULL, 0, EventSet, ESI->profile.EventCode[0], 0,
3496 if ( retval != PAPI_OK )
3498 }
3499 }
3500
3501 if ( _papi_hwi_is_sw_multiplex( ESI ) ) {
3503 if ( retval != PAPI_OK )
3505 }
3506
3507 retval = _papi_hwd[cidx]->cleanup_eventset( ESI->ctl_state );
3508 if ( retval != PAPI_OK )
3510
3511 /* Now do the magic */
3513}
3514
3540int
3542{
3543 APIDBG("Entry:\n");
3544
3545 int retval;
3546
3549}
3550
3611int
3612PAPI_state( int EventSet, int *status )
3613{
3614 APIDBG("Entry: EventSet: %d, status: %p\n", EventSet, status);
3615
3616 EventSetInfo_t *ESI;
3617
3618 if ( status == NULL )
3620
3621 /* check for good EventSetIndex value */
3622
3624 if ( ESI == NULL )
3626
3627 /*read status FROM ESI->state */
3628
3629 *status = ESI->state;
3630
3631 return ( PAPI_OK );
3632}
3633
3684int
3685PAPI_set_debug( int level )
3686{
3687 APIDBG("Entry: level: %d\n", level);
3688 PAPI_option_t option;
3689
3690 memset( &option, 0x0, sizeof ( option ) );
3691 option.debug.level = level;
3693 return ( PAPI_set_opt( PAPI_DEBUG, &option ) );
3694}
3695
3696/* Attaches to or detaches from the specified thread id */
3697inline_static int
3698_papi_set_attach( int option, int EventSet, unsigned long tid )
3699{
3700 APIDBG("Entry: option: %d, EventSet: %d, tid: %lu\n", option, EventSet, tid);
3702
3703 memset( &attach, 0x0, sizeof ( attach ) );
3704 attach.attach.eventset = EventSet;
3705 attach.attach.tid = tid;
3706 return ( PAPI_set_opt( option, &attach ) );
3707}
3708
3759int
3760PAPI_attach( int EventSet, unsigned long tid )
3761{
3762 APIDBG( "Entry: EventSet: %d, tid: %lu\n", EventSet, tid);
3763 return ( _papi_set_attach( PAPI_ATTACH, EventSet, tid ) );
3764}
3765
3816int
3818{
3819 APIDBG( "Entry: EventSet: %d\n", EventSet);
3820 return ( _papi_set_attach( PAPI_DETACH, EventSet, 0 ) );
3821}
3822
3891int
3893{
3894 APIDBG( "Entry: EventSet: %d\n", EventSet);
3895
3896 PAPI_option_t mpx;
3897 EventSetInfo_t *ESI;
3898 int cidx;
3899 int ret;
3900
3901 /* Is the EventSet already in existence? */
3902
3904
3905 if ( ESI == NULL )
3907
3908 /* if the eventset has no index return NOCMP */
3909 cidx = valid_ESI_component( ESI );
3910 if ( cidx < 0 )
3911 papi_return( cidx );
3912
3913 if ( ( ret = mpx_check( EventSet ) ) != PAPI_OK )
3914 papi_return( ret );
3915
3916 memset( &mpx, 0x0, sizeof ( mpx ) );
3920 return ( PAPI_set_opt( PAPI_MULTIPLEX, &mpx ) );
3921}
3922
4023int
4024PAPI_set_opt( int option, PAPI_option_t * ptr )
4025{
4026 APIDBG("Entry: option: %d, ptr: %p\n", option, ptr);
4027
4028 _papi_int_option_t internal;
4029 int retval = PAPI_OK;
4030 hwd_context_t *context;
4031 int cidx;
4032
4033 if ( ( option != PAPI_DEBUG ) && ( init_level == PAPI_NOT_INITED ) )
4035 if ( ptr == NULL )
4037
4038 memset( &internal, 0x0, sizeof ( _papi_int_option_t ) );
4039
4040 switch ( option ) {
4041 case PAPI_DETACH:
4042 {
4044 if ( internal.attach.ESI == NULL )
4046
4047 cidx = valid_ESI_component( internal.attach.ESI );
4048 if ( cidx < 0 )
4049 papi_return( cidx );
4050
4051 if ( _papi_hwd[cidx]->cmp_info.attach == 0 )
4053
4054 /* if attached to a cpu, return an error */
4055 if (internal.attach.ESI->state & PAPI_CPU_ATTACHED)
4057
4058 if ( ( internal.attach.ESI->state & PAPI_STOPPED ) == 0 )
4060
4061 if ( ( internal.attach.ESI->state & PAPI_ATTACHED ) == 0 )
4063
4064 internal.attach.tid = internal.attach.ESI->attach.tid;
4065 /* get the context we should use for this event set */
4066 context = _papi_hwi_get_context( internal.attach.ESI, NULL );
4067 retval = _papi_hwd[cidx]->ctl( context, PAPI_DETACH, &internal );
4068 if ( retval != PAPI_OK )
4070
4071 internal.attach.ESI->state ^= PAPI_ATTACHED;
4072 internal.attach.ESI->attach.tid = 0;
4073 return ( PAPI_OK );
4074 }
4075 case PAPI_ATTACH:
4076 {
4078 if ( internal.attach.ESI == NULL )
4080
4081 cidx = valid_ESI_component( internal.attach.ESI );
4082 if ( cidx < 0 )
4083 papi_return( cidx );
4084
4085 if ( _papi_hwd[cidx]->cmp_info.attach == 0 )
4087
4088 if ( ( internal.attach.ESI->state & PAPI_STOPPED ) == 0 )
4090
4091 if ( internal.attach.ESI->state & PAPI_ATTACHED )
4093
4094 /* if attached to a cpu, return an error */
4095 if (internal.attach.ESI->state & PAPI_CPU_ATTACHED)
4097
4098 internal.attach.tid = ptr->attach.tid;
4099 /* get the context we should use for this event set */
4100 context = _papi_hwi_get_context( internal.attach.ESI, NULL );
4101 retval = _papi_hwd[cidx]->ctl( context, PAPI_ATTACH, &internal );
4102 if ( retval != PAPI_OK )
4104
4105 internal.attach.ESI->state |= PAPI_ATTACHED;
4106 internal.attach.ESI->attach.tid = ptr->attach.tid;
4107
4109 &(internal.attach.ESI->master), ptr->attach.tid ));
4110 }
4111 case PAPI_CPU_ATTACH:
4112 {
4113 APIDBG("eventset: %d, cpu_num: %d\n", ptr->cpu.eventset, ptr->cpu.cpu_num);
4114 internal.cpu.ESI = _papi_hwi_lookup_EventSet( ptr->cpu.eventset );
4115 if ( internal.cpu.ESI == NULL )
4117
4118 internal.cpu.cpu_num = ptr->cpu.cpu_num;
4119 APIDBG("internal: %p, ESI: %p, cpu_num: %d\n", &internal, internal.cpu.ESI, internal.cpu.cpu_num);
4120
4121 cidx = valid_ESI_component( internal.cpu.ESI );
4122 if ( cidx < 0 )
4123 papi_return( cidx );
4124
4125 if ( _papi_hwd[cidx]->cmp_info.cpu == 0 )
4127
4128 // can not attach to a cpu if already attached to a process or
4129 // counters set to be inherited by child processes
4130 if ( internal.cpu.ESI->state & (PAPI_ATTACHED | PAPI_INHERIT) )
4132
4133 if ( ( internal.cpu.ESI->state & PAPI_STOPPED ) == 0 )
4135
4137 if( retval != PAPI_OK) {
4139 }
4140
4141 /* get the context we should use for this event set */
4142 context = _papi_hwi_get_context( internal.cpu.ESI, NULL );
4143 retval = _papi_hwd[cidx]->ctl( context, PAPI_CPU_ATTACH, &internal );
4144 if ( retval != PAPI_OK )
4146
4147 /* set to show this event set is attached to a cpu not a thread */
4148 internal.cpu.ESI->state |= PAPI_CPU_ATTACHED;
4149 return ( PAPI_OK );
4150 }
4151 case PAPI_DEF_MPX_NS:
4152 {
4153 cidx = 0; /* xxxx for now, assume we only check against cpu component */
4154 if ( ptr->multiplex.ns < 0 )
4156 /* We should check the resolution here with the system, either
4157 component if kernel multiplexing or PAPI if SW multiplexing. */
4158 internal.multiplex.ns = ( unsigned long ) ptr->multiplex.ns;
4159 /* get the context we should use for this event set */
4160 context = _papi_hwi_get_context( internal.cpu.ESI, NULL );
4161 /* Low level just checks/adjusts the args for this component */
4162 retval = _papi_hwd[cidx]->ctl( context, PAPI_DEF_MPX_NS, &internal );
4163 if ( retval == PAPI_OK ) {
4164 _papi_os_info.itimer_ns = ( int ) internal.multiplex.ns;
4165 ptr->multiplex.ns = ( int ) internal.multiplex.ns;
4166 }
4168 }
4169 case PAPI_DEF_ITIMER_NS:
4170 {
4171 cidx = 0; /* xxxx for now, assume we only check against cpu component */
4172 if ( ptr->itimer.ns < 0 )
4174 internal.itimer.ns = ptr->itimer.ns;
4175 /* Low level just checks/adjusts the args for this component */
4176 retval = _papi_hwd[cidx]->ctl( NULL, PAPI_DEF_ITIMER_NS, &internal );
4177 if ( retval == PAPI_OK ) {
4178 _papi_os_info.itimer_ns = internal.itimer.ns;
4179 ptr->itimer.ns = internal.itimer.ns;
4180 }
4182 }
4183 case PAPI_DEF_ITIMER:
4184 {
4185 cidx = 0; /* xxxx for now, assume we only check against cpu component */
4186 if ( ptr->itimer.ns < 0 )
4188 memcpy( &internal.itimer, &ptr->itimer,
4189 sizeof ( PAPI_itimer_option_t ) );
4190 /* Low level just checks/adjusts the args for this component */
4191 retval = _papi_hwd[cidx]->ctl( NULL, PAPI_DEF_ITIMER, &internal );
4192 if ( retval == PAPI_OK ) {
4195 if ( ptr->itimer.ns > 0 )
4197 /* flags are currently ignored, eventually the flags will be able
4198 to specify whether or not we use POSIX itimers (clock_gettimer) */
4199 }
4201 }
4202 case PAPI_MULTIPLEX:
4203 {
4204 EventSetInfo_t *ESI;
4206
4207 if ( ESI == NULL )
4209
4210 cidx = valid_ESI_component( ESI );
4211 if ( cidx < 0 )
4212 papi_return( cidx );
4213
4214 if ( !( ESI->state & PAPI_STOPPED ) )
4216 if ( ESI->state & PAPI_MULTIPLEXING )
4218
4219 if ( ptr->multiplex.ns < 0 )
4221 internal.multiplex.ESI = ESI;
4222 internal.multiplex.ns = ( unsigned long ) ptr->multiplex.ns;
4223 internal.multiplex.flags = ptr->multiplex.flags;
4224 if ( ( _papi_hwd[cidx]->cmp_info.kernel_multiplex ) &&
4225 ( ( ptr->multiplex.flags & PAPI_MULTIPLEX_FORCE_SW ) == 0 ) ) {
4226 /* get the context we should use for this event set */
4227 context = _papi_hwi_get_context( ESI, NULL );
4228 retval = _papi_hwd[cidx]->ctl( context, PAPI_MULTIPLEX, &internal );
4229 }
4230 /* Kernel or PAPI may have changed this value so send it back out to the user */
4231 ptr->multiplex.ns = ( int ) internal.multiplex.ns;
4232 if ( retval == PAPI_OK )
4234 ( &internal.multiplex ) );
4235 return ( retval );
4236 }
4237 case PAPI_DEBUG:
4238 {
4239 int level = ptr->debug.level;
4240 switch ( level ) {
4241 case PAPI_QUIET:
4242 case PAPI_VERB_ESTOP:
4243 case PAPI_VERB_ECONT:
4244 _papi_hwi_error_level = level;
4245 break;
4246 default:
4248 }
4250 return ( PAPI_OK );
4251 }
4252 case PAPI_DEFDOM:
4253 {
4254 int dom = ptr->defdomain.domain;
4255 if ( ( dom < PAPI_DOM_MIN ) || ( dom > PAPI_DOM_MAX ) )
4257
4258 /* Change the global structure. The _papi_hwd_init_control_state function
4259 in the components gets information from the global structure instead of
4260 per-thread information. */
4262 if ( cidx < 0 )
4263 papi_return( cidx );
4264
4265 /* Check what the component supports */
4266
4267 if ( dom == PAPI_DOM_ALL )
4268 dom = _papi_hwd[cidx]->cmp_info.available_domains;
4269
4270 if ( dom & ~_papi_hwd[cidx]->cmp_info.available_domains )
4272
4273 _papi_hwd[cidx]->cmp_info.default_domain = dom;
4274
4275 return ( PAPI_OK );
4276 }
4277 case PAPI_DOMAIN:
4278 {
4279 int dom = ptr->domain.domain;
4280 if ( ( dom < PAPI_DOM_MIN ) || ( dom > PAPI_DOM_MAX ) )
4282
4284 if ( internal.domain.ESI == NULL )
4286
4287 cidx = valid_ESI_component( internal.domain.ESI );
4288 if ( cidx < 0 )
4289 papi_return( cidx );
4290
4291 /* Check what the component supports */
4292
4293 if ( dom == PAPI_DOM_ALL )
4294 dom = _papi_hwd[cidx]->cmp_info.available_domains;
4295
4296 if ( dom & ~_papi_hwd[cidx]->cmp_info.available_domains )
4298
4299 if ( !( internal.domain.ESI->state & PAPI_STOPPED ) )
4301
4302 /* Try to change the domain of the eventset in the hardware */
4303 internal.domain.domain = dom;
4304 internal.domain.eventset = ptr->domain.eventset;
4305 /* get the context we should use for this event set */
4306 context = _papi_hwi_get_context( internal.domain.ESI, NULL );
4307 retval = _papi_hwd[cidx]->ctl( context, PAPI_DOMAIN, &internal );
4308 if ( retval < PAPI_OK )
4310
4311 /* Change the domain of the eventset in the library */
4312
4313 internal.domain.ESI->domain.domain = dom;
4314
4315 return ( retval );
4316 }
4317 case PAPI_DEFGRN:
4318 {
4319 int grn = ptr->defgranularity.granularity;
4320 if ( ( grn < PAPI_GRN_MIN ) || ( grn > PAPI_GRN_MAX ) )
4322
4324 if ( cidx < 0 )
4325 papi_return( cidx );
4326
4327 /* Change the component structure. The _papi_hwd_init_control_state function
4328 in the components gets information from the global structure instead of
4329 per-thread information. */
4330
4331 /* Check what the component supports */
4332
4333 if ( grn & ~_papi_hwd[cidx]->cmp_info.available_granularities )
4335
4336 /* Make sure there is only 1 set. */
4337 if ( grn ^ ( 1 << ( ffs( grn ) - 1 ) ) )
4339
4340 _papi_hwd[cidx]->cmp_info.default_granularity = grn;
4341
4342 return ( PAPI_OK );
4343 }
4344 case PAPI_GRANUL:
4345 {
4346 int grn = ptr->granularity.granularity;
4347
4348 if ( ( grn < PAPI_GRN_MIN ) || ( grn > PAPI_GRN_MAX ) )
4350
4351 internal.granularity.ESI =
4353 if ( internal.granularity.ESI == NULL )
4355
4357 if ( cidx < 0 )
4358 papi_return( cidx );
4359
4360 /* Check what the component supports */
4361
4362 if ( grn & ~_papi_hwd[cidx]->cmp_info.available_granularities )
4364
4365 /* Make sure there is only 1 set. */
4366 if ( grn ^ ( 1 << ( ffs( grn ) - 1 ) ) )
4368
4369 internal.granularity.granularity = grn;
4370 internal.granularity.eventset = ptr->granularity.eventset;
4371 retval = _papi_hwd[cidx]->ctl( NULL, PAPI_GRANUL, &internal );
4372 if ( retval < PAPI_OK )
4373 return ( retval );
4374
4375 internal.granularity.ESI->granularity.granularity = grn;
4376 return ( retval );
4377 }
4378 case PAPI_INHERIT:
4379 {
4380 EventSetInfo_t *ESI;
4382 if ( ESI == NULL )
4384
4385 cidx = valid_ESI_component( ESI );
4386 if ( cidx < 0 )
4387 papi_return( cidx );
4388
4389 if ( _papi_hwd[cidx]->cmp_info.inherit == 0 )
4391
4392 if ( ( ESI->state & PAPI_STOPPED ) == 0 )
4394
4395 /* if attached to a cpu, return an error */
4396 if (ESI->state & PAPI_CPU_ATTACHED)
4398
4399 internal.inherit.ESI = ESI;
4400 internal.inherit.inherit = ptr->inherit.inherit;
4401
4402 /* get the context we should use for this event set */
4403 context = _papi_hwi_get_context( internal.inherit.ESI, NULL );
4404 retval = _papi_hwd[cidx]->ctl( context, PAPI_INHERIT, &internal );
4405 if ( retval < PAPI_OK )
4406 return ( retval );
4407
4408 ESI->inherit.inherit = ptr->inherit.inherit;
4409 return ( retval );
4410 }
4411 case PAPI_DATA_ADDRESS:
4412 case PAPI_INSTR_ADDRESS:
4413 {
4414
4415 EventSetInfo_t *ESI;
4416
4418 if ( ESI == NULL )
4420
4421 cidx = valid_ESI_component( ESI );
4422 if ( cidx < 0 )
4423 papi_return( cidx );
4424
4425 internal.address_range.ESI = ESI;
4426
4427 if ( !( internal.address_range.ESI->state & PAPI_STOPPED ) )
4429
4430 /*set domain to be PAPI_DOM_USER */
4432
4433 internal.address_range.start = ptr->addr.start;
4434 internal.address_range.end = ptr->addr.end;
4435 /* get the context we should use for this event set */
4436 context = _papi_hwi_get_context( internal.address_range.ESI, NULL );
4437 retval = _papi_hwd[cidx]->ctl( context, option, &internal );
4438 ptr->addr.start_off = internal.address_range.start_off;
4439 ptr->addr.end_off = internal.address_range.end_off;
4441 }
4443 {
4444 APIDBG("User Events Filename is -%s-\n", ptr->events_file);
4445
4446 // go load the user defined event definitions from the applications event definition file
4447 // do not know how to find a pmu name and type for this operation yet
4448// retval = papi_load_derived_events(pmu_str, pmu_type, cidx, 0);
4449
4450// _papi_user_defined_events_setup(ptr->events_file);
4451 return( PAPI_OK );
4452 }
4453 default:
4455 }
4456}
4457
4467int
4469{
4470 APIDBG( "Entry:\n");
4471 return ( PAPI_num_cmp_hwctrs( 0 ) );
4472}
4473
4523int
4525{
4526 APIDBG( "Entry: cidx: %d\n", cidx);
4527 return ( PAPI_get_cmp_opt( PAPI_MAX_HWCTRS, NULL, cidx ) );
4528}
4529
4586int
4588{
4589 APIDBG( "Entry: EventSet: %d\n", EventSet);
4590 PAPI_option_t popt;
4591 int retval;
4592
4595 if ( retval < 0 )
4596 retval = 0;
4597 return retval;
4598}
4599
4701int
4702PAPI_get_opt( int option, PAPI_option_t * ptr )
4703{
4704 APIDBG( "Entry: option: %d, ptr: %p\n", option, ptr);
4705 EventSetInfo_t *ESI;
4706
4707 if ( ( option != PAPI_DEBUG ) && ( init_level == PAPI_NOT_INITED ) &&
4708 ( option != PAPI_LIB_VERSION ) )
4710
4711 switch ( option ) {
4712 case PAPI_DETACH:
4713 {
4714 if ( ptr == NULL )
4717 if ( ESI == NULL )
4719 ptr->attach.tid = ESI->attach.tid;
4720 return ( ( ESI->state & PAPI_ATTACHED ) == 0 );
4721 }
4722 case PAPI_ATTACH:
4723 {
4724 if ( ptr == NULL )
4727 if ( ESI == NULL )
4729 ptr->attach.tid = ESI->attach.tid;
4730 return ( ( ESI->state & PAPI_ATTACHED ) != 0 );
4731 }
4732 case PAPI_CPU_ATTACH:
4733 {
4734 if ( ptr == NULL )
4737 if ( ESI == NULL )
4739 ptr->cpu.cpu_num = ESI->CpuInfo->cpu_num;
4740 return ( ( ESI->state & PAPI_CPU_ATTACHED ) != 0 );
4741 }
4742 case PAPI_DEF_MPX_NS:
4743 {
4744 /* xxxx for now, assume we only check against cpu component */
4745 if ( ptr == NULL )
4748 return ( PAPI_OK );
4749 }
4750 case PAPI_DEF_ITIMER_NS:
4751 {
4752 /* xxxx for now, assume we only check against cpu component */
4753 if ( ptr == NULL )
4756 return ( PAPI_OK );
4757 }
4758 case PAPI_DEF_ITIMER:
4759 {
4760 /* xxxx for now, assume we only check against cpu component */
4761 if ( ptr == NULL )
4766 ptr->itimer.flags = 0;
4767 return ( PAPI_OK );
4768 }
4769 case PAPI_MULTIPLEX:
4770 {
4771 if ( ptr == NULL )
4774 if ( ESI == NULL )
4776 ptr->multiplex.ns = ESI->multiplex.ns;
4777 ptr->multiplex.flags = ESI->multiplex.flags;
4778 return ( ESI->state & PAPI_MULTIPLEXING ) != 0;
4779 }
4780 case PAPI_PRELOAD:
4781 if ( ptr == NULL )
4784 sizeof ( PAPI_preload_info_t ) );
4785 break;
4786 case PAPI_DEBUG:
4787 if ( ptr == NULL )
4791 break;
4792 case PAPI_CLOCKRATE:
4793 return ( ( int ) _papi_hwi_system_info.hw_info.cpu_max_mhz );
4794 case PAPI_MAX_CPUS:
4796 /* For now, MAX_HWCTRS and MAX CTRS are identical.
4797 At some future point, they may map onto different values.
4798 */
4799 case PAPI_INHERIT:
4800 {
4801 if ( ptr == NULL )
4804 if ( ESI == NULL )
4806 ptr->inherit.inherit = ESI->inherit.inherit;
4807 return ( PAPI_OK );
4808 }
4809 case PAPI_GRANUL:
4810 if ( ptr == NULL )
4813 if ( ESI == NULL )
4816 break;
4817 case PAPI_EXEINFO:
4818 if ( ptr == NULL )
4821 break;
4822 case PAPI_HWINFO:
4823 if ( ptr == NULL )
4826 break;
4827
4828 case PAPI_DOMAIN:
4829 if ( ptr == NULL )
4832 if ( ESI == NULL )
4834 ptr->domain.domain = ESI->domain.domain;
4835 return ( PAPI_OK );
4836 case PAPI_LIB_VERSION:
4837 return ( PAPI_VERSION );
4838/* The following cases all require a component index
4839 and are handled by PAPI_get_cmp_opt() with cidx == 0*/
4840 case PAPI_MAX_HWCTRS:
4841 case PAPI_MAX_MPX_CTRS:
4842 case PAPI_DEFDOM:
4843 case PAPI_DEFGRN:
4844 case PAPI_SHLIBINFO:
4845 case PAPI_COMPONENTINFO:
4846 return ( PAPI_get_cmp_opt( option, ptr, 0 ) );
4847 default:
4849 }
4850 return ( PAPI_OK );
4851}
4852
4894int
4895PAPI_get_cmp_opt( int option, PAPI_option_t * ptr, int cidx )
4896{
4897 APIDBG( "Entry: option: %d, ptr: %p, cidx: %d\n", option, ptr, cidx);
4898
4900 return PAPI_ECMP;
4901 }
4902
4903 switch ( option ) {
4904 /* For now, MAX_HWCTRS and MAX CTRS are identical.
4905 At some future point, they may map onto different values.
4906 */
4907 case PAPI_MAX_HWCTRS:
4908 return ( _papi_hwd[cidx]->cmp_info.num_cntrs );
4909 case PAPI_MAX_MPX_CTRS:
4910 return ( _papi_hwd[cidx]->cmp_info.num_mpx_cntrs );
4911 case PAPI_DEFDOM:
4912 return ( _papi_hwd[cidx]->cmp_info.default_domain );
4913 case PAPI_DEFGRN:
4914 return ( _papi_hwd[cidx]->cmp_info.default_granularity );
4915 case PAPI_SHLIBINFO:
4916 {
4917 int retval;
4918 if ( ptr == NULL )
4923 }
4924 case PAPI_COMPONENTINFO:
4925 if ( ptr == NULL )
4927 ptr->cmp_info = &( _papi_hwd[cidx]->cmp_info );
4928 return PAPI_OK;
4929 default:
4931 }
4932 return PAPI_OK;
4933}
4934
4946int
4948{
4949 APIDBG( "Entry:\n");
4950 return ( papi_num_components );
4951}
4952
4985int
4987{
4988 APIDBG( "Entry: EventSet: %d\n", EventSet);
4989 EventSetInfo_t *ESI;
4990
4992 if ( !ESI )
4994
4995#ifdef DEBUG
4996 /* Not necessary */
4997 if ( ESI->NumberOfEvents == 0 )
4999#endif
5000
5001 return ( ESI->NumberOfEvents );
5002}
5003
5004
5020void
5022{
5023 APIDBG( "Entry:\n");
5024
5025 EventSetInfo_t *ESI;
5026 ThreadInfo_t *master;
5028 int i, j = 0, k, retval;
5029
5030
5031 if ( init_retval == DEADBEEF ) {
5033 return;
5034 }
5035
5036 MPX_shutdown( );
5037
5038 /* Free all EventSets for this thread */
5039
5040 master = _papi_hwi_lookup_thread( 0 );
5041
5042 /* Count number of running EventSets AND */
5043 /* Stop any running EventSets in this thread */
5044
5045#ifdef DEBUG
5046again:
5047#endif
5048 for( i = 0; i < map->totalSlots; i++ ) {
5049 ESI = map->dataSlotArray[i];
5050 if ( ESI ) {
5051 if ( ESI->master == master ) {
5052 if ( ESI->state & PAPI_RUNNING ) {
5053 if((retval = PAPI_stop( i, NULL )) != PAPI_OK) {
5054 APIDBG("Call to PAPI_stop failed: %d\n", retval);
5055 }
5056 }
5058 if (retval!=PAPI_OK) PAPIERROR("Error during cleanup.");
5060 }
5061 else {
5062 if ( ESI->state & PAPI_RUNNING ) {
5063 j++;
5064 }
5065 }
5066 }
5067 }
5068
5069 /* No locking required, we're just waiting for the others
5070 to call shutdown or stop their eventsets. */
5071
5072#ifdef DEBUG
5073 if ( j != 0 ) {
5075 sleep( 1 );
5076 j = 0;
5077 goto again;
5078 }
5079#endif
5080
5081 // if we have some user events defined, release the space they allocated
5082 // give back the strings which were allocated when each event was created
5083 for ( i=0 ; i<user_defined_events_count ; i++) {
5085 papi_free (user_defined_events[i].postfix);
5086 papi_free (user_defined_events[i].long_descr);
5087 papi_free (user_defined_events[i].short_descr);
5089 for ( k=0 ; k<(int)(user_defined_events[i].count) ; k++) {
5091 }
5092 }
5093 // make sure the user events list is empty
5094 memset (user_defined_events, '\0' , sizeof(user_defined_events));
5096
5097 /* Shutdown the entire component */
5098 //_papi_hwi_shutdown_highlevel( );
5101 for( i = 0; i < papi_num_components; i++ ) {
5102 if (!_papi_hwd[i]->cmp_info.disabled) {
5103 _papi_hwd[i]->shutdown_component( );
5104 }
5105 }
5106
5107 /* Now it is safe to call re-init */
5108
5112}
5113
5162char *
5163PAPI_strerror( int errorCode )
5164{
5165 if ( ( errorCode > 0 ) || ( -errorCode > _papi_hwi_num_errors ) )
5166 return ( NULL );
5167
5168 return ( _papi_errlist[-errorCode] );
5169}
5170
5212void
5213PAPI_perror( const char *msg )
5214{
5215 char *foo;
5216
5218 if ( foo == NULL )
5219 return;
5220
5221 if ( msg )
5222 if ( *msg )
5223 fprintf( stderr, "%s: ", msg );
5224
5225 fprintf( stderr, "%s\n", foo );
5226}
5227
5347int
5348PAPI_overflow( int EventSet, int EventCode, int threshold, int flags,
5350{
5351 APIDBG( "Entry: EventSet: %d, EventCode: %#x, threshold: %d, flags: %#x, handler: %p\n", EventSet, EventCode, threshold, flags, handler);
5352 int retval, cidx, index, i;
5353 EventSetInfo_t *ESI;
5354
5356 if ( ESI == NULL ) {
5357 OVFDBG("No EventSet\n");
5359 }
5360
5361 cidx = valid_ESI_component( ESI );
5362 if ( cidx < 0 ) {
5363 OVFDBG("Component Error\n");
5364 papi_return( cidx );
5365 }
5366
5367 if ( ( ESI->state & PAPI_STOPPED ) != PAPI_STOPPED ) {
5368 OVFDBG("Already running\n");
5370 }
5371
5372 if ( ESI->state & PAPI_ATTACHED ) {
5373 OVFDBG("Attached\n");
5375 }
5376
5377 if ( ESI->state & PAPI_CPU_ATTACHED ) {
5378 OVFDBG("CPU attached\n");
5380 }
5381
5382 if ( ( index = _papi_hwi_lookup_EventCodeIndex( ESI,
5383 ( unsigned int ) EventCode ) ) < 0 ) {
5385 }
5386
5387 if ( threshold < 0 ) {
5388 OVFDBG("Threshold below zero\n");
5390 }
5391
5392 /* We do not support derived events in overflow */
5393 /* Unless it's DERIVED_CMPD in which no calculations are done */
5394
5395 if ( !( flags & PAPI_OVERFLOW_FORCE_SW ) && threshold != 0 &&
5396 ( ESI->EventInfoArray[index].derived ) &&
5397 ( ESI->EventInfoArray[index].derived != DERIVED_CMPD ) ) {
5398 OVFDBG("Derived event in overflow\n");
5400 }
5401
5402 /* the first time to call PAPI_overflow function */
5403
5404 if ( !( ESI->state & PAPI_OVERFLOWING ) ) {
5405 if ( handler == NULL ) {
5406 OVFDBG("NULL handler\n");
5408 }
5409 if ( threshold == 0 ) {
5410 OVFDBG("Zero threshold\n");
5412 }
5413 }
5414 if ( threshold > 0 &&
5415 ESI->overflow.event_counter >= _papi_hwd[cidx]->cmp_info.num_cntrs )
5417
5418 if ( threshold == 0 ) {
5419 for ( i = 0; i < ESI->overflow.event_counter; i++ ) {
5420 if ( ESI->overflow.EventCode[i] == EventCode )
5421 break;
5422 }
5423 /* EventCode not found */
5424 if ( i == ESI->overflow.event_counter )
5426 /* compact these arrays */
5427 while ( i < ESI->overflow.event_counter - 1 ) {
5428 ESI->overflow.deadline[i] = ESI->overflow.deadline[i + 1];
5429 ESI->overflow.threshold[i] = ESI->overflow.threshold[i + 1];
5430 ESI->overflow.EventIndex[i] = ESI->overflow.EventIndex[i + 1];
5431 ESI->overflow.EventCode[i] = ESI->overflow.EventCode[i + 1];
5432 i++;
5433 }
5434 ESI->overflow.deadline[i] = 0;
5435 ESI->overflow.threshold[i] = 0;
5436 ESI->overflow.EventIndex[i] = 0;
5437 ESI->overflow.EventCode[i] = 0;
5438 ESI->overflow.event_counter--;
5439 } else {
5440 if ( ESI->overflow.event_counter > 0 ) {
5441 if ( ( flags & PAPI_OVERFLOW_FORCE_SW ) &&
5444 if ( !( flags & PAPI_OVERFLOW_FORCE_SW ) &&
5447 }
5448 for ( i = 0; i < ESI->overflow.event_counter; i++ ) {
5449 if ( ESI->overflow.EventCode[i] == EventCode )
5450 break;
5451 }
5452 /* A new entry */
5453 if ( i == ESI->overflow.event_counter ) {
5454 ESI->overflow.EventCode[i] = EventCode;
5455 ESI->overflow.event_counter++;
5456 }
5457 /* New or existing entry */
5458 ESI->overflow.deadline[i] = threshold;
5459 ESI->overflow.threshold[i] = threshold;
5460 ESI->overflow.EventIndex[i] = index;
5461 ESI->overflow.flags = flags;
5462
5463 }
5464
5465 /* If overflowing is already active, we should check to
5466 make sure that we don't specify a different handler
5467 or different flags here. You can't mix them. */
5468
5469 ESI->overflow.handler = handler;
5470
5471 /* Set up the option structure for the low level.
5472 If we have hardware interrupts and we are not using
5473 forced software emulated interrupts */
5474
5475 if ( _papi_hwd[cidx]->cmp_info.hardware_intr &&
5476 !( ESI->overflow.flags & PAPI_OVERFLOW_FORCE_SW ) ) {
5477 retval = _papi_hwd[cidx]->set_overflow( ESI, index, threshold );
5478 if ( retval == PAPI_OK )
5480 else {
5481 papi_return( retval ); /* We should undo stuff here */
5482 }
5483 } else {
5484 /* Make sure hardware overflow is not set */
5486 }
5487
5488 APIDBG( "Overflow using: %s\n",
5489 ( ESI->overflow.
5490 flags & PAPI_OVERFLOW_HARDWARE ? "[Hardware]" : ESI->overflow.
5491 flags & PAPI_OVERFLOW_FORCE_SW ? "[Forced Software]" :
5492 "[Software]" ) );
5493
5494 /* Toggle the overflow flags and ESI state */
5495
5496 if ( ESI->overflow.event_counter >= 1 )
5497 ESI->state |= PAPI_OVERFLOWING;
5498 else {
5499 ESI->state ^= PAPI_OVERFLOWING;
5500 ESI->overflow.flags = 0;
5501 ESI->overflow.handler = NULL;
5502 }
5503
5504 return PAPI_OK;
5505}
5506
5603int
5604PAPI_sprofil( PAPI_sprofil_t *prof, int profcnt, int EventSet,
5605 int EventCode, int threshold, int flags )
5606{
5607 APIDBG( "Entry: prof: %p, profcnt: %d, EventSet: %d, EventCode: %#x, threshold: %d, flags: %#x\n", prof, profcnt, EventSet, EventCode, threshold, flags);
5608 EventSetInfo_t *ESI;
5609 int retval, index, i, buckets;
5610 int forceSW = 0;
5611 int cidx;
5612
5613 /* Check to make sure EventSet exists */
5615 if ( ESI == NULL ) {
5617 }
5618
5619 /* Check to make sure EventSet is stopped */
5620 if ( ( ESI->state & PAPI_STOPPED ) != PAPI_STOPPED ) {
5622 }
5623
5624 /* We cannot profile if attached */
5625 if ( ESI->state & PAPI_ATTACHED ) {
5627 }
5628
5629 /* We cannot profile if cpu attached */
5630 if ( ESI->state & PAPI_CPU_ATTACHED ) {
5632 }
5633
5634 /* Get component for EventSet */
5635 cidx = valid_ESI_component( ESI );
5636 if ( cidx < 0 ) {
5637 papi_return( cidx );
5638 }
5639
5640 /* Get index of the Event we want to profile */
5641 if ( ( index = _papi_hwi_lookup_EventCodeIndex( ESI,
5642 (unsigned int) EventCode ) ) < 0 ) {
5644 }
5645
5646 /* We do not support derived events in overflow */
5647 /* Unless it's DERIVED_CMPD in which no calculations are done */
5648 if ( ( ESI->EventInfoArray[index].derived ) &&
5649 ( ESI->EventInfoArray[index].derived != DERIVED_CMPD ) &&
5650 !( flags & PAPI_PROFIL_FORCE_SW ) ) {
5652 }
5653
5654 /* If no prof structures, then make sure count is 0 */
5655 if ( prof == NULL ) {
5656 profcnt = 0;
5657 }
5658
5659 /* check all profile regions for valid scale factors of:
5660 2 (131072/65536),
5661 1 (65536/65536),
5662 or < 1 (65535 -> 2) as defined in unix profil()
5663 2/65536 is reserved for single bucket profiling
5664 {0,1}/65536 are traditionally used to terminate profiling
5665 but are unused here since PAPI uses threshold instead
5666 */
5667 for( i = 0; i < profcnt; i++ ) {
5668 if ( !( ( prof[i].pr_scale == 131072 ) ||
5669 ( ( prof[i].pr_scale <= 65536 && prof[i].pr_scale > 1 ) ) ) ) {
5670 APIDBG( "Improper scale factor: %d\n", prof[i].pr_scale );
5672 }
5673 }
5674
5675 /* Make sure threshold is valid */
5676 if ( threshold < 0 ) {
5678 }
5679
5680 /* the first time to call PAPI_sprofil */
5681 if ( !( ESI->state & PAPI_PROFILING ) ) {
5682 if ( threshold == 0 ) {
5684 }
5685 }
5686
5687 /* ??? */
5688 if ( (threshold > 0) &&
5689 (ESI->profile.event_counter >= _papi_hwd[cidx]->cmp_info.num_cntrs) ) {
5691 }
5692
5693 if ( threshold == 0 ) {
5694 for( i = 0; i < ESI->profile.event_counter; i++ ) {
5695 if ( ESI->profile.EventCode[i] == EventCode ) {
5696 break;
5697 }
5698 }
5699
5700 /* EventCode not found */
5701 if ( i == ESI->profile.event_counter ) {
5703 }
5704
5705 /* compact these arrays */
5706 while ( i < ESI->profile.event_counter - 1 ) {
5707 ESI->profile.prof[i] = ESI->profile.prof[i + 1];
5708 ESI->profile.count[i] = ESI->profile.count[i + 1];
5709 ESI->profile.threshold[i] = ESI->profile.threshold[i + 1];
5710 ESI->profile.EventIndex[i] = ESI->profile.EventIndex[i + 1];
5711 ESI->profile.EventCode[i] = ESI->profile.EventCode[i + 1];
5712 i++;
5713 }
5714 ESI->profile.prof[i] = NULL;
5715 ESI->profile.count[i] = 0;
5716 ESI->profile.threshold[i] = 0;
5717 ESI->profile.EventIndex[i] = 0;
5718 ESI->profile.EventCode[i] = 0;
5719 ESI->profile.event_counter--;
5720 } else {
5721 if ( ESI->profile.event_counter > 0 ) {
5722 if ( ( flags & PAPI_PROFIL_FORCE_SW ) &&
5723 !( ESI->profile.flags & PAPI_PROFIL_FORCE_SW ) ) {
5725 }
5726 if ( !( flags & PAPI_PROFIL_FORCE_SW ) &&
5727 ( ESI->profile.flags & PAPI_PROFIL_FORCE_SW ) ) {
5729 }
5730 }
5731
5732 for( i = 0; i < ESI->profile.event_counter; i++ ) {
5733 if ( ESI->profile.EventCode[i] == EventCode ) {
5734 break;
5735 }
5736 }
5737
5738 if ( i == ESI->profile.event_counter ) {
5739 i = ESI->profile.event_counter;
5740 ESI->profile.event_counter++;
5741 ESI->profile.EventCode[i] = EventCode;
5742 }
5743 ESI->profile.prof[i] = prof;
5744 ESI->profile.count[i] = profcnt;
5745 ESI->profile.threshold[i] = threshold;
5746 ESI->profile.EventIndex[i] = index;
5747 }
5748
5749 APIDBG( "Profile event counter is %d\n", ESI->profile.event_counter );
5750
5751 /* Clear out old flags */
5752 if ( threshold == 0 ) {
5753 flags |= ESI->profile.flags;
5754 }
5755
5756 /* make sure no invalid flags are set */
5757 if ( flags &
5762 }
5763
5764 /* if we have kernel-based profiling, then we're just asking for
5765 signals on interrupt. */
5766 /* if we don't have kernel-based profiling, then we're asking for
5767 emulated PMU interrupt */
5768 if ( ( flags & PAPI_PROFIL_FORCE_SW ) &&
5769 ( _papi_hwd[cidx]->cmp_info.kernel_profile == 0 ) ) {
5770 forceSW = PAPI_OVERFLOW_FORCE_SW;
5771 }
5772
5773 /* make sure one and only one bucket size is set */
5774 buckets = flags & PAPI_PROFIL_BUCKETS;
5775 if ( !buckets ) {
5776 flags |= PAPI_PROFIL_BUCKET_16; /* default to 16 bit if nothing set */
5777 }
5778 else {
5779 /* return error if more than one set */
5780 if ( !( ( buckets == PAPI_PROFIL_BUCKET_16 ) ||
5781 ( buckets == PAPI_PROFIL_BUCKET_32 ) ||
5782 ( buckets == PAPI_PROFIL_BUCKET_64 ) ) ) {
5784 }
5785 }
5786
5787 /* Set up the option structure for the low level */
5788 ESI->profile.flags = flags;
5789
5790 if ( _papi_hwd[cidx]->cmp_info.kernel_profile &&
5791 !( ESI->profile.flags & PAPI_PROFIL_FORCE_SW ) ) {
5792 retval = _papi_hwd[cidx]->set_profile( ESI, index, threshold );
5793 if ( ( retval == PAPI_OK ) && ( threshold > 0 ) ) {
5794 /* We need overflowing because we use the overflow dispatch handler */
5795 ESI->state |= PAPI_OVERFLOWING;
5797 }
5798 } else {
5799 retval = PAPI_overflow( EventSet, EventCode, threshold, forceSW,
5801 }
5802
5803 if ( retval < PAPI_OK ) {
5804 papi_return( retval ); /* We should undo stuff here */
5805 }
5806
5807 /* Toggle the profiling flags and ESI state */
5808
5809 if ( ESI->profile.event_counter >= 1 ) {
5810 ESI->state |= PAPI_PROFILING;
5811 }
5812 else {
5813 ESI->state ^= PAPI_PROFILING;
5814 ESI->profile.flags = 0;
5815 }
5816
5817 return PAPI_OK;
5818}
5819
5997int
5998PAPI_profil( void *buf, unsigned bufsiz, vptr_t offset,
5999 unsigned scale, int EventSet, int EventCode, int threshold,
6000 int flags )
6001{
6002 APIDBG( "Entry: buf: %p, bufsiz: %d, offset: %p, scale: %u, EventSet: %d, EventCode: %#x, threshold: %d, flags: %#x\n", buf, bufsiz, offset, scale, EventSet, EventCode, threshold, flags);
6003 EventSetInfo_t *ESI;
6004 int i;
6005 int retval;
6006
6008 if ( ESI == NULL )
6010
6011 /* scale factors are checked for validity in PAPI_sprofil */
6012
6013 if ( threshold > 0 ) {
6014 PAPI_sprofil_t *prof;
6015
6016 for ( i = 0; i < ESI->profile.event_counter; i++ ) {
6017 if ( ESI->profile.EventCode[i] == EventCode )
6018 break;
6019 }
6020
6021 if ( i == ESI->profile.event_counter ) {
6022 prof =
6023 ( PAPI_sprofil_t * ) papi_malloc( sizeof ( PAPI_sprofil_t ) );
6024 memset( prof, 0x0, sizeof ( PAPI_sprofil_t ) );
6025 prof->pr_base = buf;
6026 prof->pr_size = bufsiz;
6027 prof->pr_off = offset;
6028 prof->pr_scale = scale;
6029
6030 retval =
6031 PAPI_sprofil( prof, 1, EventSet, EventCode, threshold, flags );
6032
6033 if ( retval != PAPI_OK )
6034 papi_free( prof );
6035 } else {
6036 prof = ESI->profile.prof[i];
6037 prof->pr_base = buf;
6038 prof->pr_size = bufsiz;
6039 prof->pr_off = offset;
6040 prof->pr_scale = scale;
6041 retval =
6042 PAPI_sprofil( prof, 1, EventSet, EventCode, threshold, flags );
6043 }
6045 }
6046
6047 for ( i = 0; i < ESI->profile.event_counter; i++ ) {
6048 if ( ESI->profile.EventCode[i] == EventCode )
6049 break;
6050 }
6051 /* EventCode not found */
6052 if ( i == ESI->profile.event_counter )
6054
6055 papi_free( ESI->profile.prof[i] );
6056 ESI->profile.prof[i] = NULL;
6057
6058 papi_return( PAPI_sprofil( NULL, 0, EventSet, EventCode, 0, flags ) );
6059}
6060
6061/* This function sets the low level default granularity
6062 for all newly manufactured eventsets. The first function
6063 preserves API compatibility and assumes component 0;
6064 The second function takes a component argument. */
6065
6116int
6117PAPI_set_granularity( int granularity )
6118{
6119 return ( PAPI_set_cmp_granularity( granularity, 0 ) );
6120}
6121
6181int
6182PAPI_set_cmp_granularity( int granularity, int cidx )
6183{
6184 PAPI_option_t ptr;
6185
6186 memset( &ptr, 0, sizeof ( ptr ) );
6188 ptr.defgranularity.granularity = granularity;
6190}
6191
6192/* This function sets the low level default counting domain
6193 for all newly manufactured eventsets. The first function
6194 preserves API compatibility and assumes component 0;
6195 The second function takes a component argument. */
6196
6247int
6248PAPI_set_domain( int domain )
6249{
6250 return ( PAPI_set_cmp_domain( domain, 0 ) );
6251}
6252
6317int
6318PAPI_set_cmp_domain( int domain, int cidx )
6319{
6320 PAPI_option_t ptr;
6321
6322 memset( &ptr, 0, sizeof ( ptr ) );
6323 ptr.defdomain.def_cidx = cidx;
6324 ptr.defdomain.domain = domain;
6326}
6327
6402int
6403PAPI_add_events( int EventSet, int *Events, int number )
6404{
6405 APIDBG( "Entry: EventSet: %d, Events: %p, number: %d\n", EventSet, Events, number);
6406 int i, retval;
6407
6408 if ( ( Events == NULL ) || ( number <= 0 ) )
6410
6411 for ( i = 0; i < number; i++ ) {
6412 retval = PAPI_add_event( EventSet, Events[i] );
6413 if ( retval != PAPI_OK ) {
6414 if ( i == 0 )
6416 else
6417 return ( i );
6418 }
6419 }
6420 return ( PAPI_OK );
6421}
6422
6490int
6491PAPI_remove_events( int EventSet, int *Events, int number )
6492{
6493 APIDBG( "Entry: EventSet: %d, Events: %p, number: %d\n", EventSet, Events, number);
6494 int i, retval;
6495
6496 if ( ( Events == NULL ) || ( number <= 0 ) )
6498
6499 for ( i = 0; i < number; i++ ) {
6500 retval = PAPI_remove_event( EventSet, Events[i] );
6501 if ( retval != PAPI_OK ) {
6502 if ( i == 0 )
6504 else
6505 return ( i );
6506 }
6507 }
6508 return ( PAPI_OK );
6509}
6510
6560int
6561PAPI_list_events( int EventSet, int *Events, int *number )
6562{
6563 APIDBG( "Entry: EventSet: %d, Events: %p, number: %p\n", EventSet, Events, number);
6564 EventSetInfo_t *ESI;
6565 int i, j;
6566
6567 if ( *number < 0 )
6569
6570 if ( ( Events == NULL ) && ( *number > 0 ) )
6572
6574 if ( !ESI )
6576
6577 if ( ( Events == NULL ) || ( *number == 0 ) ) {
6578 *number = ESI->NumberOfEvents;
6580 }
6581
6582 for ( i = 0, j = 0; j < ESI->NumberOfEvents; i++ ) {
6583 if ( ( int ) ESI->EventInfoArray[i].event_code != PAPI_NULL ) {
6584 Events[j] = ( int ) ESI->EventInfoArray[i].event_code;
6585 j++;
6586 if ( j == *number )
6587 break;
6588 }
6589 }
6590
6591 *number = j;
6592
6593 return ( PAPI_OK );
6594}
6595
6596/* xxx This is OS dependent, not component dependent, right? */
6622int
6624{
6625 if ( dest == NULL )
6626 return PAPI_EINVAL;
6627
6628 memset( ( void * ) dest, 0x0, sizeof ( PAPI_dmem_info_t ) );
6629 return ( _papi_os_vector.get_dmem_info( dest ) );
6630}
6631
6632
6673const PAPI_exe_info_t *
6675{
6676 PAPI_option_t ptr;
6677 int retval;
6678
6679 memset( &ptr, 0, sizeof ( ptr ) );
6680 retval = PAPI_get_opt( PAPI_EXEINFO, &ptr );
6681 if ( retval == PAPI_OK )
6682 return ( ptr.exe_info );
6683 else
6684 return ( NULL );
6685}
6686
6703const PAPI_shlib_info_t *
6705{
6706 PAPI_option_t ptr;
6707 int retval;
6708
6709 memset( &ptr, 0, sizeof ( ptr ) );
6711 if ( retval == PAPI_OK )
6712 return ( ptr.shlib_info );
6713 else
6714 return ( NULL );
6715}
6744const PAPI_hw_info_t *
6746{
6747 PAPI_option_t ptr;
6748 int retval;
6749
6750 memset( &ptr, 0, sizeof ( ptr ) );
6751 retval = PAPI_get_opt( PAPI_HWINFO, &ptr );
6752 if ( retval == PAPI_OK )
6753 return ( ptr.hw_info );
6754 else
6755 return ( NULL );
6756}
6757
6758
6759/* The next 4 timing functions always use component 0 */
6760
6776long long
6778{
6779 return ( _papi_os_vector.get_real_cycles( ) );
6780}
6781
6795/* FIXME */
6796long long
6798{
6799 return ( ( _papi_os_vector.get_real_nsec( )));
6800
6801}
6802
6823long long
6825{
6826 return ( _papi_os_vector.get_real_usec( ) );
6827}
6828
6859long long
6861{
6862
6863 return ( ( long long ) _papi_os_vector.get_virt_cycles( ) );
6864}
6865
6889long long
6891{
6892
6893 return ( ( _papi_os_vector.get_virt_nsec()));
6894
6895}
6896
6931long long
6933{
6934
6935 return ( ( long long ) _papi_os_vector.get_virt_usec() );
6936}
6937
6960int
6961PAPI_lock( int lck )
6962{
6963 if ( ( lck < 0 ) || ( lck >= PAPI_MAX_LOCK ) )
6965
6966 papi_return( _papi_hwi_lock( lck ) );
6967}
6968
6980int
6981PAPI_unlock( int lck )
6982{
6983 if ( ( lck < 0 ) || ( lck >= PAPI_MAX_LOCK ) )
6985
6986 papi_return( _papi_hwi_unlock( lck ) );
6987}
6988
7022int
7024{
7025 return ( init_level );
7026}
7027
7028/* This function maps the overflow_vector to event indexes in the event
7029 set, so that user can know which PAPI event overflowed.
7030 int *array---- an array of event indexes in eventset; the first index
7031 maps to the highest set bit in overflow_vector
7032 int *number--- this is an input/output parameter, user should put the
7033 size of the array into this parameter, after the function
7034 is executed, the number of indexes in *array is written
7035 to this parameter
7036*/
7037
7076int
7077PAPI_get_overflow_event_index( int EventSet, long long overflow_vector,
7078 int *array, int *number )
7079{
7080 APIDBG( "Entry: EventSet: %d, overflow_vector: %lld, array: %p, number: %p\n", EventSet, overflow_vector, array, number);
7081 EventSetInfo_t *ESI;
7082 int set_bit, j, pos;
7083 int count = 0, k;
7084
7085 if ( overflow_vector == ( long long ) 0 )
7087
7088 if ( ( array == NULL ) || ( number == NULL ) )
7090
7091 if ( *number < 1 )
7093
7095 if ( ESI == NULL )
7097
7098 /* in case the eventset is empty */
7099 if ( ESI->NumberOfEvents == 0 )
7101
7102 while ( ( set_bit = ffsll( overflow_vector ) ) ) {
7103 set_bit -= 1;
7104 overflow_vector ^= ( long long ) 1 << set_bit;
7105 for ( j = 0; j < ESI->NumberOfEvents; j++ ) {
7106 for ( k = 0, pos = 0; k < PAPI_EVENTS_IN_DERIVED_EVENT && pos >= 0; k++ ) {
7107 pos = ESI->EventInfoArray[j].pos[k];
7108 if ( ( set_bit == pos ) &&
7109 ( ( ESI->EventInfoArray[j].derived == NOT_DERIVED ) ||
7110 ( ESI->EventInfoArray[j].derived == DERIVED_CMPD ) ) ) {
7111 array[count++] = j;
7112 if ( count == *number )
7113 return PAPI_OK;
7114
7115 break;
7116 }
7117 }
7118 }
7119 }
7120 *number = count;
7121 return PAPI_OK;
7122}
7123
7124
7142int
7144{
7145 APIDBG( "Entry: EventCode: %#x\n", EventCode);
7146 return _papi_hwi_component_index( EventCode);
7147}
7148
7171{
7172 APIDBG( "Entry: name: %s\n", name);
7173 int cidx;
7174
7175 const PAPI_component_info_t *cinfo;
7176
7178
7180 if (cinfo==NULL) return PAPI_ENOCMP;
7181
7182 if (!strcmp(name,cinfo->name)) {
7183 return cidx;
7184 }
7185 }
7186
7187 return PAPI_ENOCMP;
7188}
7189
7190
7225int
7227{
7228 APIDBG( "Entry: cidx: %d\n", cidx);
7229
7230 const PAPI_component_info_t *cinfo;
7231
7232 /* Can only run before PAPI_library_init() is called */
7233 if (init_level != PAPI_NOT_INITED) {
7234 return PAPI_ENOINIT;
7235 }
7236
7238 if (cinfo==NULL) return PAPI_ENOCMP;
7239
7240 ((PAPI_component_info_t *)cinfo)->disabled=1;
7241 strcpy(((PAPI_component_info_t *)cinfo)->disabled_reason,
7242 "Disabled by PAPI_disable_component()");
7243
7244 return PAPI_OK;
7245
7246}
7247
7276int
7278{
7279 APIDBG( "Entry: name: %s\n", name);
7280 int cidx;
7281
7282 /* I can only be called before init time */
7284 return PAPI_ENOINIT;
7285 }
7286
7288 if (cidx>=0) {
7290 }
7291
7292 return PAPI_ENOCMP;
7293}
7294
7330int
7331PAPI_enum_dev_type(int enum_modifier, void **handle)
7332{
7333 return _papi_hwi_enum_dev_type(enum_modifier, handle);
7334}
7335
7389int
7391{
7392 return _papi_hwi_get_dev_type_attr(handle, attr, val);
7393}
7394
7503int
7504PAPI_get_dev_attr(void *handle, int id, PAPI_dev_attr_e attr, void *val)
7505{
7506 return _papi_hwi_get_dev_attr(handle, id, attr, val);
7507}
static papi_handle_t handle
Definition: Gamum.c:21
double tmp
int i
int _papi_hwi_init_os(void)
Definition: aix.c:1213
PAPI_os_info_t _papi_os_info
Definition: aix.c:1210
papi_os_vector_t _papi_os_vector
Definition: aix.c:1288
static long count
Accumulate and reset counters in an EventSet.
add PAPI preset or native hardware event to an event set
add multiple PAPI presets or native hardware events to an event set
add PAPI preset or native hardware event by name to an EventSet
Assign a component index to an existing but empty EventSet.
Attach PAPI event set to the specified thread id.
Empty and destroy an EventSet.
Create a new empty PAPI EventSet.
Empty and destroy an EventSet.
Detach PAPI event set from previously specified thread id and restore to executing thread.
disables the named component
disables the specified component
Enumerate PAPI preset or native events for a given component.
returns handle of next device type
Enumerate PAPI preset or native events.
Simplified call to get arbitrary events per cycle, real and processor time.
Convert a numeric hardware event code to a name.
Convert a name to a numeric hardware event code.
Simplified call to get Mflips/s (floating point instruction rate), real and processor time.
Simplified call to get Mflops/s (floating point operation rate), real and processor time.
Get component specific PAPI options.
returns the component index for the named component
get information about a specific software component
returns device attributes
returns device type attributes
Get information about the dynamic memory usage of the current program.
return component an event belongs to
Get the event's name and description info.
return index for component an eventset is assigned to
Get the multiplexing status of specified event set.
Get PAPI library or event set options.
converts an overflow vector into an array of indexes to overflowing events
Retrieve a pointer to a thread specific data structure.
Stop a running high-level event set.
Simplified call to get instructions per cycle, real and processor time.
initialize the PAPI library.
list the events in an event set
List the registered thread ids.
Lock one of two mutex variables defined in papi.h.
Return the number of hardware counters for the specified component.
Return the number of events in an event set.
Set up an event set to begin registering overflows.
Produces a string on standard error, describing the last library error.
Generate a histogram of hardware counter overflows vs. PC addresses.
Query if PAPI event exists.
Query if a named PAPI event exists.
Read hardware counters with a timestamp.
Read hardware counters from an event set.
removes a hardware event from a PAPI event set.
Remove an array of hardware event codes from a PAPI event set.
removes a named hardware event from a PAPI event set.
Reset the hardware event counts in an event set.
Set the default counting domain for new event sets bound to the specified component.
Set the default counting granularity for eventsets bound to the specified component.
Set the current debug level for error output from PAPI.
Set the default counting domain for new event sets bound to the cpu component.
Set the default counting granularity for eventsets bound to the cpu component.
Convert a standard event set to a multiplexed event set.
Set PAPI library or event set options.
Store a pointer to a thread specific data structure.
Generate PC histogram data from multiple code regions where hardware counter overflow occurs.
Start counting hardware events in an event set.
Return the counting state of an EventSet.
Stop counting hardware events in an event set.
Returns a string describing the PAPI error code.
Initialize thread support in the PAPI library.
Unlock one of the mutex variables defined in papi.h.
Write counter values into counters.
struct papi_vectors * _papi_hwd[]
int _papi_hwi_lookup_or_create_cpu(CpuInfo_t **here, unsigned int cpu_num)
Definition: cpus.c:59
volatile int buf[CACHE_FLUSH_BUFFER_SIZE_INTS]
Definition: do_loops.c:12
char * evt_name(evstock *stock, int index)
Definition: eventstock.c:193
int _papi_hwi_stop_timer(int timer, int signal)
Definition: extras.c:463
int _papi_hwi_start_signal(int signal, int need_context, int cidx)
Definition: extras.c:403
int _papi_hwi_stop_signal(int signal)
Definition: extras.c:443
int _papi_hwi_start_timer(int timer, int signal, int ns)
Definition: extras.c:368
#define PAPI_CPU_ATTACH
Definition: f90papi.h:19
#define PAPI_MAX_MPX_CTRS
Definition: f90papi.h:172
#define PAPI_DOM_USER
Definition: f90papi.h:174
#define PAPI_VER_CURRENT
Definition: f90papi.h:54
#define PAPI_VERSION
Definition: f90papi.h:193
#define PAPI_INSTR_ADDRESS
Definition: f90papi.h:209
#define PAPI_PROFIL_BUCKET_32
Definition: f90papi.h:248
#define PAPI_OK
Definition: f90papi.h:73
#define PAPI_GRN_MIN
Definition: f90papi.h:111
#define PAPI_LIB_VERSION
Definition: f90papi.h:67
#define PAPI_NOT_INITED
Definition: f90papi.h:231
#define PAPI_CLOCKRATE
Definition: f90papi.h:110
#define PAPI_LOW_LEVEL_INITED
Definition: f90papi.h:269
#define PAPI_ENUM_FIRST
Definition: f90papi.h:85
#define PAPI_REF_CYC
Definition: f90papi.h:324
#define PAPI_NULL
Definition: f90papi.h:78
#define PAPI_QUIET
Definition: f90papi.h:132
#define PAPI_PROFIL_WEIGHTED
Definition: f90papi.h:167
#define PAPI_DP_OPS
Definition: f90papi.h:296
#define PAPI_DEBUG
Definition: f90papi.h:51
#define PAPI_PROFILING
Definition: f90papi.h:150
#define PAPI_THREAD_LEVEL_INITED
Definition: f90papi.h:48
#define PAPI_PROFIL_POSIX
Definition: f90papi.h:44
#define PAPI_DEFGRN
Definition: f90papi.h:26
#define PAPI_PROFIL_BUCKET_16
Definition: f90papi.h:144
#define PAPI_VERB_ECONT
Definition: f90papi.h:164
#define PAPI_GRANUL
Definition: f90papi.h:179
#define PAPI_PROFIL_INST_EAR
Definition: f90papi.h:206
#define PAPI_TOT_CYC
Definition: f90papi.h:308
#define PAPI_ATTACHED
Definition: f90papi.h:185
#define PAPI_GRN_MAX
Definition: f90papi.h:238
#define PAPI_ECNFLCT
Definition: f90papi.h:234
#define PAPI_DETACH
Definition: f90papi.h:64
#define PAPI_ENOEVNT
Definition: f90papi.h:139
#define PAPI_EDELAY_INIT
Definition: f90papi.h:271
#define PAPI_ENOEVST
Definition: f90papi.h:95
#define PAPI_USER_EVENTS_FILE
Definition: f90papi.h:58
#define PAPI_OVERFLOW_FORCE_SW
Definition: f90papi.h:131
#define PAPI_ATTACH
Definition: f90papi.h:70
#define PAPI_EINVAL
Definition: f90papi.h:115
#define PAPI_ENOSUPP
Definition: f90papi.h:244
#define PAPI_TLS_NUM
Definition: f90papi.h:190
#define PAPI_FP_INS
Definition: f90papi.h:366
#define PAPI_DOM_MAX
Definition: f90papi.h:196
#define PAPI_EINVAL_DOM
Definition: f90papi.h:175
#define PAPI_MAX_STR_LEN
Definition: f90papi.h:77
#define PAPI_MULTIPLEXING
Definition: f90papi.h:148
#define PAPI_VEC_SP
Definition: f90papi.h:354
#define PAPI_RUNNING
Definition: f90papi.h:165
#define PAPI_EMISC
Definition: f90papi.h:122
#define PAPI_DOMAIN
Definition: f90papi.h:159
#define PAPI_DEF_MPX_NS
Definition: f90papi.h:235
#define PAPI_CPU_ATTACHED
Definition: f90papi.h:96
#define PAPI_INHERIT
Definition: f90papi.h:76
#define PAPI_SHLIBINFO
Definition: f90papi.h:204
#define PAPI_ENOCMP
Definition: f90papi.h:79
#define PAPI_FP_OPS
Definition: f90papi.h:319
#define PAPI_TLS_ALL_THREADS
Definition: f90papi.h:173
#define PAPI_VEC_DP
Definition: f90papi.h:355
#define PAPI_MULTIPLEX_FORCE_SW
Definition: f90papi.h:62
#define PAPI_ECMP
Definition: f90papi.h:214
#define PAPI_EISRUN
Definition: f90papi.h:277
#define PAPI_DATA_ADDRESS
Definition: f90papi.h:89
#define PAPI_PROFIL_BUCKETS
Definition: f90papi.h:137
#define PAPI_MAX_HWCTRS
Definition: f90papi.h:270
#define PAPI_DOM_MIN
Definition: f90papi.h:88
#define PAPI_TOT_INS
Definition: f90papi.h:317
#define PAPI_OVERFLOWING
Definition: f90papi.h:240
#define PAPI_OVERFLOW_HARDWARE
Definition: f90papi.h:157
#define PAPI_ENOMEM
Definition: f90papi.h:16
#define PAPI_ENOINIT
Definition: f90papi.h:160
#define PAPI_PRELOAD
Definition: f90papi.h:37
#define PAPI_MULTIPLEX_DEFAULT
Definition: f90papi.h:152
#define PAPI_PROFIL_FORCE_SW
Definition: f90papi.h:257
#define PAPI_ENOTPRESET
Definition: f90papi.h:178
#define PAPI_HWINFO
Definition: f90papi.h:27
#define PAPI_NUM_TLS
Definition: f90papi.h:22
#define PAPI_PROFIL_BUCKET_64
Definition: f90papi.h:198
#define PAPI_MAX_CPUS
Definition: f90papi.h:119
#define PAPI_DEFDOM
Definition: f90papi.h:188
#define PAPI_COMPONENTINFO
Definition: f90papi.h:75
#define PAPI_EXEINFO
Definition: f90papi.h:36
#define PAPI_STOPPED
Definition: f90papi.h:158
#define PAPI_SP_OPS
Definition: f90papi.h:290
#define PAPI_VERB_ESTOP
Definition: f90papi.h:200
#define PAPI_MULTIPLEX
Definition: f90papi.h:223
#define PAPI_PROFIL_COMPRESS
Definition: f90papi.h:53
#define PAPI_ENOTRUN
Definition: f90papi.h:146
#define PAPI_HUGE_STR_LEN
Definition: f90papi.h:120
#define PAPI_PROFIL_RANDOM
Definition: f90papi.h:143
#define PAPI_PROFIL_DATA_EAR
Definition: f90papi.h:127
#define PAPI_DOM_ALL
Definition: f90papi.h:261
long long PAPI_get_virt_cyc(void)
Definition: papi.c:6860
long long PAPI_get_real_cyc(void)
Definition: papi.c:6777
int PAPI_register_thread(void)
Definition: papi.c:750
int PAPI_num_components(void)
Definition: papi.c:4947
long long PAPI_get_virt_nsec(void)
Definition: papi.c:6890
int PAPI_is_initialized(void)
Definition: papi.c:7023
long long PAPI_get_real_nsec(void)
Definition: papi.c:6797
int PAPI_multiplex_init(void)
Definition: papi.c:3541
unsigned long PAPI_thread_id(void)
Definition: papi.c:704
void PAPI_shutdown(void)
Definition: papi.c:5021
long long PAPI_get_virt_usec(void)
Definition: papi.c:6932
int PAPI_unregister_thread(void)
Definition: papi.c:786
const PAPI_exe_info_t * PAPI_get_executable_info(void)
Definition: papi.c:6674
long long PAPI_get_real_usec(void)
Definition: papi.c:6824
const PAPI_shlib_info_t * PAPI_get_shared_lib_info(void)
Definition: papi.c:6704
int PAPI_rate_stop()
Definition: papi.c:415
const PAPI_hw_info_t * PAPI_get_hardware_info(void)
Definition: papi.c:6745
#define PAPI_DEF_ITIMER
Definition: papi.h:462
#define PAPI_DEF_ITIMER_NS
Definition: papi.h:463
PAPI_dev_type_attr_e
Definition: papi.h:1049
PAPI_dev_attr_e
Definition: papi.h:1068
char events[MAX_EVENTS][BUFSIZ]
static int EventSet
Definition: init_fini.c:8
static long long values[NUM_EVENTS]
Definition: init_fini.c:10
static int threshold
void * thread(void *arg)
Definition: kufrin.c:38
static double a[MATRIX_SIZE][MATRIX_SIZE]
Definition: libmsr_basic.c:38
static double b[MATRIX_SIZE][MATRIX_SIZE]
Definition: libmsr_basic.c:39
static double c[MATRIX_SIZE][MATRIX_SIZE]
Definition: libmsr_basic.c:40
static int num_events
uint8_t version
#define PAPI_UE_MASK
#define PAPI_MAX_USER_EVENTS
#define PAPI_PRESET_MASK
#define PAPI_PRESET_AND_MASK
#define PAPI_NATIVE_MASK
#define PAPI_MAX_PRESET_EVENTS
#define PAPI_UE_AND_MASK
inline_static int _papi_set_attach(int option, int EventSet, unsigned long tid)
Definition: papi.c:3698
static int _rate_calls(float *real_time, float *proc_time, int *events, long long *values, long long *ins, float *rate, int mode)
Definition: papi.c:467
THREAD_LOCAL_STORAGE_KEYWORD RateInfo * _rate_state
Definition: papi.c:69
inline_static int valid_component(int cidx)
Definition: papi.c:628
inline_static int valid_ESI_component(EventSetInfo_t *ESI)
Definition: papi.c:636
bool _papi_rate_initiated
Definition: papi.c:70
hwi_presets_t user_defined_events[PAPI_MAX_USER_EVENTS]
Definition: papi_internal.c:59
#define FLIP
Definition: papi.c:52
static int _start_new_rate_call(float *real_time, float *proc_time, int *events, int num_events, long long *ins, float *rate)
Definition: papi.c:437
#define papi_return(a)
Definition: papi.c:592
static int init_retval
Definition: papi.c:625
int _papi_hwi_debug
Definition: papi.c:621
int PAPI_num_hwctrs(void)
Definition: papi.c:4468
static void _internal_papi_init(void)
Definition: papi.c:81
int user_defined_events_count
Definition: papi_internal.c:60
static int _internal_check_rate_state()
Definition: papi.c:123
#define IPC
Definition: papi.c:54
#define STOP
Definition: papi.c:51
#define FLOP
Definition: papi.c:53
static void _internal_onetime_papi_init(void)
Definition: papi.c:104
#define EPC
Definition: papi.c:55
Return codes and api definitions.
@ PAPI_PRESET_ENUM_AVAIL
Definition: papi.h:490
void(* PAPI_overflow_handler_t)(int EventSet, void *address, long long overflow_vector, void *context)
Definition: papi.h:573
unsigned long PAPI_thread_id_t
Definition: papi.h:564
#define IS_USER_DEFINED(EventCode)
Definition: papi.h:232
void * vptr_t
Definition: papi.h:576
#define IS_NATIVE(EventCode)
Definition: papi.h:230
#define IS_PRESET(EventCode)
Definition: papi.h:231
hwi_presets_t _papi_hwi_presets[PAPI_MAX_PRESET_EVENTS]
#define DEBUG_SUBSTRATE
Definition: papi_debug.h:27
#define DEBUG_LEAK
Definition: papi_debug.h:35
#define DEBUG_OVERFLOW
Definition: papi_debug.h:32
unsigned long int(* _papi_hwi_thread_id_fn)(void)
Definition: threads.c:42
#define DEBUG_ALL
Definition: papi_debug.h:37
#define OVFDBG(format, args...)
Definition: papi_debug.h:69
#define DEBUG_HIGHLEVEL
Definition: papi_debug.h:36
#define ISLEVEL(a)
Definition: papi_debug.h:55
#define DEBUG_MULTIPLEX
Definition: papi_debug.h:31
#define APIDBG(format, args...)
Definition: papi_debug.h:65
#define DEBUG_MEMORY
Definition: papi_debug.h:34
#define DEBUG_INTERNAL
Definition: papi_debug.h:29
#define DEBUG_THREADS
Definition: papi_debug.h:30
#define DEBUG_API
Definition: papi_debug.h:28
#define DEBUG_PROFILE
Definition: papi_debug.h:33
int pthread_once_t
FILE * stderr
int _papi_hwi_enum_dev_type(int enum_modifier, void **handle)
int _papi_hwi_get_user_event_info(int EventCode, PAPI_event_info_t *info)
int init_level
Definition: papi_internal.c:53
int _papi_hwi_get_dev_type_attr(void *handle, PAPI_dev_type_attr_e attr, void *value)
int _papi_hwi_native_to_eventcode(int cidx, int event_code, int ntv_idx, const char *event_name)
int _papi_hwi_add_event(EventSetInfo_t *ESI, int EventCode)
void _papi_hwi_shutdown_global_internal(void)
int _papi_hwi_get_native_event_info(unsigned int EventCode, PAPI_event_info_t *info)
void _papi_hwi_free_EventSet(EventSetInfo_t *ESI)
void _papi_hwi_dummy_handler(int EventSet, void *address, long long overflow_vector, void *context)
void PAPIERROR(char *format,...)
THREAD_LOCAL_STORAGE_KEYWORD int _papi_hl_events_running
Definition: papi_internal.c:63
int _papi_hwi_is_sw_multiplex(EventSetInfo_t *ESI)
int _papi_hwi_native_code_to_name(unsigned int EventCode, char *hwi_name, int len)
void _papi_hwi_init_errors(void)
int _papi_hwi_eventcode_to_native(int event_code)
int _papi_hwi_errno
Definition: papi_internal.c:57
char * _papi_hwi_get_papi_event_string()
int _papi_hwi_error_level
Definition: papi_internal.c:54
void _papi_hwi_free_papi_event_string()
EventSetInfo_t * _papi_hwi_lookup_EventSet(int eventset)
int _papi_hwi_num_errors
Definition: papi_internal.c:58
int _papi_hwi_lookup_EventCodeIndex(const EventSetInfo_t *ESI, unsigned int EventCode)
int _papi_hwi_init_global(int PE_OR_PEU)
hwd_context_t * _papi_hwi_get_context(EventSetInfo_t *ESI, int *is_dirty)
int _papi_hwi_get_dev_attr(void *handle, int id, PAPI_dev_attr_e attr, void *value)
int _papi_hwi_init_global_internal(void)
PAPI_debug_handler_t _papi_hwi_debug_handler
Definition: papi_internal.c:55
int _papi_hwi_remove_EventSet(EventSetInfo_t *ESI)
int _papi_hwi_native_name_to_code(const char *in, int *out)
int _papi_hwi_create_eventset(int *EventSet, ThreadInfo_t *handle)
int _papi_hwi_component_index(int event_code)
int _papi_hwi_get_preset_event_info(int EventCode, PAPI_event_info_t *info)
int _papi_hwi_convert_eventset_to_multiplex(_papi_int_multiplex_t *mpx)
THREAD_LOCAL_STORAGE_KEYWORD int _papi_rate_events_running
Definition: papi_internal.c:62
int _papi_hwi_read(hwd_context_t *context, EventSetInfo_t *ESI, long long *values)
char ** _papi_errlist
Definition: papi_internal.c:84
int _papi_hwi_assign_eventset(EventSetInfo_t *ESI, int cidx)
int papi_num_components
int _papi_hwi_remove_event(EventSetInfo_t *ESI, int EventCode)
int _papi_hwi_invalid_cmp(int cidx)
void _papi_hwi_set_papi_event_code(unsigned int event_code, int update_flag)
int _papi_hwi_cleanup_eventset(EventSetInfo_t *ESI)
int _papi_hwi_query_native_event(unsigned int EventCode)
void _papi_hwi_map_events_to_native(EventSetInfo_t *ESI)
#define inline_static
#define PAPI_SHUTDOWN_SYNC_str
Definition: papi_internal.h:42
#define PAPI_SHUTDOWN_str
Definition: papi_internal.h:41
#define NOT_DERIVED
Definition: papi_internal.h:68
#define DEADBEEF
Definition: papi_internal.h:26
#define THREADS_LOCK
Definition: papi_internal.h:87
#define NEED_CONTEXT
Definition: papi_internal.h:97
#define DERIVED_CMPD
Definition: papi_internal.h:72
static double array[ARRAYSIZE]
Definition: papi_l1_dca.c:23
#define PAPI_MAX_LOCK
Definition: papi_lock.h:18
void _papi_mem_cleanup_all()
Definition: papi_memory.c:303
#define papi_free(a)
Definition: papi_memory.h:35
#define papi_malloc(a)
Definition: papi_memory.h:34
static int cidx
papi_mdi_t _papi_hwi_system_info
Definition: papi_internal.c:56
static int attach(hwd_control_state_t *ctl, unsigned long tid)
Definition: perfctr.c:248
if(file==NULL) goto out
static int total
Definition: rapl_overflow.c:9
void handler(int EventSet, void *address, long long overflow_vector, void *context)
Definition: rapl_overflow.c:21
const char * name
Definition: rocs.c:225
int
Definition: sde_internal.h:89
long long int long long
Definition: sde_internal.h:85
Definition: cpus.h:11
EventSetInfo_t ** running_eventset
Definition: cpus.h:15
EventSetInfo_t ** dataSlotArray
int pos[PAPI_EVENTS_IN_DERIVED_EVENT]
unsigned int event_code
EventSetInheritInfo_t inherit
EventSetMultiplexInfo_t multiplex
EventSetProfileInfo_t profile
long long * sw_stop
struct _ThreadInfo * master
long long * hw_start
EventSetAttachInfo_t attach
struct _CpuInfo * CpuInfo
EventSetGranularityInfo_t granularity
EventInfo_t * EventInfoArray
hwd_control_state_t * ctl_state
NativeInfo_t * NativeInfoArray
EventSetOverflowInfo_t overflow
EventSetDomainInfo_t domain
MPX_EventSet * mpx_evset
Definition: sw_multiplex.h:32
PAPI_overflow_handler_t handler
PAPI_sprofil_t ** prof
unsigned long tid
Definition: papi.h:812
char name[PAPI_MAX_STR_LEN]
Definition: papi.h:627
unsigned int cpu_num
Definition: papi.h:818
PAPI_debug_handler_t handler
Definition: papi.h:679
A pointer to the following is passed to PAPI_get_dmem_info()
Definition: papi.h:865
get the executable's info
Definition: papi.h:696
Hardware info structure.
Definition: papi.h:774
int ncpu
Definition: papi.h:775
int cpu_max_mhz
Definition: papi.h:790
vptr_t pr_off
Definition: papi.h:582
unsigned pr_size
Definition: papi.h:581
void * pr_base
Definition: papi.h:580
unsigned pr_scale
Definition: papi.h:583
Definition: papi.c:61
int event_0
Definition: papi.c:63
int EventSet
Definition: papi.c:62
short int running
Definition: papi.c:64
long long last_real_time
Definition: papi.c:65
long long last_proc_time
Definition: papi.c:66
EventSetInfo_t * ESI
EventSetInfo_t * ESI
unsigned long tid
EventSetInfo_t * ESI
unsigned int cpu_num
EventSetInfo_t * ESI
EventSetInfo_t * ESI
EventSetInfo_t * ESI
EventSetInfo_t * ESI
DynamicArray_t global_eventset_map
PAPI_exe_info_t exe_info
PAPI_hw_info_t hw_info
PAPI_preload_info_t preload_info
PAPI_shlib_info_t shlib_info
long long(* get_virt_nsec)(void)
Definition: papi_vector.h:66
long long(* get_real_nsec)(void)
Definition: papi_vector.h:65
long long(* get_virt_usec)(void)
Definition: papi_vector.h:64
int(* get_dmem_info)(PAPI_dmem_info_t *)
Definition: papi_vector.h:70
int(* update_shlib_info)(papi_mdi_t *mdi)
Definition: papi_vector.h:67
long long(* get_real_usec)(void)
Definition: papi_vector.h:63
long long(* get_virt_cycles)(void)
Definition: papi_vector.h:62
long long(* get_real_cycles)(void)
Definition: papi_vector.h:61
void MPX_shutdown(void)
int mpx_check(int EventSet)
int MPX_read(MPX_EventSet *mpx_events, long long *values, int called_by_stop)
Definition: sw_multiplex.c:823
int mpx_init(int interval_ns)
int MPX_start(MPX_EventSet *mpx_events)
Definition: sw_multiplex.c:692
int MPX_reset(MPX_EventSet *mpx_events)
Definition: sw_multiplex.c:937
int MPX_stop(MPX_EventSet *mpx_events, long long *values)
Definition: sw_multiplex.c:974
int MPX_cleanup(MPX_EventSet **mpx_events)
int _papi_hwi_init_global_threads(void)
Definition: threads.c:541
unsigned long _papi_gettid(void)
Definition: threads.c:613
int _papi_hwi_shutdown_thread(ThreadInfo_t *thread, int force_shutdown)
Definition: threads.c:424
int _papi_hwi_set_thread_id_fn(unsigned long(*id_fn)(void))
Definition: threads.c:358
int _papi_hwi_gather_all_thrspec_data(int tag, PAPI_all_thr_spec_t *where)
Definition: threads.c:568
int _papi_hwi_shutdown_global_threads(void)
Definition: threads.c:470
inline_static int _papi_hwi_lookup_or_create_thread(ThreadInfo_t **here, int tid)
Definition: threads.h:150
inline_static ThreadInfo_t * _papi_hwi_lookup_thread(int custom_tid)
Definition: threads.h:97
inline_static int _papi_hwi_lock(int lck)
Definition: threads.h:69
#define THREAD_LOCAL_STORAGE_KEYWORD
Definition: threads.h:16
inline_static int _papi_hwi_unlock(int lck)
Definition: threads.h:83
A pointer to the following is passed to PAPI_set/get_opt()
Definition: papi.h:843
PAPI_preload_info_t preload
Definition: papi.h:844
PAPI_granularity_option_t granularity
Definition: papi.h:847
PAPI_shlib_info_t * shlib_info
Definition: papi.h:856
PAPI_user_defined_events_file_t events_file
Definition: papi.h:860
PAPI_domain_option_t defdomain
Definition: papi.h:850
PAPI_domain_option_t domain
Definition: papi.h:849
PAPI_inherit_option_t inherit
Definition: papi.h:846
PAPI_hw_info_t * hw_info
Definition: papi.h:855
PAPI_component_info_t * cmp_info
Definition: papi.h:858
PAPI_itimer_option_t itimer
Definition: papi.h:854
PAPI_multiplex_option_t multiplex
Definition: papi.h:853
PAPI_cpu_option_t cpu
Definition: papi.h:852
PAPI_addr_range_option_t addr
Definition: papi.h:859
PAPI_granularity_option_t defgranularity
Definition: papi.h:848
PAPI_attach_option_t attach
Definition: papi.h:851
PAPI_debug_option_t debug
Definition: papi.h:845
PAPI_exe_info_t * exe_info
Definition: papi.h:857
_papi_int_domain_t domain
_papi_int_multiplex_t multiplex
_papi_int_granularity_t granularity
_papi_int_attach_t attach
_papi_int_inherit_t inherit
_papi_int_cpu_t cpu
_papi_int_itimer_t itimer
_papi_int_addr_range_t address_range
int retval
Definition: zero_fork.c:53