PAPI 7.1.0.0
Loading...
Searching...
No Matches
libpfms.h File Reference
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Typedefs

typedef int(* pfms_ovfl_t) (pfarg_msg_t *msg)
 

Functions

int pfms_initialize (void)
 
int pfms_create (uint64_t *cpu_list, size_t n, pfarg_ctx_t *ctx, pfms_ovfl_t *ovfl, void **desc)
 
int pfms_write_pmcs (void *desc, pfarg_pmc_t *pmcs, uint32_t n)
 
int pfms_write_pmds (void *desc, pfarg_pmd_t *pmds, uint32_t n)
 
int pfms_read_pmds (void *desc, pfarg_pmd_t *pmds, uint32_t n)
 
int pfms_start (void *desc)
 
int pfms_stop (void *desc)
 
int pfms_close (void *desc)
 
int pfms_unload (void *desc)
 
int pfms_load (void *desc)
 

Typedef Documentation

◆ pfms_ovfl_t

typedef int(* pfms_ovfl_t) (pfarg_msg_t *msg)

Definition at line 31 of file libpfms.h.

Function Documentation

◆ pfms_close()

int pfms_close ( void *  desc)

Definition at line 608 of file libpfms.c.

609{
610 size_t k;
612 int ret;
613
614 if (desc == NULL) {
615 dprint("invalid parameters\n");
616 return -1;
617 }
618 s = (pfms_session_t *)desc;
619
620 if (s->ncpus == 0) {
621 dprint("invalid session content 0 CPUS\n");
622 return -1;
623 }
624
625 for(k=0; k < ncpus; k++) {
626 if (tds[k].barrier == &s->barrier) {
627 tds[k].cmd = CMD_CLOSE;
628 sem_post(&tds[k].cmd_sem);
629 }
630 }
631 barrier_wait(&s->barrier);
632
633 ret = 0;
634
635 pthread_mutex_lock(&tds_lock);
636 /*
637 * check for errors
638 */
639 for(k=0; k < ncpus; k++) {
640 if (tds[k].barrier == &s->barrier) {
641 if (tds[k].ret) {
642 dprint("failure on CPU%zu\n", k);
643 }
644 ret |= tds[k].ret;
645 tds[k].barrier = NULL;
646 }
647 }
648
649 pthread_mutex_unlock(&tds_lock);
650
651 free(s);
652
653 /*
654 * XXX: we cannot undo close
655 */
656 return ret ? -1 : 0;
657}
double s
Definition: byte_profile.c:36
static pfms_thread_t * tds
Definition: libpfms.c:64
static uint32_t ncpus
Definition: libpfms.c:63
@ CMD_CLOSE
Definition: libpfms.c:29
static int barrier_wait(barrier_t *b)
Definition: libpfms.c:95
#define dprint(format, arg...)
Definition: libpfms.c:18
static pthread_mutex_t tds_lock
Definition: libpfms.c:65
barrier_t * barrier
Definition: libpfms.c:55
pfms_cmd_t cmd
Definition: libpfms.c:49
Here is the call graph for this function:
Here is the caller graph for this function:

◆ pfms_create()

int pfms_create ( uint64_t *  cpu_list,
size_t  n,
pfarg_ctx_t ctx,
pfms_ovfl_t ovfl,
void **  desc 
)

Definition at line 327 of file libpfms.c.

328{
329 uint64_t v;
330 size_t k, i;
331 uint32_t num, cpu;
333 int ret;
334
335 if (cpu_list == NULL || n == 0 || ctx == NULL || desc == NULL) {
336 dprint("invalid parameters\n");
337 return -1;
338 }
339
340 if ((ctx->ctx_flags & PFM_FL_SYSTEM_WIDE) == 0) {
341 dprint("only works for system wide\n");
342 return -1;
343 }
344
345 *desc = NULL;
346
347 /*
348 * XXX: assuming CPU are contiguously indexed
349 */
350 num = 0;
351 for(k=0, cpu = 0; k < n; k++, cpu+=64) {
352 v = cpu_list[k];
353 for(i=0; v && i < 63; i++, v>>=1, cpu++) {
354 if (v & 0x1) {
355 if (cpu >= ncpus) {
356 dprint("unavailable CPU%u\n", cpu);
357 return -1;
358 }
359 num++;
360 }
361 }
362 }
363
364 if (num == 0)
365 return 0;
366
367 s = calloc(1, sizeof(*s));
368 if (s == NULL) {
369 dprint("cannot allocate %u contexts\n", num);
370 return -1;
371 }
372 s->ncpus = num;
373
374 printf("%u-way session\n", num);
375
376 /*
377 * +1 to account for main thread waiting
378 */
379 ret = barrier_init(&s->barrier, num + 1);
380 if (ret) {
381 dprint("cannot init barrier\n");
382 goto error_free;
383 }
384
385 /*
386 * lock thread descriptor table, no other create_session, close_session
387 * can occur
388 */
389 pthread_mutex_lock(&tds_lock);
390
391 if (create_wthreads(cpu_list, n))
392 goto error_free_unlock;
393
394 /*
395 * check all needed threads are available
396 */
397 for(k=0, cpu = 0; k < n; k++, cpu += 64) {
398 v = cpu_list[k];
399 for(i=0; v && i < 63; i++, v>>=1, cpu++) {
400 if (v & 0x1) {
401 if (tds[cpu].barrier) {
402 dprint("CPU%u already managing a session\n", cpu);
403 goto error_free_unlock;
404 }
405
406 }
407 }
408 }
409
410 /*
411 * send create context order
412 */
413 for(k=0, cpu = 0; k < n; k++, cpu += 64) {
414 v = cpu_list[k];
415 for(i=0; v && i < 63; i++, v>>=1, cpu++) {
416 if (v & 0x1) {
417 tds[cpu].cmd = CMD_CTX;
418 tds[cpu].data = ctx;
419 tds[cpu].barrier = &s->barrier;
420 sem_post(&tds[cpu].cmd_sem);
421 }
422 }
423 }
424 barrier_wait(&s->barrier);
425
426 ret = 0;
427
428 /*
429 * check for errors
430 */
431 for(k=0; k < ncpus; k++) {
432 if (tds[k].barrier == &s->barrier) {
433 ret = tds[k].ret;
434 if (ret)
435 break;
436 }
437 }
438 /*
439 * undo if error found
440 */
441 if (k < ncpus) {
442 for(k=0; k < ncpus; k++) {
443 if (tds[k].barrier == &s->barrier) {
444 if (tds[k].ret == 0) {
445 tds[k].cmd = CMD_CLOSE;
446 sem_post(&tds[k].cmd_sem);
447 }
448 /* mark as free */
449 tds[k].barrier = NULL;
450 }
451 }
452 }
453 pthread_mutex_unlock(&tds_lock);
454
455 if (ret == 0) *desc = s;
456
457 return ret ? -1 : 0;
458
459error_free_unlock:
460 pthread_mutex_unlock(&tds_lock);
461
462error_free:
463 free(s);
464 return -1;
465}
int i
#define PFM_FL_SYSTEM_WIDE
static int create_wthreads(uint64_t *cpu_list, uint32_t n)
Definition: libpfms.c:277
static int barrier_init(barrier_t *b, uint32_t count)
Definition: libpfms.c:68
@ CMD_CTX
Definition: libpfms.c:21
uint32_t ctx_flags
Definition: perfmon_v2.h:19
void * data
Definition: libpfms.c:50
Here is the call graph for this function:
Here is the caller graph for this function:

◆ pfms_initialize()

int pfms_initialize ( void  )

Definition at line 300 of file libpfms.c.

301{
302 printf("cpu_t=%zu thread=%zu session_t=%zu\n",
303 sizeof(pfms_cpu_t),
304 sizeof(pfms_thread_t),
305 sizeof(pfms_session_t));
306
307 ncpus = (uint32_t)sysconf(_SC_NPROCESSORS_ONLN);
308 if (ncpus == -1) {
309 dprint("cannot retrieve number of online processors\n");
310 return -1;
311 }
312
313 dprint("configured for %u CPUs\n", ncpus);
314
315 /*
316 * XXX: assuming CPU are contiguously indexed
317 */
318 tds = calloc(ncpus, sizeof(*tds));
319 if (tds == NULL) {
320 dprint("cannot allocate thread descriptors\n");
321 return -1;
322 }
323 return 0;
324}
Here is the caller graph for this function:

◆ pfms_load()

int pfms_load ( void *  desc)

Definition at line 468 of file libpfms.c.

469{
470 uint32_t k;
472 int ret;
473
474 if (desc == NULL) {
475 dprint("invalid parameters\n");
476 return -1;
477 }
478 s = (pfms_session_t *)desc;
479
480 if (s->ncpus == 0) {
481 dprint("invalid session content 0 CPUS\n");
482 return -1;
483 }
484 /*
485 * send create context order
486 */
487 for(k=0; k < ncpus; k++) {
488 if (tds[k].barrier == &s->barrier) {
489 tds[k].cmd = CMD_LOAD;
490 sem_post(&tds[k].cmd_sem);
491 }
492 }
493
494 barrier_wait(&s->barrier);
495
496 ret = 0;
497
498 /*
499 * check for errors
500 */
501 for(k=0; k < ncpus; k++) {
502 if (tds[k].barrier == &s->barrier) {
503 ret = tds[k].ret;
504 if (ret) {
505 dprint("failure on CPU%u\n", k);
506 break;
507 }
508 }
509 }
510
511 /*
512 * if error, unload all others
513 */
514 if (k < ncpus) {
515 for(k=0; k < ncpus; k++) {
516 if (tds[k].barrier == &s->barrier) {
517 if (tds[k].ret == 0) {
518 tds[k].cmd = CMD_UNLOAD;
519 sem_post(&tds[k].cmd_sem);
520 }
521 }
522 }
523 }
524 return ret ? -1 : 0;
525}
@ CMD_UNLOAD
Definition: libpfms.c:23
@ CMD_LOAD
Definition: libpfms.c:22
Here is the call graph for this function:
Here is the caller graph for this function:

◆ pfms_read_pmds()

int pfms_read_pmds ( void *  desc,
pfarg_pmd_t pmds,
uint32_t  n 
)

Definition at line 660 of file libpfms.c.

661{
663 uint32_t k, pmds_per_cpu;
664 int ret;
665
666 if (desc == NULL) {
667 dprint("invalid parameters\n");
668 return -1;
669 }
670 s = (pfms_session_t *)desc;
671
672 if (s->ncpus == 0) {
673 dprint("invalid session content 0 CPUS\n");
674 return -1;
675 }
676 if (n % s->ncpus) {
677 dprint("invalid number of pfarg_pmd_t provided, must be multiple of %u\n", s->ncpus);
678 return -1;
679 }
680 pmds_per_cpu = n / s->ncpus;
681
682 dprint("n=%u ncpus=%u per_cpu=%u\n", n, s->ncpus, pmds_per_cpu);
683
684 for(k=0; k < ncpus; k++) {
685 if (tds[k].barrier == &s->barrier) {
686 tds[k].cmd = CMD_RPMDS;
687 tds[k].data = pmds;
688 tds[k].ndata= pmds_per_cpu;
689 sem_post(&tds[k].cmd_sem);
690 pmds += pmds_per_cpu;
691 }
692 }
693 barrier_wait(&s->barrier);
694
695 ret = 0;
696
697 /*
698 * check for errors
699 */
700 for(k=0; k < ncpus; k++) {
701 if (tds[k].barrier == &s->barrier) {
702 ret = tds[k].ret;
703 if (ret) {
704 dprint("failure on CPU%u\n", k);
705 break;
706 }
707 }
708 }
709 /*
710 * cannot undo pfm_read_pmds
711 */
712 return ret ? -1 : 0;
713}
@ CMD_RPMDS
Definition: libpfms.c:26
uint32_t ndata
Definition: libpfms.c:51
Here is the call graph for this function:
Here is the caller graph for this function:

◆ pfms_start()

int pfms_start ( void *  desc)

Definition at line 584 of file libpfms.c.

585{
586 return __pfms_do_simple_cmd(CMD_START, desc, NULL, 0);
587}
@ CMD_START
Definition: libpfms.c:28
static int __pfms_do_simple_cmd(pfms_cmd_t cmd, void *desc, void *data, uint32_t n)
Definition: libpfms.c:528
Here is the call graph for this function:
Here is the caller graph for this function:

◆ pfms_stop()

int pfms_stop ( void *  desc)

Definition at line 590 of file libpfms.c.

591{
592 return __pfms_do_simple_cmd(CMD_STOP, desc, NULL, 0);
593}
@ CMD_STOP
Definition: libpfms.c:27
Here is the call graph for this function:
Here is the caller graph for this function:

◆ pfms_unload()

int pfms_unload ( void *  desc)

Definition at line 578 of file libpfms.c.

579{
580 return __pfms_do_simple_cmd(CMD_UNLOAD, desc, NULL, 0);
581}
Here is the call graph for this function:

◆ pfms_write_pmcs()

int pfms_write_pmcs ( void *  desc,
pfarg_pmc_t pmcs,
uint32_t  n 
)

Definition at line 596 of file libpfms.c.

597{
598 return __pfms_do_simple_cmd(CMD_WPMCS, desc, pmcs, n);
599}
@ CMD_WPMCS
Definition: libpfms.c:24
Here is the call graph for this function:
Here is the caller graph for this function:

◆ pfms_write_pmds()

int pfms_write_pmds ( void *  desc,
pfarg_pmd_t pmds,
uint32_t  n 
)

Definition at line 602 of file libpfms.c.

603{
604 return __pfms_do_simple_cmd(CMD_WPMDS, desc, pmds, n);
605}
@ CMD_WPMDS
Definition: libpfms.c:25
Here is the call graph for this function:
Here is the caller graph for this function: