467{
469 uint64_t old =
pe->tail;
470 unsigned char *data = ((
unsigned char*)
pe->mmap_buf) + getpagesize();
471 int diff;
472
473 diff = head - old;
474 if ( diff < 0 ) {
475 SUBDBG(
"WARNING: failed to keep up with mmap data. head = %" PRIu64
476 ", tail = %" PRIu64 ". Discarding samples.\n", head, old );
477
478 old = head;
479 }
480
481 for( ; old != head; ) {
484 size_t size = event->
header.size;
485
486
487
488 if ( ( old &
pe->mask ) + size != ( ( old + size ) &
pe->mask ) ) {
489 uint64_t offset = old;
490 uint64_t len =
min(
sizeof ( *event ), size ), cpy;
491 void *dst = &event_copy;
492
493 do {
494 cpy =
min(
pe->mask + 1 - ( offset &
pe->mask ), len );
495 memcpy( dst, &data[offset &
pe->mask], cpy );
496 offset += cpy;
497 dst = ((unsigned char*)dst) + cpy;
498 len -= cpy;
499 } while ( len );
500
501 event = &event_copy;
502 }
503 old += size;
504
505 SUBDBG(
"event->type = %08x\n", event->header.type );
506 SUBDBG(
"event->size = %d\n", event->header.size );
507
508 switch ( event->header.type ) {
509 case PERF_RECORD_SAMPLE:
511 (
vptr_t ) (
unsigned long ) event->ip.ip,
512 0, profile_index );
513 break;
514
515 case PERF_RECORD_LOST:
516 SUBDBG(
"Warning: because of a mmap buffer overrun, %" PRId64
517 " events were lost.\n"
518 "Loss was recorded when counter id %#"PRIx64
519 " overflowed.\n", event->lost.lost, event->lost.id );
520 break;
521 default:
522 SUBDBG(
"Error: unexpected header type - %d\n",
523 event->header.type );
524 break;
525 }
526 }
527
530}
#define SUBDBG(format, args...)
static uint64_t mmap_read_head(pe_event_info_t *pe)
static void mmap_write_tail(pe_event_info_t *pe, uint64_t tail)
static const pme_power_entry_t * pe
struct perf_event_header header