static void sigio_handler(int n) { pfarg_msg_t msg; int fd = ctx_fd; int r; if (event1_name && pfm_read_pmds(fd, pd+1, 1) == -1) fatal_error("pfm_read_pmds: %s", strerror(errno)); retry: r = read(fd, &msg, sizeof(msg)); if (r != sizeof(msg)) { if(r == -1 && errno == EINTR) { warning("read interrupted, retrying\n"); goto retry; } fatal_error("cannot read overflow message: %s\n", strerror(errno)); } if (msg.type != PFM_MSG_OVFL) fatal_error("unexpected msg type: %d\n",msg.type); /* * increment our notification counter */ notification_received++; /* * XXX: risky to do printf() in signal handler! */ if (event1_name) printf("Notification %lu: %"PRIu64" %s ip=0x%llx\n", notification_received, pd[1].reg_value, event1_name, (unsigned long long)msg.pfm_ovfl_msg.msg_ovfl_ip); else printf("Notification %lu ip=0x%llx\n", notification_received, (unsigned long long)msg.pfm_ovfl_msg.msg_ovfl_ip); /* * And resume monitoring */ if (pfm_restart(fd) == -1) fatal_error("pfm_restart: %d\n", errno); }
/** * restart_counting * * Arguments: <context_id> * * Call the pfm_restart system-call to clear the data counters and start * counting from zero for a perfmon context that was previously loaded. **/ static int restart_counting(int argc, char **argv) { struct context *ctx; cpu_set_t old_cpu_set; int system_wide; int ctx_id; int rc; ctx_id = strtoul(argv[1], NULL, 0); if (ctx_id <= 0) { LOG_ERROR("context ID must be a positive integer."); return EINVAL; } ctx = find_context(ctx_id); if (!ctx) { LOG_ERROR("Can't find context with ID %d.", ctx_id); return EINVAL; } system_wide = ctx->ctx_arg.ctx_flags & PFM_FL_SYSTEM_WIDE; if (system_wide && ctx->cpu >= 0) { rc = set_affinity(ctx->cpu, &old_cpu_set); if (rc) { return rc; } } rc = pfm_restart(ctx->fd); if (rc) { rc = errno; LOG_ERROR("pfm_restart system call returned an error: %d.", rc); return rc; } if (system_wide && ctx->cpu >= 0) { revert_affinity(&old_cpu_set); } LOG_INFO("Restarted counting for context %d.", ctx_id); return 0; }