PAPI  5.1.0.2
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 
01517 int
01518 PAPI_get_eventset_component( int EventSet)
01519 {
01520     EventSetInfo_t *ESI;
01521     int retval;
01522 
01523 /* validate eventset */
01524     ESI = _papi_hwi_lookup_EventSet( EventSet );
01525     if ( ESI == NULL )
01526         papi_return( PAPI_ENOEVST );
01527 
01528 /* check if a component has been assigned */ 
01529     if ( ESI->CmpIdx < 0 )
01530       papi_return( PAPI_ENOCMP );
01531 
01532 /* validate CmpIdx */
01533     retval = valid_component( ESI->CmpIdx );
01534     if ( retval < 0 )
01535         papi_return( retval );
01536 
01537 /* return the index */
01538     return ( ESI->CmpIdx );
01539 }
01540 
01541 
01611 int
01612 PAPI_add_event( int EventSet, int EventCode )
01613 {
01614    APIDBG("Entry: EventSet: %d, EventCode: 0x%x\n", EventSet, EventCode);
01615     EventSetInfo_t *ESI;
01616 
01617     /* Is the EventSet already in existence? */
01618 
01619     ESI = _papi_hwi_lookup_EventSet( EventSet );
01620     if ( ESI == NULL )
01621         papi_return( PAPI_ENOEVST );
01622 
01623     /* Check argument for validity */
01624 
01625     if ( ( ( EventCode & PAPI_PRESET_MASK ) == 0 ) &&
01626          ( EventCode & PAPI_NATIVE_MASK ) == 0 )
01627         papi_return( PAPI_EINVAL );
01628 
01629     /* Of course, it must be stopped in order to modify it. */
01630 
01631     if ( ESI->state & PAPI_RUNNING )
01632         papi_return( PAPI_EISRUN );
01633 
01634     /* Now do the magic. */
01635 
01636     papi_return( _papi_hwi_add_event( ESI, EventCode ) );
01637 }
01638 
01706 int
01707 PAPI_remove_event( int EventSet, int EventCode )
01708 {
01709     EventSetInfo_t *ESI;
01710     int i,retval;
01711 
01712     /* check for pre-existing ESI */
01713 
01714     ESI = _papi_hwi_lookup_EventSet( EventSet );
01715     if ( ESI == NULL )
01716         papi_return( PAPI_ENOEVST );
01717 
01718     /* Check argument for validity */
01719 
01720     if ( ( !IS_PRESET(EventCode) ) &&
01721         ( !IS_NATIVE(EventCode) ) &&
01722         ( !IS_USER_DEFINED(EventCode) ))
01723         papi_return( PAPI_EINVAL );
01724 
01725     /* Of course, it must be stopped in order to modify it. */
01726 
01727     if ( !( ESI->state & PAPI_STOPPED ) )
01728         papi_return( PAPI_EISRUN );
01729 
01730     /* if the state is PAPI_OVERFLOWING, you must first call
01731        PAPI_overflow with threshold=0 to remove the overflow flag */
01732 
01733     /* Turn off the event that is overflowing */
01734     if ( ESI->state & PAPI_OVERFLOWING ) {
01735        for ( i = 0; i < ESI->overflow.event_counter; i++ ) {
01736            if ( ESI->overflow.EventCode[i] == EventCode ) {
01737           retval = PAPI_overflow( EventSet, EventCode, 0, 0,
01738                       ESI->overflow.handler );
01739           if (retval!=PAPI_OK) return retval;
01740           break;
01741            }
01742        }
01743     }
01744 
01745     /* force the user to call PAPI_profil to clear the PAPI_PROFILING flag */
01746     if ( ESI->state & PAPI_PROFILING ) {
01747         for ( i = 0; i < ESI->profile.event_counter; i++ ) {
01748             if ( ESI->profile.EventCode[i] == EventCode ) {
01749                 PAPI_sprofil( NULL, 0, EventSet, EventCode, 0, 0 );
01750                 break;
01751             }
01752         }
01753     }
01754 
01755     /* Now do the magic. */
01756 
01757     papi_return( _papi_hwi_remove_event( ESI, EventCode ) );
01758 }
01759 
01823 int
01824 PAPI_add_named_event( int EventSet, char *EventName )
01825 {
01826     int ret, code;
01827     
01828     ret = PAPI_event_name_to_code( EventName, &code );
01829     if ( ret == PAPI_OK ) ret = PAPI_add_event( EventSet, code );
01830     papi_return( ret );
01831 }
01832 
01900 int
01901 PAPI_remove_named_event( int EventSet, char *EventName )
01902 {
01903     int ret, code;
01904     
01905     ret = PAPI_event_name_to_code( EventName, &code );
01906     if ( ret == PAPI_OK ) ret = PAPI_remove_event( EventSet, code );
01907     papi_return( ret );
01908 }
01909 
01951 int
01952 PAPI_destroy_eventset( int *EventSet )
01953 {
01954     EventSetInfo_t *ESI;
01955 
01956     APIDBG("Destroying Eventset %d\n",*EventSet);
01957 
01958     /* check for pre-existing ESI */
01959 
01960     if ( EventSet == NULL )
01961         papi_return( PAPI_EINVAL );
01962 
01963     ESI = _papi_hwi_lookup_EventSet( *EventSet );
01964     if ( ESI == NULL )
01965         papi_return( PAPI_ENOEVST );
01966 
01967     if ( !( ESI->state & PAPI_STOPPED ) )
01968         papi_return( PAPI_EISRUN );
01969 
01970     if ( ESI->NumberOfEvents )
01971         papi_return( PAPI_EINVAL );
01972 
01973     _papi_hwi_remove_EventSet( ESI );
01974     *EventSet = PAPI_NULL;
01975 
01976     return PAPI_OK;
01977 }
01978 
01979 /* simply checks for valid EventSet, calls component start() call */
02033 int
02034 PAPI_start( int EventSet )
02035 {
02036     APIDBG("Entry: EventSet: %d\n", EventSet);
02037     int is_dirty=0;
02038     int retval;
02039     EventSetInfo_t *ESI;
02040     ThreadInfo_t *thread = NULL;
02041     CpuInfo_t *cpu = NULL;
02042     hwd_context_t *context;
02043     int cidx;
02044 
02045     ESI = _papi_hwi_lookup_EventSet( EventSet );
02046     if ( ESI == NULL ) {
02047        papi_return( PAPI_ENOEVST );
02048     }
02049 
02050     cidx = valid_ESI_component( ESI );
02051     if ( cidx < 0 ) {
02052        papi_return( cidx );
02053     }
02054 
02055     /* only one event set per thread/cpu can be running at any time, */
02056     /* so if another event set is running, the user must stop that   */
02057         /* event set explicitly */
02058 
02059         thread = ESI->master;
02060     cpu = ESI->CpuInfo;
02061 
02062     /* check cpu attached case first */
02063     if (ESI->state & PAPI_CPU_ATTACHED) {
02064        if ( cpu->running_eventset[cidx] ) {
02065           papi_return( PAPI_EISRUN );
02066        }
02067     } else {
02068         if ( thread->running_eventset[cidx] ) {
02069            papi_return( PAPI_EISRUN );
02070         }
02071     } 
02072     
02073     /* Check that there are added events */
02074     if ( ESI->NumberOfEvents < 1 ) {
02075        papi_return( PAPI_EINVAL );
02076     }
02077 
02078     /* If multiplexing is enabled for this eventset,
02079        call John May's code. */
02080 
02081     if ( _papi_hwi_is_sw_multiplex( ESI ) ) {
02082        retval = MPX_start( ESI->multiplex.mpx_evset );
02083        if ( retval != PAPI_OK ) {
02084           papi_return( retval );
02085        }
02086 
02087        /* Update the state of this EventSet */
02088        ESI->state ^= PAPI_STOPPED;
02089        ESI->state |= PAPI_RUNNING;
02090 
02091        return PAPI_OK;
02092     }
02093 
02094     /* get the context we should use for this event set */
02095     context = _papi_hwi_get_context( ESI, &is_dirty );
02096     if (is_dirty) {
02097        /* we need to reset the context state because it was last used   */
02098        /* for some other event set and does not contain the information */
02099            /* for our events.                                               */
02100        retval = _papi_hwd[ESI->CmpIdx]->update_control_state( 
02101                                                         ESI->ctl_state,
02102                             ESI->NativeInfoArray,
02103                             ESI->NativeCount,
02104                             context);
02105        if ( retval != PAPI_OK ) {
02106           papi_return( retval );
02107        }
02108         
02109        /* now that the context contains this event sets information,    */
02110        /* make sure the position array in the EventInfoArray is correct */
02111 
02112        /* We have to do this because ->update_control_state() can */
02113        /* in theory re-order the native events out from under us. */
02114        _papi_hwi_map_events_to_native( ESI );
02115 
02116     }
02117 
02118     /* If overflowing is enabled, turn it on */
02119     if ( ( ESI->state & PAPI_OVERFLOWING ) &&
02120          !( ESI->overflow.flags & PAPI_OVERFLOW_HARDWARE ) ) {
02121        retval = _papi_hwi_start_signal( _papi_os_info.itimer_sig, 
02122                         NEED_CONTEXT, cidx );
02123        if ( retval != PAPI_OK ) {
02124           papi_return( retval );
02125        }
02126 
02127        /* Update the state of this EventSet and thread */
02128        /* before to avoid races                        */
02129        ESI->state ^= PAPI_STOPPED;
02130        ESI->state |= PAPI_RUNNING;
02131            /* can not be attached to thread or cpu if overflowing */
02132        thread->running_eventset[cidx] = ESI;
02133 
02134        retval = _papi_hwd[cidx]->start( context, ESI->ctl_state );
02135        if ( retval != PAPI_OK ) {
02136           _papi_hwi_stop_signal( _papi_os_info.itimer_sig );
02137           ESI->state ^= PAPI_RUNNING;
02138           ESI->state |= PAPI_STOPPED;
02139           thread->running_eventset[cidx] = NULL;
02140           papi_return( retval );
02141        }
02142 
02143        retval = _papi_hwi_start_timer( _papi_os_info.itimer_num,
02144                        _papi_os_info.itimer_sig,
02145                        _papi_os_info.itimer_ns );
02146        if ( retval != PAPI_OK ) {
02147           _papi_hwi_stop_signal( _papi_os_info.itimer_sig );
02148           _papi_hwd[cidx]->stop( context, ESI->ctl_state );
02149           ESI->state ^= PAPI_RUNNING;
02150           ESI->state |= PAPI_STOPPED;
02151           thread->running_eventset[cidx] = NULL;
02152           papi_return( retval );
02153        }
02154     } else {
02155        /* Update the state of this EventSet and thread before */
02156        /* to avoid races                                      */
02157        ESI->state ^= PAPI_STOPPED;
02158        ESI->state |= PAPI_RUNNING;
02159         
02160        /* if not attached to cpu or another process */
02161        if ( !(ESI->state & PAPI_CPU_ATTACHED) ) {
02162           if ( !( ESI->state & PAPI_ATTACHED ) ) {
02163          thread->running_eventset[cidx] = ESI;
02164           }
02165        } else {
02166           cpu->running_eventset[cidx] = ESI;
02167        }
02168 
02169        retval = _papi_hwd[cidx]->start( context, ESI->ctl_state );
02170        if ( retval != PAPI_OK ) {
02171           _papi_hwd[cidx]->stop( context, ESI->ctl_state );
02172           ESI->state ^= PAPI_RUNNING;
02173           ESI->state |= PAPI_STOPPED;
02174           if ( !(ESI->state & PAPI_CPU_ATTACHED) ) {
02175          if ( !( ESI->state & PAPI_ATTACHED ) ) 
02176             thread->running_eventset[cidx] = NULL;
02177           } else {
02178          cpu->running_eventset[cidx] = NULL;
02179           }
02180           papi_return( retval );
02181        }
02182     }
02183 
02184     return retval;
02185 }
02186 
02187 /* checks for valid EventSet, calls component stop() function. */
02238 int
02239 PAPI_stop( int EventSet, long long *values )
02240 {
02241    APIDBG("Entry: EventSet: %d, values: %p\n", EventSet, values);
02242     EventSetInfo_t *ESI;
02243     hwd_context_t *context;
02244     int cidx, retval;
02245 
02246     ESI = _papi_hwi_lookup_EventSet( EventSet );
02247     if ( ESI == NULL )
02248         papi_return( PAPI_ENOEVST );
02249 
02250     cidx = valid_ESI_component( ESI );
02251     if ( cidx < 0 )
02252         papi_return( cidx );
02253 
02254     if ( !( ESI->state & PAPI_RUNNING ) )
02255         papi_return( PAPI_ENOTRUN );
02256 
02257     /* If multiplexing is enabled for this eventset, turn if off */
02258 
02259     if ( _papi_hwi_is_sw_multiplex( ESI ) ) {
02260         retval = MPX_stop( ESI->multiplex.mpx_evset, values );
02261         if ( retval != PAPI_OK )
02262             papi_return( retval );
02263 
02264         /* Update the state of this EventSet */
02265 
02266         ESI->state ^= PAPI_RUNNING;
02267         ESI->state |= PAPI_STOPPED;
02268 
02269         return ( PAPI_OK );
02270     }
02271 
02272     /* get the context we should use for this event set */
02273     context = _papi_hwi_get_context( ESI, NULL );
02274     /* Read the current counter values into the EventSet */
02275     retval = _papi_hwi_read( context, ESI, ESI->sw_stop );
02276     if ( retval != PAPI_OK )
02277         papi_return( retval );
02278 
02279     /* Remove the control bits from the active counter config. */
02280     retval = _papi_hwd[cidx]->stop( context, ESI->ctl_state );
02281     if ( retval != PAPI_OK )
02282         papi_return( retval );
02283     if ( values )
02284         memcpy( values, ESI->sw_stop,
02285                 ( size_t ) ESI->NumberOfEvents * sizeof ( long long ) );
02286 
02287     /* If kernel profiling is in use, flush and process the kernel buffer */
02288 
02289     if ( ESI->state & PAPI_PROFILING ) {
02290         if ( _papi_hwd[cidx]->cmp_info.kernel_profile &&
02291              !( ESI->profile.flags & PAPI_PROFIL_FORCE_SW ) ) {
02292             retval = _papi_hwd[cidx]->stop_profiling( ESI->master, ESI );
02293             if ( retval < PAPI_OK )
02294                 papi_return( retval );
02295         }
02296     }
02297 
02298     /* If overflowing is enabled, turn it off */
02299 
02300     if ( ESI->state & PAPI_OVERFLOWING ) {
02301         if ( !( ESI->overflow.flags & PAPI_OVERFLOW_HARDWARE ) ) {
02302             retval = _papi_hwi_stop_timer( _papi_os_info.itimer_num,
02303                                _papi_os_info.itimer_sig );
02304             if ( retval != PAPI_OK )
02305                 papi_return( retval );
02306             _papi_hwi_stop_signal( _papi_os_info.itimer_sig );
02307         }
02308     }
02309 
02310     /* Update the state of this EventSet */
02311 
02312     ESI->state ^= PAPI_RUNNING;
02313     ESI->state |= PAPI_STOPPED;
02314 
02315     /* Update the running event set for this thread */
02316     if ( !(ESI->state & PAPI_CPU_ATTACHED) ) {
02317         if ( !( ESI->state & PAPI_ATTACHED ))
02318             ESI->master->running_eventset[cidx] = NULL;
02319     } else {
02320         ESI->CpuInfo->running_eventset[cidx] = NULL;
02321     }
02322     
02323 #if defined(DEBUG)
02324     if ( _papi_hwi_debug & DEBUG_API ) {
02325         int i;
02326         for ( i = 0; i < ESI->NumberOfEvents; i++ ) {
02327             APIDBG( "PAPI_stop ESI->sw_stop[%d]:\t%llu\n", i, ESI->sw_stop[i] );
02328         }
02329     }
02330 #endif
02331 
02332     return ( PAPI_OK );
02333 }
02334 
02383 int
02384 PAPI_reset( int EventSet )
02385 {
02386     int retval = PAPI_OK;
02387     EventSetInfo_t *ESI;
02388     hwd_context_t *context;
02389     int cidx;
02390 
02391     ESI = _papi_hwi_lookup_EventSet( EventSet );
02392     if ( ESI == NULL )
02393         papi_return( PAPI_ENOEVST );
02394 
02395     cidx = valid_ESI_component( ESI );
02396     if ( cidx < 0 )
02397         papi_return( cidx );
02398 
02399     if ( ESI->state & PAPI_RUNNING ) {
02400         if ( _papi_hwi_is_sw_multiplex( ESI ) ) {
02401             retval = MPX_reset( ESI->multiplex.mpx_evset );
02402         } else {
02403             /* If we're not the only one running, then just
02404                read the current values into the ESI->start
02405                array. This holds the starting value for counters
02406                that are shared. */
02407             /* get the context we should use for this event set */
02408             context = _papi_hwi_get_context( ESI, NULL );
02409             retval = _papi_hwd[cidx]->reset( context, ESI->ctl_state );
02410         }
02411     } else {
02412 #ifdef __bgp__
02413         //  For BG/P, we always want to reset the 'real' hardware counters.  The counters
02414         //  can be controlled via multiple interfaces, and we need to ensure that the values
02415         //  are truly zero...
02416         /* get the context we should use for this event set */
02417         context = _papi_hwi_get_context( ESI, NULL );
02418         retval = _papi_hwd[cidx]->reset( context, ESI->ctl_state );
02419 #endif
02420         memset( ESI->sw_stop, 0x00,
02421                 ( size_t ) ESI->NumberOfEvents * sizeof ( long long ) );
02422     }
02423 
02424     APIDBG( "PAPI_reset returns %d\n", retval );
02425     papi_return( retval );
02426 }
02427 
02484 int
02485 PAPI_read( int EventSet, long long *values )
02486 {
02487     EventSetInfo_t *ESI;
02488     hwd_context_t *context;
02489     int cidx, retval = PAPI_OK;
02490 
02491     ESI = _papi_hwi_lookup_EventSet( EventSet );
02492     if ( ESI == NULL )
02493         papi_return( PAPI_ENOEVST );
02494 
02495     cidx = valid_ESI_component( ESI );
02496     if ( cidx < 0 )
02497         papi_return( cidx );
02498 
02499     if ( values == NULL )
02500         papi_return( PAPI_EINVAL );
02501 
02502     if ( ESI->state & PAPI_RUNNING ) {
02503         if ( _papi_hwi_is_sw_multiplex( ESI ) ) {
02504           retval = MPX_read( ESI->multiplex.mpx_evset, values, 0 );
02505         } else {
02506             /* get the context we should use for this event set */
02507             context = _papi_hwi_get_context( ESI, NULL );
02508             retval = _papi_hwi_read( context, ESI, values );
02509         }
02510         if ( retval != PAPI_OK )
02511             papi_return( retval );
02512     } else {
02513         memcpy( values, ESI->sw_stop,
02514                 ( size_t ) ESI->NumberOfEvents * sizeof ( long long ) );
02515     }
02516 
02517 #if defined(DEBUG)
02518     if ( ISLEVEL( DEBUG_API ) ) {
02519         int i;
02520         for ( i = 0; i < ESI->NumberOfEvents; i++ ) {
02521             APIDBG( "PAPI_read values[%d]:\t%lld\n", i, values[i] );
02522         }
02523     }
02524 #endif
02525 
02526     APIDBG( "PAPI_read returns %d\n", retval );
02527     return ( PAPI_OK );
02528 }
02529 
02574 int
02575 PAPI_read_ts( int EventSet, long long *values, long long *cycles )
02576 {
02577     EventSetInfo_t *ESI;
02578     hwd_context_t *context;
02579     int cidx, retval = PAPI_OK;
02580 
02581     ESI = _papi_hwi_lookup_EventSet( EventSet );
02582     if ( ESI == NULL )
02583         papi_return( PAPI_ENOEVST );
02584 
02585     cidx = valid_ESI_component( ESI );
02586     if ( cidx < 0 )
02587         papi_return( cidx );
02588 
02589     if ( values == NULL )
02590         papi_return( PAPI_EINVAL );
02591 
02592     if ( ESI->state & PAPI_RUNNING ) {
02593         if ( _papi_hwi_is_sw_multiplex( ESI ) ) {
02594           retval = MPX_read( ESI->multiplex.mpx_evset, values, 0 );
02595         } else {
02596             /* get the context we should use for this event set */
02597             context = _papi_hwi_get_context( ESI, NULL );
02598             retval = _papi_hwi_read( context, ESI, values );
02599         }
02600         if ( retval != PAPI_OK )
02601             papi_return( retval );
02602     } else {
02603         memcpy( values, ESI->sw_stop,
02604                 ( size_t ) ESI->NumberOfEvents * sizeof ( long long ) );
02605     }
02606 
02607     *cycles = _papi_os_vector.get_real_cycles(  );
02608 
02609 #if defined(DEBUG)
02610     if ( ISLEVEL( DEBUG_API ) ) {
02611         int i;
02612         for ( i = 0; i < ESI->NumberOfEvents; i++ ) {
02613             APIDBG( "PAPI_read values[%d]:\t%lld\n", i, values[i] );
02614         }
02615     }
02616 #endif
02617 
02618     APIDBG( "PAPI_read_ts returns %d\n", retval );
02619     return PAPI_OK;
02620 }
02621 
02670 int
02671 PAPI_accum( int EventSet, long long *values )
02672 {
02673     EventSetInfo_t *ESI;
02674     hwd_context_t *context;
02675     int i, cidx, retval;
02676     long long a, b, c;
02677 
02678     ESI = _papi_hwi_lookup_EventSet( EventSet );
02679     if ( ESI == NULL )
02680         papi_return( PAPI_ENOEVST );
02681 
02682     cidx = valid_ESI_component( ESI );
02683     if ( cidx < 0 )
02684         papi_return( cidx );
02685 
02686     if ( values == NULL )
02687         papi_return( PAPI_EINVAL );
02688 
02689     if ( ESI->state & PAPI_RUNNING ) {
02690         if ( _papi_hwi_is_sw_multiplex( ESI ) ) {
02691           retval = MPX_read( ESI->multiplex.mpx_evset, ESI->sw_stop, 0 );
02692         } else {
02693             /* get the context we should use for this event set */
02694             context = _papi_hwi_get_context( ESI, NULL );
02695             retval = _papi_hwi_read( context, ESI, ESI->sw_stop );
02696         }
02697         if ( retval != PAPI_OK )
02698             papi_return( retval );
02699     }
02700 
02701     for ( i = 0; i < ESI->NumberOfEvents; i++ ) {
02702         a = ESI->sw_stop[i];
02703         b = values[i];
02704         c = a + b;
02705         values[i] = c;
02706     }
02707 
02708     papi_return( PAPI_reset( EventSet ) );
02709 }
02710 
02737 int
02738 PAPI_write( int EventSet, long long *values )
02739 {
02740     int cidx, retval = PAPI_OK;
02741     EventSetInfo_t *ESI;
02742     hwd_context_t *context;
02743 
02744     ESI = _papi_hwi_lookup_EventSet( EventSet );
02745     if ( ESI == NULL )
02746         papi_return( PAPI_ENOEVST );
02747 
02748     cidx = valid_ESI_component( ESI );
02749     if ( cidx < 0 )
02750         papi_return( cidx );
02751 
02752     if ( values == NULL )
02753         papi_return( PAPI_EINVAL );
02754 
02755     if ( ESI->state & PAPI_RUNNING ) {
02756         /* get the context we should use for this event set */
02757         context = _papi_hwi_get_context( ESI, NULL );
02758         retval = _papi_hwd[cidx]->write( context, ESI->ctl_state, values );
02759         if ( retval != PAPI_OK )
02760             return ( retval );
02761     }
02762 
02763     memcpy( ESI->hw_start, values,
02764             ( size_t ) _papi_hwd[cidx]->cmp_info.num_cntrs *
02765             sizeof ( long long ) );
02766 
02767     return ( retval );
02768 }
02769 
02812 int
02813 PAPI_cleanup_eventset( int EventSet )
02814 {
02815     EventSetInfo_t *ESI;
02816     int i, cidx, total, retval;
02817 
02818     APIDBG("Attempting to cleanup Eventset %d\n",EventSet);
02819 
02820     /* Is the EventSet already in existence? */
02821 
02822     ESI = _papi_hwi_lookup_EventSet( EventSet );
02823     if ( ESI == NULL )
02824         papi_return( PAPI_ENOEVST );
02825 
02826     /* if the eventset has no index and no events, return OK
02827        otherwise return NOCMP */
02828     cidx = valid_ESI_component( ESI );
02829     if ( cidx < 0 ) {
02830         if ( ESI->NumberOfEvents )
02831             papi_return( cidx );
02832         papi_return( PAPI_OK );
02833     }
02834 
02835     /* Of course, it must be stopped in order to modify it. */
02836 
02837     if ( ESI->state & PAPI_RUNNING )
02838         papi_return( PAPI_EISRUN );
02839 
02840     /* clear overflow flag and turn off hardware overflow handler */
02841     if ( ESI->state & PAPI_OVERFLOWING ) {
02842         total = ESI->overflow.event_counter;
02843         for ( i = 0; i < total; i++ ) {
02844             retval = PAPI_overflow( EventSet,
02845                                     ESI->overflow.EventCode[0], 0, 0, NULL );
02846             if ( retval != PAPI_OK )
02847                 papi_return( retval );
02848         }
02849     }
02850 
02851     /* clear profile flag and turn off hardware profile handler */
02852     if ( ( ESI->state & PAPI_PROFILING ) &&
02853          _papi_hwd[cidx]->cmp_info.hardware_intr &&
02854          !( ESI->profile.flags & PAPI_PROFIL_FORCE_SW ) ) {
02855         total = ESI->profile.event_counter;
02856         for ( i = 0; i < total; i++ ) {
02857             retval =
02858                 PAPI_sprofil( NULL, 0, EventSet, ESI->profile.EventCode[0], 0,
02859                               PAPI_PROFIL_POSIX );
02860             if ( retval != PAPI_OK )
02861                 papi_return( retval );
02862         }
02863     }
02864 
02865     if ( _papi_hwi_is_sw_multiplex( ESI ) ) {
02866         retval = MPX_cleanup( &ESI->multiplex.mpx_evset );
02867         if ( retval != PAPI_OK )
02868             papi_return( retval );
02869     }
02870 
02871     retval = _papi_hwd[cidx]->cleanup_eventset( ESI->ctl_state );
02872     if ( retval != PAPI_OK ) 
02873         papi_return( retval );
02874 
02875     /* Now do the magic */
02876     papi_return( _papi_hwi_cleanup_eventset( ESI ) );
02877 }
02878 
02906 int
02907 PAPI_multiplex_init( void )
02908 {
02909     int retval;
02910 
02911     retval = mpx_init( _papi_os_info.itimer_ns );
02912     papi_return( retval );
02913 }
02914 
02975 int
02976 PAPI_state( int EventSet, int *status )
02977 {
02978     EventSetInfo_t *ESI;
02979 
02980     if ( status == NULL )
02981         papi_return( PAPI_EINVAL );
02982 
02983     /* check for good EventSetIndex value */
02984 
02985     ESI = _papi_hwi_lookup_EventSet( EventSet );
02986     if ( ESI == NULL )
02987         papi_return( PAPI_ENOEVST );
02988 
02989     /*read status FROM ESI->state */
02990 
02991     *status = ESI->state;
02992 
02993     return ( PAPI_OK );
02994 }
02995 
03046 int
03047 PAPI_set_debug( int level )
03048 {
03049     PAPI_option_t option;
03050 
03051     memset( &option, 0x0, sizeof ( option ) );
03052     option.debug.level = level;
03053     option.debug.handler = _papi_hwi_debug_handler;
03054     return ( PAPI_set_opt( PAPI_DEBUG, &option ) );
03055 }
03056 
03057 /* Attaches to or detaches from the specified thread id */
03058 inline_static int
03059 _papi_set_attach( int option, int EventSet, unsigned long tid )
03060 {
03061     PAPI_option_t attach;
03062 
03063     memset( &attach, 0x0, sizeof ( attach ) );
03064     attach.attach.eventset = EventSet;
03065     attach.attach.tid = tid;
03066     return ( PAPI_set_opt( option, &attach ) );
03067 }
03068 
03122 int
03123 PAPI_attach( int EventSet, unsigned long tid )
03124 {
03125     return ( _papi_set_attach( PAPI_ATTACH, EventSet, tid ) );
03126 }
03127 
03181 int
03182 PAPI_detach( int EventSet )
03183 {
03184     return ( _papi_set_attach( PAPI_DETACH, EventSet, 0 ) );
03185 }
03186 
03255 int
03256 PAPI_set_multiplex( int EventSet )
03257 {
03258     PAPI_option_t mpx;
03259     EventSetInfo_t *ESI;
03260     int cidx;
03261     int ret;
03262 
03263     /* Is the EventSet already in existence? */
03264 
03265     ESI = _papi_hwi_lookup_EventSet( EventSet );
03266 
03267     if ( ESI == NULL )
03268         papi_return( PAPI_ENOEVST );
03269 
03270     /* if the eventset has no index return NOCMP */
03271     cidx = valid_ESI_component( ESI );
03272     if ( cidx < 0 )
03273         papi_return( cidx );
03274 
03275     if ( ( ret = mpx_check( EventSet ) ) != PAPI_OK )
03276         papi_return( ret );
03277 
03278     memset( &mpx, 0x0, sizeof ( mpx ) );
03279     mpx.multiplex.eventset = EventSet;
03280     mpx.multiplex.flags = PAPI_MULTIPLEX_DEFAULT;
03281     mpx.multiplex.ns = _papi_os_info.itimer_ns;
03282     return ( PAPI_set_opt( PAPI_MULTIPLEX, &mpx ) );
03283 }
03284 
03385 int
03386 PAPI_set_opt( int option, PAPI_option_t * ptr )
03387 {
03388     APIDBG("Entry:  option: %d, ptr: %p\n", option, ptr);
03389 
03390     _papi_int_option_t internal;
03391     int retval = PAPI_OK;
03392     hwd_context_t *context;
03393     int cidx;
03394 
03395     if ( ( option != PAPI_DEBUG ) && ( init_level == PAPI_NOT_INITED ) )
03396         papi_return( PAPI_ENOINIT );
03397     if ( ptr == NULL )
03398         papi_return( PAPI_EINVAL );
03399 
03400     memset( &internal, 0x0, sizeof ( _papi_int_option_t ) );
03401 
03402     switch ( option ) {
03403     case PAPI_DETACH:
03404     {
03405         internal.attach.ESI = _papi_hwi_lookup_EventSet( ptr->attach.eventset );
03406         if ( internal.attach.ESI == NULL )
03407             papi_return( PAPI_ENOEVST );
03408 
03409         cidx = valid_ESI_component( internal.attach.ESI );
03410         if ( cidx < 0 )
03411             papi_return( cidx );
03412 
03413         if ( _papi_hwd[cidx]->cmp_info.attach == 0 )
03414             papi_return( PAPI_ECMP );
03415 
03416         /* if attached to a cpu, return an error */
03417         if (internal.attach.ESI->state & PAPI_CPU_ATTACHED)
03418             papi_return( PAPI_ECMP );
03419 
03420         if ( ( internal.attach.ESI->state & PAPI_STOPPED ) == 0 )
03421             papi_return( PAPI_EISRUN );
03422 
03423         if ( ( internal.attach.ESI->state & PAPI_ATTACHED ) == 0 )
03424             papi_return( PAPI_EINVAL );
03425 
03426         internal.attach.tid = internal.attach.ESI->attach.tid;
03427         /* get the context we should use for this event set */
03428         context = _papi_hwi_get_context( internal.attach.ESI, NULL );
03429         retval = _papi_hwd[cidx]->ctl( context, PAPI_DETACH, &internal );
03430         if ( retval != PAPI_OK )
03431             papi_return( retval );
03432 
03433         internal.attach.ESI->state ^= PAPI_ATTACHED;
03434         internal.attach.ESI->attach.tid = 0;
03435         return ( PAPI_OK );
03436     }
03437     case PAPI_ATTACH:
03438     {
03439         internal.attach.ESI = _papi_hwi_lookup_EventSet( ptr->attach.eventset );
03440         if ( internal.attach.ESI == NULL )
03441             papi_return( PAPI_ENOEVST );
03442 
03443         cidx = valid_ESI_component( internal.attach.ESI );
03444         if ( cidx < 0 )
03445             papi_return( cidx );
03446 
03447         if ( _papi_hwd[cidx]->cmp_info.attach == 0 )
03448             papi_return( PAPI_ECMP );
03449 
03450         if ( ( internal.attach.ESI->state & PAPI_STOPPED ) == 0 )
03451             papi_return( PAPI_EISRUN );
03452 
03453         if ( internal.attach.ESI->state & PAPI_ATTACHED )
03454             papi_return( PAPI_EINVAL );
03455 
03456         /* if attached to a cpu, return an error */
03457         if (internal.attach.ESI->state & PAPI_CPU_ATTACHED)
03458             papi_return( PAPI_ECMP );
03459 
03460         internal.attach.tid = ptr->attach.tid;
03461         /* get the context we should use for this event set */
03462         context = _papi_hwi_get_context( internal.attach.ESI, NULL );
03463         retval = _papi_hwd[cidx]->ctl( context, PAPI_ATTACH, &internal );
03464         if ( retval != PAPI_OK )
03465             papi_return( retval );
03466 
03467         internal.attach.ESI->state |= PAPI_ATTACHED;
03468         internal.attach.ESI->attach.tid = ptr->attach.tid;
03469 
03470         papi_return (_papi_hwi_lookup_or_create_thread( 
03471                       &(internal.attach.ESI->master), ptr->attach.tid ));
03472     }
03473     case PAPI_CPU_ATTACH:
03474     {
03475         APIDBG("eventset: %d, cpu_num: %d\n", ptr->cpu.eventset, ptr->cpu.cpu_num);
03476         internal.cpu.ESI = _papi_hwi_lookup_EventSet( ptr->cpu.eventset );
03477         if ( internal.cpu.ESI == NULL )
03478             papi_return( PAPI_ENOEVST );
03479 
03480         internal.cpu.cpu_num = ptr->cpu.cpu_num;
03481         APIDBG("internal: %p, ESI: %p, cpu_num: %d\n", &internal, internal.cpu.ESI, internal.cpu.cpu_num);
03482 
03483         cidx = valid_ESI_component( internal.cpu.ESI );
03484         if ( cidx < 0 )
03485             papi_return( cidx );
03486 
03487         if ( _papi_hwd[cidx]->cmp_info.cpu == 0 )
03488             papi_return( PAPI_ECMP );
03489 
03490         // can not attach to a cpu if already attached to a process or 
03491         // counters set to be inherited by child processes
03492         if ( internal.cpu.ESI->state & (PAPI_ATTACHED | PAPI_INHERIT) )
03493             papi_return( PAPI_EINVAL );
03494 
03495         if ( ( internal.cpu.ESI->state & PAPI_STOPPED ) == 0 )
03496             papi_return( PAPI_EISRUN );
03497 
03498         retval = _papi_hwi_lookup_or_create_cpu(&internal.cpu.ESI->CpuInfo, internal.cpu.cpu_num);
03499         if( retval != PAPI_OK) {
03500             papi_return( retval );
03501         }
03502 
03503         /* get the context we should use for this event set */
03504         context = _papi_hwi_get_context( internal.cpu.ESI, NULL );
03505         retval = _papi_hwd[cidx]->ctl( context, PAPI_CPU_ATTACH, &internal );
03506         if ( retval != PAPI_OK )
03507             papi_return( retval );
03508 
03509         /* set to show this event set is attached to a cpu not a thread */
03510         internal.cpu.ESI->state |= PAPI_CPU_ATTACHED;
03511         return ( PAPI_OK );
03512     }
03513     case PAPI_DEF_MPX_NS:
03514     {
03515         cidx = 0;            /* xxxx for now, assume we only check against cpu component */
03516         if ( ptr->multiplex.ns < 0 )
03517             papi_return( PAPI_EINVAL );
03518         /* We should check the resolution here with the system, either
03519            component if kernel multiplexing or PAPI if SW multiplexing. */
03520         internal.multiplex.ns = ( unsigned long ) ptr->multiplex.ns;
03521         /* get the context we should use for this event set */
03522         context = _papi_hwi_get_context( internal.cpu.ESI, NULL );
03523         /* Low level just checks/adjusts the args for this component */
03524         retval = _papi_hwd[cidx]->ctl( context, PAPI_DEF_MPX_NS, &internal );
03525         if ( retval == PAPI_OK ) {
03526             _papi_os_info.itimer_ns = ( int ) internal.multiplex.ns;
03527             ptr->multiplex.ns = ( int ) internal.multiplex.ns;
03528         }
03529         papi_return( retval );
03530     }
03531     case PAPI_DEF_ITIMER_NS:
03532     {
03533         cidx = 0;            /* xxxx for now, assume we only check against cpu component */
03534         if ( ptr->itimer.ns < 0 )
03535             papi_return( PAPI_EINVAL );
03536         internal.itimer.ns = ptr->itimer.ns;
03537         /* Low level just checks/adjusts the args for this component */
03538         retval = _papi_hwd[cidx]->ctl( NULL, PAPI_DEF_ITIMER_NS, &internal );
03539         if ( retval == PAPI_OK ) {
03540             _papi_os_info.itimer_ns = internal.itimer.ns;
03541             ptr->itimer.ns = internal.itimer.ns;
03542         }
03543         papi_return( retval );
03544     }
03545     case PAPI_DEF_ITIMER:
03546     {
03547         cidx = 0;            /* xxxx for now, assume we only check against cpu component */
03548         if ( ptr->itimer.ns < 0 )
03549             papi_return( PAPI_EINVAL );
03550         memcpy( &internal.itimer, &ptr->itimer,
03551                 sizeof ( PAPI_itimer_option_t ) );
03552         /* Low level just checks/adjusts the args for this component */
03553         retval = _papi_hwd[cidx]->ctl( NULL, PAPI_DEF_ITIMER, &internal );
03554         if ( retval == PAPI_OK ) {
03555             _papi_os_info.itimer_num = ptr->itimer.itimer_num;
03556             _papi_os_info.itimer_sig = ptr->itimer.itimer_sig;
03557             if ( ptr->itimer.ns > 0 )
03558                 _papi_os_info.itimer_ns = ptr->itimer.ns;
03559             /* flags are currently ignored, eventually the flags will be able
03560                to specify whether or not we use POSIX itimers (clock_gettimer) */
03561         }
03562         papi_return( retval );
03563     }
03564     case PAPI_MULTIPLEX:
03565     {
03566         EventSetInfo_t *ESI;
03567         ESI = _papi_hwi_lookup_EventSet( ptr->multiplex.eventset );
03568        
03569         if ( ESI == NULL )
03570             papi_return( PAPI_ENOEVST );
03571 
03572         cidx = valid_ESI_component( ESI );
03573         if ( cidx < 0 )
03574             papi_return( cidx );
03575        
03576         if ( !( ESI->state & PAPI_STOPPED ) )
03577             papi_return( PAPI_EISRUN );
03578         if ( ESI->state & PAPI_MULTIPLEXING )
03579             papi_return( PAPI_EINVAL );
03580 
03581         if ( ptr->multiplex.ns < 0 )
03582             papi_return( PAPI_EINVAL );
03583         internal.multiplex.ESI = ESI;
03584         internal.multiplex.ns = ( unsigned long ) ptr->multiplex.ns;
03585         internal.multiplex.flags = ptr->multiplex.flags;
03586         if ( ( _papi_hwd[cidx]->cmp_info.kernel_multiplex ) &&
03587              ( ( ptr->multiplex.flags & PAPI_MULTIPLEX_FORCE_SW ) == 0 ) ) {
03588             /* get the context we should use for this event set */
03589             context = _papi_hwi_get_context( ESI, NULL );
03590             retval = _papi_hwd[cidx]->ctl( context, PAPI_MULTIPLEX, &internal );
03591         }
03592         /* Kernel or PAPI may have changed this value so send it back out to the user */
03593         ptr->multiplex.ns = ( int ) internal.multiplex.ns;
03594         if ( retval == PAPI_OK )
03595             papi_return( _papi_hwi_convert_eventset_to_multiplex
03596                          ( &internal.multiplex ) );
03597         return ( retval );
03598     }
03599     case PAPI_DEBUG:
03600     {
03601         int level = ptr->debug.level;
03602         switch ( level ) {
03603         case PAPI_QUIET:
03604         case PAPI_VERB_ESTOP:
03605         case PAPI_VERB_ECONT:
03606             _papi_hwi_error_level = level;
03607             break;
03608         default:
03609             papi_return( PAPI_EINVAL );
03610         }
03611         _papi_hwi_debug_handler = ptr->debug.handler;
03612         return ( PAPI_OK );
03613     }
03614     case PAPI_DEFDOM:
03615     {
03616         int dom = ptr->defdomain.domain;
03617         if ( ( dom < PAPI_DOM_MIN ) || ( dom > PAPI_DOM_MAX ) )
03618             papi_return( PAPI_EINVAL );
03619 
03620         /* Change the global structure. The _papi_hwd_init_control_state function 
03621            in the components gets information from the global structure instead of
03622            per-thread information. */
03623         cidx = valid_component( ptr->defdomain.def_cidx );
03624         if ( cidx < 0 )
03625             papi_return( cidx );
03626 
03627         /* Check what the component supports */
03628 
03629         if ( dom == PAPI_DOM_ALL )
03630             dom = _papi_hwd[cidx]->cmp_info.available_domains;
03631 
03632         if ( dom & ~_papi_hwd[cidx]->cmp_info.available_domains )
03633             papi_return( PAPI_EINVAL );
03634 
03635         _papi_hwd[cidx]->cmp_info.default_domain = dom;
03636 
03637         return ( PAPI_OK );
03638     }
03639     case PAPI_DOMAIN:
03640     {
03641         int dom = ptr->domain.domain;
03642         if ( ( dom < PAPI_DOM_MIN ) || ( dom > PAPI_DOM_MAX ) )
03643             papi_return( PAPI_EINVAL_DOM );
03644 
03645         internal.domain.ESI = _papi_hwi_lookup_EventSet( ptr->domain.eventset );
03646         if ( internal.domain.ESI == NULL )
03647             papi_return( PAPI_ENOEVST );
03648 
03649         cidx = valid_ESI_component( internal.domain.ESI );
03650         if ( cidx < 0 )
03651             papi_return( cidx );
03652 
03653         /* Check what the component supports */
03654 
03655         if ( dom == PAPI_DOM_ALL )
03656             dom = _papi_hwd[cidx]->cmp_info.available_domains;
03657 
03658         if ( dom & ~_papi_hwd[cidx]->cmp_info.available_domains )
03659             papi_return( PAPI_EINVAL_DOM );
03660 
03661         if ( !( internal.domain.ESI->state & PAPI_STOPPED ) )
03662             papi_return( PAPI_EISRUN );
03663 
03664         /* Try to change the domain of the eventset in the hardware */
03665         internal.domain.domain = dom;
03666         internal.domain.eventset = ptr->domain.eventset;
03667         /* get the context we should use for this event set */
03668         context = _papi_hwi_get_context( internal.domain.ESI, NULL );
03669         retval = _papi_hwd[cidx]->ctl( context, PAPI_DOMAIN, &internal );
03670         if ( retval < PAPI_OK )
03671             papi_return( retval );
03672 
03673         /* Change the domain of the eventset in the library */
03674 
03675         internal.domain.ESI->domain.domain = dom;
03676 
03677         return ( retval );
03678     }
03679     case PAPI_DEFGRN:
03680     {
03681         int grn = ptr->defgranularity.granularity;
03682         if ( ( grn < PAPI_GRN_MIN ) || ( grn > PAPI_GRN_MAX ) )
03683             papi_return( PAPI_EINVAL );
03684 
03685         cidx = valid_component( ptr->defgranularity.def_cidx );
03686         if ( cidx < 0 )
03687             papi_return( cidx );
03688 
03689         /* Change the component structure. The _papi_hwd_init_control_state function 
03690            in the components gets information from the global structure instead of
03691            per-thread information. */
03692 
03693         /* Check what the component supports */
03694 
03695         if ( grn & ~_papi_hwd[cidx]->cmp_info.available_granularities )
03696             papi_return( PAPI_EINVAL );
03697 
03698         /* Make sure there is only 1 set. */
03699         if ( grn ^ ( 1 << ( ffs( grn ) - 1 ) ) )
03700             papi_return( PAPI_EINVAL );
03701 
03702         _papi_hwd[cidx]->cmp_info.default_granularity = grn;
03703 
03704         return ( PAPI_OK );
03705     }
03706     case PAPI_GRANUL:
03707     {
03708         int grn = ptr->granularity.granularity;
03709 
03710         if ( ( grn < PAPI_GRN_MIN ) || ( grn > PAPI_GRN_MAX ) )
03711             papi_return( PAPI_EINVAL );
03712 
03713         internal.granularity.ESI =
03714             _papi_hwi_lookup_EventSet( ptr->granularity.eventset );
03715         if ( internal.granularity.ESI == NULL )
03716             papi_return( PAPI_ENOEVST );
03717 
03718         cidx = valid_ESI_component( internal.granularity.ESI );
03719         if ( cidx < 0 )
03720             papi_return( cidx );
03721 
03722         /* Check what the component supports */
03723 
03724         if ( grn & ~_papi_hwd[cidx]->cmp_info.available_granularities )
03725             papi_return( PAPI_EINVAL );
03726 
03727         /* Make sure there is only 1 set. */
03728         if ( grn ^ ( 1 << ( ffs( grn ) - 1 ) ) )
03729             papi_return( PAPI_EINVAL );
03730 
03731         internal.granularity.granularity = grn;
03732         internal.granularity.eventset = ptr->granularity.eventset;
03733         retval = _papi_hwd[cidx]->ctl( NULL, PAPI_GRANUL, &internal );
03734         if ( retval < PAPI_OK )
03735             return ( retval );
03736 
03737         internal.granularity.ESI->granularity.granularity = grn;
03738         return ( retval );
03739     }
03740     case PAPI_INHERIT:
03741     {
03742         EventSetInfo_t *ESI;
03743         ESI = _papi_hwi_lookup_EventSet( ptr->inherit.eventset );
03744         if ( ESI == NULL )
03745             papi_return( PAPI_ENOEVST );
03746 
03747         cidx = valid_ESI_component( ESI );
03748         if ( cidx < 0 )
03749             papi_return( cidx );
03750 
03751         if ( _papi_hwd[cidx]->cmp_info.inherit == 0 )
03752             papi_return( PAPI_ECMP );
03753 
03754         if ( ( ESI->state & PAPI_STOPPED ) == 0 )
03755             papi_return( PAPI_EISRUN );
03756 
03757         /* if attached to a cpu, return an error */
03758         if (ESI->state & PAPI_CPU_ATTACHED)
03759             papi_return( PAPI_ECMP );
03760 
03761         internal.inherit.ESI = ESI;
03762         internal.inherit.inherit = ptr->inherit.inherit;
03763 
03764         /* get the context we should use for this event set */
03765         context = _papi_hwi_get_context( internal.inherit.ESI, NULL );
03766         retval = _papi_hwd[cidx]->ctl( context, PAPI_INHERIT, &internal );
03767         if ( retval < PAPI_OK )
03768             return ( retval );
03769 
03770         ESI->inherit.inherit = ptr->inherit.inherit;
03771         return ( retval );
03772     }
03773     case PAPI_DATA_ADDRESS:
03774     case PAPI_INSTR_ADDRESS:
03775     {
03776 
03777         EventSetInfo_t *ESI;
03778 
03779         ESI = _papi_hwi_lookup_EventSet( ptr->addr.eventset );
03780         if ( ESI == NULL )
03781             papi_return( PAPI_ENOEVST );
03782 
03783         cidx = valid_ESI_component( ESI );
03784         if ( cidx < 0 )
03785             papi_return( cidx );
03786 
03787         internal.address_range.ESI = ESI;
03788 
03789         if ( !( internal.address_range.ESI->state & PAPI_STOPPED ) )
03790             papi_return( PAPI_EISRUN );
03791 
03792         /*set domain to be PAPI_DOM_USER */
03793         internal.address_range.domain = PAPI_DOM_USER;
03794 
03795         internal.address_range.start = ptr->addr.start;
03796         internal.address_range.end = ptr->addr.end;
03797         /* get the context we should use for this event set */
03798         context = _papi_hwi_get_context( internal.address_range.ESI, NULL );
03799         retval = _papi_hwd[cidx]->ctl( context, option, &internal );
03800         ptr->addr.start_off = internal.address_range.start_off;
03801         ptr->addr.end_off = internal.address_range.end_off;
03802         papi_return( retval );
03803     }
03804     case PAPI_USER_EVENTS_FILE:
03805     {
03806       SUBDBG("Filename is -%s-\n", ptr->events_file);
03807       _papi_user_defined_events_setup(ptr->events_file);
03808       return( PAPI_OK );
03809     }
03810     default:
03811         papi_return( PAPI_EINVAL );
03812     }
03813 }
03814 
03824 int
03825 PAPI_num_hwctrs( void )
03826 {
03827     return ( PAPI_num_cmp_hwctrs( 0 ) );
03828 }
03829 
03879 int
03880 PAPI_num_cmp_hwctrs( int cidx )
03881 {
03882     return ( PAPI_get_cmp_opt( PAPI_MAX_HWCTRS, NULL, cidx ) );
03883 }
03884 
03941 int
03942 PAPI_get_multiplex( int EventSet )
03943 {
03944     PAPI_option_t popt;
03945     int retval;
03946 
03947     popt.multiplex.eventset = EventSet;
03948     retval = PAPI_get_opt( PAPI_MULTIPLEX, &popt );
03949     if ( retval < 0 )
03950         retval = 0;
03951     return retval;
03952 }
03953 
04055 int
04056 PAPI_get_opt( int option, PAPI_option_t * ptr )
04057 {
04058     EventSetInfo_t *ESI;
04059 
04060     if ( ( option != PAPI_DEBUG ) && ( init_level == PAPI_NOT_INITED ) )
04061         papi_return( PAPI_ENOINIT );
04062 
04063     switch ( option ) {
04064     case PAPI_DETACH:
04065     {
04066         if ( ptr == NULL )
04067             papi_return( PAPI_EINVAL );
04068         ESI = _papi_hwi_lookup_EventSet( ptr->attach.eventset );
04069         if ( ESI == NULL )
04070             papi_return( PAPI_ENOEVST );
04071         ptr->attach.tid = ESI->attach.tid;
04072         return ( ( ESI->state & PAPI_ATTACHED ) == 0 );
04073     }
04074     case PAPI_ATTACH:
04075     {
04076         if ( ptr == NULL )
04077             papi_return( PAPI_EINVAL );
04078         ESI = _papi_hwi_lookup_EventSet( ptr->attach.eventset );
04079         if ( ESI == NULL )
04080             papi_return( PAPI_ENOEVST );
04081         ptr->attach.tid = ESI->attach.tid;
04082         return ( ( ESI->state & PAPI_ATTACHED ) != 0 );
04083     }
04084     case PAPI_CPU_ATTACH:
04085     {
04086         if ( ptr == NULL )
04087             papi_return( PAPI_EINVAL );
04088         ESI = _papi_hwi_lookup_EventSet( ptr->attach.eventset );
04089         if ( ESI == NULL )
04090             papi_return( PAPI_ENOEVST );
04091         ptr->cpu.cpu_num = ESI->CpuInfo->cpu_num;
04092         return ( ( ESI->state & PAPI_CPU_ATTACHED ) != 0 );
04093     }
04094     case PAPI_DEF_MPX_NS:
04095     {
04096         /* xxxx for now, assume we only check against cpu component */
04097         if ( ptr == NULL )
04098             papi_return( PAPI_EINVAL );
04099         ptr->multiplex.ns = _papi_os_info.itimer_ns;
04100         return ( PAPI_OK );
04101     }
04102     case PAPI_DEF_ITIMER_NS:
04103     {
04104         /* xxxx for now, assume we only check against cpu component */
04105         if ( ptr == NULL )
04106             papi_return( PAPI_EINVAL );
04107         ptr->itimer.ns = _papi_os_info.itimer_ns;
04108         return ( PAPI_OK );
04109     }
04110     case PAPI_DEF_ITIMER:
04111     {
04112         /* xxxx for now, assume we only check against cpu component */
04113         if ( ptr == NULL )
04114             papi_return( PAPI_EINVAL );
04115         ptr->itimer.itimer_num = _papi_os_info.itimer_num;
04116         ptr->itimer.itimer_sig = _papi_os_info.itimer_sig;
04117         ptr->itimer.ns = _papi_os_info.itimer_ns;
04118         ptr->itimer.flags = 0;
04119         return ( PAPI_OK );
04120     }
04121     case PAPI_MULTIPLEX:
04122     {
04123         if ( ptr == NULL )
04124             papi_return( PAPI_EINVAL );
04125         ESI = _papi_hwi_lookup_EventSet( ptr->multiplex.eventset );
04126         if ( ESI == NULL )
04127             papi_return( PAPI_ENOEVST );
04128         ptr->multiplex.ns = ESI->multiplex.ns;
04129         ptr->multiplex.flags = ESI->multiplex.flags;
04130         return ( ESI->state & PAPI_MULTIPLEXING ) != 0;
04131     }
04132     case PAPI_PRELOAD:
04133         if ( ptr == NULL )
04134             papi_return( PAPI_EINVAL );
04135         memcpy( &ptr->preload, &_papi_hwi_system_info.preload_info,
04136                 sizeof ( PAPI_preload_info_t ) );
04137         break;
04138     case PAPI_DEBUG:
04139         if ( ptr == NULL )
04140             papi_return( PAPI_EINVAL );
04141         ptr->debug.level = _papi_hwi_error_level;
04142         ptr->debug.handler = _papi_hwi_debug_handler;
04143         break;
04144     case PAPI_CLOCKRATE:
04145         return ( ( int ) _papi_hwi_system_info.hw_info.cpu_max_mhz );
04146     case PAPI_MAX_CPUS:
04147         return ( _papi_hwi_system_info.hw_info.ncpu );
04148         /* For now, MAX_HWCTRS and MAX CTRS are identical.
04149            At some future point, they may map onto different values.
04150          */
04151     case PAPI_INHERIT:
04152     {
04153         if ( ptr == NULL )
04154             papi_return( PAPI_EINVAL );
04155         ESI = _papi_hwi_lookup_EventSet( ptr->inherit.eventset );
04156         if ( ESI == NULL )
04157             papi_return( PAPI_ENOEVST );
04158         ptr->inherit.inherit = ESI->inherit.inherit;
04159         return ( PAPI_OK );
04160     }
04161     case PAPI_GRANUL:
04162         if ( ptr == NULL )
04163             papi_return( PAPI_EINVAL );
04164         ESI = _papi_hwi_lookup_EventSet( ptr->granularity.eventset );
04165         if ( ESI == NULL )
04166             papi_return( PAPI_ENOEVST );
04167         ptr->granularity.granularity = ESI->granularity.granularity;
04168         break;
04169     case PAPI_EXEINFO:
04170         if ( ptr == NULL )
04171             papi_return( PAPI_EINVAL );
04172         ptr->exe_info = &_papi_hwi_system_info.exe_info;
04173         break;
04174     case PAPI_HWINFO:
04175         if ( ptr == NULL )
04176             papi_return( PAPI_EINVAL );
04177         ptr->hw_info = &_papi_hwi_system_info.hw_info;
04178         break;
04179 
04180     case PAPI_DOMAIN:
04181         if ( ptr == NULL )
04182             papi_return( PAPI_EINVAL );
04183         ESI = _papi_hwi_lookup_EventSet( ptr->domain.eventset );
04184         if ( ESI == NULL )
04185             papi_return( PAPI_ENOEVST );
04186         ptr->domain.domain = ESI->domain.domain;
04187         return ( PAPI_OK );
04188     case PAPI_LIB_VERSION:
04189         return ( PAPI_VERSION );
04190 /* The following cases all require a component index 
04191     and are handled by PAPI_get_cmp_opt() with cidx == 0*/
04192     case PAPI_MAX_HWCTRS:
04193     case PAPI_MAX_MPX_CTRS:
04194     case PAPI_DEFDOM:
04195     case PAPI_DEFGRN:
04196     case PAPI_SHLIBINFO:
04197     case PAPI_COMPONENTINFO:
04198         return ( PAPI_get_cmp_opt( option, ptr, 0 ) );
04199     default:
04200         papi_return( PAPI_EINVAL );
04201     }
04202     return ( PAPI_OK );
04203 }
04204 
04246 int
04247 PAPI_get_cmp_opt( int option, PAPI_option_t * ptr, int cidx )
04248 {
04249 
04250   if (_papi_hwi_invalid_cmp(cidx)) {
04251      return PAPI_ECMP;
04252   }
04253 
04254     switch ( option ) {
04255         /* For now, MAX_HWCTRS and MAX CTRS are identical.
04256            At some future point, they may map onto different values.
04257          */
04258     case PAPI_MAX_HWCTRS:
04259         return ( _papi_hwd[cidx]->cmp_info.num_cntrs );
04260     case PAPI_MAX_MPX_CTRS:
04261         return ( _papi_hwd[cidx]->cmp_info.num_mpx_cntrs );
04262     case PAPI_DEFDOM:
04263         return ( _papi_hwd[cidx]->cmp_info.default_domain );
04264     case PAPI_DEFGRN:
04265         return ( _papi_hwd[cidx]->cmp_info.default_granularity );
04266     case PAPI_SHLIBINFO:
04267     {
04268         int retval;
04269         if ( ptr == NULL )
04270             papi_return( PAPI_EINVAL );
04271         retval = _papi_os_vector.update_shlib_info( &_papi_hwi_system_info );
04272         ptr->shlib_info = &_papi_hwi_system_info.shlib_info;
04273         papi_return( retval );
04274     }
04275     case PAPI_COMPONENTINFO:
04276         if ( ptr == NULL )
04277             papi_return( PAPI_EINVAL );
04278         ptr->cmp_info = &( _papi_hwd[cidx]->cmp_info );
04279         return PAPI_OK;
04280     default:
04281       papi_return( PAPI_EINVAL );
04282     }
04283     return PAPI_OK;
04284 }
04285 
04297 int
04298 PAPI_num_components( void )
04299 {
04300     return ( papi_num_components );
04301 }
04302 
04337 int
04338 PAPI_num_events( int EventSet )
04339 {
04340     EventSetInfo_t *ESI;
04341 
04342     ESI = _papi_hwi_lookup_EventSet( EventSet );
04343     if ( !ESI )
04344         papi_return( PAPI_ENOEVST );
04345 
04346 #ifdef DEBUG
04347     /* Not necessary */
04348     if ( ESI->NumberOfEvents == 0 )
04349         papi_return( PAPI_EINVAL );
04350 #endif
04351 
04352     return ( ESI->NumberOfEvents );
04353 }
04354 
04355 
04371 void
04372 PAPI_shutdown( void )
04373 {
04374         EventSetInfo_t *ESI;
04375         ThreadInfo_t *master;
04376         DynamicArray_t *map = &_papi_hwi_system_info.global_eventset_map;
04377         int i, j = 0, retval;
04378 
04379 
04380     APIDBG( "Enter\n" );
04381     if ( init_retval == DEADBEEF ) {
04382         PAPIERROR( PAPI_SHUTDOWN_str );
04383         return;
04384     }
04385 
04386     MPX_shutdown(  );
04387 
04388     /* Free all EventSets for this thread */
04389 
04390    master = _papi_hwi_lookup_thread( 0 );
04391 
04392       /* Count number of running EventSets AND */
04393       /* Stop any running EventSets in this thread */
04394 
04395 #ifdef DEBUG
04396 again:
04397 #endif
04398    for( i = 0; i < map->totalSlots; i++ ) {
04399       ESI = map->dataSlotArray[i];
04400       if ( ESI ) {
04401      if ( ESI->master == master ) {
04402         if ( ESI->state & PAPI_RUNNING ) {
04403            retval=PAPI_stop( i, NULL );
04404         }
04405         retval=PAPI_cleanup_eventset( i );
04406         if (retval!=PAPI_OK) PAPIERROR("Error during cleanup.\n");
04407         _papi_hwi_free_EventSet( ESI );
04408      } 
04409          else {
04410             if ( ESI->state & PAPI_RUNNING ) {
04411            j++;
04412         }
04413      }
04414       }
04415    }
04416 
04417     /* No locking required, we're just waiting for the others
04418        to call shutdown or stop their eventsets. */
04419 
04420 #ifdef DEBUG
04421     if ( j != 0 ) {
04422         PAPIERROR( PAPI_SHUTDOWN_SYNC_str );
04423         sleep( 1 );
04424         j = 0;
04425         goto again;
04426     }
04427 #endif
04428 
04429     /* Shutdown the entire component */
04430 
04431     _papi_cleanup_user_events();
04432 
04433     _papi_hwi_shutdown_highlevel(  );
04434     _papi_hwi_shutdown_global_internal(  );
04435     _papi_hwi_shutdown_global_threads(  );
04436     for( i = 0; i < papi_num_components; i++ ) {
04437        if (!_papi_hwd[i]->cmp_info.disabled) {
04438               _papi_hwd[i]->shutdown_component(  );
04439        }
04440     }
04441 
04442     /* Now it is safe to call re-init */
04443 
04444     init_retval = DEADBEEF;
04445     init_level = PAPI_NOT_INITED;
04446     _papi_mem_cleanup_all(  );
04447 }
04448 
04497 char *
04498 PAPI_strerror( int errorCode )
04499 {
04500     if ( ( errorCode > 0 ) || ( -errorCode > _papi_hwi_num_errors ) )
04501         return ( NULL );
04502 
04503     return ( _papi_errlist[-errorCode] );
04504 }
04505 
04547 void
04548 PAPI_perror( char *msg )
04549 {
04550     char *foo;
04551 
04552     foo = PAPI_strerror( _papi_hwi_errno );
04553     if ( foo == NULL )
04554         return;
04555 
04556     if ( msg )
04557         if ( *msg )
04558                 fprintf( stderr, "%s: ", msg );
04559 
04560     fprintf( stderr, "%s\n", foo );
04561 }
04562 
04683 int
04684 PAPI_overflow( int EventSet, int EventCode, int threshold, int flags,
04685            PAPI_overflow_handler_t handler )
04686 {
04687     int retval, cidx, index, i;
04688     EventSetInfo_t *ESI;
04689 
04690     ESI = _papi_hwi_lookup_EventSet( EventSet );
04691     if ( ESI == NULL ) {
04692         OVFDBG("No EventSet\n");
04693         papi_return( PAPI_ENOEVST );
04694         }
04695 
04696     cidx = valid_ESI_component( ESI );
04697     if ( cidx < 0 ) {
04698         OVFDBG("Component Error\n");
04699         papi_return( cidx );
04700     }
04701 
04702     if ( ( ESI->state & PAPI_STOPPED ) != PAPI_STOPPED ) {
04703         OVFDBG("Already running\n");
04704         papi_return( PAPI_EISRUN );
04705     }
04706 
04707     if ( ESI->state & PAPI_ATTACHED ) {
04708         OVFDBG("Attached\n");
04709         papi_return( PAPI_EINVAL );
04710     }
04711     
04712     if ( ESI->state & PAPI_CPU_ATTACHED ) {
04713         OVFDBG("CPU attached\n");
04714         papi_return( PAPI_EINVAL );
04715     }
04716     
04717     if ( ( index = _papi_hwi_lookup_EventCodeIndex( ESI,
04718                         ( unsigned int ) EventCode ) ) < 0 ) {
04719         papi_return( PAPI_ENOEVNT );
04720     }
04721 
04722     if ( threshold < 0 ) {
04723         OVFDBG("Threshold below zero\n");
04724         papi_return( PAPI_EINVAL );
04725     }
04726 
04727     /* We do not support derived events in overflow */
04728     /* Unless it's DERIVED_CMPD in which no calculations are done */
04729 
04730     if ( !( flags & PAPI_OVERFLOW_FORCE_SW ) && threshold != 0 &&
04731          ( ESI->EventInfoArray[index].derived ) &&
04732          ( ESI->EventInfoArray[index].derived != DERIVED_CMPD ) ) {
04733         OVFDBG("Derived event in overflow\n");
04734         papi_return( PAPI_EINVAL );
04735     }
04736 
04737     /* the first time to call PAPI_overflow function */
04738 
04739     if ( !( ESI->state & PAPI_OVERFLOWING ) ) {
04740         if ( handler == NULL ) {
04741             OVFDBG("NULL handler\n");
04742             papi_return( PAPI_EINVAL );
04743         }
04744         if ( threshold == 0 ) {
04745             OVFDBG("Zero threshold\n");
04746             papi_return( PAPI_EINVAL );
04747         }
04748     }
04749     if ( threshold > 0 &&
04750          ESI->overflow.event_counter >= _papi_hwd[cidx]->cmp_info.num_cntrs )
04751         papi_return( PAPI_ECNFLCT );
04752 
04753     if ( threshold == 0 ) {
04754         for ( i = 0; i < ESI->overflow.event_counter; i++ ) {
04755             if ( ESI->overflow.EventCode[i] == EventCode )
04756                 break;
04757         }
04758         /* EventCode not found */
04759         if ( i == ESI->overflow.event_counter )
04760             papi_return( PAPI_EINVAL );
04761         /* compact these arrays */
04762         while ( i < ESI->overflow.event_counter - 1 ) {
04763             ESI->overflow.deadline[i] = ESI->overflow.deadline[i + 1];
04764             ESI->overflow.threshold[i] = ESI->overflow.threshold[i + 1];
04765             ESI->overflow.EventIndex[i] = ESI->overflow.EventIndex[i + 1];
04766             ESI->overflow.EventCode[i] = ESI->overflow.EventCode[i + 1];
04767             i++;
04768         }
04769         ESI->overflow.deadline[i] = 0;
04770         ESI->overflow.threshold[i] = 0;
04771         ESI->overflow.EventIndex[i] = 0;
04772         ESI->overflow.EventCode[i] = 0;
04773         ESI->overflow.event_counter--;
04774     } else {
04775         if ( ESI->overflow.event_counter > 0 ) {
04776             if ( ( flags & PAPI_OVERFLOW_FORCE_SW ) &&
04777                  ( ESI->overflow.flags & PAPI_OVERFLOW_HARDWARE ) )
04778                 papi_return( PAPI_ECNFLCT );
04779             if ( !( flags & PAPI_OVERFLOW_FORCE_SW ) &&
04780                  ( ESI->overflow.flags & PAPI_OVERFLOW_FORCE_SW ) )
04781                 papi_return( PAPI_ECNFLCT );
04782         }
04783         for ( i = 0; i < ESI->overflow.event_counter; i++ ) {
04784             if ( ESI->overflow.EventCode[i] == EventCode )
04785                 break;
04786         }
04787         /* A new entry */
04788         if ( i == ESI->overflow.event_counter ) {
04789             ESI->overflow.EventCode[i] = EventCode;
04790             ESI->overflow.event_counter++;
04791         }
04792         /* New or existing entry */
04793         ESI->overflow.deadline[i] = threshold;
04794         ESI->overflow.threshold[i] = threshold;
04795         ESI->overflow.EventIndex[i] = index;
04796         ESI->overflow.flags = flags;
04797 
04798     }
04799 
04800     /* If overflowing is already active, we should check to
04801        make sure that we don't specify a different handler
04802        or different flags here. You can't mix them. */
04803 
04804     ESI->overflow.handler = handler;
04805 
04806     /* Set up the option structure for the low level.
04807        If we have hardware interrupts and we are not using
04808        forced software emulated interrupts */
04809 
04810     if ( _papi_hwd[cidx]->cmp_info.hardware_intr &&
04811          !( ESI->overflow.flags & PAPI_OVERFLOW_FORCE_SW ) ) {
04812         retval = _papi_hwd[cidx]->set_overflow( ESI, index, threshold );
04813         if ( retval == PAPI_OK )
04814             ESI->overflow.flags |= PAPI_OVERFLOW_HARDWARE;
04815         else {
04816             papi_return( retval );  /* We should undo stuff here */
04817         }
04818     } else {
04819         /* Make sure hardware overflow is not set */
04820         ESI->overflow.flags &= ~( PAPI_OVERFLOW_HARDWARE );
04821     }
04822 
04823     APIDBG( "Overflow using: %s\n",
04824             ( ESI->overflow.
04825               flags & PAPI_OVERFLOW_HARDWARE ? "[Hardware]" : ESI->overflow.
04826               flags & PAPI_OVERFLOW_FORCE_SW ? "[Forced Software]" :
04827               "[Software]" ) );
04828 
04829     /* Toggle the overflow flags and ESI state */
04830 
04831     if ( ESI->overflow.event_counter >= 1 )
04832         ESI->state |= PAPI_OVERFLOWING;
04833     else {
04834         ESI->state ^= PAPI_OVERFLOWING;
04835         ESI->overflow.flags = 0;
04836         ESI->overflow.handler = NULL;
04837     }
04838 
04839     return PAPI_OK;
04840 }
04841 
04938 int
04939 PAPI_sprofil( PAPI_sprofil_t *prof, int profcnt, int EventSet,
04940               int EventCode, int threshold, int flags )
04941 {
04942    EventSetInfo_t *ESI;
04943    int retval, index, i, buckets;
04944    int forceSW = 0;
04945    int cidx;
04946 
04947    /* Check to make sure EventSet exists */
04948    ESI = _papi_hwi_lookup_EventSet( EventSet );
04949    if ( ESI == NULL ) {
04950       papi_return( PAPI_ENOEVST );
04951    }
04952 
04953    /* Check to make sure EventSet is stopped */
04954    if ( ( ESI->state & PAPI_STOPPED ) != PAPI_STOPPED ) {
04955       papi_return( PAPI_EISRUN );
04956    }
04957 
04958    /* We cannot profile if attached */
04959    if ( ESI->state & PAPI_ATTACHED ) {
04960       papi_return( PAPI_EINVAL );
04961    }
04962 
04963    /* We cannot profile if cpu attached */
04964    if ( ESI->state & PAPI_CPU_ATTACHED ) {
04965       papi_return( PAPI_EINVAL );
04966    }
04967 
04968    /* Get component for EventSet */
04969    cidx = valid_ESI_component( ESI );
04970    if ( cidx < 0 ) {
04971       papi_return( cidx );
04972    }
04973 
04974    /* Get index of the Event we want to profile */
04975    if ( ( index = _papi_hwi_lookup_EventCodeIndex( ESI,
04976                       (unsigned int) EventCode ) ) < 0 ) {
04977       papi_return( PAPI_ENOEVNT );
04978    }
04979 
04980    /* We do not support derived events in overflow */
04981    /* Unless it's DERIVED_CMPD in which no calculations are done */
04982    if ( ( ESI->EventInfoArray[index].derived ) &&
04983     ( ESI->EventInfoArray[index].derived != DERIVED_CMPD ) &&
04984     !( flags & PAPI_PROFIL_FORCE_SW ) ) {
04985       papi_return( PAPI_EINVAL );
04986    }
04987 
04988    /* If no prof structures, then make sure count is 0 */
04989    if ( prof == NULL ) {
04990       profcnt = 0;
04991    }
04992 
04993    /* check all profile regions for valid scale factors of:
04994       2 (131072/65536),
04995       1 (65536/65536),
04996       or < 1 (65535 -> 2) as defined in unix profil()
04997       2/65536 is reserved for single bucket profiling
04998       {0,1}/65536 are traditionally used to terminate profiling
04999       but are unused here since PAPI uses threshold instead
05000     */
05001    for( i = 0; i < profcnt; i++ ) {
05002       if ( !( ( prof[i].pr_scale == 131072 ) ||
05003        ( ( prof[i].pr_scale <= 65536 && prof[i].pr_scale > 1 ) ) ) ) {
05004      APIDBG( "Improper scale factor: %d\n", prof[i].pr_scale );
05005      papi_return( PAPI_EINVAL );
05006       }
05007    }
05008 
05009    /* Make sure threshold is valid */
05010    if ( threshold < 0 ) {
05011       papi_return( PAPI_EINVAL );
05012    }
05013 
05014    /* the first time to call PAPI_sprofil */
05015    if ( !( ESI->state & PAPI_PROFILING ) ) {
05016       if ( threshold == 0 ) {
05017      papi_return( PAPI_EINVAL );
05018       }
05019    }
05020 
05021    /* ??? */
05022    if ( (threshold > 0) &&
05023     (ESI->profile.event_counter >= _papi_hwd[cidx]->cmp_info.num_cntrs) ) {
05024       papi_return( PAPI_ECNFLCT );
05025    }
05026 
05027    if ( threshold == 0 ) {
05028       for( i = 0; i < ESI->profile.event_counter; i++ ) {
05029      if ( ESI->profile.EventCode[i] == EventCode ) {
05030         break;
05031      }
05032       }
05033         
05034       /* EventCode not found */
05035       if ( i == ESI->profile.event_counter ) {
05036      papi_return( PAPI_EINVAL );
05037       }
05038 
05039       /* compact these arrays */
05040       while ( i < ESI->profile.event_counter - 1 ) {
05041          ESI->profile.prof[i] = ESI->profile.prof[i + 1];
05042      ESI->profile.count[i] = ESI->profile.count[i + 1];
05043      ESI->profile.threshold[i] = ESI->profile.threshold[i + 1];
05044      ESI->profile.EventIndex[i] = ESI->profile.EventIndex[i + 1];
05045      ESI->profile.EventCode[i] = ESI->profile.EventCode[i + 1];
05046      i++;
05047       }
05048       ESI->profile.prof[i] = NULL;
05049       ESI->profile.count[i] = 0;
05050       ESI->profile.threshold[i] = 0;
05051       ESI->profile.EventIndex[i] = 0;
05052       ESI->profile.EventCode[i] = 0;
05053       ESI->profile.event_counter--;
05054    } else {
05055       if ( ESI->profile.event_counter > 0 ) {
05056      if ( ( flags & PAPI_PROFIL_FORCE_SW ) &&
05057           !( ESI->profile.flags & PAPI_PROFIL_FORCE_SW ) ) {
05058         papi_return( PAPI_ECNFLCT );
05059      }
05060      if ( !( flags & PAPI_PROFIL_FORCE_SW ) &&
05061           ( ESI->profile.flags & PAPI_PROFIL_FORCE_SW ) ) {
05062         papi_return( PAPI_ECNFLCT );
05063      }
05064       }
05065 
05066       for( i = 0; i < ESI->profile.event_counter; i++ ) {
05067      if ( ESI->profile.EventCode[i] == EventCode ) {
05068         break;
05069      }
05070       }
05071 
05072       if ( i == ESI->profile.event_counter ) {
05073      i = ESI->profile.event_counter;
05074      ESI->profile.event_counter++;
05075      ESI->profile.EventCode[i] = EventCode;
05076       }
05077       ESI->profile.prof[i] = prof;
05078       ESI->profile.count[i] = profcnt;
05079       ESI->profile.threshold[i] = threshold;
05080       ESI->profile.EventIndex[i] = index;
05081    }
05082 
05083    APIDBG( "Profile event counter is %d\n", ESI->profile.event_counter );
05084 
05085    /* Clear out old flags */
05086    if ( threshold == 0 ) {
05087       flags |= ESI->profile.flags;
05088    }
05089 
05090    /* make sure no invalid flags are set */
05091    if ( flags &
05092     ~( PAPI_PROFIL_POSIX | PAPI_PROFIL_RANDOM | PAPI_PROFIL_WEIGHTED |
05093        PAPI_PROFIL_COMPRESS | PAPI_PROFIL_BUCKETS | PAPI_PROFIL_FORCE_SW |
05094        PAPI_PROFIL_INST_EAR | PAPI_PROFIL_DATA_EAR ) ) {
05095       papi_return( PAPI_EINVAL );
05096    }
05097 
05098    /* if we have kernel-based profiling, then we're just asking for 
05099       signals on interrupt. */
05100    /* if we don't have kernel-based profiling, then we're asking for 
05101       emulated PMU interrupt */
05102    if ( ( flags & PAPI_PROFIL_FORCE_SW ) &&
05103     ( _papi_hwd[cidx]->cmp_info.kernel_profile == 0 ) ) {
05104       forceSW = PAPI_OVERFLOW_FORCE_SW;
05105    }
05106 
05107    /* make sure one and only one bucket size is set */
05108    buckets = flags & PAPI_PROFIL_BUCKETS;
05109    if ( !buckets ) {
05110       flags |= PAPI_PROFIL_BUCKET_16;   /* default to 16 bit if nothing set */
05111    }
05112    else {
05113       /* return error if more than one set */
05114       if ( !( ( buckets == PAPI_PROFIL_BUCKET_16 ) ||
05115           ( buckets == PAPI_PROFIL_BUCKET_32 ) ||
05116           ( buckets == PAPI_PROFIL_BUCKET_64 ) ) ) {
05117      papi_return( PAPI_EINVAL );
05118       }
05119    }
05120 
05121    /* Set up the option structure for the low level */
05122    ESI->profile.flags = flags;
05123 
05124    if ( _papi_hwd[cidx]->cmp_info.kernel_profile &&
05125     !( ESI->profile.flags & PAPI_PROFIL_FORCE_SW ) ) {
05126       retval = _papi_hwd[cidx]->set_profile( ESI, index, threshold );
05127       if ( ( retval == PAPI_OK ) && ( threshold > 0 ) ) {
05128      /* We need overflowing because we use the overflow dispatch handler */
05129      ESI->state |= PAPI_OVERFLOWING;
05130      ESI->overflow.flags |= PAPI_OVERFLOW_HARDWARE;
05131       }
05132    } else {
05133       retval = PAPI_overflow( EventSet, EventCode, threshold, forceSW,
05134                   _papi_hwi_dummy_handler );
05135    }
05136     
05137    if ( retval < PAPI_OK ) {
05138       papi_return( retval );    /* We should undo stuff here */
05139    }
05140 
05141    /* Toggle the profiling flags and ESI state */
05142 
05143    if ( ESI->profile.event_counter >= 1 ) {
05144       ESI->state |= PAPI_PROFILING;
05145    }
05146    else {
05147       ESI->state ^= PAPI_PROFILING;
05148       ESI->profile.flags = 0;
05149    }
05150 
05151    return PAPI_OK;
05152 }
05153 
05331 int
05332 PAPI_profil( void *buf, unsigned bufsiz, caddr_t offset,
05333              unsigned scale, int EventSet, int EventCode, int threshold,
05334              int flags )
05335 {
05336     EventSetInfo_t *ESI;
05337     int i;
05338     int retval;
05339 
05340     ESI = _papi_hwi_lookup_EventSet( EventSet );
05341     if ( ESI == NULL )
05342         papi_return( PAPI_ENOEVST );
05343 
05344     /* scale factors are checked for validity in PAPI_sprofil */
05345 
05346     if ( threshold > 0 ) {
05347         PAPI_sprofil_t *prof;
05348 
05349         for ( i = 0; i < ESI->profile.event_counter; i++ ) {
05350             if ( ESI->profile.EventCode[i] == EventCode )
05351                 break;
05352         }
05353 
05354         if ( i == ESI->profile.event_counter ) {
05355             prof =
05356                 ( PAPI_sprofil_t * ) papi_malloc( sizeof ( PAPI_sprofil_t ) );
05357             memset( prof, 0x0, sizeof ( PAPI_sprofil_t ) );
05358             prof->pr_base = buf;
05359             prof->pr_size = bufsiz;
05360             prof->pr_off = offset;
05361             prof->pr_scale = scale;
05362 
05363             retval =
05364                 PAPI_sprofil( prof, 1, EventSet, EventCode, threshold, flags );
05365 
05366             if ( retval != PAPI_OK )
05367                 papi_free( prof );
05368         } else {
05369             prof = ESI->profile.prof[i];
05370             prof->pr_base = buf;
05371             prof->pr_size = bufsiz;
05372             prof->pr_off = offset;
05373             prof->pr_scale = scale;
05374             retval =
05375                 PAPI_sprofil( prof, 1, EventSet, EventCode, threshold, flags );
05376         }
05377         papi_return( retval );
05378     }
05379 
05380     for ( i = 0; i < ESI->profile.event_counter; i++ ) {
05381         if ( ESI->profile.EventCode[i] == EventCode )
05382             break;
05383     }
05384     /* EventCode not found */
05385     if ( i == ESI->profile.event_counter )
05386         papi_return( PAPI_EINVAL );
05387 
05388     papi_free( ESI->profile.prof[i] );
05389     ESI->profile.prof[i] = NULL;
05390 
05391     papi_return( PAPI_sprofil( NULL, 0, EventSet, EventCode, 0, flags ) );
05392 }
05393 
05394 /* This function sets the low level default granularity
05395    for all newly manufactured eventsets. The first function
05396    preserves API compatibility and assumes component 0;
05397    The second function takes a component argument. */
05398 
05449 int
05450 PAPI_set_granularity( int granularity )
05451 {
05452     return ( PAPI_set_cmp_granularity( granularity, 0 ) );
05453 }
05454 
05514 int
05515 PAPI_set_cmp_granularity( int granularity, int cidx )
05516 {
05517     PAPI_option_t ptr;
05518 
05519     memset( &ptr, 0, sizeof ( ptr ) );
05520     ptr.defgranularity.def_cidx = cidx;
05521     ptr.defgranularity.granularity = granularity;
05522     papi_return( PAPI_set_opt( PAPI_DEFGRN, &ptr ) );
05523 }
05524 
05525 /* This function sets the low level default counting domain
05526    for all newly manufactured eventsets. The first function
05527    preserves API compatibility and assumes component 0;
05528    The second function takes a component argument. */
05529 
05580 int
05581 PAPI_set_domain( int domain )
05582 {
05583     return ( PAPI_set_cmp_domain( domain, 0 ) );
05584 }
05585 
05650 int
05651 PAPI_set_cmp_domain( int domain, int cidx )
05652 {
05653     PAPI_option_t ptr;
05654 
05655     memset( &ptr, 0, sizeof ( ptr ) );
05656     ptr.defdomain.def_cidx = cidx;
05657     ptr.defdomain.domain = domain;
05658     papi_return( PAPI_set_opt( PAPI_DEFDOM, &ptr ) );
05659 }
05660 
05735 int
05736 PAPI_add_events( int EventSet, int *Events, int number )
05737 {
05738     int i, retval;
05739 
05740     if ( ( Events == NULL ) || ( number <= 0 ) )
05741         papi_return( PAPI_EINVAL );
05742 
05743     for ( i = 0; i < number; i++ ) {
05744         retval = PAPI_add_event( EventSet, Events[i] );
05745         if ( retval != PAPI_OK ) {
05746             if ( i == 0 )
05747                 papi_return( retval );
05748             else
05749                 return ( i );
05750         }
05751     }
05752     return ( PAPI_OK );
05753 }
05754 
05822 int
05823 PAPI_remove_events( int EventSet, int *Events, int number )
05824 {
05825     int i, retval;
05826 
05827     if ( ( Events == NULL ) || ( number <= 0 ) )
05828         papi_return( PAPI_EINVAL );
05829 
05830     for ( i = 0; i < number; i++ ) {
05831         retval = PAPI_remove_event( EventSet, Events[i] );
05832         if ( retval != PAPI_OK ) {
05833             if ( i == 0 )
05834                 papi_return( retval );
05835             else
05836                 return ( i );
05837         }
05838     }
05839     return ( PAPI_OK );
05840 }
05841 
05882 int
05883 PAPI_list_events( int EventSet, int *Events, int *number )
05884 {
05885     EventSetInfo_t *ESI;
05886     int i, j;
05887 
05888     if ( ( Events == NULL ) || ( *number <= 0 ) )
05889         papi_return( PAPI_EINVAL );
05890 
05891     ESI = _papi_hwi_lookup_EventSet( EventSet );
05892     if ( !ESI )
05893         papi_return( PAPI_ENOEVST );
05894 
05895     for ( i = 0, j = 0; j < ESI->NumberOfEvents; i++ ) {
05896         if ( ( int ) ESI->EventInfoArray[i].event_code != PAPI_NULL ) {
05897             Events[j] = ( int ) ESI->EventInfoArray[i].event_code;
05898             j++;
05899             if ( j == *number )
05900                 break;
05901         }
05902     }
05903 
05904     *number = j;
05905 
05906     return ( PAPI_OK );
05907 }
05908 
05909 /* xxx This is OS dependent, not component dependent, right? */
05935 int
05936 PAPI_get_dmem_info( PAPI_dmem_info_t * dest )
05937 {
05938     if ( dest == NULL )
05939         return PAPI_EINVAL;
05940 
05941     memset( ( void * ) dest, 0x0, sizeof ( PAPI_dmem_info_t ) );
05942     return ( _papi_os_vector.get_dmem_info( dest ) );
05943 }
05944 
05945 
05989 const PAPI_exe_info_t *
05990 PAPI_get_executable_info( void )
05991 {
05992     PAPI_option_t ptr;
05993     int retval;
05994 
05995     memset( &ptr, 0, sizeof ( ptr ) );
05996     retval = PAPI_get_opt( PAPI_EXEINFO, &ptr );
05997     if ( retval == PAPI_OK )
05998         return ( ptr.exe_info );
05999     else
06000         return ( NULL );
06001 }
06002 
06019 const PAPI_shlib_info_t *
06020 PAPI_get_shared_lib_info( void )
06021 {
06022     PAPI_option_t ptr;
06023     int retval;
06024 
06025     memset( &ptr, 0, sizeof ( ptr ) );
06026     retval = PAPI_get_opt( PAPI_SHLIBINFO, &ptr );
06027     if ( retval == PAPI_OK )
06028         return ( ptr.shlib_info );
06029     else
06030         return ( NULL );
06031 }
06060 const PAPI_hw_info_t *
06061 PAPI_get_hardware_info( void )
06062 {
06063     PAPI_option_t ptr;
06064     int retval;
06065 
06066     memset( &ptr, 0, sizeof ( ptr ) );
06067     retval = PAPI_get_opt( PAPI_HWINFO, &ptr );
06068     if ( retval == PAPI_OK )
06069         return ( ptr.hw_info );
06070     else
06071         return ( NULL );
06072 }
06073 
06074 
06075 /* The next 4 timing functions always use component 0 */
06076 
06092 long long
06093 PAPI_get_real_cyc( void )
06094 {
06095     return ( _papi_os_vector.get_real_cycles(  ) );
06096 }
06097 
06111 /* FIXME */
06112 long long
06113 PAPI_get_real_nsec( void )
06114 {
06115   return ( ( _papi_os_vector.get_real_nsec(  )));
06116 
06117 }
06118 
06139 long long
06140 PAPI_get_real_usec( void )
06141 {
06142     return ( _papi_os_vector.get_real_usec(  ) );
06143 }
06144 
06175 long long
06176 PAPI_get_virt_cyc( void )
06177 {
06178 
06179     return ( ( long long ) _papi_os_vector.get_virt_cycles( ) );
06180 }
06181 
06205 long long
06206 PAPI_get_virt_nsec( void )
06207 {
06208 
06209   return ( ( _papi_os_vector.get_virt_nsec()));
06210 
06211 }
06212 
06247 long long
06248 PAPI_get_virt_usec( void )
06249 {
06250 
06251     return ( ( long long ) _papi_os_vector.get_virt_usec() );
06252 }
06253 
06278 int
06279 PAPI_lock( int lck )
06280 {
06281     if ( ( lck < 0 ) || ( lck >= PAPI_NUM_LOCK ) )
06282         papi_return( PAPI_EINVAL );
06283 
06284     papi_return( _papi_hwi_lock( lck ) );
06285 }
06286 
06298 int
06299 PAPI_unlock( int lck )
06300 {
06301     if ( ( lck < 0 ) || ( lck >= PAPI_NUM_LOCK ) )
06302         papi_return( PAPI_EINVAL );
06303 
06304     papi_return( _papi_hwi_unlock( lck ) );
06305 }
06306 
06340 int
06341 PAPI_is_initialized( void )
06342 {
06343     return ( init_level );
06344 }
06345 
06346 /* This function maps the overflow_vector to event indexes in the event
06347    set, so that user can know which PAPI event overflowed.
06348    int *array---- an array of event indexes in eventset; the first index
06349                   maps to the highest set bit in overflow_vector
06350    int *number--- this is an input/output parameter, user should put the
06351                   size of the array into this parameter, after the function
06352                   is executed, the number of indexes in *array is written
06353                   to this parameter
06354 */
06355 
06394 int
06395 PAPI_get_overflow_event_index( int EventSet, long long overflow_vector,
06396                                int *array, int *number )
06397 {
06398     EventSetInfo_t *ESI;
06399     int set_bit, j, pos;
06400     int count = 0, k;
06401 
06402     if ( overflow_vector == ( long long ) 0 )
06403         papi_return( PAPI_EINVAL );
06404 
06405     if ( ( array == NULL ) || ( number == NULL ) )
06406         papi_return( PAPI_EINVAL );
06407 
06408     if ( *number < 1 )
06409         papi_return( PAPI_EINVAL );
06410 
06411     ESI = _papi_hwi_lookup_EventSet( EventSet );
06412     if ( ESI == NULL )
06413         papi_return( PAPI_ENOEVST );
06414 
06415     /* in case the eventset is empty */
06416     if ( ESI->NumberOfEvents == 0 )
06417         papi_return( PAPI_EINVAL );
06418 
06419     while ( ( set_bit = ffsll( overflow_vector ) ) ) {
06420         set_bit -= 1;
06421         overflow_vector ^= ( long long ) 1 << set_bit;
06422         for ( j = 0; j < ESI->NumberOfEvents; j++ ) {
06423             for ( k = 0, pos = 0; k < PAPI_EVENTS_IN_DERIVED_EVENT && pos >= 0; k++ ) {
06424                 pos = ESI->EventInfoArray[j].pos[k];
06425                 if ( ( set_bit == pos ) &&
06426                      ( ( ESI->EventInfoArray[j].derived == NOT_DERIVED ) ||
06427                        ( ESI->EventInfoArray[j].derived == DERIVED_CMPD ) ) ) {
06428                     array[count++] = j;
06429                     if ( count == *number )
06430                         return PAPI_OK;
06431 
06432                     break;
06433                 }
06434             }
06435         }
06436     }
06437     *number = count;
06438     return PAPI_OK;
06439 }
06440 
06441 
06459 int
06460 PAPI_get_event_component( int EventCode)
06461 {
06462     return _papi_hwi_component_index( EventCode);
06463 }
06464 
06486 int  PAPI_get_component_index(char *name)
06487 {
06488   int cidx;
06489 
06490   const PAPI_component_info_t *cinfo;
06491 
06492   for(cidx=0;cidx<papi_num_components;cidx++) {
06493 
06494      cinfo=PAPI_get_component_info(cidx); 
06495      if (cinfo==NULL) return PAPI_ENOCMP;
06496 
06497      if (!strncmp(name,cinfo->name,strlen(cinfo->name))) {
06498         return cidx;
06499      }
06500   }
06501 
06502   return PAPI_ENOCMP;
06503 }
06504 
06505 
06541 int
06542 PAPI_disable_component( int cidx )
06543 {
06544 
06545    const PAPI_component_info_t *cinfo;
06546 
06547    /* Can only run before PAPI_library_init() is called */
06548    if (init_level != PAPI_NOT_INITED) {
06549       return PAPI_ENOINIT;
06550    }
06551      
06552    cinfo=PAPI_get_component_info(cidx); 
06553    if (cinfo==NULL) return PAPI_ENOCMP;
06554 
06555    ((PAPI_component_info_t *)cinfo)->disabled=1;
06556    strcpy(((PAPI_component_info_t *)cinfo)->disabled_reason,
06557            "Disabled by PAPI_disable_component()");
06558 
06559    return PAPI_OK;
06560  
06561 }
06562 
06591 int
06592 PAPI_disable_component_by_name( char *name )
06593 {
06594     int cidx;
06595 
06596     /* I can only be called before init time */
06597     if (init_level!=PAPI_NOT_INITED) {
06598         return PAPI_ENOINIT;
06599     }
06600 
06601     cidx = PAPI_get_component_index(name);
06602     if (cidx>=0) {
06603         return PAPI_disable_component(cidx);
06604     } 
06605 
06606     return PAPI_ENOCMP;
06607 }
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines