PAPI  5.0.1.0
papi.c
Go to the documentation of this file.
00001 /****************************/
00002 /* THIS IS OPEN SOURCE CODE */
00003 /****************************/
00004 
00024 #include <stdio.h>
00025 #include <string.h>
00026 #include <stdlib.h>
00027 #include <unistd.h> 
00028 
00029 #include "papi.h"
00030 #include "papi_internal.h"
00031 #include "papi_vector.h"
00032 #include "papi_memory.h"
00033 
00034 #include "papi_user_events.h"
00035 
00036 #include "extras.h"
00037 #include "sw_multiplex.h"
00038 #include "papi_hl.h"
00039 
00040 /*******************************/
00041 /* BEGIN EXTERNAL DECLARATIONS */
00042 /*******************************/
00043 
00044 
00045 #ifdef DEBUG
00046 #define papi_return(a) do { \
00047     int b = a; \
00048     if (b != PAPI_OK) {\
00049         _papi_hwi_errno = b;\
00050     } \
00051     return((_papi_hwi_debug_handler ? _papi_hwi_debug_handler(b) : b)); \
00052 } while (0)
00053 #else
00054 #define papi_return(a) do { \
00055     int b = a; \
00056     if (b != PAPI_OK) {\
00057         _papi_hwi_errno = b;\
00058     } \
00059     return(b);\
00060 } while(0)
00061 #endif
00062 
00063 
00064 /*
00065 #ifdef DEBUG
00066 #define papi_return(a) return((_papi_hwi_debug_handler ? _papi_hwi_debug_handler(a) : a))
00067 #else
00068 #define papi_return(a) return(a)
00069 #endif
00070 */
00071 
00072 #ifdef DEBUG
00073 int _papi_hwi_debug;
00074 #endif
00075 
00076 
00077 static int init_retval = DEADBEEF;
00078 
00079 inline_static int
00080 valid_component( int cidx )
00081 {
00082     if ( _papi_hwi_invalid_cmp( cidx ) )
00083         return ( PAPI_ENOCMP );
00084     return ( cidx );
00085 }
00086 
00087 inline_static int
00088 valid_ESI_component( EventSetInfo_t * ESI )
00089 {
00090     return ( valid_component( ESI->CmpIdx ) );
00091 }
00092 
00116 int
00117 PAPI_thread_init( unsigned long int ( *id_fn ) ( void ) )
00118 {
00119     /* Thread support not implemented on Alpha/OSF because the OSF pfm
00120      * counter device driver does not support per-thread counters.
00121      * When this is updated, we can remove this if statement
00122      */
00123     if ( init_level == PAPI_NOT_INITED )
00124         papi_return( PAPI_ENOINIT );
00125 
00126     if ( ( init_level & PAPI_THREAD_LEVEL_INITED ) )
00127         papi_return( PAPI_OK );
00128 
00129     init_level |= PAPI_THREAD_LEVEL_INITED;
00130     papi_return( _papi_hwi_set_thread_id_fn( id_fn ) );
00131 }
00132 
00155 unsigned long
00156 PAPI_thread_id( void )
00157 {
00158     if ( _papi_hwi_thread_id_fn != NULL )
00159         return ( ( *_papi_hwi_thread_id_fn ) (  ) );
00160     else
00161 #ifdef DEBUG
00162     if ( _papi_hwi_debug_handler )
00163         return ( unsigned long ) _papi_hwi_debug_handler( PAPI_EMISC );
00164 #endif
00165     return ( unsigned long ) PAPI_EMISC;
00166 }
00167 
00168 /* Thread Functions */
00169 
00170 /* 
00171  * Notify PAPI that a thread has 'appeared'
00172  * We lookup the thread, if it does not exist we create it
00173  */
00174 
00203 int
00204 PAPI_register_thread( void )
00205 {
00206     ThreadInfo_t *thread;
00207 
00208     if ( init_level == PAPI_NOT_INITED )
00209         papi_return( PAPI_ENOINIT );
00210     papi_return( _papi_hwi_lookup_or_create_thread( &thread, 0 ) );
00211 }
00212 
00213 /* 
00214  * Notify PAPI that a thread has 'disappeared'
00215  * We lookup the thread, if it does not exist we return an error
00216  */
00239 int
00240 PAPI_unregister_thread( void )
00241 {
00242     ThreadInfo_t *thread = _papi_hwi_lookup_thread( 0 );
00243 
00244     if ( thread )
00245         papi_return( _papi_hwi_shutdown_thread( thread ) );
00246 
00247     papi_return( PAPI_EMISC );
00248 }
00249 
00283 int
00284 PAPI_list_threads( PAPI_thread_id_t *tids, int *number )
00285 {
00286     PAPI_all_thr_spec_t tmp;
00287     int retval;
00288 
00289     /* If tids == NULL, then just count the threads, don't gather a list. */
00290     /* If tids != NULL, then we need the length of the tids array in num. */
00291 
00292     if ( ( number == NULL ) || ( tids && ( *number <= 0 ) ) )
00293         papi_return( PAPI_EINVAL );
00294 
00295     memset( &tmp, 0x0, sizeof ( tmp ) );
00296 
00297     /* data == NULL, since we don't want the thread specific pointers. */
00298     /* tids may be NULL, if the user doesn't want the thread IDs. */
00299 
00300     tmp.num = *number;
00301     tmp.id = tids;
00302     tmp.data = NULL;
00303 
00304     retval = _papi_hwi_gather_all_thrspec_data( 0, &tmp );
00305     if ( retval == PAPI_OK )
00306         *number = tmp.num;
00307 
00308     papi_return( retval );
00309 }
00310 
00359 int
00360 PAPI_get_thr_specific( int tag, void **ptr )
00361 {
00362     ThreadInfo_t *thread;
00363     int doall = 0, retval = PAPI_OK;
00364 
00365     if ( init_level == PAPI_NOT_INITED )
00366         papi_return( PAPI_ENOINIT );
00367     if ( tag & PAPI_TLS_ALL_THREADS ) {
00368         tag = tag ^ PAPI_TLS_ALL_THREADS;
00369         doall = 1;
00370     }
00371     if ( ( tag < 0 ) || ( tag > PAPI_TLS_NUM ) )
00372         papi_return( PAPI_EINVAL );
00373 
00374     if ( doall )
00375         papi_return( _papi_hwi_gather_all_thrspec_data
00376                      ( tag, ( PAPI_all_thr_spec_t * ) ptr ) );
00377 
00378     retval = _papi_hwi_lookup_or_create_thread( &thread, 0 );
00379     if ( retval == PAPI_OK )
00380         *ptr = thread->thread_storage[tag];
00381     else
00382         papi_return( retval );
00383 
00384     return ( PAPI_OK );
00385 }
00386 
00435 int
00436 PAPI_set_thr_specific( int tag, void *ptr )
00437 {
00438     ThreadInfo_t *thread;
00439     int retval = PAPI_OK;
00440 
00441     if ( init_level == PAPI_NOT_INITED )
00442         papi_return( PAPI_ENOINIT );
00443     if ( ( tag < 0 ) || ( tag > PAPI_NUM_TLS ) )
00444         papi_return( PAPI_EINVAL );
00445 
00446     retval = _papi_hwi_lookup_or_create_thread( &thread, 0 );
00447     if ( retval == PAPI_OK ) {
00448        _papi_hwi_lock( THREADS_LOCK );
00449        thread->thread_storage[tag] = ptr;
00450        _papi_hwi_unlock( THREADS_LOCK );
00451     }
00452     else
00453         return ( retval );
00454 
00455     return ( PAPI_OK );
00456 }
00457 
00458 
00497 int
00498 PAPI_library_init( int version )
00499 {
00500     char *filename;
00501     int tmp = 0, tmpel;
00502 
00503     /* This is a poor attempt at a lock. 
00504        For 3.1 this should be replaced with a 
00505        true UNIX semaphore. We cannot use PAPI
00506        locks here because they are not initialized yet */
00507     static int _in_papi_library_init_cnt = 0;
00508 #ifdef DEBUG
00509     char *var;
00510 #endif
00511     _papi_hwi_init_errors();
00512 
00513     if ( version != PAPI_VER_CURRENT )
00514         papi_return( PAPI_EINVAL );
00515 
00516     ++_in_papi_library_init_cnt;
00517     while ( _in_papi_library_init_cnt > 1 ) {
00518         PAPIERROR( "Multiple callers of PAPI_library_init" );
00519         sleep( 1 );
00520     }
00521 
00522     /* This checks to see if we have forked or called init more than once.
00523        If we have forked, then we continue to init. If we have not forked, 
00524        we check to see the status of initialization. */
00525 
00526     APIDBG( "Initializing library: current PID %d, old PID %d\n", 
00527                 getpid(  ), _papi_hwi_system_info.pid );
00528 
00529     if ( _papi_hwi_system_info.pid == getpid(  ) ) {
00530         /* If the magic environment variable PAPI_ALLOW_STOLEN is set,
00531            we call shutdown if PAPI has been initialized. This allows
00532            tools that use LD_PRELOAD to run on applications that use PAPI.
00533            In this circumstance, PAPI_ALLOW_STOLEN will be set to 'stolen'
00534            so the tool can check for this case. */
00535 
00536         if ( getenv( "PAPI_ALLOW_STOLEN" ) ) {
00537             char buf[PAPI_HUGE_STR_LEN];
00538             if ( init_level != PAPI_NOT_INITED )
00539                 PAPI_shutdown(  );
00540             sprintf( buf, "%s=%s", "PAPI_ALLOW_STOLEN", "stolen" );
00541             putenv( buf );
00542         }
00543 
00544         /* If the library has been successfully initialized *OR*
00545            the library attempted initialization but failed. */
00546 
00547         else if ( ( init_level != PAPI_NOT_INITED ) ||
00548                   ( init_retval != DEADBEEF ) ) {
00549             _in_papi_library_init_cnt--;
00550             if ( init_retval < PAPI_OK )
00551                 papi_return( init_retval );
00552             else
00553                 return ( init_retval );
00554         }
00555 
00556         APIDBG( "system_info was initialized, but init did not succeed\n" );
00557     }
00558 #ifdef DEBUG
00559     var = ( char * ) getenv( "PAPI_DEBUG" );
00560     _papi_hwi_debug = 0;
00561 
00562     if ( var != NULL ) {
00563         if ( strlen( var ) != 0 ) {
00564             if ( strstr( var, "SUBSTRATE" ) )
00565                 _papi_hwi_debug |= DEBUG_SUBSTRATE;
00566             if ( strstr( var, "API" ) )
00567                 _papi_hwi_debug |= DEBUG_API;
00568             if ( strstr( var, "INTERNAL" ) )
00569                 _papi_hwi_debug |= DEBUG_INTERNAL;
00570             if ( strstr( var, "THREADS" ) )
00571                 _papi_hwi_debug |= DEBUG_THREADS;
00572             if ( strstr( var, "MULTIPLEX" ) )
00573                 _papi_hwi_debug |= DEBUG_MULTIPLEX;
00574             if ( strstr( var, "OVERFLOW" ) )
00575                 _papi_hwi_debug |= DEBUG_OVERFLOW;
00576             if ( strstr( var, "PROFILE" ) )
00577                 _papi_hwi_debug |= DEBUG_PROFILE;
00578             if ( strstr( var, "MEMORY" ) )
00579                 _papi_hwi_debug |= DEBUG_MEMORY;
00580             if ( strstr( var, "LEAK" ) )
00581                 _papi_hwi_debug |= DEBUG_LEAK;
00582             if ( strstr( var, "ALL" ) )
00583                 _papi_hwi_debug |= DEBUG_ALL;
00584         }
00585 
00586         if ( _papi_hwi_debug == 0 )
00587             _papi_hwi_debug |= DEBUG_API;
00588     }
00589 #endif
00590 
00591     /* Be verbose for now */
00592 
00593     tmpel = _papi_hwi_error_level;
00594     _papi_hwi_error_level = PAPI_VERB_ECONT;
00595 
00596     /* Initialize internal globals */
00597     if ( _papi_hwi_init_global_internal(  ) != PAPI_OK ) {
00598         _in_papi_library_init_cnt--;
00599         _papi_hwi_error_level = tmpel;
00600         papi_return( PAPI_EINVAL );
00601     }
00602 
00603     /* Initialize OS */
00604     tmp = _papi_hwi_init_os();
00605     if ( tmp ) {
00606        init_retval = tmp;
00607        _papi_hwi_shutdown_global_internal(  );
00608        _in_papi_library_init_cnt--;
00609        _papi_hwi_error_level = tmpel;
00610        papi_return( init_retval );
00611     }
00612 
00613     /* Initialize component globals */
00614 
00615     tmp = _papi_hwi_init_global(  );
00616     if ( tmp ) {
00617         init_retval = tmp;
00618         _papi_hwi_shutdown_global_internal(  );
00619         _in_papi_library_init_cnt--;
00620         _papi_hwi_error_level = tmpel;
00621         papi_return( init_retval );
00622     }
00623     
00624     /* Initialize thread globals, including the main threads  */
00625 
00626     tmp = _papi_hwi_init_global_threads(  );
00627     if ( tmp ) {
00628         int i;
00629         init_retval = tmp;
00630         _papi_hwi_shutdown_global_internal(  );
00631         for ( i = 0; i < papi_num_components; i++ ) {
00632             if (!_papi_hwd[i]->cmp_info.disabled) {
00633                        _papi_hwd[i]->shutdown_component(  );
00634             }
00635         }
00636         _in_papi_library_init_cnt--;
00637         _papi_hwi_error_level = tmpel;
00638         papi_return( init_retval );
00639     }
00640 
00641     init_level = PAPI_LOW_LEVEL_INITED;
00642     _in_papi_library_init_cnt--;
00643     _papi_hwi_error_level = tmpel;
00644 
00645 #ifdef STATIC_USER_EVENTS
00646     _papi_user_defined_events_setup(NULL);
00647 #endif
00648 
00649     if ( (filename = getenv( "PAPI_USER_EVENTS_FILE" )) != NULL ) {
00650       _papi_user_defined_events_setup(filename);
00651     }
00652 
00653     return ( init_retval = PAPI_VER_CURRENT );
00654 }
00655 
00699 int
00700 PAPI_query_event( int EventCode )
00701 {
00702     if ( IS_PRESET(EventCode) ) {
00703         EventCode &= PAPI_PRESET_AND_MASK;
00704         if ( EventCode >= PAPI_MAX_PRESET_EVENTS )
00705             papi_return( PAPI_ENOTPRESET );
00706 
00707         if ( _papi_hwi_presets[EventCode].count )
00708                 papi_return (PAPI_OK);
00709         else
00710             return PAPI_ENOEVNT;
00711     }
00712 
00713     if ( IS_NATIVE(EventCode) ) {
00714         papi_return( _papi_hwi_query_native_event
00715                      ( ( unsigned int ) EventCode ) );
00716     }
00717 
00718     if ( IS_USER_DEFINED(EventCode) ) {
00719       EventCode &= PAPI_UE_AND_MASK;
00720       if ( EventCode < 0 || EventCode > (int)_papi_user_events_count)
00721         return ( PAPI_EINVAL );
00722 
00723       papi_return( PAPI_OK );
00724     }
00725 
00726     papi_return( PAPI_ENOEVNT );
00727 }
00728 
00769 int
00770 PAPI_query_named_event( char *EventName )
00771 {
00772     int ret, code;
00773     
00774     ret = PAPI_event_name_to_code( EventName, &code );
00775     if ( ret == PAPI_OK ) ret = PAPI_query_event( code );
00776     papi_return( ret);
00777 }
00778 
00779 
00809 const PAPI_component_info_t *
00810 PAPI_get_component_info( int cidx )
00811 {
00812     if ( _papi_hwi_invalid_cmp( cidx ) )
00813         return ( NULL );
00814     else
00815         return ( &( _papi_hwd[cidx]->cmp_info ) );
00816 }
00817 
00818 /* PAPI_get_event_info:
00819    tests input EventCode and returns a filled in PAPI_event_info_t 
00820    structure containing descriptive strings and values for the 
00821    specified event. Handles both preset and native events by 
00822    calling either _papi_hwi_get_event_info or 
00823    _papi_hwi_get_native_event_info.
00824 */
00847 int
00848 PAPI_get_event_info( int EventCode, PAPI_event_info_t *info )
00849 {
00850         int i;
00851 
00852     if ( info == NULL )
00853        papi_return( PAPI_EINVAL );
00854 
00855     if ( IS_PRESET(EventCode) ) {
00856            i = EventCode & PAPI_PRESET_AND_MASK;
00857        if ( i >= PAPI_MAX_PRESET_EVENTS )
00858           papi_return( PAPI_ENOTPRESET );
00859        papi_return( _papi_hwi_get_preset_event_info( EventCode, info ) );
00860     }
00861 
00862     if ( IS_NATIVE(EventCode) ) {
00863        papi_return( _papi_hwi_get_native_event_info
00864               ( ( unsigned int ) EventCode, info ) );
00865     }
00866 
00867     if ( IS_USER_DEFINED(EventCode) ) {
00868        papi_return( PAPI_OK );
00869     }
00870     papi_return( PAPI_ENOTPRESET );
00871 }
00872 
00873 
00925 int
00926 PAPI_event_code_to_name( int EventCode, char *out )
00927 {
00928     if ( out == NULL )
00929         papi_return( PAPI_EINVAL );
00930 
00931     if ( IS_PRESET(EventCode) ) {
00932         EventCode &= PAPI_PRESET_AND_MASK;
00933         if ( ( EventCode >= PAPI_MAX_PRESET_EVENTS )
00934              || ( _papi_hwi_presets[EventCode].symbol == NULL ) )
00935             papi_return( PAPI_ENOTPRESET );
00936 
00937         strncpy( out, _papi_hwi_presets[EventCode].symbol,
00938                  PAPI_MAX_STR_LEN );
00939         papi_return( PAPI_OK );
00940     }
00941 
00942     if ( IS_NATIVE(EventCode) ) {
00943         return ( _papi_hwi_native_code_to_name
00944                  ( ( unsigned int ) EventCode, out, PAPI_MAX_STR_LEN ) );
00945     }
00946 
00947     if ( IS_USER_DEFINED(EventCode) ) {
00948       EventCode &= PAPI_UE_AND_MASK;
00949 
00950       if ( EventCode < 0 || EventCode > (int)_papi_user_events_count )
00951         papi_return( PAPI_EINVAL );
00952 
00953       strncpy( out, _papi_user_events[EventCode].symbol,
00954           PAPI_MIN_STR_LEN);
00955       papi_return( PAPI_OK );
00956     }
00957 
00958     papi_return( PAPI_ENOEVNT );
00959 }
00960 
01012 int
01013 PAPI_event_name_to_code( char *in, int *out )
01014 {
01015    APIDBG("Entry: in: %p, name: %s, out: %p\n", in, in, out);
01016     int i;
01017 
01018     if ( ( in == NULL ) || ( out == NULL ) )
01019         papi_return( PAPI_EINVAL );
01020 
01021     if ( init_level == PAPI_NOT_INITED )
01022         papi_return( PAPI_ENOINIT );
01023 
01024     /* All presets start with "PAPI_" so no need to */
01025     /* do an exhaustive search if that's not there  */
01026     if (strncmp(in, "PAPI_", 5) == 0) {
01027        for(i = 0; i < PAPI_MAX_PRESET_EVENTS; i++ ) {
01028           if ( ( _papi_hwi_presets[i].symbol )
01029            && ( strcasecmp( _papi_hwi_presets[i].symbol, in ) == 0) ) {
01030          *out = ( int ) ( i | PAPI_PRESET_MASK );
01031          papi_return( PAPI_OK );
01032           }
01033        }
01034     }
01035 
01036     for ( i=0; i < (int)_papi_user_events_count; i++ ) {
01037       if ( strcasecmp( _papi_user_events[i].symbol, in ) == 0 ) {
01038         *out = (int) ( i | PAPI_UE_MASK );
01039         papi_return( PAPI_OK );
01040       }
01041     }
01042 
01043     papi_return( _papi_hwi_native_name_to_code( in, out ) );
01044 }
01045 
01046 /* Updates EventCode to next valid value, or returns error; 
01047   modifier can specify {all / available} for presets, or other values for native tables 
01048   and may be platform specific (Major groups / all mask bits; P / M / E chip, etc) */
01049 
01155 int
01156 PAPI_enum_event( int *EventCode, int modifier )
01157 {
01158     int i = *EventCode;
01159     int retval;
01160     int cidx;
01161     int event_code;
01162 
01163     cidx = _papi_hwi_component_index( *EventCode );
01164     if (cidx < 0) return PAPI_ENOCMP;
01165 
01166     /* Do we handle presets in componets other than CPU? */
01167     /* if (( IS_PRESET(i) ) && cidx > 0 )) return PAPI_ENOCMP; */
01168         
01169     if ( IS_PRESET(i) ) {
01170         if ( modifier == PAPI_ENUM_FIRST ) {
01171             *EventCode = ( int ) PAPI_PRESET_MASK;
01172             return ( PAPI_OK );
01173         }
01174         i &= PAPI_PRESET_AND_MASK;
01175         while ( ++i < PAPI_MAX_PRESET_EVENTS ) {
01176             if ( _papi_hwi_presets[i].symbol == NULL )
01177                 return ( PAPI_ENOEVNT );    /* NULL pointer terminates list */
01178             if ( modifier & PAPI_PRESET_ENUM_AVAIL ) {
01179                 if ( _papi_hwi_presets[i].count == 0 )
01180                     continue;
01181             }
01182             *EventCode = ( int ) ( i | PAPI_PRESET_MASK );
01183             return ( PAPI_OK );
01184         }
01185     } else if ( IS_NATIVE(i) ) {
01186         /* Should check against num native events here */
01187 
01188         event_code=_papi_hwi_eventcode_to_native((int)*EventCode);
01189         retval = _papi_hwd[cidx]->ntv_enum_events((unsigned int *)&event_code, modifier );
01190 
01191             /* re-apply Component ID to the returned Event */
01192         *EventCode = _papi_hwi_native_to_eventcode(cidx,event_code);
01193 
01194         return retval;
01195     } else if ( IS_USER_DEFINED(i) ) {
01196       if ( modifier == PAPI_ENUM_FIRST ) {
01197         *EventCode = (int) 0x0;
01198         return ( PAPI_OK );
01199       }
01200 
01201       i &= PAPI_UE_AND_MASK;
01202       ++i;
01203 
01204       if ( (int)_papi_user_events_count <= i )
01205         *EventCode = i;
01206       return ( PAPI_OK );
01207     }
01208 
01209     papi_return( PAPI_EINVAL );
01210 }
01211 
01212 
01320 int
01321 PAPI_enum_cmp_event( int *EventCode, int modifier, int cidx )
01322 {
01323     int i = *EventCode;
01324     int retval;
01325     int event_code;
01326 
01327     if ( _papi_hwi_invalid_cmp(cidx) || ( (IS_PRESET(i)) && cidx > 0 ) ) {
01328         return PAPI_ENOCMP;
01329     }
01330 
01331     if ( IS_PRESET(i) ) {
01332         if ( modifier == PAPI_ENUM_FIRST ) {
01333             *EventCode = ( int ) PAPI_PRESET_MASK;
01334             return PAPI_OK;
01335         }
01336         i &= PAPI_PRESET_AND_MASK;
01337         while ( ++i < PAPI_MAX_PRESET_EVENTS ) {
01338             if ( _papi_hwi_presets[i].symbol == NULL )
01339                 return ( PAPI_ENOEVNT );    /* NULL pointer terminates list */
01340             if ( modifier & PAPI_PRESET_ENUM_AVAIL ) {
01341                 if ( _papi_hwi_presets[i].count == 0 )
01342                     continue;
01343             }
01344             *EventCode = ( int ) ( i | PAPI_PRESET_MASK );
01345             return PAPI_OK;
01346         }
01347     } else if ( IS_NATIVE(i) ) {
01348 //      if (!_papi_hwd[cidx]->cmp_info.disabled) {
01349 //                return PAPI_ENOEVNT 
01350 //            }
01351         /* Should we check against num native events here? */
01352         event_code=_papi_hwi_eventcode_to_native(*EventCode);
01353         retval = _papi_hwd[cidx]->ntv_enum_events((unsigned int *)&event_code, modifier );
01354         
01355             /* re-apply Component ID to the returned Event */
01356         *EventCode = _papi_hwi_native_to_eventcode(cidx,event_code);
01357 
01358         return retval;
01359     } 
01360 
01361     papi_return( PAPI_EINVAL );
01362 }
01363 
01410 int
01411 PAPI_create_eventset( int *EventSet )
01412 {
01413    APIDBG("Entry: EventSet: %p\n", EventSet);
01414     ThreadInfo_t *master;
01415     int retval;
01416 
01417     if ( init_level == PAPI_NOT_INITED )
01418         papi_return( PAPI_ENOINIT );
01419     retval = _papi_hwi_lookup_or_create_thread( &master, 0 );
01420     if ( retval )
01421         papi_return( retval );
01422 
01423     papi_return( _papi_hwi_create_eventset( EventSet, master ) );
01424 }
01425 
01474 int
01475 PAPI_assign_eventset_component( int EventSet, int cidx )
01476 {
01477     EventSetInfo_t *ESI;
01478     int retval;
01479 
01480     ESI = _papi_hwi_lookup_EventSet( EventSet );
01481     if ( ESI == NULL )
01482         papi_return( PAPI_ENOEVST );
01483 
01484 /* validate cidx */
01485     retval = valid_component( cidx );
01486     if ( retval < 0 )
01487         papi_return( retval );
01488 
01489 /* cowardly refuse to reassign eventsets */ 
01490     if ( ESI->CmpIdx >= 0 )
01491       return PAPI_EINVAL;
01492 
01493     return ( _papi_hwi_assign_eventset( ESI, cidx ) );
01494 }
01495 
01565 int
01566 PAPI_add_event( int EventSet, int EventCode )
01567 {
01568    APIDBG("Entry: EventSet: %d, EventCode: 0x%x\n", EventSet, EventCode);
01569     EventSetInfo_t *ESI;
01570 
01571     /* Is the EventSet already in existence? */
01572 
01573     ESI = _papi_hwi_lookup_EventSet( EventSet );
01574     if ( ESI == NULL )
01575         papi_return( PAPI_ENOEVST );
01576 
01577     /* Check argument for validity */
01578 
01579     if ( ( ( EventCode & PAPI_PRESET_MASK ) == 0 ) &&
01580          ( EventCode & PAPI_NATIVE_MASK ) == 0 )
01581         papi_return( PAPI_EINVAL );
01582 
01583     /* Of course, it must be stopped in order to modify it. */
01584 
01585     if ( ESI->state & PAPI_RUNNING )
01586         papi_return( PAPI_EISRUN );
01587 
01588     /* Now do the magic. */
01589 
01590     papi_return( _papi_hwi_add_event( ESI, EventCode ) );
01591 }
01592 
01660 int
01661 PAPI_remove_event( int EventSet, int EventCode )
01662 {
01663     EventSetInfo_t *ESI;
01664     int i,retval;
01665 
01666     /* check for pre-existing ESI */
01667 
01668     ESI = _papi_hwi_lookup_EventSet( EventSet );
01669     if ( ESI == NULL )
01670         papi_return( PAPI_ENOEVST );
01671 
01672     /* Check argument for validity */
01673 
01674     if ( ( !IS_PRESET(EventCode) ) &&
01675         ( !IS_NATIVE(EventCode) ) &&
01676         ( !IS_USER_DEFINED(EventCode) ))
01677         papi_return( PAPI_EINVAL );
01678 
01679     /* Of course, it must be stopped in order to modify it. */
01680 
01681     if ( !( ESI->state & PAPI_STOPPED ) )
01682         papi_return( PAPI_EISRUN );
01683 
01684     /* if the state is PAPI_OVERFLOWING, you must first call
01685        PAPI_overflow with threshold=0 to remove the overflow flag */
01686 
01687     /* Turn off the event that is overflowing */
01688     if ( ESI->state & PAPI_OVERFLOWING ) {
01689        for ( i = 0; i < ESI->overflow.event_counter; i++ ) {
01690            if ( ESI->overflow.EventCode[i] == EventCode ) {
01691           retval = PAPI_overflow( EventSet, EventCode, 0, 0,
01692                       ESI->overflow.handler );
01693           if (retval!=PAPI_OK) return retval;
01694           break;
01695            }
01696        }
01697     }
01698 
01699     /* force the user to call PAPI_profil to clear the PAPI_PROFILING flag */
01700     if ( ESI->state & PAPI_PROFILING ) {
01701         for ( i = 0; i < ESI->profile.event_counter; i++ ) {
01702             if ( ESI->profile.EventCode[i] == EventCode ) {
01703                 PAPI_sprofil( NULL, 0, EventSet, EventCode, 0, 0 );
01704                 break;
01705             }
01706         }
01707     }
01708 
01709     /* Now do the magic. */
01710 
01711     papi_return( _papi_hwi_remove_event( ESI, EventCode ) );
01712 }
01713 
01777 int
01778 PAPI_add_named_event( int EventSet, char *EventName )
01779 {
01780     int ret, code;
01781     
01782     ret = PAPI_event_name_to_code( EventName, &code );
01783     if ( ret == PAPI_OK ) ret = PAPI_add_event( EventSet, code );
01784     papi_return( ret );
01785 }
01786 
01854 int
01855 PAPI_remove_named_event( int EventSet, char *EventName )
01856 {
01857     int ret, code;
01858     
01859     ret = PAPI_event_name_to_code( EventName, &code );
01860     if ( ret == PAPI_OK ) ret = PAPI_remove_event( EventSet, code );
01861     papi_return( ret );
01862 }
01863 
01905 int
01906 PAPI_destroy_eventset( int *EventSet )
01907 {
01908     EventSetInfo_t *ESI;
01909 
01910     APIDBG("Destroying Eventset %d\n",*EventSet);
01911 
01912     /* check for pre-existing ESI */
01913 
01914     if ( EventSet == NULL )
01915         papi_return( PAPI_EINVAL );
01916 
01917     ESI = _papi_hwi_lookup_EventSet( *EventSet );
01918     if ( ESI == NULL )
01919         papi_return( PAPI_ENOEVST );
01920 
01921     if ( !( ESI->state & PAPI_STOPPED ) )
01922         papi_return( PAPI_EISRUN );
01923 
01924     if ( ESI->NumberOfEvents )
01925         papi_return( PAPI_EINVAL );
01926 
01927     _papi_hwi_remove_EventSet( ESI );
01928     *EventSet = PAPI_NULL;
01929 
01930     return PAPI_OK;
01931 }
01932 
01933 /* simply checks for valid EventSet, calls component start() call */
01987 int
01988 PAPI_start( int EventSet )
01989 {
01990     APIDBG("Entry: EventSet: %d\n", EventSet);
01991     int is_dirty=0;
01992     int retval;
01993     EventSetInfo_t *ESI;
01994     ThreadInfo_t *thread = NULL;
01995     CpuInfo_t *cpu = NULL;
01996     hwd_context_t *context;
01997     int cidx;
01998 
01999     ESI = _papi_hwi_lookup_EventSet( EventSet );
02000     if ( ESI == NULL ) {
02001        papi_return( PAPI_ENOEVST );
02002     }
02003 
02004     cidx = valid_ESI_component( ESI );
02005     if ( cidx < 0 ) {
02006        papi_return( cidx );
02007     }
02008 
02009     /* only one event set per thread/cpu can be running at any time, */
02010     /* so if another event set is running, the user must stop that   */
02011         /* event set explicitly */
02012 
02013         thread = ESI->master;
02014     cpu = ESI->CpuInfo;
02015 
02016     /* check cpu attached case first */
02017     if (ESI->state & PAPI_CPU_ATTACHED) {
02018        if ( cpu->running_eventset[cidx] ) {
02019           papi_return( PAPI_EISRUN );
02020        }
02021     } else {
02022         if ( thread->running_eventset[cidx] ) {
02023            papi_return( PAPI_EISRUN );
02024         }
02025     } 
02026     
02027     /* Check that there are added events */
02028     if ( ESI->NumberOfEvents < 1 ) {
02029        papi_return( PAPI_EINVAL );
02030     }
02031 
02032     /* If multiplexing is enabled for this eventset,
02033        call John May's code. */
02034 
02035     if ( _papi_hwi_is_sw_multiplex( ESI ) ) {
02036        retval = MPX_start( ESI->multiplex.mpx_evset );
02037        if ( retval != PAPI_OK ) {
02038           papi_return( retval );
02039        }
02040 
02041        /* Update the state of this EventSet */
02042        ESI->state ^= PAPI_STOPPED;
02043        ESI->state |= PAPI_RUNNING;
02044 
02045        return PAPI_OK;
02046     }
02047 
02048     /* get the context we should use for this event set */
02049     context = _papi_hwi_get_context( ESI, &is_dirty );
02050     if (is_dirty) {
02051        /* we need to reset the context state because it was last used   */
02052        /* for some other event set and does not contain the information */
02053            /* for our events.                                               */
02054        retval = _papi_hwd[ESI->CmpIdx]->update_control_state( 
02055                                                         ESI->ctl_state,
02056                             ESI->NativeInfoArray,
02057                             ESI->NativeCount,
02058                             context);
02059        if ( retval != PAPI_OK ) {
02060           papi_return( retval );
02061        }
02062         
02063        /* now that the context contains this event sets information,    */
02064        /* make sure the position array in the EventInfoArray is correct */
02065 
02066        /* We have to do this because ->update_control_state() can */
02067        /* in theory re-order the native events out from under us. */
02068        _papi_hwi_map_events_to_native( ESI );
02069 
02070     }
02071 
02072     /* If overflowing is enabled, turn it on */
02073     if ( ( ESI->state & PAPI_OVERFLOWING ) &&
02074          !( ESI->overflow.flags & PAPI_OVERFLOW_HARDWARE ) ) {
02075        retval = _papi_hwi_start_signal( _papi_os_info.itimer_sig, 
02076                         NEED_CONTEXT, cidx );
02077        if ( retval != PAPI_OK ) {
02078           papi_return( retval );
02079        }
02080 
02081        /* Update the state of this EventSet and thread */
02082        /* before to avoid races                        */
02083        ESI->state ^= PAPI_STOPPED;
02084        ESI->state |= PAPI_RUNNING;
02085            /* can not be attached to thread or cpu if overflowing */
02086        thread->running_eventset[cidx] = ESI;
02087 
02088        retval = _papi_hwd[cidx]->start( context, ESI->ctl_state );
02089        if ( retval != PAPI_OK ) {
02090           _papi_hwi_stop_signal( _papi_os_info.itimer_sig );
02091           ESI->state ^= PAPI_RUNNING;
02092           ESI->state |= PAPI_STOPPED;
02093           thread->running_eventset[cidx] = NULL;
02094           papi_return( retval );
02095        }
02096 
02097        retval = _papi_hwi_start_timer( _papi_os_info.itimer_num,
02098                        _papi_os_info.itimer_sig,
02099                        _papi_os_info.itimer_ns );
02100        if ( retval != PAPI_OK ) {
02101           _papi_hwi_stop_signal( _papi_os_info.itimer_sig );
02102           _papi_hwd[cidx]->stop( context, ESI->ctl_state );
02103           ESI->state ^= PAPI_RUNNING;
02104           ESI->state |= PAPI_STOPPED;
02105           thread->running_eventset[cidx] = NULL;
02106           papi_return( retval );
02107        }
02108     } else {
02109        /* Update the state of this EventSet and thread before */
02110        /* to avoid races                                      */
02111        ESI->state ^= PAPI_STOPPED;
02112        ESI->state |= PAPI_RUNNING;
02113         
02114        /* if not attached to cpu or another process */
02115        if ( !(ESI->state & PAPI_CPU_ATTACHED) ) {
02116           if ( !( ESI->state & PAPI_ATTACHED ) ) {
02117          thread->running_eventset[cidx] = ESI;
02118           }
02119        } else {
02120           cpu->running_eventset[cidx] = ESI;
02121        }
02122 
02123        retval = _papi_hwd[cidx]->start( context, ESI->ctl_state );
02124        if ( retval != PAPI_OK ) {
02125           _papi_hwd[cidx]->stop( context, ESI->ctl_state );
02126           ESI->state ^= PAPI_RUNNING;
02127           ESI->state |= PAPI_STOPPED;
02128           if ( !(ESI->state & PAPI_CPU_ATTACHED) ) {
02129          if ( !( ESI->state & PAPI_ATTACHED ) ) 
02130             thread->running_eventset[cidx] = NULL;
02131           } else {
02132          cpu->running_eventset[cidx] = NULL;
02133           }
02134           papi_return( retval );
02135        }
02136     }
02137 
02138     return retval;
02139 }
02140 
02141 /* checks for valid EventSet, calls component stop() function. */
02192 int
02193 PAPI_stop( int EventSet, long long *values )
02194 {
02195    APIDBG("Entry: EventSet: %d, values: %p\n", EventSet, values);
02196     EventSetInfo_t *ESI;
02197     hwd_context_t *context;
02198     int cidx, retval;
02199 
02200     ESI = _papi_hwi_lookup_EventSet( EventSet );
02201     if ( ESI == NULL )
02202         papi_return( PAPI_ENOEVST );
02203 
02204     cidx = valid_ESI_component( ESI );
02205     if ( cidx < 0 )
02206         papi_return( cidx );
02207 
02208     if ( !( ESI->state & PAPI_RUNNING ) )
02209         papi_return( PAPI_ENOTRUN );
02210 
02211     /* If multiplexing is enabled for this eventset, turn if off */
02212 
02213     if ( _papi_hwi_is_sw_multiplex( ESI ) ) {
02214         retval = MPX_stop( ESI->multiplex.mpx_evset, values );
02215         if ( retval != PAPI_OK )
02216             papi_return( retval );
02217 
02218         /* Update the state of this EventSet */
02219 
02220         ESI->state ^= PAPI_RUNNING;
02221         ESI->state |= PAPI_STOPPED;
02222 
02223         return ( PAPI_OK );
02224     }
02225 
02226     /* get the context we should use for this event set */
02227     context = _papi_hwi_get_context( ESI, NULL );
02228     /* Read the current counter values into the EventSet */
02229     retval = _papi_hwi_read( context, ESI, ESI->sw_stop );
02230     if ( retval != PAPI_OK )
02231         papi_return( retval );
02232 
02233     /* Remove the control bits from the active counter config. */
02234     retval = _papi_hwd[cidx]->stop( context, ESI->ctl_state );
02235     if ( retval != PAPI_OK )
02236         papi_return( retval );
02237     if ( values )
02238         memcpy( values, ESI->sw_stop,
02239                 ( size_t ) ESI->NumberOfEvents * sizeof ( long long ) );
02240 
02241     /* If kernel profiling is in use, flush and process the kernel buffer */
02242 
02243     if ( ESI->state & PAPI_PROFILING ) {
02244         if ( _papi_hwd[cidx]->cmp_info.kernel_profile &&
02245              !( ESI->profile.flags & PAPI_PROFIL_FORCE_SW ) ) {
02246             retval = _papi_hwd[cidx]->stop_profiling( ESI->master, ESI );
02247             if ( retval < PAPI_OK )
02248                 papi_return( retval );
02249         }
02250     }
02251 
02252     /* If overflowing is enabled, turn it off */
02253 
02254     if ( ESI->state & PAPI_OVERFLOWING ) {
02255         if ( !( ESI->overflow.flags & PAPI_OVERFLOW_HARDWARE ) ) {
02256             retval = _papi_hwi_stop_timer( _papi_os_info.itimer_num,
02257                                _papi_os_info.itimer_sig );
02258             if ( retval != PAPI_OK )
02259                 papi_return( retval );
02260             _papi_hwi_stop_signal( _papi_os_info.itimer_sig );
02261         }
02262     }
02263 
02264     /* Update the state of this EventSet */
02265 
02266     ESI->state ^= PAPI_RUNNING;
02267     ESI->state |= PAPI_STOPPED;
02268 
02269     /* Update the running event set for this thread */
02270     if ( !(ESI->state & PAPI_CPU_ATTACHED) ) {
02271         if ( !( ESI->state & PAPI_ATTACHED ))
02272             ESI->master->running_eventset[cidx] = NULL;
02273     } else {
02274         ESI->CpuInfo->running_eventset[cidx] = NULL;
02275     }
02276     
02277 #if defined(DEBUG)
02278     if ( _papi_hwi_debug & DEBUG_API ) {
02279         int i;
02280         for ( i = 0; i < ESI->NumberOfEvents; i++ ) {
02281             APIDBG( "PAPI_stop ESI->sw_stop[%d]:\t%llu\n", i, ESI->sw_stop[i] );
02282         }
02283     }
02284 #endif
02285 
02286     return ( PAPI_OK );
02287 }
02288 
02337 int
02338 PAPI_reset( int EventSet )
02339 {
02340     int retval = PAPI_OK;
02341     EventSetInfo_t *ESI;
02342     hwd_context_t *context;
02343     int cidx;
02344 
02345     ESI = _papi_hwi_lookup_EventSet( EventSet );
02346     if ( ESI == NULL )
02347         papi_return( PAPI_ENOEVST );
02348 
02349     cidx = valid_ESI_component( ESI );
02350     if ( cidx < 0 )
02351         papi_return( cidx );
02352 
02353     if ( ESI->state & PAPI_RUNNING ) {
02354         if ( _papi_hwi_is_sw_multiplex( ESI ) ) {
02355             retval = MPX_reset( ESI->multiplex.mpx_evset );
02356         } else {
02357             /* If we're not the only one running, then just
02358                read the current values into the ESI->start
02359                array. This holds the starting value for counters
02360                that are shared. */
02361             /* get the context we should use for this event set */
02362             context = _papi_hwi_get_context( ESI, NULL );
02363             retval = _papi_hwd[cidx]->reset( context, ESI->ctl_state );
02364         }
02365     } else {
02366 #ifdef __bgp__
02367         //  For BG/P, we always want to reset the 'real' hardware counters.  The counters
02368         //  can be controlled via multiple interfaces, and we need to ensure that the values
02369         //  are truly zero...
02370         /* get the context we should use for this event set */
02371         context = _papi_hwi_get_context( ESI, NULL );
02372         retval = _papi_hwd[cidx]->reset( context, ESI->ctl_state );
02373 #endif
02374         memset( ESI->sw_stop, 0x00,
02375                 ( size_t ) ESI->NumberOfEvents * sizeof ( long long ) );
02376     }
02377 
02378     APIDBG( "PAPI_reset returns %d\n", retval );
02379     papi_return( retval );
02380 }
02381 
02438 int
02439 PAPI_read( int EventSet, long long *values )
02440 {
02441     EventSetInfo_t *ESI;
02442     hwd_context_t *context;
02443     int cidx, retval = PAPI_OK;
02444 
02445     ESI = _papi_hwi_lookup_EventSet( EventSet );
02446     if ( ESI == NULL )
02447         papi_return( PAPI_ENOEVST );
02448 
02449     cidx = valid_ESI_component( ESI );
02450     if ( cidx < 0 )
02451         papi_return( cidx );
02452 
02453     if ( values == NULL )
02454         papi_return( PAPI_EINVAL );
02455 
02456     if ( ESI->state & PAPI_RUNNING ) {
02457         if ( _papi_hwi_is_sw_multiplex( ESI ) ) {
02458           retval = MPX_read( ESI->multiplex.mpx_evset, values, 0 );
02459         } else {
02460             /* get the context we should use for this event set */
02461             context = _papi_hwi_get_context( ESI, NULL );
02462             retval = _papi_hwi_read( context, ESI, values );
02463         }
02464         if ( retval != PAPI_OK )
02465             papi_return( retval );
02466     } else {
02467         memcpy( values, ESI->sw_stop,
02468                 ( size_t ) ESI->NumberOfEvents * sizeof ( long long ) );
02469     }
02470 
02471 #if defined(DEBUG)
02472     if ( ISLEVEL( DEBUG_API ) ) {
02473         int i;
02474         for ( i = 0; i < ESI->NumberOfEvents; i++ ) {
02475             APIDBG( "PAPI_read values[%d]:\t%lld\n", i, values[i] );
02476         }
02477     }
02478 #endif
02479 
02480     APIDBG( "PAPI_read returns %d\n", retval );
02481     return ( PAPI_OK );
02482 }
02483 
02528 int
02529 PAPI_read_ts( int EventSet, long long *values, long long *cycles )
02530 {
02531     EventSetInfo_t *ESI;
02532     hwd_context_t *context;
02533     int cidx, retval = PAPI_OK;
02534 
02535     ESI = _papi_hwi_lookup_EventSet( EventSet );
02536     if ( ESI == NULL )
02537         papi_return( PAPI_ENOEVST );
02538 
02539     cidx = valid_ESI_component( ESI );
02540     if ( cidx < 0 )
02541         papi_return( cidx );
02542 
02543     if ( values == NULL )
02544         papi_return( PAPI_EINVAL );
02545 
02546     if ( ESI->state & PAPI_RUNNING ) {
02547         if ( _papi_hwi_is_sw_multiplex( ESI ) ) {
02548           retval = MPX_read( ESI->multiplex.mpx_evset, values, 0 );
02549         } else {
02550             /* get the context we should use for this event set */
02551             context = _papi_hwi_get_context( ESI, NULL );
02552             retval = _papi_hwi_read( context, ESI, values );
02553         }
02554         if ( retval != PAPI_OK )
02555             papi_return( retval );
02556     } else {
02557         memcpy( values, ESI->sw_stop,
02558                 ( size_t ) ESI->NumberOfEvents * sizeof ( long long ) );
02559     }
02560 
02561     *cycles = _papi_os_vector.get_real_cycles(  );
02562 
02563 #if defined(DEBUG)
02564     if ( ISLEVEL( DEBUG_API ) ) {
02565         int i;
02566         for ( i = 0; i < ESI->NumberOfEvents; i++ ) {
02567             APIDBG( "PAPI_read values[%d]:\t%lld\n", i, values[i] );
02568         }
02569     }
02570 #endif
02571 
02572     APIDBG( "PAPI_read_ts returns %d\n", retval );
02573     return PAPI_OK;
02574 }
02575 
02624 int
02625 PAPI_accum( int EventSet, long long *values )
02626 {
02627     EventSetInfo_t *ESI;
02628     hwd_context_t *context;
02629     int i, cidx, retval;
02630     long long a, b, c;
02631 
02632     ESI = _papi_hwi_lookup_EventSet( EventSet );
02633     if ( ESI == NULL )
02634         papi_return( PAPI_ENOEVST );
02635 
02636     cidx = valid_ESI_component( ESI );
02637     if ( cidx < 0 )
02638         papi_return( cidx );
02639 
02640     if ( values == NULL )
02641         papi_return( PAPI_EINVAL );
02642 
02643     if ( ESI->state & PAPI_RUNNING ) {
02644         if ( _papi_hwi_is_sw_multiplex( ESI ) ) {
02645           retval = MPX_read( ESI->multiplex.mpx_evset, ESI->sw_stop, 0 );
02646         } else {
02647             /* get the context we should use for this event set */
02648             context = _papi_hwi_get_context( ESI, NULL );
02649             retval = _papi_hwi_read( context, ESI, ESI->sw_stop );
02650         }
02651         if ( retval != PAPI_OK )
02652             papi_return( retval );
02653     }
02654 
02655     for ( i = 0; i < ESI->NumberOfEvents; i++ ) {
02656         a = ESI->sw_stop[i];
02657         b = values[i];
02658         c = a + b;
02659         values[i] = c;
02660     }
02661 
02662     papi_return( PAPI_reset( EventSet ) );
02663 }
02664 
02691 int
02692 PAPI_write( int EventSet, long long *values )
02693 {
02694     int cidx, retval = PAPI_OK;
02695     EventSetInfo_t *ESI;
02696     hwd_context_t *context;
02697 
02698     ESI = _papi_hwi_lookup_EventSet( EventSet );
02699     if ( ESI == NULL )
02700         papi_return( PAPI_ENOEVST );
02701 
02702     cidx = valid_ESI_component( ESI );
02703     if ( cidx < 0 )
02704         papi_return( cidx );
02705 
02706     if ( values == NULL )
02707         papi_return( PAPI_EINVAL );
02708 
02709     if ( ESI->state & PAPI_RUNNING ) {
02710         /* get the context we should use for this event set */
02711         context = _papi_hwi_get_context( ESI, NULL );
02712         retval = _papi_hwd[cidx]->write( context, ESI->ctl_state, values );
02713         if ( retval != PAPI_OK )
02714             return ( retval );
02715     }
02716 
02717     memcpy( ESI->hw_start, values,
02718             ( size_t ) _papi_hwd[cidx]->cmp_info.num_cntrs *
02719             sizeof ( long long ) );
02720 
02721     return ( retval );
02722 }
02723 
02766 int
02767 PAPI_cleanup_eventset( int EventSet )
02768 {
02769     EventSetInfo_t *ESI;
02770     int i, cidx, total, retval;
02771 
02772     APIDBG("Attempting to cleanup Eventset %d\n",EventSet);
02773 
02774     /* Is the EventSet already in existence? */
02775 
02776     ESI = _papi_hwi_lookup_EventSet( EventSet );
02777     if ( ESI == NULL )
02778         papi_return( PAPI_ENOEVST );
02779 
02780     /* if the eventset has no index and no events, return OK
02781        otherwise return NOCMP */
02782     cidx = valid_ESI_component( ESI );
02783     if ( cidx < 0 ) {
02784         if ( ESI->NumberOfEvents )
02785             papi_return( cidx );
02786         papi_return( PAPI_OK );
02787     }
02788 
02789     /* Of course, it must be stopped in order to modify it. */
02790 
02791     if ( ESI->state & PAPI_RUNNING )
02792         papi_return( PAPI_EISRUN );
02793 
02794     /* clear overflow flag and turn off hardware overflow handler */
02795     if ( ESI->state & PAPI_OVERFLOWING ) {
02796         total = ESI->overflow.event_counter;
02797         for ( i = 0; i < total; i++ ) {
02798             retval = PAPI_overflow( EventSet,
02799                                     ESI->overflow.EventCode[0], 0, 0, NULL );
02800             if ( retval != PAPI_OK )
02801                 papi_return( retval );
02802         }
02803     }
02804 
02805     /* clear profile flag and turn off hardware profile handler */
02806     if ( ( ESI->state & PAPI_PROFILING ) &&
02807          _papi_hwd[cidx]->cmp_info.hardware_intr &&
02808          !( ESI->profile.flags & PAPI_PROFIL_FORCE_SW ) ) {
02809         total = ESI->profile.event_counter;
02810         for ( i = 0; i < total; i++ ) {
02811             retval =
02812                 PAPI_sprofil( NULL, 0, EventSet, ESI->profile.EventCode[0], 0,
02813                               PAPI_PROFIL_POSIX );
02814             if ( retval != PAPI_OK )
02815                 papi_return( retval );
02816         }
02817     }
02818 
02819     if ( _papi_hwi_is_sw_multiplex( ESI ) ) {
02820         retval = MPX_cleanup( &ESI->multiplex.mpx_evset );
02821         if ( retval != PAPI_OK )
02822             papi_return( retval );
02823     }
02824 
02825     retval = _papi_hwd[cidx]->cleanup_eventset( ESI->ctl_state );
02826     if ( retval != PAPI_OK ) 
02827         papi_return( retval );
02828 
02829     /* Now do the magic */
02830     papi_return( _papi_hwi_cleanup_eventset( ESI ) );
02831 }
02832 
02860 int
02861 PAPI_multiplex_init( void )
02862 {
02863     int retval;
02864 
02865     retval = mpx_init( _papi_os_info.itimer_ns );
02866     papi_return( retval );
02867 }
02868 
02929 int
02930 PAPI_state( int EventSet, int *status )
02931 {
02932     EventSetInfo_t *ESI;
02933 
02934     if ( status == NULL )
02935         papi_return( PAPI_EINVAL );
02936 
02937     /* check for good EventSetIndex value */
02938 
02939     ESI = _papi_hwi_lookup_EventSet( EventSet );
02940     if ( ESI == NULL )
02941         papi_return( PAPI_ENOEVST );
02942 
02943     /*read status FROM ESI->state */
02944 
02945     *status = ESI->state;
02946 
02947     return ( PAPI_OK );
02948 }
02949 
03000 int
03001 PAPI_set_debug( int level )
03002 {
03003     PAPI_option_t option;
03004 
03005     memset( &option, 0x0, sizeof ( option ) );
03006     option.debug.level = level;
03007     option.debug.handler = _papi_hwi_debug_handler;
03008     return ( PAPI_set_opt( PAPI_DEBUG, &option ) );
03009 }
03010 
03011 /* Attaches to or detaches from the specified thread id */
03012 inline_static int
03013 _papi_set_attach( int option, int EventSet, unsigned long tid )
03014 {
03015     PAPI_option_t attach;
03016 
03017     memset( &attach, 0x0, sizeof ( attach ) );
03018     attach.attach.eventset = EventSet;
03019     attach.attach.tid = tid;
03020     return ( PAPI_set_opt( option, &attach ) );
03021 }
03022 
03076 int
03077 PAPI_attach( int EventSet, unsigned long tid )
03078 {
03079     return ( _papi_set_attach( PAPI_ATTACH, EventSet, tid ) );
03080 }
03081 
03135 int
03136 PAPI_detach( int EventSet )
03137 {
03138     return ( _papi_set_attach( PAPI_DETACH, EventSet, 0 ) );
03139 }
03140 
03209 int
03210 PAPI_set_multiplex( int EventSet )
03211 {
03212     PAPI_option_t mpx;
03213     EventSetInfo_t *ESI;
03214     int cidx;
03215     int ret;
03216 
03217     /* Is the EventSet already in existence? */
03218 
03219     ESI = _papi_hwi_lookup_EventSet( EventSet );
03220 
03221     if ( ESI == NULL )
03222         papi_return( PAPI_ENOEVST );
03223 
03224     /* if the eventset has no index return NOCMP */
03225     cidx = valid_ESI_component( ESI );
03226     if ( cidx < 0 )
03227         papi_return( cidx );
03228 
03229     if ( ( ret = mpx_check( EventSet ) ) != PAPI_OK )
03230         papi_return( ret );
03231 
03232     memset( &mpx, 0x0, sizeof ( mpx ) );
03233     mpx.multiplex.eventset = EventSet;
03234     mpx.multiplex.flags = PAPI_MULTIPLEX_DEFAULT;
03235     mpx.multiplex.ns = _papi_os_info.itimer_ns;
03236     return ( PAPI_set_opt( PAPI_MULTIPLEX, &mpx ) );
03237 }
03238 
03339 int
03340 PAPI_set_opt( int option, PAPI_option_t * ptr )
03341 {
03342     APIDBG("Entry:  option: %d, ptr: %p\n", option, ptr);
03343 
03344     _papi_int_option_t internal;
03345     int retval = PAPI_OK;
03346     hwd_context_t *context;
03347     int cidx;
03348 
03349     if ( ( option != PAPI_DEBUG ) && ( init_level == PAPI_NOT_INITED ) )
03350         papi_return( PAPI_ENOINIT );
03351     if ( ptr == NULL )
03352         papi_return( PAPI_EINVAL );
03353 
03354     memset( &internal, 0x0, sizeof ( _papi_int_option_t ) );
03355 
03356     switch ( option ) {
03357     case PAPI_DETACH:
03358     {
03359         internal.attach.ESI = _papi_hwi_lookup_EventSet( ptr->attach.eventset );
03360         if ( internal.attach.ESI == NULL )
03361             papi_return( PAPI_ENOEVST );
03362 
03363         cidx = valid_ESI_component( internal.attach.ESI );
03364         if ( cidx < 0 )
03365             papi_return( cidx );
03366 
03367         if ( _papi_hwd[cidx]->cmp_info.attach == 0 )
03368             papi_return( PAPI_ECMP );
03369 
03370         /* if attached to a cpu, return an error */
03371         if (internal.attach.ESI->state & PAPI_CPU_ATTACHED)
03372             papi_return( PAPI_ECMP );
03373 
03374         if ( ( internal.attach.ESI->state & PAPI_STOPPED ) == 0 )
03375             papi_return( PAPI_EISRUN );
03376 
03377         if ( ( internal.attach.ESI->state & PAPI_ATTACHED ) == 0 )
03378             papi_return( PAPI_EINVAL );
03379 
03380         internal.attach.tid = internal.attach.ESI->attach.tid;
03381         /* get the context we should use for this event set */
03382         context = _papi_hwi_get_context( internal.attach.ESI, NULL );
03383         retval = _papi_hwd[cidx]->ctl( context, PAPI_DETACH, &internal );
03384         if ( retval != PAPI_OK )
03385             papi_return( retval );
03386 
03387         internal.attach.ESI->state ^= PAPI_ATTACHED;
03388         internal.attach.ESI->attach.tid = 0;
03389         return ( PAPI_OK );
03390     }
03391     case PAPI_ATTACH:
03392     {
03393         internal.attach.ESI = _papi_hwi_lookup_EventSet( ptr->attach.eventset );
03394         if ( internal.attach.ESI == NULL )
03395             papi_return( PAPI_ENOEVST );
03396 
03397         cidx = valid_ESI_component( internal.attach.ESI );
03398         if ( cidx < 0 )
03399             papi_return( cidx );
03400 
03401         if ( _papi_hwd[cidx]->cmp_info.attach == 0 )
03402             papi_return( PAPI_ECMP );
03403 
03404         if ( ( internal.attach.ESI->state & PAPI_STOPPED ) == 0 )
03405             papi_return( PAPI_EISRUN );
03406 
03407         if ( internal.attach.ESI->state & PAPI_ATTACHED )
03408             papi_return( PAPI_EINVAL );
03409 
03410         /* if attached to a cpu, return an error */
03411         if (internal.attach.ESI->state & PAPI_CPU_ATTACHED)
03412             papi_return( PAPI_ECMP );
03413 
03414         internal.attach.tid = ptr->attach.tid;
03415         /* get the context we should use for this event set */
03416         context = _papi_hwi_get_context( internal.attach.ESI, NULL );
03417         retval = _papi_hwd[cidx]->ctl( context, PAPI_ATTACH, &internal );
03418         if ( retval != PAPI_OK )
03419             papi_return( retval );
03420 
03421         internal.attach.ESI->state |= PAPI_ATTACHED;
03422         internal.attach.ESI->attach.tid = ptr->attach.tid;
03423 
03424         _papi_hwi_lookup_or_create_thread( 
03425                       &(internal.attach.ESI->master), ptr->attach.tid );
03426 
03427         return ( PAPI_OK );
03428     }
03429     case PAPI_CPU_ATTACH:
03430     {
03431         APIDBG("eventset: %d, cpu_num: %d\n", ptr->cpu.eventset, ptr->cpu.cpu_num);
03432         internal.cpu.ESI = _papi_hwi_lookup_EventSet( ptr->cpu.eventset );
03433         if ( internal.cpu.ESI == NULL )
03434             papi_return( PAPI_ENOEVST );
03435 
03436         internal.cpu.cpu_num = ptr->cpu.cpu_num;
03437         APIDBG("internal: %p, ESI: %p, cpu_num: %d\n", &internal, internal.cpu.ESI, internal.cpu.cpu_num);
03438 
03439         cidx = valid_ESI_component( internal.cpu.ESI );
03440         if ( cidx < 0 )
03441             papi_return( cidx );
03442 
03443         if ( _papi_hwd[cidx]->cmp_info.cpu == 0 )
03444             papi_return( PAPI_ECMP );
03445 
03446         // can not attach to a cpu if already attached to a process or 
03447         // counters set to be inherited by child processes
03448         if ( internal.cpu.ESI->state & (PAPI_ATTACHED | PAPI_INHERIT) )
03449             papi_return( PAPI_EINVAL );
03450 
03451         if ( ( internal.cpu.ESI->state & PAPI_STOPPED ) == 0 )
03452             papi_return( PAPI_EISRUN );
03453 
03454         retval = _papi_hwi_lookup_or_create_cpu(&internal.cpu.ESI->CpuInfo, internal.cpu.cpu_num);
03455         if( retval != PAPI_OK) {
03456             papi_return( retval );
03457         }
03458 
03459         /* get the context we should use for this event set */
03460         context = _papi_hwi_get_context( internal.cpu.ESI, NULL );
03461         retval = _papi_hwd[cidx]->ctl( context, PAPI_CPU_ATTACH, &internal );
03462         if ( retval != PAPI_OK )
03463             papi_return( retval );
03464 
03465         /* set to show this event set is attached to a cpu not a thread */
03466         internal.cpu.ESI->state |= PAPI_CPU_ATTACHED;
03467         return ( PAPI_OK );
03468     }
03469     case PAPI_DEF_MPX_NS:
03470     {
03471         cidx = 0;            /* xxxx for now, assume we only check against cpu component */
03472         if ( ptr->multiplex.ns < 0 )
03473             papi_return( PAPI_EINVAL );
03474         /* We should check the resolution here with the system, either
03475            component if kernel multiplexing or PAPI if SW multiplexing. */
03476         internal.multiplex.ns = ( unsigned long ) ptr->multiplex.ns;
03477         /* get the context we should use for this event set */
03478         context = _papi_hwi_get_context( internal.cpu.ESI, NULL );
03479         /* Low level just checks/adjusts the args for this component */
03480         retval = _papi_hwd[cidx]->ctl( context, PAPI_DEF_MPX_NS, &internal );
03481         if ( retval == PAPI_OK ) {
03482             _papi_os_info.itimer_ns = ( int ) internal.multiplex.ns;
03483             ptr->multiplex.ns = ( int ) internal.multiplex.ns;
03484         }
03485         papi_return( retval );
03486     }
03487     case PAPI_DEF_ITIMER_NS:
03488     {
03489         cidx = 0;            /* xxxx for now, assume we only check against cpu component */
03490         if ( ptr->itimer.ns < 0 )
03491             papi_return( PAPI_EINVAL );
03492         internal.itimer.ns = ptr->itimer.ns;
03493         /* Low level just checks/adjusts the args for this component */
03494         retval = _papi_hwd[cidx]->ctl( NULL, PAPI_DEF_ITIMER_NS, &internal );
03495         if ( retval == PAPI_OK ) {
03496             _papi_os_info.itimer_ns = internal.itimer.ns;
03497             ptr->itimer.ns = internal.itimer.ns;
03498         }
03499         papi_return( retval );
03500     }
03501     case PAPI_DEF_ITIMER:
03502     {
03503         cidx = 0;            /* xxxx for now, assume we only check against cpu component */
03504         if ( ptr->itimer.ns < 0 )
03505             papi_return( PAPI_EINVAL );
03506         memcpy( &internal.itimer, &ptr->itimer,
03507                 sizeof ( PAPI_itimer_option_t ) );
03508         /* Low level just checks/adjusts the args for this component */
03509         retval = _papi_hwd[cidx]->ctl( NULL, PAPI_DEF_ITIMER, &internal );
03510         if ( retval == PAPI_OK ) {
03511             _papi_os_info.itimer_num = ptr->itimer.itimer_num;
03512             _papi_os_info.itimer_sig = ptr->itimer.itimer_sig;
03513             if ( ptr->itimer.ns > 0 )
03514                 _papi_os_info.itimer_ns = ptr->itimer.ns;
03515             /* flags are currently ignored, eventually the flags will be able
03516                to specify whether or not we use POSIX itimers (clock_gettimer) */
03517         }
03518         papi_return( retval );
03519     }
03520     case PAPI_MULTIPLEX:
03521     {
03522         EventSetInfo_t *ESI;
03523         ESI = _papi_hwi_lookup_EventSet( ptr->multiplex.eventset );
03524        
03525         if ( ESI == NULL )
03526             papi_return( PAPI_ENOEVST );
03527 
03528         cidx = valid_ESI_component( ESI );
03529         if ( cidx < 0 )
03530             papi_return( cidx );
03531        
03532         if ( !( ESI->state & PAPI_STOPPED ) )
03533             papi_return( PAPI_EISRUN );
03534         if ( ESI->state & PAPI_MULTIPLEXING )
03535             papi_return( PAPI_EINVAL );
03536 
03537         if ( ptr->multiplex.ns < 0 )
03538             papi_return( PAPI_EINVAL );
03539         internal.multiplex.ESI = ESI;
03540         internal.multiplex.ns = ( unsigned long ) ptr->multiplex.ns;
03541         internal.multiplex.flags = ptr->multiplex.flags;
03542         if ( ( _papi_hwd[cidx]->cmp_info.kernel_multiplex ) &&
03543              ( ( ptr->multiplex.flags & PAPI_MULTIPLEX_FORCE_SW ) == 0 ) ) {
03544             /* get the context we should use for this event set */
03545             context = _papi_hwi_get_context( ESI, NULL );
03546             retval = _papi_hwd[cidx]->ctl( context, PAPI_MULTIPLEX, &internal );
03547         }
03548         /* Kernel or PAPI may have changed this value so send it back out to the user */
03549         ptr->multiplex.ns = ( int ) internal.multiplex.ns;
03550         if ( retval == PAPI_OK )
03551             papi_return( _papi_hwi_convert_eventset_to_multiplex
03552                          ( &internal.multiplex ) );
03553         return ( retval );
03554     }
03555     case PAPI_DEBUG:
03556     {
03557         int level = ptr->debug.level;
03558         switch ( level ) {
03559         case PAPI_QUIET:
03560         case PAPI_VERB_ESTOP:
03561         case PAPI_VERB_ECONT:
03562             _papi_hwi_error_level = level;
03563             break;
03564         default:
03565             papi_return( PAPI_EINVAL );
03566         }
03567         _papi_hwi_debug_handler = ptr->debug.handler;
03568         return ( PAPI_OK );
03569     }
03570     case PAPI_DEFDOM:
03571     {
03572         int dom = ptr->defdomain.domain;
03573         if ( ( dom < PAPI_DOM_MIN ) || ( dom > PAPI_DOM_MAX ) )
03574             papi_return( PAPI_EINVAL );
03575 
03576         /* Change the global structure. The _papi_hwd_init_control_state function 
03577            in the components gets information from the global structure instead of
03578            per-thread information. */
03579         cidx = valid_component( ptr->defdomain.def_cidx );
03580         if ( cidx < 0 )
03581             papi_return( cidx );
03582 
03583         /* Check what the component supports */
03584 
03585         if ( dom == PAPI_DOM_ALL )
03586             dom = _papi_hwd[cidx]->cmp_info.available_domains;
03587 
03588         if ( dom & ~_papi_hwd[cidx]->cmp_info.available_domains )
03589             papi_return( PAPI_EINVAL );
03590 
03591         _papi_hwd[cidx]->cmp_info.default_domain = dom;
03592 
03593         return ( PAPI_OK );
03594     }
03595     case PAPI_DOMAIN:
03596     {
03597         int dom = ptr->domain.domain;
03598         if ( ( dom < PAPI_DOM_MIN ) || ( dom > PAPI_DOM_MAX ) )
03599             papi_return( PAPI_EINVAL_DOM );
03600 
03601         internal.domain.ESI = _papi_hwi_lookup_EventSet( ptr->domain.eventset );
03602         if ( internal.domain.ESI == NULL )
03603             papi_return( PAPI_ENOEVST );
03604 
03605         cidx = valid_ESI_component( internal.domain.ESI );
03606         if ( cidx < 0 )
03607             papi_return( cidx );
03608 
03609         /* Check what the component supports */
03610 
03611         if ( dom == PAPI_DOM_ALL )
03612             dom = _papi_hwd[cidx]->cmp_info.available_domains;
03613 
03614         if ( dom & ~_papi_hwd[cidx]->cmp_info.available_domains )
03615             papi_return( PAPI_EINVAL_DOM );
03616 
03617         if ( !( internal.domain.ESI->state & PAPI_STOPPED ) )
03618             papi_return( PAPI_EISRUN );
03619 
03620         /* Try to change the domain of the eventset in the hardware */
03621         internal.domain.domain = dom;
03622         internal.domain.eventset = ptr->domain.eventset;
03623         /* get the context we should use for this event set */
03624         context = _papi_hwi_get_context( internal.domain.ESI, NULL );
03625         retval = _papi_hwd[cidx]->ctl( context, PAPI_DOMAIN, &internal );
03626         if ( retval < PAPI_OK )
03627             papi_return( retval );
03628 
03629         /* Change the domain of the eventset in the library */
03630 
03631         internal.domain.ESI->domain.domain = dom;
03632 
03633         return ( retval );
03634     }
03635     case PAPI_DEFGRN:
03636     {
03637         int grn = ptr->defgranularity.granularity;
03638         if ( ( grn < PAPI_GRN_MIN ) || ( grn > PAPI_GRN_MAX ) )
03639             papi_return( PAPI_EINVAL );
03640 
03641         cidx = valid_component( ptr->defgranularity.def_cidx );
03642         if ( cidx < 0 )
03643             papi_return( cidx );
03644 
03645         /* Change the component structure. The _papi_hwd_init_control_state function 
03646            in the components gets information from the global structure instead of
03647            per-thread information. */
03648 
03649         /* Check what the component supports */
03650 
03651         if ( grn & ~_papi_hwd[cidx]->cmp_info.available_granularities )
03652             papi_return( PAPI_EINVAL );
03653 
03654         /* Make sure there is only 1 set. */
03655         if ( grn ^ ( 1 << ( ffs( grn ) - 1 ) ) )
03656             papi_return( PAPI_EINVAL );
03657 
03658         _papi_hwd[cidx]->cmp_info.default_granularity = grn;
03659 
03660         return ( PAPI_OK );
03661     }
03662     case PAPI_GRANUL:
03663     {
03664         int grn = ptr->granularity.granularity;
03665 
03666         if ( ( grn < PAPI_GRN_MIN ) || ( grn > PAPI_GRN_MAX ) )
03667             papi_return( PAPI_EINVAL );
03668 
03669         internal.granularity.ESI =
03670             _papi_hwi_lookup_EventSet( ptr->granularity.eventset );
03671         if ( internal.granularity.ESI == NULL )
03672             papi_return( PAPI_ENOEVST );
03673 
03674         cidx = valid_ESI_component( internal.granularity.ESI );
03675         if ( cidx < 0 )
03676             papi_return( cidx );
03677 
03678         /* Check what the component supports */
03679 
03680         if ( grn & ~_papi_hwd[cidx]->cmp_info.available_granularities )
03681             papi_return( PAPI_EINVAL );
03682 
03683         /* Make sure there is only 1 set. */
03684         if ( grn ^ ( 1 << ( ffs( grn ) - 1 ) ) )
03685             papi_return( PAPI_EINVAL );
03686 
03687         internal.granularity.granularity = grn;
03688         internal.granularity.eventset = ptr->granularity.eventset;
03689         retval = _papi_hwd[cidx]->ctl( NULL, PAPI_GRANUL, &internal );
03690         if ( retval < PAPI_OK )
03691             return ( retval );
03692 
03693         internal.granularity.ESI->granularity.granularity = grn;
03694         return ( retval );
03695     }
03696     case PAPI_INHERIT:
03697     {
03698         if ( ptr == NULL )
03699             papi_return( PAPI_EINVAL );
03700         EventSetInfo_t *ESI;
03701         ESI = _papi_hwi_lookup_EventSet( ptr->inherit.eventset );
03702         if ( ESI == NULL )
03703             papi_return( PAPI_ENOEVST );
03704 
03705         cidx = valid_ESI_component( ESI );
03706         if ( cidx < 0 )
03707             papi_return( cidx );
03708 
03709         if ( _papi_hwd[cidx]->cmp_info.inherit == 0 )
03710             papi_return( PAPI_ECMP );
03711 
03712         if ( ( ESI->state & PAPI_STOPPED ) == 0 )
03713             papi_return( PAPI_EISRUN );
03714 
03715         /* if attached to a cpu, return an error */
03716         if (ESI->state & PAPI_CPU_ATTACHED)
03717             papi_return( PAPI_ECMP );
03718 
03719         internal.inherit.ESI = ESI;
03720         internal.inherit.inherit = ptr->inherit.inherit;
03721 
03722         /* get the context we should use for this event set */
03723         context = _papi_hwi_get_context( internal.inherit.ESI, NULL );
03724         retval = _papi_hwd[cidx]->ctl( context, PAPI_INHERIT, &internal );
03725         if ( retval < PAPI_OK )
03726             return ( retval );
03727 
03728         ESI->inherit.inherit = ptr->inherit.inherit;
03729         return ( retval );
03730     }
03731     case PAPI_DATA_ADDRESS:
03732     case PAPI_INSTR_ADDRESS:
03733     {
03734 
03735         EventSetInfo_t *ESI;
03736 
03737         ESI = _papi_hwi_lookup_EventSet( ptr->addr.eventset );
03738         if ( ESI == NULL )
03739             papi_return( PAPI_ENOEVST );
03740 
03741         cidx = valid_ESI_component( ESI );
03742         if ( cidx < 0 )
03743             papi_return( cidx );
03744 
03745         internal.address_range.ESI = ESI;
03746 
03747         if ( !( internal.address_range.ESI->state & PAPI_STOPPED ) )
03748             papi_return( PAPI_EISRUN );
03749 
03750         /*set domain to be PAPI_DOM_USER */
03751         internal.address_range.domain = PAPI_DOM_USER;
03752 
03753         internal.address_range.start = ptr->addr.start;
03754         internal.address_range.end = ptr->addr.end;
03755         /* get the context we should use for this event set */
03756         context = _papi_hwi_get_context( internal.address_range.ESI, NULL );
03757         retval = _papi_hwd[cidx]->ctl( context, option, &internal );
03758         ptr->addr.start_off = internal.address_range.start_off;
03759         ptr->addr.end_off = internal.address_range.end_off;
03760         papi_return( retval );
03761     }
03762     case PAPI_USER_EVENTS_FILE:
03763     {
03764       SUBDBG("Filename is -%s-\n", ptr->events_file);
03765       _papi_user_defined_events_setup(ptr->events_file);
03766       return( PAPI_OK );
03767     }
03768     default:
03769         papi_return( PAPI_EINVAL );
03770     }
03771 }
03772 
03782 int
03783 PAPI_num_hwctrs( void )
03784 {
03785     return ( PAPI_num_cmp_hwctrs( 0 ) );
03786 }
03787 
03837 int
03838 PAPI_num_cmp_hwctrs( int cidx )
03839 {
03840     return ( PAPI_get_cmp_opt( PAPI_MAX_HWCTRS, NULL, cidx ) );
03841 }
03842 
03899 int
03900 PAPI_get_multiplex( int EventSet )
03901 {
03902     PAPI_option_t popt;
03903     int retval;
03904 
03905     popt.multiplex.eventset = EventSet;
03906     retval = PAPI_get_opt( PAPI_MULTIPLEX, &popt );
03907     if ( retval < 0 )
03908         retval = 0;
03909     return retval;
03910 }
03911 
04013 int
04014 PAPI_get_opt( int option, PAPI_option_t * ptr )
04015 {
04016     EventSetInfo_t *ESI;
04017 
04018     if ( ( option != PAPI_DEBUG ) && ( init_level == PAPI_NOT_INITED ) )
04019         papi_return( PAPI_ENOINIT );
04020 
04021     switch ( option ) {
04022     case PAPI_DETACH:
04023     {
04024         if ( ptr == NULL )
04025             papi_return( PAPI_EINVAL );
04026         ESI = _papi_hwi_lookup_EventSet( ptr->attach.eventset );
04027         if ( ESI == NULL )
04028             papi_return( PAPI_ENOEVST );
04029         ptr->attach.tid = ESI->attach.tid;
04030         return ( ( ESI->state & PAPI_ATTACHED ) == 0 );
04031     }
04032     case PAPI_ATTACH:
04033     {
04034         if ( ptr == NULL )
04035             papi_return( PAPI_EINVAL );
04036         ESI = _papi_hwi_lookup_EventSet( ptr->attach.eventset );
04037         if ( ESI == NULL )
04038             papi_return( PAPI_ENOEVST );
04039         ptr->attach.tid = ESI->attach.tid;
04040         return ( ( ESI->state & PAPI_ATTACHED ) != 0 );
04041     }
04042     case PAPI_CPU_ATTACH:
04043     {
04044         if ( ptr == NULL )
04045             papi_return( PAPI_EINVAL );
04046         ESI = _papi_hwi_lookup_EventSet( ptr->attach.eventset );
04047         if ( ESI == NULL )
04048             papi_return( PAPI_ENOEVST );
04049         ptr->cpu.cpu_num = ESI->CpuInfo->cpu_num;
04050         return ( ( ESI->state & PAPI_CPU_ATTACHED ) != 0 );
04051     }
04052     case PAPI_DEF_MPX_NS:
04053     {
04054         /* xxxx for now, assume we only check against cpu component */
04055         if ( ptr == NULL )
04056             papi_return( PAPI_EINVAL );
04057         ptr->multiplex.ns = _papi_os_info.itimer_ns;
04058         return ( PAPI_OK );
04059     }
04060     case PAPI_DEF_ITIMER_NS:
04061     {
04062         /* xxxx for now, assume we only check against cpu component */
04063         if ( ptr == NULL )
04064             papi_return( PAPI_EINVAL );
04065         ptr->itimer.ns = _papi_os_info.itimer_ns;
04066         return ( PAPI_OK );
04067     }
04068     case PAPI_DEF_ITIMER:
04069     {
04070         /* xxxx for now, assume we only check against cpu component */
04071         if ( ptr == NULL )
04072             papi_return( PAPI_EINVAL );
04073         ptr->itimer.itimer_num = _papi_os_info.itimer_num;
04074         ptr->itimer.itimer_sig = _papi_os_info.itimer_sig;
04075         ptr->itimer.ns = _papi_os_info.itimer_ns;
04076         ptr->itimer.flags = 0;
04077         return ( PAPI_OK );
04078     }
04079     case PAPI_MULTIPLEX:
04080     {
04081         if ( ptr == NULL )
04082             papi_return( PAPI_EINVAL );
04083         ESI = _papi_hwi_lookup_EventSet( ptr->multiplex.eventset );
04084         if ( ESI == NULL )
04085             papi_return( PAPI_ENOEVST );
04086         ptr->multiplex.ns = ESI->multiplex.ns;
04087         ptr->multiplex.flags = ESI->multiplex.flags;
04088         return ( ESI->state & PAPI_MULTIPLEXING ) != 0;
04089     }
04090     case PAPI_PRELOAD:
04091         if ( ptr == NULL )
04092             papi_return( PAPI_EINVAL );
04093         memcpy( &ptr->preload, &_papi_hwi_system_info.preload_info,
04094                 sizeof ( PAPI_preload_info_t ) );
04095         break;
04096     case PAPI_DEBUG:
04097         if ( ptr == NULL )
04098             papi_return( PAPI_EINVAL );
04099         ptr->debug.level = _papi_hwi_error_level;
04100         ptr->debug.handler = _papi_hwi_debug_handler;
04101         break;
04102     case PAPI_CLOCKRATE:
04103         return ( ( int ) _papi_hwi_system_info.hw_info.cpu_max_mhz );
04104     case PAPI_MAX_CPUS:
04105         return ( _papi_hwi_system_info.hw_info.ncpu );
04106         /* For now, MAX_HWCTRS and MAX CTRS are identical.
04107            At some future point, they may map onto different values.
04108          */
04109     case PAPI_INHERIT:
04110     {
04111         if ( ptr == NULL )
04112             papi_return( PAPI_EINVAL );
04113         ESI = _papi_hwi_lookup_EventSet( ptr->inherit.eventset );
04114         if ( ESI == NULL )
04115             papi_return( PAPI_ENOEVST );
04116         ptr->inherit.inherit = ESI->inherit.inherit;
04117         return ( PAPI_OK );
04118     }
04119     case PAPI_GRANUL:
04120         if ( ptr == NULL )
04121             papi_return( PAPI_EINVAL );
04122         ESI = _papi_hwi_lookup_EventSet( ptr->granularity.eventset );
04123         if ( ESI == NULL )
04124             papi_return( PAPI_ENOEVST );
04125         ptr->granularity.granularity = ESI->granularity.granularity;
04126         break;
04127     case PAPI_EXEINFO:
04128         if ( ptr == NULL )
04129             papi_return( PAPI_EINVAL );
04130         ptr->exe_info = &_papi_hwi_system_info.exe_info;
04131         break;
04132     case PAPI_HWINFO:
04133         if ( ptr == NULL )
04134             papi_return( PAPI_EINVAL );
04135         ptr->hw_info = &_papi_hwi_system_info.hw_info;
04136         break;
04137 
04138     case PAPI_DOMAIN:
04139         if ( ptr == NULL )
04140             papi_return( PAPI_EINVAL );
04141         ESI = _papi_hwi_lookup_EventSet( ptr->domain.eventset );
04142         if ( ESI == NULL )
04143             papi_return( PAPI_ENOEVST );
04144         ptr->domain.domain = ESI->domain.domain;
04145         return ( PAPI_OK );
04146     case PAPI_LIB_VERSION:
04147         return ( PAPI_VERSION );
04148 /* The following cases all require a component index 
04149     and are handled by PAPI_get_cmp_opt() with cidx == 0*/
04150     case PAPI_MAX_HWCTRS:
04151     case PAPI_MAX_MPX_CTRS:
04152     case PAPI_DEFDOM:
04153     case PAPI_DEFGRN:
04154     case PAPI_SHLIBINFO:
04155     case PAPI_COMPONENTINFO:
04156         return ( PAPI_get_cmp_opt( option, ptr, 0 ) );
04157     default:
04158         papi_return( PAPI_EINVAL );
04159     }
04160     return ( PAPI_OK );
04161 }
04162 
04204 int
04205 PAPI_get_cmp_opt( int option, PAPI_option_t * ptr, int cidx )
04206 {
04207 
04208   if (_papi_hwi_invalid_cmp(cidx)) {
04209      return PAPI_ECMP;
04210   }
04211 
04212     switch ( option ) {
04213         /* For now, MAX_HWCTRS and MAX CTRS are identical.
04214            At some future point, they may map onto different values.
04215          */
04216     case PAPI_MAX_HWCTRS:
04217         return ( _papi_hwd[cidx]->cmp_info.num_cntrs );
04218     case PAPI_MAX_MPX_CTRS:
04219         return ( _papi_hwd[cidx]->cmp_info.num_mpx_cntrs );
04220     case PAPI_DEFDOM:
04221         return ( _papi_hwd[cidx]->cmp_info.default_domain );
04222     case PAPI_DEFGRN:
04223         return ( _papi_hwd[cidx]->cmp_info.default_granularity );
04224     case PAPI_SHLIBINFO:
04225     {
04226         int retval;
04227         if ( ptr == NULL )
04228             papi_return( PAPI_EINVAL );
04229         retval = _papi_os_vector.update_shlib_info( &_papi_hwi_system_info );
04230         ptr->shlib_info = &_papi_hwi_system_info.shlib_info;
04231         papi_return( retval );
04232     }
04233     case PAPI_COMPONENTINFO:
04234         if ( ptr == NULL )
04235             papi_return( PAPI_EINVAL );
04236         ptr->cmp_info = &( _papi_hwd[cidx]->cmp_info );
04237         return PAPI_OK;
04238     default:
04239       papi_return( PAPI_EINVAL );
04240     }
04241     return PAPI_OK;
04242 }
04243 
04255 int
04256 PAPI_num_components( void )
04257 {
04258     return ( papi_num_components );
04259 }
04260 
04295 int
04296 PAPI_num_events( int EventSet )
04297 {
04298     EventSetInfo_t *ESI;
04299 
04300     ESI = _papi_hwi_lookup_EventSet( EventSet );
04301     if ( !ESI )
04302         papi_return( PAPI_ENOEVST );
04303 
04304 #ifdef DEBUG
04305     /* Not necessary */
04306     if ( ESI->NumberOfEvents == 0 )
04307         papi_return( PAPI_EINVAL );
04308 #endif
04309 
04310     return ( ESI->NumberOfEvents );
04311 }
04312 
04313 
04329 void
04330 PAPI_shutdown( void )
04331 {
04332         EventSetInfo_t *ESI;
04333         ThreadInfo_t *master;
04334         DynamicArray_t *map = &_papi_hwi_system_info.global_eventset_map;
04335         int i, j = 0, retval;
04336 
04337 
04338     APIDBG( "Enter\n" );
04339     if ( init_retval == DEADBEEF ) {
04340         PAPIERROR( PAPI_SHUTDOWN_str );
04341         return;
04342     }
04343 
04344     MPX_shutdown(  );
04345 
04346     /* Free all EventSets for this thread */
04347 
04348    master = _papi_hwi_lookup_thread( 0 );
04349 
04350       /* Count number of running EventSets AND */
04351       /* Stop any running EventSets in this thread */
04352 
04353 #ifdef DEBUG
04354 again:
04355 #endif
04356    for( i = 0; i < map->totalSlots; i++ ) {
04357       ESI = map->dataSlotArray[i];
04358       if ( ESI ) {
04359      if ( ESI->master == master ) {
04360         if ( ESI->state & PAPI_RUNNING ) {
04361            retval=PAPI_stop( i, NULL );
04362         }
04363         retval=PAPI_cleanup_eventset( i );
04364         if (retval!=PAPI_OK) PAPIERROR("Error during cleanup.\n");
04365         _papi_hwi_free_EventSet( ESI );
04366      } 
04367          else {
04368             if ( ESI->state & PAPI_RUNNING ) {
04369            j++;
04370         }
04371      }
04372       }
04373    }
04374 
04375     /* No locking required, we're just waiting for the others
04376        to call shutdown or stop their eventsets. */
04377 
04378 #ifdef DEBUG
04379     if ( j != 0 ) {
04380         PAPIERROR( PAPI_SHUTDOWN_SYNC_str );
04381         sleep( 1 );
04382         j = 0;
04383         goto again;
04384     }
04385 #endif
04386 
04387     /* Shutdown the entire component */
04388 
04389     _papi_cleanup_user_events();
04390 
04391     _papi_hwi_shutdown_highlevel(  );
04392     _papi_hwi_shutdown_global_internal(  );
04393     _papi_hwi_shutdown_global_threads(  );
04394     for( i = 0; i < papi_num_components; i++ ) {
04395        if (!_papi_hwd[i]->cmp_info.disabled) {
04396               _papi_hwd[i]->shutdown_component(  );
04397        }
04398     }
04399 
04400     /* Now it is safe to call re-init */
04401 
04402     init_retval = DEADBEEF;
04403     init_level = PAPI_NOT_INITED;
04404     _papi_mem_cleanup_all(  );
04405 }
04406 
04455 char *
04456 PAPI_strerror( int errorCode )
04457 {
04458     if ( ( errorCode > 0 ) || ( -errorCode > _papi_hwi_num_errors ) )
04459         return ( NULL );
04460 
04461     return ( _papi_errlist[-errorCode] );
04462 }
04463 
04505 void
04506 PAPI_perror( char *msg )
04507 {
04508     char *foo;
04509 
04510     foo = PAPI_strerror( _papi_hwi_errno );
04511     if ( foo == NULL )
04512         return;
04513 
04514     if ( msg )
04515         if ( *msg )
04516                 fprintf( stderr, "%s: ", msg );
04517 
04518     fprintf( stderr, "%s\n", foo );
04519 }
04520 
04647 int
04648 PAPI_overflow( int EventSet, int EventCode, int threshold, int flags,
04649            PAPI_overflow_handler_t handler )
04650 {
04651     int retval, cidx, index, i;
04652     EventSetInfo_t *ESI;
04653 
04654     ESI = _papi_hwi_lookup_EventSet( EventSet );
04655     if ( ESI == NULL ) {
04656         OVFDBG("No EventSet\n");
04657         papi_return( PAPI_ENOEVST );
04658         }
04659 
04660     cidx = valid_ESI_component( ESI );
04661     if ( cidx < 0 ) {
04662         OVFDBG("Component Error\n");
04663         papi_return( cidx );
04664     }
04665 
04666     if ( ( ESI->state & PAPI_STOPPED ) != PAPI_STOPPED ) {
04667         OVFDBG("Already running\n");
04668         papi_return( PAPI_EISRUN );
04669     }
04670 
04671     if ( ESI->state & PAPI_ATTACHED ) {
04672         OVFDBG("Attached\n");
04673         papi_return( PAPI_EINVAL );
04674     }
04675     
04676     if ( ESI->state & PAPI_CPU_ATTACHED ) {
04677         OVFDBG("CPU attached\n");
04678         papi_return( PAPI_EINVAL );
04679     }
04680     
04681     if ( ( index = _papi_hwi_lookup_EventCodeIndex( ESI,
04682                         ( unsigned int ) EventCode ) ) < 0 ) {
04683         papi_return( PAPI_ENOEVNT );
04684     }
04685 
04686     if ( threshold < 0 ) {
04687         OVFDBG("Threshold below zero\n");
04688         papi_return( PAPI_EINVAL );
04689     }
04690 
04691     /* We do not support derived events in overflow */
04692     /* Unless it's DERIVED_CMPD in which no calculations are done */
04693 
04694     if ( !( flags & PAPI_OVERFLOW_FORCE_SW ) && threshold != 0 &&
04695          ( ESI->EventInfoArray[index].derived ) &&
04696          ( ESI->EventInfoArray[index].derived != DERIVED_CMPD ) ) {
04697         OVFDBG("Derived event in overflow\n");
04698         papi_return( PAPI_EINVAL );
04699     }
04700 
04701     /* the first time to call PAPI_overflow function */
04702 
04703     if ( !( ESI->state & PAPI_OVERFLOWING ) ) {
04704         if ( handler == NULL ) {
04705             OVFDBG("NULL handler\n");
04706             papi_return( PAPI_EINVAL );
04707         }
04708         if ( threshold == 0 ) {
04709             OVFDBG("Zero threshold\n");
04710             papi_return( PAPI_EINVAL );
04711         }
04712     }
04713     if ( threshold > 0 &&
04714          ESI->overflow.event_counter >= _papi_hwd[cidx]->cmp_info.num_cntrs )
04715         papi_return( PAPI_ECNFLCT );
04716 
04717     if ( threshold == 0 ) {
04718         for ( i = 0; i < ESI->overflow.event_counter; i++ ) {
04719             if ( ESI->overflow.EventCode[i] == EventCode )
04720                 break;
04721         }
04722         /* EventCode not found */
04723         if ( i == ESI->overflow.event_counter )
04724             papi_return( PAPI_EINVAL );
04725         /* compact these arrays */
04726         while ( i < ESI->overflow.event_counter - 1 ) {
04727             ESI->overflow.deadline[i] = ESI->overflow.deadline[i + 1];
04728             ESI->overflow.threshold[i] = ESI->overflow.threshold[i + 1];
04729             ESI->overflow.EventIndex[i] = ESI->overflow.EventIndex[i + 1];
04730             ESI->overflow.EventCode[i] = ESI->overflow.EventCode[i + 1];
04731             i++;
04732         }
04733         ESI->overflow.deadline[i] = 0;
04734         ESI->overflow.threshold[i] = 0;
04735         ESI->overflow.EventIndex[i] = 0;
04736         ESI->overflow.EventCode[i] = 0;
04737         ESI->overflow.event_counter--;
04738     } else {
04739         if ( ESI->overflow.event_counter > 0 ) {
04740             if ( ( flags & PAPI_OVERFLOW_FORCE_SW ) &&
04741                  ( ESI->overflow.flags & PAPI_OVERFLOW_HARDWARE ) )
04742                 papi_return( PAPI_ECNFLCT );
04743             if ( !( flags & PAPI_OVERFLOW_FORCE_SW ) &&
04744                  ( ESI->overflow.flags & PAPI_OVERFLOW_FORCE_SW ) )
04745                 papi_return( PAPI_ECNFLCT );
04746         }
04747         for ( i = 0; i < ESI->overflow.event_counter; i++ ) {
04748             if ( ESI->overflow.EventCode[i] == EventCode )
04749                 break;
04750         }
04751         /* A new entry */
04752         if ( i == ESI->overflow.event_counter ) {
04753             ESI->overflow.EventCode[i] = EventCode;
04754             ESI->overflow.event_counter++;
04755         }
04756         /* New or existing entry */
04757         ESI->overflow.deadline[i] = threshold;
04758         ESI->overflow.threshold[i] = threshold;
04759         ESI->overflow.EventIndex[i] = index;
04760         ESI->overflow.flags = flags;
04761 
04762     }
04763 
04764     /* If overflowing is already active, we should check to
04765        make sure that we don't specify a different handler
04766        or different flags here. You can't mix them. */
04767 
04768     ESI->overflow.handler = handler;
04769 
04770     /* Set up the option structure for the low level.
04771        If we have hardware interrupts and we are not using
04772        forced software emulated interrupts */
04773 
04774     if ( _papi_hwd[cidx]->cmp_info.hardware_intr &&
04775          !( ESI->overflow.flags & PAPI_OVERFLOW_FORCE_SW ) ) {
04776         retval = _papi_hwd[cidx]->set_overflow( ESI, index, threshold );
04777         if ( retval == PAPI_OK )
04778             ESI->overflow.flags |= PAPI_OVERFLOW_HARDWARE;
04779         else {
04780             papi_return( retval );  /* We should undo stuff here */
04781         }
04782     } else {
04783         /* Make sure hardware overflow is not set */
04784         ESI->overflow.flags &= ~( PAPI_OVERFLOW_HARDWARE );
04785     }
04786 
04787     APIDBG( "Overflow using: %s\n",
04788             ( ESI->overflow.
04789               flags & PAPI_OVERFLOW_HARDWARE ? "[Hardware]" : ESI->overflow.
04790               flags & PAPI_OVERFLOW_FORCE_SW ? "[Forced Software]" :
04791               "[Software]" ) );
04792 
04793     /* Toggle the overflow flags and ESI state */
04794 
04795     if ( ESI->overflow.event_counter >= 1 )
04796         ESI->state |= PAPI_OVERFLOWING;
04797     else {
04798         ESI->state ^= PAPI_OVERFLOWING;
04799         ESI->overflow.flags = 0;
04800         ESI->overflow.handler = NULL;
04801     }
04802 
04803     return PAPI_OK;
04804 }
04805 
04902 int
04903 PAPI_sprofil( PAPI_sprofil_t *prof, int profcnt, int EventSet,
04904               int EventCode, int threshold, int flags )
04905 {
04906    EventSetInfo_t *ESI;
04907    int retval, index, i, buckets;
04908    int forceSW = 0;
04909    int cidx;
04910 
04911    /* Check to make sure EventSet exists */
04912    ESI = _papi_hwi_lookup_EventSet( EventSet );
04913    if ( ESI == NULL ) {
04914       papi_return( PAPI_ENOEVST );
04915    }
04916 
04917    /* Check to make sure EventSet is stopped */
04918    if ( ( ESI->state & PAPI_STOPPED ) != PAPI_STOPPED ) {
04919       papi_return( PAPI_EISRUN );
04920    }
04921 
04922    /* We cannot profile if attached */
04923    if ( ESI->state & PAPI_ATTACHED ) {
04924       papi_return( PAPI_EINVAL );
04925    }
04926 
04927    /* We cannot profile if cpu attached */
04928    if ( ESI->state & PAPI_CPU_ATTACHED ) {
04929       papi_return( PAPI_EINVAL );
04930    }
04931 
04932    /* Get component for EventSet */
04933    cidx = valid_ESI_component( ESI );
04934    if ( cidx < 0 ) {
04935       papi_return( cidx );
04936    }
04937 
04938    /* Get index of the Event we want to profile */
04939    if ( ( index = _papi_hwi_lookup_EventCodeIndex( ESI,
04940                       (unsigned int) EventCode ) ) < 0 ) {
04941       papi_return( PAPI_ENOEVNT );
04942    }
04943 
04944    /* We do not support derived events in overflow */
04945    /* Unless it's DERIVED_CMPD in which no calculations are done */
04946    if ( ( ESI->EventInfoArray[index].derived ) &&
04947     ( ESI->EventInfoArray[index].derived != DERIVED_CMPD ) &&
04948     !( flags & PAPI_PROFIL_FORCE_SW ) ) {
04949       papi_return( PAPI_EINVAL );
04950    }
04951 
04952    /* If no prof structures, then make sure count is 0 */
04953    if ( prof == NULL ) {
04954       profcnt = 0;
04955    }
04956 
04957    /* check all profile regions for valid scale factors of:
04958       2 (131072/65536),
04959       1 (65536/65536),
04960       or < 1 (65535 -> 2) as defined in unix profil()
04961       2/65536 is reserved for single bucket profiling
04962       {0,1}/65536 are traditionally used to terminate profiling
04963       but are unused here since PAPI uses threshold instead
04964     */
04965    for( i = 0; i < profcnt; i++ ) {
04966       if ( !( ( prof[i].pr_scale == 131072 ) ||
04967        ( ( prof[i].pr_scale <= 65536 && prof[i].pr_scale > 1 ) ) ) ) {
04968      APIDBG( "Improper scale factor: %d\n", prof[i].pr_scale );
04969      papi_return( PAPI_EINVAL );
04970       }
04971    }
04972 
04973    /* Make sure threshold is valid */
04974    if ( threshold < 0 ) {
04975       papi_return( PAPI_EINVAL );
04976    }
04977 
04978    /* the first time to call PAPI_sprofil */
04979    if ( !( ESI->state & PAPI_PROFILING ) ) {
04980       if ( threshold == 0 ) {
04981      papi_return( PAPI_EINVAL );
04982       }
04983    }
04984 
04985    /* ??? */
04986    if ( (threshold > 0) &&
04987     (ESI->profile.event_counter >= _papi_hwd[cidx]->cmp_info.num_cntrs) ) {
04988       papi_return( PAPI_ECNFLCT );
04989    }
04990 
04991    if ( threshold == 0 ) {
04992       for( i = 0; i < ESI->profile.event_counter; i++ ) {
04993      if ( ESI->profile.EventCode[i] == EventCode ) {
04994         break;
04995      }
04996       }
04997         
04998       /* EventCode not found */
04999       if ( i == ESI->profile.event_counter ) {
05000      papi_return( PAPI_EINVAL );
05001       }
05002 
05003       /* compact these arrays */
05004       while ( i < ESI->profile.event_counter - 1 ) {
05005          ESI->profile.prof[i] = ESI->profile.prof[i + 1];
05006      ESI->profile.count[i] = ESI->profile.count[i + 1];
05007      ESI->profile.threshold[i] = ESI->profile.threshold[i + 1];
05008      ESI->profile.EventIndex[i] = ESI->profile.EventIndex[i + 1];
05009      ESI->profile.EventCode[i] = ESI->profile.EventCode[i + 1];
05010      i++;
05011       }
05012       ESI->profile.prof[i] = NULL;
05013       ESI->profile.count[i] = 0;
05014       ESI->profile.threshold[i] = 0;
05015       ESI->profile.EventIndex[i] = 0;
05016       ESI->profile.EventCode[i] = 0;
05017       ESI->profile.event_counter--;
05018    } else {
05019       if ( ESI->profile.event_counter > 0 ) {
05020      if ( ( flags & PAPI_PROFIL_FORCE_SW ) &&
05021           !( ESI->profile.flags & PAPI_PROFIL_FORCE_SW ) ) {
05022         papi_return( PAPI_ECNFLCT );
05023      }
05024      if ( !( flags & PAPI_PROFIL_FORCE_SW ) &&
05025           ( ESI->profile.flags & PAPI_PROFIL_FORCE_SW ) ) {
05026         papi_return( PAPI_ECNFLCT );
05027      }
05028       }
05029 
05030       for( i = 0; i < ESI->profile.event_counter; i++ ) {
05031      if ( ESI->profile.EventCode[i] == EventCode ) {
05032         break;
05033      }
05034       }
05035 
05036       if ( i == ESI->profile.event_counter ) {
05037      i = ESI->profile.event_counter;
05038      ESI->profile.event_counter++;
05039      ESI->profile.EventCode[i] = EventCode;
05040       }
05041       ESI->profile.prof[i] = prof;
05042       ESI->profile.count[i] = profcnt;
05043       ESI->profile.threshold[i] = threshold;
05044       ESI->profile.EventIndex[i] = index;
05045    }
05046 
05047    APIDBG( "Profile event counter is %d\n", ESI->profile.event_counter );
05048 
05049    /* Clear out old flags */
05050    if ( threshold == 0 ) {
05051       flags |= ESI->profile.flags;
05052    }
05053 
05054    /* make sure no invalid flags are set */
05055    if ( flags &
05056     ~( PAPI_PROFIL_POSIX | PAPI_PROFIL_RANDOM | PAPI_PROFIL_WEIGHTED |
05057        PAPI_PROFIL_COMPRESS | PAPI_PROFIL_BUCKETS | PAPI_PROFIL_FORCE_SW |
05058        PAPI_PROFIL_INST_EAR | PAPI_PROFIL_DATA_EAR ) ) {
05059       papi_return( PAPI_EINVAL );
05060    }
05061 
05062    /* if we have kernel-based profiling, then we're just asking for 
05063       signals on interrupt. */
05064    /* if we don't have kernel-based profiling, then we're asking for 
05065       emulated PMU interrupt */
05066    if ( ( flags & PAPI_PROFIL_FORCE_SW ) &&
05067     ( _papi_hwd[cidx]->cmp_info.kernel_profile == 0 ) ) {
05068       forceSW = PAPI_OVERFLOW_FORCE_SW;
05069    }
05070 
05071    /* make sure one and only one bucket size is set */
05072    buckets = flags & PAPI_PROFIL_BUCKETS;
05073    if ( !buckets ) {
05074       flags |= PAPI_PROFIL_BUCKET_16;   /* default to 16 bit if nothing set */
05075    }
05076    else {
05077       /* return error if more than one set */
05078       if ( !( ( buckets == PAPI_PROFIL_BUCKET_16 ) ||
05079           ( buckets == PAPI_PROFIL_BUCKET_32 ) ||
05080           ( buckets == PAPI_PROFIL_BUCKET_64 ) ) ) {
05081      papi_return( PAPI_EINVAL );
05082       }
05083    }
05084 
05085    /* Set up the option structure for the low level */
05086    ESI->profile.flags = flags;
05087 
05088    if ( _papi_hwd[cidx]->cmp_info.kernel_profile &&
05089     !( ESI->profile.flags & PAPI_PROFIL_FORCE_SW ) ) {
05090       retval = _papi_hwd[cidx]->set_profile( ESI, index, threshold );
05091       if ( ( retval == PAPI_OK ) && ( threshold > 0 ) ) {
05092      /* We need overflowing because we use the overflow dispatch handler */
05093      ESI->state |= PAPI_OVERFLOWING;
05094      ESI->overflow.flags |= PAPI_OVERFLOW_HARDWARE;
05095       }
05096    } else {
05097       retval = PAPI_overflow( EventSet, EventCode, threshold, forceSW,
05098                   _papi_hwi_dummy_handler );
05099    }
05100     
05101    if ( retval < PAPI_OK ) {
05102       papi_return( retval );    /* We should undo stuff here */
05103    }
05104 
05105    /* Toggle the profiling flags and ESI state */
05106 
05107    if ( ESI->profile.event_counter >= 1 ) {
05108       ESI->state |= PAPI_PROFILING;
05109    }
05110    else {
05111       ESI->state ^= PAPI_PROFILING;
05112       ESI->profile.flags = 0;
05113    }
05114 
05115    return PAPI_OK;
05116 }
05117 
05295 int
05296 PAPI_profil( void *buf, unsigned bufsiz, caddr_t offset,
05297              unsigned scale, int EventSet, int EventCode, int threshold,
05298              int flags )
05299 {
05300     EventSetInfo_t *ESI;
05301     int i;
05302     int retval;
05303 
05304     ESI = _papi_hwi_lookup_EventSet( EventSet );
05305     if ( ESI == NULL )
05306         papi_return( PAPI_ENOEVST );
05307 
05308     /* scale factors are checked for validity in PAPI_sprofil */
05309 
05310     if ( threshold > 0 ) {
05311         PAPI_sprofil_t *prof;
05312 
05313         for ( i = 0; i < ESI->profile.event_counter; i++ ) {
05314             if ( ESI->profile.EventCode[i] == EventCode )
05315                 break;
05316         }
05317 
05318         if ( i == ESI->profile.event_counter ) {
05319             prof =
05320                 ( PAPI_sprofil_t * ) papi_malloc( sizeof ( PAPI_sprofil_t ) );
05321             memset( prof, 0x0, sizeof ( PAPI_sprofil_t ) );
05322             prof->pr_base = buf;
05323             prof->pr_size = bufsiz;
05324             prof->pr_off = offset;
05325             prof->pr_scale = scale;
05326 
05327             retval =
05328                 PAPI_sprofil( prof, 1, EventSet, EventCode, threshold, flags );
05329 
05330             if ( retval != PAPI_OK )
05331                 papi_free( prof );
05332         } else {
05333             prof = ESI->profile.prof[i];
05334             prof->pr_base = buf;
05335             prof->pr_size = bufsiz;
05336             prof->pr_off = offset;
05337             prof->pr_scale = scale;
05338             retval =
05339                 PAPI_sprofil( prof, 1, EventSet, EventCode, threshold, flags );
05340         }
05341         papi_return( retval );
05342     }
05343 
05344     for ( i = 0; i < ESI->profile.event_counter; i++ ) {
05345         if ( ESI->profile.EventCode[i] == EventCode )
05346             break;
05347     }
05348     /* EventCode not found */
05349     if ( i == ESI->profile.event_counter )
05350         papi_return( PAPI_EINVAL );
05351 
05352     papi_free( ESI->profile.prof[i] );
05353     ESI->profile.prof[i] = NULL;
05354 
05355     papi_return( PAPI_sprofil( NULL, 0, EventSet, EventCode, 0, flags ) );
05356 }
05357 
05358 /* This function sets the low level default granularity
05359    for all newly manufactured eventsets. The first function
05360    preserves API compatibility and assumes component 0;
05361    The second function takes a component argument. */
05362 
05413 int
05414 PAPI_set_granularity( int granularity )
05415 {
05416     return ( PAPI_set_cmp_granularity( granularity, 0 ) );
05417 }
05418 
05478 int
05479 PAPI_set_cmp_granularity( int granularity, int cidx )
05480 {
05481     PAPI_option_t ptr;
05482 
05483     memset( &ptr, 0, sizeof ( ptr ) );
05484     ptr.defgranularity.def_cidx = cidx;
05485     ptr.defgranularity.granularity = granularity;
05486     papi_return( PAPI_set_opt( PAPI_DEFGRN, &ptr ) );
05487 }
05488 
05489 /* This function sets the low level default counting domain
05490    for all newly manufactured eventsets. The first function
05491    preserves API compatibility and assumes component 0;
05492    The second function takes a component argument. */
05493 
05544 int
05545 PAPI_set_domain( int domain )
05546 {
05547     return ( PAPI_set_cmp_domain( domain, 0 ) );
05548 }
05549 
05614 int
05615 PAPI_set_cmp_domain( int domain, int cidx )
05616 {
05617     PAPI_option_t ptr;
05618 
05619     memset( &ptr, 0, sizeof ( ptr ) );
05620     ptr.defdomain.def_cidx = cidx;
05621     ptr.defdomain.domain = domain;
05622     papi_return( PAPI_set_opt( PAPI_DEFDOM, &ptr ) );
05623 }
05624 
05699 int
05700 PAPI_add_events( int EventSet, int *Events, int number )
05701 {
05702     int i, retval;
05703 
05704     if ( ( Events == NULL ) || ( number <= 0 ) )
05705         papi_return( PAPI_EINVAL );
05706 
05707     for ( i = 0; i < number; i++ ) {
05708         retval = PAPI_add_event( EventSet, Events[i] );
05709         if ( retval != PAPI_OK ) {
05710             if ( i == 0 )
05711                 papi_return( retval );
05712             else
05713                 return ( i );
05714         }
05715     }
05716     return ( PAPI_OK );
05717 }
05718 
05786 int
05787 PAPI_remove_events( int EventSet, int *Events, int number )
05788 {
05789     int i, retval;
05790 
05791     if ( ( Events == NULL ) || ( number <= 0 ) )
05792         papi_return( PAPI_EINVAL );
05793 
05794     for ( i = 0; i < number; i++ ) {
05795         retval = PAPI_remove_event( EventSet, Events[i] );
05796         if ( retval != PAPI_OK ) {
05797             if ( i == 0 )
05798                 papi_return( retval );
05799             else
05800                 return ( i );
05801         }
05802     }
05803     return ( PAPI_OK );
05804 }
05805 
05846 int
05847 PAPI_list_events( int EventSet, int *Events, int *number )
05848 {
05849     EventSetInfo_t *ESI;
05850     int i, j;
05851 
05852     if ( ( Events == NULL ) || ( *number <= 0 ) )
05853         papi_return( PAPI_EINVAL );
05854 
05855     ESI = _papi_hwi_lookup_EventSet( EventSet );
05856     if ( !ESI )
05857         papi_return( PAPI_ENOEVST );
05858 
05859     for ( i = 0, j = 0; j < ESI->NumberOfEvents; i++ ) {
05860         if ( ( int ) ESI->EventInfoArray[i].event_code != PAPI_NULL ) {
05861             Events[j] = ( int ) ESI->EventInfoArray[i].event_code;
05862             j++;
05863             if ( j == *number )
05864                 break;
05865         }
05866     }
05867 
05868     *number = j;
05869 
05870     return ( PAPI_OK );
05871 }
05872 
05873 /* xxx This is OS dependent, not component dependent, right? */
05899 int
05900 PAPI_get_dmem_info( PAPI_dmem_info_t * dest )
05901 {
05902     if ( dest == NULL )
05903         return PAPI_EINVAL;
05904 
05905     memset( ( void * ) dest, 0x0, sizeof ( PAPI_dmem_info_t ) );
05906     return ( _papi_os_vector.get_dmem_info( dest ) );
05907 }
05908 
05909 
05953 const PAPI_exe_info_t *
05954 PAPI_get_executable_info( void )
05955 {
05956     PAPI_option_t ptr;
05957     int retval;
05958 
05959     memset( &ptr, 0, sizeof ( ptr ) );
05960     retval = PAPI_get_opt( PAPI_EXEINFO, &ptr );
05961     if ( retval == PAPI_OK )
05962         return ( ptr.exe_info );
05963     else
05964         return ( NULL );
05965 }
05966 
05983 const PAPI_shlib_info_t *
05984 PAPI_get_shared_lib_info( void )
05985 {
05986     PAPI_option_t ptr;
05987     int retval;
05988 
05989     memset( &ptr, 0, sizeof ( ptr ) );
05990     retval = PAPI_get_opt( PAPI_SHLIBINFO, &ptr );
05991     if ( retval == PAPI_OK )
05992         return ( ptr.shlib_info );
05993     else
05994         return ( NULL );
05995 }
06024 const PAPI_hw_info_t *
06025 PAPI_get_hardware_info( void )
06026 {
06027     PAPI_option_t ptr;
06028     int retval;
06029 
06030     memset( &ptr, 0, sizeof ( ptr ) );
06031     retval = PAPI_get_opt( PAPI_HWINFO, &ptr );
06032     if ( retval == PAPI_OK )
06033         return ( ptr.hw_info );
06034     else
06035         return ( NULL );
06036 }
06037 
06038 
06039 /* The next 4 timing functions always use component 0 */
06040 
06056 long long
06057 PAPI_get_real_cyc( void )
06058 {
06059     return ( _papi_os_vector.get_real_cycles(  ) );
06060 }
06061 
06075 /* FIXME */
06076 long long
06077 PAPI_get_real_nsec( void )
06078 {
06079   return ( ( _papi_os_vector.get_real_nsec(  )));
06080 
06081 }
06082 
06103 long long
06104 PAPI_get_real_usec( void )
06105 {
06106     return ( _papi_os_vector.get_real_usec(  ) );
06107 }
06108 
06139 long long
06140 PAPI_get_virt_cyc( void )
06141 {
06142 
06143     return ( ( long long ) _papi_os_vector.get_virt_cycles( ) );
06144 }
06145 
06169 long long
06170 PAPI_get_virt_nsec( void )
06171 {
06172 
06173   return ( ( _papi_os_vector.get_virt_nsec()));
06174 
06175 }
06176 
06211 long long
06212 PAPI_get_virt_usec( void )
06213 {
06214 
06215     return ( ( long long ) _papi_os_vector.get_virt_usec() );
06216 }
06217 
06242 int
06243 PAPI_lock( int lck )
06244 {
06245     if ( ( lck < 0 ) || ( lck >= PAPI_NUM_LOCK ) )
06246         papi_return( PAPI_EINVAL );
06247 
06248     papi_return( _papi_hwi_lock( lck ) );
06249 }
06250 
06262 int
06263 PAPI_unlock( int lck )
06264 {
06265     if ( ( lck < 0 ) || ( lck >= PAPI_NUM_LOCK ) )
06266         papi_return( PAPI_EINVAL );
06267 
06268     papi_return( _papi_hwi_unlock( lck ) );
06269 }
06270 
06304 int
06305 PAPI_is_initialized( void )
06306 {
06307     return ( init_level );
06308 }
06309 
06310 /* This function maps the overflow_vector to event indexes in the event
06311    set, so that user can know which PAPI event overflowed.
06312    int *array---- an array of event indexes in eventset; the first index
06313                   maps to the highest set bit in overflow_vector
06314    int *number--- this is an input/output parameter, user should put the
06315                   size of the array into this parameter, after the function
06316                   is executed, the number of indexes in *array is written
06317                   to this parameter
06318 */
06319 
06358 int
06359 PAPI_get_overflow_event_index( int EventSet, long long overflow_vector,
06360                                int *array, int *number )
06361 {
06362     EventSetInfo_t *ESI;
06363     int set_bit, j, pos;
06364     int count = 0, k;
06365 
06366     if ( overflow_vector == ( long long ) 0 )
06367         papi_return( PAPI_EINVAL );
06368 
06369     if ( ( array == NULL ) || ( number == NULL ) )
06370         papi_return( PAPI_EINVAL );
06371 
06372     if ( *number < 1 )
06373         papi_return( PAPI_EINVAL );
06374 
06375     ESI = _papi_hwi_lookup_EventSet( EventSet );
06376     if ( ESI == NULL )
06377         papi_return( PAPI_ENOEVST );
06378 
06379     /* in case the eventset is empty */
06380     if ( ESI->NumberOfEvents == 0 )
06381         papi_return( PAPI_EINVAL );
06382 
06383     while ( ( set_bit = ffsll( overflow_vector ) ) ) {
06384         set_bit -= 1;
06385         overflow_vector ^= ( long long ) 1 << set_bit;
06386         for ( j = 0; j < ESI->NumberOfEvents; j++ ) {
06387             for ( k = 0, pos = 0; k < PAPI_EVENTS_IN_DERIVED_EVENT && pos >= 0; k++ ) {
06388                 pos = ESI->EventInfoArray[j].pos[k];
06389                 if ( ( set_bit == pos ) &&
06390                      ( ( ESI->EventInfoArray[j].derived == NOT_DERIVED ) ||
06391                        ( ESI->EventInfoArray[j].derived == DERIVED_CMPD ) ) ) {
06392                     array[count++] = j;
06393                     if ( count == *number )
06394                         return PAPI_OK;
06395 
06396                     break;
06397                 }
06398             }
06399         }
06400     }
06401     *number = count;
06402     return PAPI_OK;
06403 }
06404 
06405 
06423 int
06424 PAPI_get_event_component( int EventCode)
06425 {
06426     return _papi_hwi_component_index( EventCode);
06427 }
06428 
06450 int  PAPI_get_component_index(char *name)
06451 {
06452   int cidx;
06453 
06454   const PAPI_component_info_t *cinfo;
06455 
06456   for(cidx=0;cidx<papi_num_components;cidx++) {
06457 
06458      cinfo=PAPI_get_component_info(cidx); 
06459      if (cinfo==NULL) return PAPI_ENOCMP;
06460 
06461      if (!strncmp(name,cinfo->name,strlen(cinfo->name))) {
06462         return cidx;
06463      }
06464   }
06465 
06466   return PAPI_ENOCMP;
06467 }
06468 
06469 
06505 int
06506 PAPI_disable_component( int cidx )
06507 {
06508 
06509    const PAPI_component_info_t *cinfo;
06510 
06511    /* Can only run before PAPI_library_init() is called */
06512    if (init_level != PAPI_NOT_INITED) {
06513       return PAPI_ENOINIT;
06514    }
06515      
06516    cinfo=PAPI_get_component_info(cidx); 
06517    if (cinfo==NULL) return PAPI_ENOCMP;
06518 
06519    ((PAPI_component_info_t *)cinfo)->disabled=1;
06520    strcpy(((PAPI_component_info_t *)cinfo)->disabled_reason,
06521            "Disabled by PAPI_disable_component()");
06522 
06523    return PAPI_OK;
06524  
06525 }
06526 
06555 int
06556 PAPI_disable_component_by_name( char *name )
06557 {
06558     int cidx;
06559 
06560     /* I can only be called before init time */
06561     if (init_level!=PAPI_NOT_INITED) {
06562         return PAPI_ENOINIT;
06563     }
06564 
06565     cidx = PAPI_get_component_index(name);
06566     if (cidx>=0) {
06567         return PAPI_disable_component(cidx);
06568     } 
06569 
06570     return PAPI_ENOCMP;
06571 }
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines