PAPI 7.1.0.0
Loading...
Searching...
No Matches
linux-powercap-ppc.c
Go to the documentation of this file.
1
10#include <stdio.h>
11#include <dirent.h>
12#include <unistd.h>
13#include <dirent.h>
14#include <fcntl.h>
15#include <string.h>
16#include <stdint.h>
17#include <errno.h>
18#include <unistd.h>
19#include <sys/types.h>
20#include <sys/stat.h>
21
22#include "linux-powercap-ppc.h"
23
24// The following macro exit if a string function has an error. It should
25// never happen; but it is necessary to prevent compiler warnings. We print
26// something just in case there is programmer error in invoking the function.
27#define HANDLE_STRING_ERROR {fprintf(stderr,"%s:%i unexpected string function error.\n",__FILE__,__LINE__); exit(-1);}
28
29
32
33static int num_events=0;
34
38 = {"MIN_POWER", "MAX_POWER", "CURRENT_POWER"};
39static const char *pkg_sys_names[PKG_NUM_EVENTS]
40 = {"powercap-min", "powercap-max", "powercap-current"};
42 = {"Minimum value allowed for power capping.",
43 "Maximum value allowed for power capping.",
44 "Current power drawned by package."};
46 = {O_RDONLY, O_RDONLY, O_RDWR};
47
49
51
53
54/***************************************************************************/
55/****** BEGIN FUNCTIONS USED INTERNALLY SPECIFIC TO THIS COMPONENT *******/
56/***************************************************************************/
57
58/* Null terminated version of strncpy */
59static char *
60_local_strlcpy( char *dst, const char *src, size_t size )
61{
62 char *retval = strncpy( dst, src, size );
63 if ( size > 0 ) dst[size-1] = '\0';
64
65 return( retval );
66}
67
68static long long
70{
71 int sz = pread(event_fds[index], read_buff, PAPI_MAX_STR_LEN, 0);
72 read_buff[sz] = '\0';
73
74 return atoll(read_buff);
75}
76
77static int
78write_powercap_value( int index, long long value )
79{
80 size_t ret = snprintf(write_buff, sizeof(write_buff), "%lld", value);
81 if (ret <= 0 || sizeof(write_buff) <= ret)
82 return PAPI_ENOSUPP;
83
85 int sz = pwrite(event_fds[index], write_buff, PAPI_MAX_STR_LEN, 0);
86 if ( sz == -1 ) {
87 perror("Error in pwrite(): ");
88 }
90
91 return 1;
92}
93
94/************************* PAPI Functions **********************************/
95
96/*
97 * This is called whenever a thread is initialized
98 */
99static int
101{
102 (void) ctx;
103
104 return PAPI_OK;
105}
106
107/*
108 * Called when PAPI process is initialized (i.e. PAPI_library_init)
109 */
110static int
112{
113 int retval = PAPI_OK;
114 int e = -1;
115 char events_dir[128];
116 char event_path[128];
117 char *strCpy;
118
119 DIR *events;
120
121 const PAPI_hw_info_t *hw_info;
123
124 /* check if IBM processor */
126 strCpy=strncpy(_powercap_ppc_vector.cmp_info.disabled_reason, "Not an IBM Power9 processor", PAPI_MAX_STR_LEN);
128 if (strCpy == NULL) HANDLE_STRING_ERROR;
130 goto fn_fail;
131 }
132
133 num_events = 0;
134
135 /* Check the existence, and correct access modes to pkg directory path */
136 size_t ret = snprintf(events_dir, sizeof(events_dir), "/sys/firmware/opal/powercap/system-powercap/");
137 if (ret <= 0 || sizeof(events_dir) <= ret) HANDLE_STRING_ERROR;
138
139 if ( NULL == (events = opendir(events_dir)) ) {
141 "Directory /sys/firmware/opal/powercap/system-powercap missing.",
144 if (strCpy == NULL) HANDLE_STRING_ERROR;
146 goto fn_fail;
147 }
148
149 /* opendir needs clean up. */
150 closedir(events);
151
152 /* loop through events and create powercap event entries */
153 for ( e = 0; e < PKG_NUM_EVENTS; ++e ) {
154 /* compose string to individual event */
155 size_t ret = snprintf(event_path, sizeof(event_path), "%s%s", events_dir, pkg_sys_names[e]);
156 if (ret <= 0 || sizeof(event_path) <= ret) HANDLE_STRING_ERROR;
157
158 /* if it's not a valid pkg event path we skip it */
159 if (access(event_path, F_OK) == -1) continue;
160
163 "%s", pkg_event_names[e]);
165 if (ret <= 0 || sizeof(powercap_ppc_ntv_events[num_events].name) <= ret) HANDLE_STRING_ERROR;
166
167 ret = snprintf(powercap_ppc_ntv_events[num_events].description,
168 sizeof(powercap_ppc_ntv_events[num_events].description),
169 "%s", pkg_event_descs[e]);
171 if (ret <= 0 || sizeof(powercap_ppc_ntv_events[num_events].description) <= ret) HANDLE_STRING_ERROR;
175 if (ret <= 0 || sizeof(powercap_ppc_ntv_events[num_events].units) <= ret) HANDLE_STRING_ERROR;
176
179
181
182 event_fds[num_events] = open(event_path, O_SYNC|pkg_sys_flags[e]);
183
184 num_events++;
185 }
186
187 /* Export the total number of events available */
191
192 /* Export the component id */
194
195 fn_exit:
196 _papi_hwd[cidx]->cmp_info.disabled = retval;
197 return retval;
198 fn_fail:
199 goto fn_exit;
200}
201
202
203/*
204 * Control of counters (Reading/Writing/Starting/Stopping/Setup)
205 * functions
206 */
207static int
209{
211 memset( control, 0, sizeof ( _powercap_ppc_control_state_t ) );
212
213 return PAPI_OK;
214}
215
216static int
219 int count,
220 hwd_context_t *ctx )
221{
222 (void) ctx;
223 int i, index;
224
226 control->active_counters = count;
227
228 for ( i = 0; i < count; ++i ) {
229 index = native[i].ni_event;
230 control->which_counter[i]=index;
231 native[i].ni_position = i;
232 }
233
234 return PAPI_OK;
235}
236
237/*
238 * There are no counters to start, all three values are instantaneous
239 * */
240static int
242{
243 (void) ctx;
244 (void) ctl;
245
246 return PAPI_OK;
247}
248
249static int
251{
252 (void) ctx;
253 (void) ctl;
254
255 return PAPI_OK;
256}
257
258/*
259 * Shutdown a thread
260 * */
261static int
263{
264 (void) ctx;
265 SUBDBG( "Enter _powercap_ppc_shutdown_thread\n" );
266 return PAPI_OK;
267}
268
269
270static int
272 long long **events, int flags )
273{
274 SUBDBG("Enter _powercap_ppc_read\n");
275
276 (void) flags;
277 (void) ctx;
279
280 long long curr_val = 0;
281
282 int c, i;
283 for( c = 0; c < control->active_counters; c++ ) {
284 i = control->which_counter[c];
285 curr_val = read_powercap_value(i);
286 SUBDBG("%d, current value %lld\n", i, curr_val);
287 control->count[c]=curr_val;
288 }
289
290 *events = ( ( _powercap_ppc_control_state_t* ) ctl )->count;
291
292 return PAPI_OK;
293}
294
295/*
296 * One counter only is writable, the current power one
297 * */
298static int
300{
301 (void) ctx;
303
304 int i;
305 for (i = 0; i < control->active_counters; i++) {
308 }
309
310 return PAPI_OK;
311}
312
313/*
314 * Close opened file descriptors.
315 */
316static int
318{
319 int i;
320 for( i = 0; i < num_events; i++ ) {
321 close(event_fds[i]);
322 }
323
324 return PAPI_OK;
325}
326
327static int
329{
330 SUBDBG( "Enter: ctx: %p\n", ctx );
331 (void) ctx;
332 (void) code;
333 (void) option;
334
335 return PAPI_OK;
336}
337
338
339static int
341{
342 (void) ctl;
343 if ( PAPI_DOM_ALL != domain )
344 return PAPI_EINVAL;
345
346 return PAPI_OK;
347}
348
349
350static int
352{
353 (void) ctx;
354 (void) ctl;
355
356 return PAPI_OK;
357}
358
359/*
360 * Native Event functions
361 */
362static int
363_powercap_ppc_ntv_enum_events( unsigned int *EventCode, int modifier )
364{
365 int index;
366 switch ( modifier ) {
367 case PAPI_ENUM_FIRST:
368 *EventCode = 0;
369 return PAPI_OK;
370 case PAPI_ENUM_EVENTS:
371 index = *EventCode;
372 if ( index < num_events - 1 ) {
373 *EventCode = *EventCode + 1;
374 return PAPI_OK;
375 } else {
376 return PAPI_ENOEVNT;
377 }
378
379 default:
380 return PAPI_EINVAL;
381 }
382}
383
384/*
385 *
386 */
387static int
388_powercap_ppc_ntv_code_to_name( unsigned int EventCode, char *name, int len )
389{
390 int index = EventCode & PAPI_NATIVE_AND_MASK;
391
392 if ( index >= 0 && index < num_events ) {
394 return PAPI_OK;
395 }
396
397 return PAPI_ENOEVNT;
398}
399
400static int
401_powercap_ppc_ntv_code_to_info( unsigned int EventCode, PAPI_event_info_t *info )
402{
403 int index = EventCode;
404
405 if ( index < 0 || index >= num_events )
406 return PAPI_ENOEVNT;
407
408 _local_strlcpy( info->symbol, powercap_ppc_ntv_events[index].name, sizeof( info->symbol ) - 1 );
409 _local_strlcpy( info->units, powercap_ppc_ntv_events[index].units, sizeof( info->units ) - 1 );
410 _local_strlcpy( info->long_descr, powercap_ppc_ntv_events[index].description, sizeof( info->long_descr ) - 1 );
411
413 return PAPI_OK;
414}
415
416static int
417_powercap_ppc_ntv_name_to_code( const char *name, unsigned int *EventCode)
418{
419 if (!strcmp(name, "MIN_POWER")) *EventCode = 0;
420 else if (!strcmp(name, "MAX_POWER")) *EventCode = 1;
421 else if (!strcmp(name, "CURRENT_POWER")) *EventCode = 2;
422 return PAPI_OK;
423}
424
426 .cmp_info = {
427 .name = "powercap_ppc",
428 .short_name = "powercap_ppc",
429 .description = "Linux powercap energy measurements for IBM PowerPC (9) architectures",
430 .version = "5.7.0",
431 .default_domain = PAPI_DOM_ALL,
432 .default_granularity = PAPI_GRN_SYS,
433 .available_granularities = PAPI_GRN_SYS,
434 .hardware_intr_sig = PAPI_INT_SIGNAL,
435 .available_domains = PAPI_DOM_ALL,
436 },
437
438 /* sizes of framework-opaque component-private structures */
439 .size = {
440 .context = sizeof ( _powercap_ppc_context_t ),
441 .control_state = sizeof ( _powercap_ppc_control_state_t ),
442 .reg_value = sizeof ( _powercap_ppc_register_t ),
443 .reg_alloc = sizeof ( _powercap_ppc_reg_alloc_t ),
444 },
445 /* function pointers in this component */
446 .init_thread = _powercap_ppc_init_thread,
447 .init_component = _powercap_ppc_init_component,
448 .init_control_state = _powercap_ppc_init_control_state,
449 .update_control_state = _powercap_ppc_update_control_state,
450 .start = _powercap_ppc_start,
451 .stop = _powercap_ppc_stop,
452 .read = _powercap_ppc_read,
453 .write = _powercap_ppc_write,
454 .shutdown_thread = _powercap_ppc_shutdown_thread,
455 .shutdown_component = _powercap_ppc_shutdown_component,
456 .ctl = _powercap_ppc_ctl,
457
458 .set_domain = _powercap_ppc_set_domain,
459 .reset = _powercap_ppc_reset,
460
461 .ntv_enum_events = _powercap_ppc_ntv_enum_events,
462 .ntv_name_to_code = _powercap_ppc_ntv_name_to_code,
463 .ntv_code_to_name = _powercap_ppc_ntv_code_to_name,
464 .ntv_code_to_info = _powercap_ppc_ntv_code_to_info,
465};
int i
int open(const char *pathname, int flags, mode_t mode)
Definition: appio.c:188
int close(int fd)
Definition: appio.c:179
static const PAPI_hw_info_t * hw_info
Definition: byte_profile.c:28
static long count
struct papi_vectors * _papi_hwd[]
#define PAPI_ENUM_EVENTS
Definition: f90papi.h:224
#define PAPI_OK
Definition: f90papi.h:73
#define PAPI_ENUM_FIRST
Definition: f90papi.h:85
#define PAPI_VENDOR_IBM
Definition: f90papi.h:61
#define PAPI_ENOEVNT
Definition: f90papi.h:139
#define PAPI_EINVAL
Definition: f90papi.h:115
#define PAPI_ENOSUPP
Definition: f90papi.h:244
#define PAPI_MAX_STR_LEN
Definition: f90papi.h:77
#define PAPI_GRN_SYS
Definition: f90papi.h:43
#define PAPI_DATATYPE_INT64
Definition: f90papi.h:227
#define PAPI_DOM_ALL
Definition: f90papi.h:261
char events[MAX_EVENTS][BUFSIZ]
static long long values[NUM_EVENTS]
Definition: init_fini.c:10
static double c[MATRIX_SIZE][MATRIX_SIZE]
Definition: libmsr_basic.c:40
static char read_buff[PAPI_MAX_STR_LEN]
static const char * pkg_sys_names[PKG_NUM_EVENTS]
static int _powercap_ppc_init_thread(hwd_context_t *ctx)
static int _powercap_ppc_start(hwd_context_t *ctx, hwd_control_state_t *ctl)
static int num_events
static int _powercap_ppc_read(hwd_context_t *ctx, hwd_control_state_t *ctl, long long **events, int flags)
static int _powercap_ppc_shutdown_component(void)
static int _powercap_ppc_init_component(int cidx)
static int _powercap_ppc_ntv_enum_events(unsigned int *EventCode, int modifier)
static char * _local_strlcpy(char *dst, const char *src, size_t size)
static int _powercap_ppc_init_control_state(hwd_control_state_t *ctl)
static const char * pkg_event_descs[PKG_NUM_EVENTS]
static int _powercap_ppc_ntv_code_to_info(unsigned int EventCode, PAPI_event_info_t *info)
static int _powercap_ppc_ntv_name_to_code(const char *name, unsigned int *EventCode)
static long long read_powercap_value(int index)
static int event_fds[POWERCAP_MAX_COUNTERS]
static mode_t pkg_sys_flags[PKG_NUM_EVENTS]
static int pkg_events[PKG_NUM_EVENTS]
static int write_powercap_value(int index, long long value)
static char write_buff[PAPI_MAX_STR_LEN]
static int _powercap_ppc_write(hwd_context_t *ctx, hwd_control_state_t *ctl, long long *values)
papi_vector_t _powercap_ppc_vector
static int _powercap_ppc_ctl(hwd_context_t *ctx, int code, _papi_int_option_t *option)
static int _powercap_ppc_set_domain(hwd_control_state_t *ctl, int domain)
static const char * pkg_event_names[PKG_NUM_EVENTS]
static int _powercap_ppc_reset(hwd_context_t *ctx, hwd_control_state_t *ctl)
static int _powercap_ppc_ntv_code_to_name(unsigned int EventCode, char *name, int len)
static _powercap_ppc_native_event_entry_t powercap_ppc_ntv_events[(PKG_NUM_EVENTS)]
static int _powercap_ppc_shutdown_thread(hwd_context_t *ctx)
static int _powercap_ppc_stop(hwd_context_t *ctx, hwd_control_state_t *ctl)
#define HANDLE_STRING_ERROR
static int _powercap_ppc_update_control_state(hwd_control_state_t *ctl, NativeInfo_t *native, int count, hwd_context_t *ctx)
#define papi_powercap_ppc_unlock()
#define PKG_MAX_POWER
#define papi_powercap_ppc_lock()
#define PKG_MIN_POWER
#define PKG_CUR_POWER
#define POWERCAP_MAX_COUNTERS
#define PAPI_NATIVE_AND_MASK
#define SUBDBG(format, args...)
Definition: papi_debug.h:64
#define PAPI_INT_SIGNAL
Definition: papi_internal.h:52
static int native
static int cidx
papi_mdi_t _papi_hwi_system_info
Definition: papi_internal.c:56
#define PKG_NUM_EVENTS
Definition: perfnec.h:56
char units[MAX_EVENTS][BUFSIZ]
Definition: powercap_plot.c:15
const char * name
Definition: rocs.c:225
char name[PAPI_MAX_STR_LEN]
Definition: papi.h:627
char disabled_reason[PAPI_HUGE_STR_LEN]
Definition: papi.h:634
char units[PAPI_MIN_STR_LEN]
Definition: papi.h:969
char symbol[PAPI_HUGE_STR_LEN]
Definition: papi.h:960
char long_descr[PAPI_HUGE_STR_LEN]
Definition: papi.h:963
Hardware info structure.
Definition: papi.h:774
int vendor
Definition: papi.h:781
long long which_counter[POWERCAP_MAX_COUNTERS]
long long count[POWERCAP_MAX_COUNTERS]
int return_type
char name[PAPI_MAX_STR_LEN]
char description[PAPI_MAX_STR_LEN]
int type
_powercap_ppc_register_t resources
char units[PAPI_MIN_STR_LEN]
PAPI_hw_info_t hw_info
PAPI_component_info_t cmp_info
Definition: papi_vector.h:20
int retval
Definition: zero_fork.c:53