The current code (5.1.0.2) will never return the number of events in the eventset unless the supplied array (and thus the size argument) is larger than the event set. The man page clearly states that the returned number may be greater than the array size if the event set does not fit in the supplied array. In particular the call PAPI_list_events(EventSet, NULL, &n) should be allowed if n=0 at the time of the call.
Now, this may break some existing code out there
Since I have no code that relies on the above behaviour I think we should fix the library to follow its spec and that way find out who has programmed their apps according to library behaviour and not library spec
Cheers,
/Nils
- Code: Select all
--- orig/papi.c 2013-01-15 21:44:44.000000000 +0100
+++ patched/papi.c 2013-03-21 10:12:38.999322342 +0100
@@ -5882,26 +5882,36 @@ PAPI_remove_events( int EventSet, int *E
int
PAPI_list_events( int EventSet, int *Events, int *number )
{
+ int maxEvents = *number;
EventSetInfo_t *ESI;
int i, j;
- if ( ( Events == NULL ) || ( *number <= 0 ) )
+ if ( ( number == NULL ) || ( *number < 0 ) )
papi_return( PAPI_EINVAL );
ESI = _papi_hwi_lookup_EventSet( EventSet );
if ( !ESI )
papi_return( PAPI_ENOEVST );
+ /* The spec states that we always return the number of events in the event set */
+ *number = ESI->NumberOfEvents;
+
+ if ( maxEvents == 0 )
+ papi_return( PAPI_OK );
+
+ /* We better have a valid pointer now that we are going to write stuff */
+ if ( Events == NULL )
+ papi_return( PAPI_EINVAL );
+
for ( i = 0, j = 0; j < ESI->NumberOfEvents; i++ ) {
if ( ( int ) ESI->EventInfoArray[i].event_code != PAPI_NULL ) {
Events[j] = ( int ) ESI->EventInfoArray[i].event_code;
j++;
- if ( j == *number )
+ if ( j == maxEvents )
break;
}
}
- *number = j;
return ( PAPI_OK );
}
