PAPI  5.7.0.0
coretemp_freebsd.c
Go to the documentation of this file.
1 /****************************/
2 /* THIS IS OPEN SOURCE CODE */
3 /****************************/
4 
22 #include <sys/types.h>
23 #include <sys/resource.h>
24 #include <sys/sysctl.h>
25 
26 #include <stdio.h>
27 #include <string.h>
28 #include <stdlib.h>
29 #include <inttypes.h>
30 
31 /* Headers required by PAPI */
32 #include "papi.h"
33 #include "papi_internal.h"
34 #include "papi_vector.h"
35 #include "papi_memory.h"
36 
37 #define CORETEMP_MAX_COUNTERS 32 /* Can we tune this dynamically? */
38 #define TRUE (1==1)
39 #define FALSE (1!=1)
40 #define UNREFERENCED(x) (void)x
41 
42 /* Structure that stores private information for each event */
43 typedef struct coretemp_register
44 {
45  int mib[4];
46  /* Access to registers through these MIBs + sysctl (3) call */
47 
48  unsigned int selector;
52 
54 typedef struct coretemp_native_event_entry
55 {
58  char description[PAPI_MAX_STR_LEN];
60 
61 /* This structure is used when doing register allocation
62  it possibly is not necessary when there are no
63  register constraints */
64 typedef struct coretemp_reg_alloc
65 {
68 
69 /* Holds control flags, usually out-of band configuration of the hardware */
70 typedef struct coretemp_control_state
71 {
75 
76 /* Holds per-thread information */
77 typedef struct coretemp_context
78 {
81 
84 
86 static int CORETEMP_NUM_EVENTS = 0;
87 
88 
89 /********************************************************************/
90 /* Below are the functions required by the PAPI component interface */
91 /********************************************************************/
92 
95 {
96  int mib[4];
97  size_t len;
98  UNREFERENCED(ctx);
99 
100  ( void ) mib; /*unused */
101  ( void ) len; /*unused */
102 
103  SUBDBG("coretemp_init_thread %p...\n", ctx);
104 
105 #if 0
106  /* what does this do? VMW */
107 
108  len = 4;
109  if (sysctlnametomib ("dev.coretemp.0.%driver", mib, &len) == -1)
110  return PAPI_ECMP;
111 #endif
112 
113  return PAPI_OK;
114 }
115 
116 
122 {
123  int ret;
124  int i;
125  int mib[4];
126  size_t len;
127  char tmp[128];
128 
129  SUBDBG("coretemp_init_component...\n");
130 
131  /* Count the number of cores (counters) that have sensors allocated */
132  i = 0;
134  sprintf (tmp, "dev.coretemp.%d.%%driver", i);
135  len = 4;
136  ret = sysctlnametomib (tmp, mib, &len);
137  while (ret != -1)
138  {
140  i++;
141  sprintf (tmp, "dev.coretemp.%d.%%driver", i);
142  len = 4;
143  ret = sysctlnametomib (tmp, mib, &len);
144  }
145 
146  if (CORETEMP_NUM_EVENTS == 0)
147  return PAPI_OK;
148 
149  /* Allocate memory for the our event table */
152  if (coretemp_native_table == NULL)
153  {
154  perror( "malloc():Could not get memory for coretemp events table" );
155  return PAPI_ENOMEM;
156  }
157 
158  /* Allocate native events internal structures */
159  for (i = 0; i < CORETEMP_NUM_EVENTS; i++)
160  {
161  /* Event name */
162  sprintf (coretemp_native_table[i].name, "CORETEMP_CPU_%d", i);
163 
164  /* Event description */
165  sprintf (coretemp_native_table[i].description, "CPU On-Die Thermal Sensor #%d", i);
166 
167  /* Event extra bits -> save MIB to faster access later */
168  sprintf (tmp, "dev.cpu.%d.temperature", i);
169  len = 4;
170  if (sysctlnametomib (tmp, coretemp_native_table[i].resources.mib, &len) == -1)
171  return PAPI_ECMP;
172 
174  }
175 
176  return PAPI_OK;
177 }
178 
179 
182 {
183  int i;
184 
185  SUBDBG("coretemp_init_control_state... %p\n", ctrl);
187 
188  for (i = 0; i < CORETEMP_MAX_COUNTERS; i++)
189  c->added[i] = FALSE;
190 
191  return PAPI_OK;
192 }
193 
194 
199 int coretemp_ntv_enum_events (unsigned int *EventCode, int modifier)
200 {
201 
202  switch ( modifier )
203  {
204  /* return EventCode of first event */
205  case PAPI_ENUM_FIRST:
206  *EventCode = 0;
207  return PAPI_OK;
208  break;
209 
210  /* return EventCode of passed-in Event */
211  case PAPI_ENUM_EVENTS:
212  {
213  int index = *EventCode;
214 
215  if ( index < CORETEMP_NUM_EVENTS - 1 )
216  {
217  *EventCode = *EventCode + 1;
218  return PAPI_OK;
219  }
220  else
221  return PAPI_ENOEVNT;
222  break;
223  }
224 
225  default:
226  return PAPI_EINVAL;
227  }
228 
229  return PAPI_EINVAL;
230 }
231 
237 int coretemp_ntv_code_to_name (unsigned int EventCode, char *name, int len)
238 {
239  int index = EventCode;
240 
241  strncpy( name, coretemp_native_table[index].name, len );
242 
243  return PAPI_OK;
244 }
245 
251 int coretemp_ntv_code_to_descr (unsigned int EventCode, char *name, int len)
252 {
253  int index = EventCode;
254 
255  strncpy( name, coretemp_native_table[index].description, len );
256 
257  return PAPI_OK;
258 }
259 
262 int coretemp_ntv_code_to_bits (unsigned int EventCode, hwd_register_t * bits)
263 {
264  UNREFERENCED(EventCode);
265  UNREFERENCED(bits);
266 
267  return PAPI_OK;
268 }
269 
272  NativeInfo_t * native, int count, hwd_context_t * ctx )
273 {
274  int i, index;
276  UNREFERENCED(ctx);
277 
278  SUBDBG("coretemp_update_control_state %p %p...\n", ptr, ctx);
279 
280  for (i = 0; i < count; i++)
281  {
282  index = native[i].ni_event;
283  native[i].ni_position = coretemp_native_table[index].resources.selector - 1;
284  c->added[native[i].ni_position] = TRUE;
285 
286  SUBDBG ("\nnative[%i].ni_position = coretemp_native_table[%i].resources.selector-1 = %i;\n",
287  i, index, native[i].ni_position );
288  }
289 
290  return PAPI_OK;
291 }
292 
295 {
296  UNREFERENCED(ctx);
297  UNREFERENCED(ctrl);
298 
299  SUBDBG( "coretemp_start %p %p...\n", ctx, ctrl );
300 
301  /* Nothing to be done */
302 
303  return PAPI_OK;
304 }
305 
306 
309 {
310  UNREFERENCED(ctx);
311  UNREFERENCED(ctrl);
312 
313  SUBDBG("coretemp_stop %p %p...\n", ctx, ctrl);
314 
315  /* Nothing to be done */
316 
317  return PAPI_OK;
318 }
319 
320 
323  long_long ** events, int flags)
324 {
325  int i;
327  UNREFERENCED(ctx);
328  UNREFERENCED(flags);
329 
330  SUBDBG("coretemp_read... %p %d\n", ctx, flags);
331 
332  for (i = 0; i < CORETEMP_MAX_COUNTERS; i++)
333  if (c->added[i])
334  {
335  int tmp;
336  size_t len = sizeof(tmp);
337 
338  if (sysctl (coretemp_native_table[i].resources.mib, 4, &tmp, &len, NULL, 0) == -1)
339  c->counters[i] = 0;
340  else
341  c->counters[i] = tmp/10;
342  /* Coretemp module returns temperature in tenths of kelvin
343  Kelvin are useful to avoid negative values... but will have
344  negative temperatures ??? */
345  }
346 
347  *events = c->counters;
348 
349  return PAPI_OK;
350 }
351 
353 /* otherwise, the updated state is written to ESI->hw_start */
355  long_long events[] )
356 {
357  UNREFERENCED(ctx);
359  UNREFERENCED(ctrl);
360 
361  SUBDBG("coretemp_write... %p %p\n", ctx, ctrl);
362 
363  /* These sensor counters cannot be writtn */
364 
365  return PAPI_OK;
366 }
367 
368 
371 {
372  UNREFERENCED(ctx);
373  UNREFERENCED(ctrl);
374 
375  SUBDBG("coretemp_reset ctx=%p ctrl=%p...\n", ctx, ctrl);
376 
377  /* These sensors cannot be reseted */
378 
379  return PAPI_OK;
380 }
381 
384 {
385 
386  SUBDBG( "coretemp_shutdown_component...\n");
387 
388  /* Last chance to clean up */
390 
391  return PAPI_OK;
392 }
393 
394 
395 
401 int coretemp_ctl (hwd_context_t * ctx, int code, _papi_int_option_t * option)
402 {
403  UNREFERENCED(ctx);
404  UNREFERENCED(code);
405  UNREFERENCED(option);
406 
407  SUBDBG( "coretemp_ctl... %p %d %p\n", ctx, code, option );
408 
409  /* FIXME. This should maybe set up more state, such as which counters are active and */
410  /* counter mappings. */
411 
412  return PAPI_OK;
413 }
414 
424 int coretemp_set_domain (hwd_control_state_t * cntrl, int domain)
425 {
426  UNREFERENCED(cntrl);
427 
428  SUBDBG ("coretemp_set_domain... %p %d\n", cntrl, domain);
429 
430  if (PAPI_DOM_ALL & domain)
431  {
432  SUBDBG( " PAPI_DOM_ALL \n" );
433  return PAPI_OK;
434  }
435  return PAPI_EINVAL ;
436 
437 }
438 
439 
442  .cmp_info = {
443  /* default component information (unspecified values are initialized to 0) */
444  .name = "coretemp_freebsd",
445  .short_name = "coretemp",
446  .version = "5.0",
447  .num_mpx_cntrs = CORETEMP_MAX_COUNTERS,
448  .num_cntrs = CORETEMP_MAX_COUNTERS,
449  .default_domain = PAPI_DOM_ALL,
450  .available_domains = PAPI_DOM_ALL,
451  .default_granularity = PAPI_GRN_SYS,
452  .available_granularities = PAPI_GRN_SYS,
453  .hardware_intr_sig = PAPI_INT_SIGNAL,
454 
455  /* component specific cmp_info initializations */
456  .fast_real_timer = 0,
457  .fast_virtual_timer = 0,
458  .attach = 0,
459  .attach_must_ptrace = 0,
460  }
461  ,
462 
463  /* sizes of framework-opaque component-private structures */
464  .size = {
465  .context = sizeof ( coretemp_context_t ),
466  .control_state = sizeof ( coretemp_control_state_t ),
467  .reg_value = sizeof ( coretemp_register_t ),
468  .reg_alloc = sizeof ( coretemp_reg_alloc_t ),
469  }
470  ,
471  /* function pointers in this component */
472  .init_thread = coretemp_init_thread,
473  .init_component = coretemp_init_component,
474  .init_control_state = coretemp_init_control_state,
475  .start = coretemp_start,
476  .stop = coretemp_stop,
477  .read = coretemp_read,
478  .write = coretemp_write,
479  .shutdown_component = coretemp_shutdown_component,
480  .ctl = coretemp_ctl,
481 
482  .update_control_state = coretemp_update_control_state,
483  .set_domain = coretemp_set_domain,
484  .reset = coretemp_reset,
485 
486  .ntv_enum_events = coretemp_ntv_enum_events,
487  .ntv_code_to_name = coretemp_ntv_code_to_name,
488  .ntv_code_to_descr = coretemp_ntv_code_to_descr,
489  .ntv_code_to_bits = coretemp_ntv_code_to_bits,
490 };
491 
int coretemp_init_control_state(hwd_control_state_t *ctrl)
#define PAPI_OK
Definition: fpapi.h:105
int coretemp_ntv_code_to_descr(unsigned int EventCode, char *name, int len)
#define PAPI_ENOMEM
Definition: fpapi.h:107
static const char * name
Definition: fork_overflow.c:31
#define PAPI_EINVAL
Definition: fpapi.h:106
int coretemp_init_component()
#define papi_free(a)
Definition: papi_memory.h:35
int coretemp_reset(hwd_context_t *ctx, hwd_control_state_t *ctrl)
#define papi_malloc(a)
Definition: papi_memory.h:34
int coretemp_ntv_code_to_bits(unsigned int EventCode, hwd_register_t *bits)
int coretemp_ctl(hwd_context_t *ctx, int code, _papi_int_option_t *option)
coretemp_register_t resources
#define PAPI_GRN_SYS
Definition: fpapi.h:71
PAPI_component_info_t cmp_info
Definition: papi_vector.h:20
double c
Definition: multiplex.c:22
double tmp
Return codes and api definitions.
char events[MAX_EVENTS][BUFSIZ]
#define PAPI_ECMP
Definition: fpapi.h:109
int coretemp_init_thread(hwd_context_t *ctx)
int coretemp_set_domain(hwd_control_state_t *cntrl, int domain)
#define FALSE
int coretemp_stop(hwd_context_t *ctx, hwd_control_state_t *ctrl)
int coretemp_start(hwd_context_t *ctx, hwd_control_state_t *ctrl)
coretemp_register_t ra_bits
static int native
#define SUBDBG(format, args...)
Definition: papi_debug.h:63
int coretemp_ntv_code_to_name(unsigned int EventCode, char *name, int len)
int coretemp_read(hwd_context_t *ctx, hwd_control_state_t *ctrl, long_long **events, int flags)
long long ret
Definition: iozone.c:1346
char name[PAPI_MAX_STR_LEN]
Definition: papi.h:630
#define PAPI_INT_SIGNAL
Definition: papi_internal.h:53
int coretemp_shutdown_component(void)
coretemp_control_state_t state
int coretemp_update_control_state(hwd_control_state_t *ptr, NativeInfo_t *native, int count, hwd_context_t *ctx)
#define TRUE
static int CORETEMP_NUM_EVENTS
#define CORETEMP_MAX_COUNTERS
#define PAPI_ENOEVNT
Definition: fpapi.h:112
#define long_long
Definition: papi.h:553
papi_vector_t _coretemp_freebsd_vector
static coretemp_native_event_entry_t * coretemp_native_table
int coretemp_write(hwd_context_t *ctx, hwd_control_state_t *ctrl, long_long events[])
int coretemp_ntv_enum_events(unsigned int *EventCode, int modifier)
#define PAPI_DOM_ALL
Definition: fpapi.h:25
static long count
#define UNREFERENCED(x)
int i
Definition: fileop.c:140
#define PAPI_MAX_STR_LEN
Definition: fpapi.h:43