opd_perfmon.c revision 5bbbe460405564a1aed8a67a13c43e9356ffc656
110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project/** 210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project * @file opd_perfmon.c 310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project * perfmonctl() handling 410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project * 510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project * @remark Copyright 2003 OProfile authors 610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project * @remark Read the file COPYING 710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project * 810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project * @author John Levon 910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project */ 1010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 1110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project#ifdef __ia64__ 1210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 1310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project/* need this for sched_setaffinity() in <sched.h> */ 1410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project#define _GNU_SOURCE 1510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 1610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project#include "oprofiled.h" 1710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project#include "opd_perfmon.h" 1810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project#include "opd_events.h" 1910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 2010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project#include "op_cpu_type.h" 2110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project#include "op_libiberty.h" 2210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project#include "op_hw_config.h" 2310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 2410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project#include <sys/syscall.h> 2510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project#include <sys/wait.h> 2610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project#include <unistd.h> 2710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project#include <limits.h> 2810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project#include <signal.h> 2910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project#include <stdio.h> 3010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project#include <stdlib.h> 3110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project#include <string.h> 3210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project#include <errno.h> 335bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng#include <sys/types.h> 345bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng#include <sys/stat.h> 3510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project#ifdef HAVE_SCHED_SETAFFINITY 3610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project#include <sched.h> 3710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project#endif 3810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 3910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Projectextern op_cpu cpu_type; 4010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 4110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project#ifndef HAVE_SCHED_SETAFFINITY 4210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 4310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project/* many glibc's are not yet up to date */ 4410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project#ifndef __NR_sched_setaffinity 4510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project#define __NR_sched_setaffinity 1231 4610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project#endif 4710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 4810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project/* Copied from glibc's <sched.h> and <bits/sched.h> and munged */ 4910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project#define CPU_SETSIZE 1024 5010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project#define __NCPUBITS (8 * sizeof (unsigned long)) 5110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Projecttypedef struct 5210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project{ 5310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project unsigned long __bits[CPU_SETSIZE / __NCPUBITS]; 5410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project} cpu_set_t; 5510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 5610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project#define CPU_SET(cpu, cpusetp) \ 5710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project ((cpusetp)->__bits[(cpu)/__NCPUBITS] |= (1UL << ((cpu) % __NCPUBITS))) 5810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project#define CPU_ZERO(cpusetp) \ 5910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project memset((cpusetp), 0, sizeof(cpu_set_t)) 6010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 6110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Projectstatic int 6210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Projectsched_setaffinity(pid_t pid, size_t len, cpu_set_t const * cpusetp) 6310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project{ 6410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project return syscall(__NR_sched_setaffinity, pid, len, cpusetp); 6510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project} 6610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project#endif 6710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 6810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 6910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project#ifndef HAVE_PERFMONCTL 7010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project#ifndef __NR_perfmonctl 7110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project#define __NR_perfmonctl 1175 7210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project#endif 7310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 7410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Projectstatic int perfmonctl(int fd, int cmd, void * arg, int narg) 7510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project{ 7610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project return syscall(__NR_perfmonctl, fd, cmd, arg, narg); 7710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project} 7810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project#endif 7910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 8010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 8110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Projectstatic unsigned char uuid[16] = { 8210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 0x77, 0x7a, 0x6e, 0x61, 0x20, 0x65, 0x73, 0x69, 8310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 0x74, 0x6e, 0x72, 0x20, 0x61, 0x65, 0x0a, 0x6c 8410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project}; 8510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 8610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 8710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Projectstatic size_t nr_cpus; 8810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 8910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Projectstruct child { 9010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project pid_t pid; 9110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project int up_pipe[2]; 9210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project int ctx_fd; 9310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project sig_atomic_t sigusr1; 9410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project sig_atomic_t sigusr2; 9510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project sig_atomic_t sigterm; 9610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project}; 9710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 9810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Projectstatic struct child * children; 9910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 10010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Projectstatic void perfmon_start_child(int ctx_fd) 10110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project{ 10210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project if (perfmonctl(ctx_fd, PFM_START, 0, 0) == -1) { 10310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project exit(EXIT_FAILURE); 10410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project } 10510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project} 10610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 10710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 10810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Projectstatic void perfmon_stop_child(int ctx_fd) 10910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project{ 11010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project if (perfmonctl(ctx_fd, PFM_STOP, 0, 0) == -1) { 11110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project exit(EXIT_FAILURE); 11210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project } 11310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project} 11410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 11510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 11610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Projectstatic void child_sigusr1(int val __attribute__((unused))) 11710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project{ 11810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project size_t i; 11910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 12010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project for (i = 0; i < nr_cpus; ++i) { 12110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project if (children[i].pid == getpid()) { 12210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project children[i].sigusr1 = 1; 12310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project return; 12410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project } 12510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project } 12610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project} 12710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 12810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 12910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Projectstatic void child_sigusr2(int val __attribute__((unused))) 13010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project{ 13110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project size_t i; 13210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 13310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project for (i = 0; i < nr_cpus; ++i) { 13410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project if (children[i].pid == getpid()) { 13510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project children[i].sigusr2 = 1; 13610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project return; 13710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project } 13810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project } 13910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project} 14010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 14110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 14210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Projectstatic void child_sigterm(int val __attribute__((unused))) 14310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project{ 14410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project kill(getppid(), SIGTERM); 14510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project} 14610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 14710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 14810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Projectstatic void set_affinity(size_t cpu) 14910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project{ 15010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project cpu_set_t set; 1515bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng int err; 15210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 15310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project CPU_ZERO(&set); 15410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project CPU_SET(cpu, &set); 15510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 1565bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng err = sched_setaffinity(getpid(), sizeof(set), &set); 15710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 15810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project if (err == -1) { 1595bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng perror("Failed to set affinity"); 16010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project exit(EXIT_FAILURE); 16110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project } 16210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project} 16310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 16410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 16510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Projectstatic void setup_signals(void) 16610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project{ 16710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project struct sigaction act; 16810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project sigset_t mask; 16910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 17010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project sigemptyset(&mask); 17110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project sigaddset(&mask, SIGUSR1); 17210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project sigaddset(&mask, SIGUSR2); 17310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project sigprocmask(SIG_BLOCK, &mask, NULL); 17410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 17510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project act.sa_handler = child_sigusr1; 17610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project act.sa_flags = 0; 17710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project sigemptyset(&act.sa_mask); 17810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 17910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project if (sigaction(SIGUSR1, &act, NULL)) { 1805bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng perror("oprofiled: install of SIGUSR1 handler failed"); 18110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project exit(EXIT_FAILURE); 18210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project } 18310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 18410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project act.sa_handler = child_sigusr2; 18510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project act.sa_flags = 0; 18610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project sigemptyset(&act.sa_mask); 18710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 18810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project if (sigaction(SIGUSR2, &act, NULL)) { 1895bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng perror("oprofiled: install of SIGUSR2 handler failed"); 19010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project exit(EXIT_FAILURE); 19110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project } 19210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 19310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project act.sa_handler = child_sigterm; 19410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project act.sa_flags = 0; 19510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project sigemptyset(&act.sa_mask); 19610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 19710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project if (sigaction(SIGTERM, &act, NULL)) { 1985bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng perror("oprofiled: install of SIGTERM handler failed"); 19910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project exit(EXIT_FAILURE); 20010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project } 20110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project} 20210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 20310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 20410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project/** create the per-cpu context */ 20510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Projectstatic void create_context(struct child * self) 20610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project{ 20710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project pfarg_context_t ctx; 20810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project int err; 20910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 21010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project memset(&ctx, 0, sizeof(pfarg_context_t)); 21110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project memcpy(&ctx.ctx_smpl_buf_id, &uuid, 16); 21210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project ctx.ctx_flags = PFM_FL_SYSTEM_WIDE; 21310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 21410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project err = perfmonctl(0, PFM_CREATE_CONTEXT, &ctx, 1); 21510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project if (err == -1) { 2165bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng perror("CREATE_CONTEXT failed"); 21710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project exit(EXIT_FAILURE); 21810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project } 21910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 22010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project self->ctx_fd = ctx.ctx_fd; 22110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project} 22210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 22310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 22410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project/** program the perfmon counters */ 22510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Projectstatic void write_pmu(struct child * self) 22610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project{ 22710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project pfarg_reg_t pc[OP_MAX_COUNTERS]; 22810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project pfarg_reg_t pd[OP_MAX_COUNTERS]; 22910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project int err; 23010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project size_t i; 23110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 23210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project memset(pc, 0, sizeof(pc)); 23310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project memset(pd, 0, sizeof(pd)); 23410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 23510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project#define PMC_GEN_INTERRUPT (1UL << 5) 23610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project#define PMC_PRIV_MONITOR (1UL << 6) 23710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project/* McKinley requires pmc4 to have bit 23 set (enable PMU). 23810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project * It is supposedly ignored in other pmc registers. 23910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project */ 24010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project#define PMC_MANDATORY (1UL << 23) 24110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project#define PMC_USER (1UL << 3) 24210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project#define PMC_KERNEL (1UL << 0) 24310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project for (i = 0; i < op_nr_counters && opd_events[i].name; ++i) { 24410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project struct opd_event * event = &opd_events[i]; 24510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project pc[i].reg_num = event->counter + 4; 24610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project pc[i].reg_value = PMC_GEN_INTERRUPT; 24710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project pc[i].reg_value |= PMC_PRIV_MONITOR; 24810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project pc[i].reg_value |= PMC_MANDATORY; 24910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project (event->user) ? (pc[i].reg_value |= PMC_USER) 25010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project : (pc[i].reg_value &= ~PMC_USER); 25110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project (event->kernel) ? (pc[i].reg_value |= PMC_KERNEL) 25210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project : (pc[i].reg_value &= ~PMC_KERNEL); 25310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project pc[i].reg_value &= ~(0xff << 8); 25410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project pc[i].reg_value |= ((event->value & 0xff) << 8); 25510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project pc[i].reg_value &= ~(0xf << 16); 25610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project pc[i].reg_value |= ((event->um & 0xf) << 16); 25710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project pc[i].reg_smpl_eventid = event->counter; 25810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project } 25910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 26010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project for (i = 0; i < op_nr_counters && opd_events[i].name; ++i) { 26110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project struct opd_event * event = &opd_events[i]; 26210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project pd[i].reg_value = ~0UL - event->count + 1; 26310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project pd[i].reg_short_reset = ~0UL - event->count + 1; 26410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project pd[i].reg_num = event->counter + 4; 26510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project } 26610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 26710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project err = perfmonctl(self->ctx_fd, PFM_WRITE_PMCS, pc, i); 26810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project if (err == -1) { 2695bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng perror("Couldn't write PMCs"); 27010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project exit(EXIT_FAILURE); 27110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project } 27210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 27310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project err = perfmonctl(self->ctx_fd, PFM_WRITE_PMDS, pd, i); 27410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project if (err == -1) { 2755bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng perror("Couldn't write PMDs"); 27610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project exit(EXIT_FAILURE); 27710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project } 27810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project} 27910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 28010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 28110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Projectstatic void load_context(struct child * self) 28210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project{ 28310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project pfarg_load_t load_args; 28410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project int err; 28510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 28610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project memset(&load_args, 0, sizeof(load_args)); 28710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project load_args.load_pid = self->pid; 28810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 28910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project err = perfmonctl(self->ctx_fd, PFM_LOAD_CONTEXT, &load_args, 1); 29010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project if (err == -1) { 2915bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng perror("Couldn't load context"); 29210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project exit(EXIT_FAILURE); 29310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project } 29410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project} 29510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 29610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 29710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Projectstatic void notify_parent(struct child * self, size_t cpu) 29810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project{ 29910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project for (;;) { 30010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project ssize_t ret; 30110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project ret = write(self->up_pipe[1], &cpu, sizeof(size_t)); 30210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project if (ret == sizeof(size_t)) 30310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project break; 30410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project if (ret < 0 && errno != EINTR) { 3055bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng perror("Failed to write child pipe:"); 30610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project exit(EXIT_FAILURE); 30710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project } 30810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project } 30910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project} 31010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 3115bbbe460405564a1aed8a67a13c43e9356ffc656Ben Chengstatic struct child * inner_child; 3125bbbe460405564a1aed8a67a13c43e9356ffc656Ben Chengvoid close_pipe(void) 3135bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng{ 3145bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng close(inner_child->up_pipe[1]); 3155bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng} 31610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 31710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Projectstatic void run_child(size_t cpu) 31810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project{ 31910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project struct child * self = &children[cpu]; 32010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 32110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project self->pid = getpid(); 32210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project self->sigusr1 = 0; 32310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project self->sigusr2 = 0; 32410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project self->sigterm = 0; 32510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 3265bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng inner_child = self; 3275bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng if (atexit(close_pipe)){ 3285bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng close_pipe(); 3295bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng exit(EXIT_FAILURE); 3305bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng } 3315bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng 3325bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng umask(0); 3335bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng /* Change directory to allow directory to be removed */ 3345bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng if (chdir("/") < 0) { 3355bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng perror("Unable to chdir to \"/\""); 3365bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng exit(EXIT_FAILURE); 3375bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng } 3385bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng 33910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project setup_signals(); 34010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 34110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project set_affinity(cpu); 34210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 34310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project create_context(self); 34410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 34510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project write_pmu(self); 34610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 34710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project load_context(self); 34810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 34910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project notify_parent(self, cpu); 35010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 3515bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng /* Redirect standard files to /dev/null */ 3525bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng freopen( "/dev/null", "r", stdin); 3535bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng freopen( "/dev/null", "w", stdout); 3545bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng freopen( "/dev/null", "w", stderr); 3555bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng 35610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project for (;;) { 35710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project sigset_t sigmask; 35810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project sigfillset(&sigmask); 35910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project sigdelset(&sigmask, SIGUSR1); 36010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project sigdelset(&sigmask, SIGUSR2); 36110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project sigdelset(&sigmask, SIGTERM); 36210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 36310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project if (self->sigusr1) { 36410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project perfmon_start_child(self->ctx_fd); 36510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project self->sigusr1 = 0; 36610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project } 36710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 36810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project if (self->sigusr2) { 36910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project perfmon_stop_child(self->ctx_fd); 37010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project self->sigusr2 = 0; 37110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project } 37210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 37310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project sigsuspend(&sigmask); 37410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project } 37510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project} 37610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 37710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 37810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Projectstatic void wait_for_child(struct child * child) 37910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project{ 38010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project size_t tmp; 38110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project for (;;) { 38210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project ssize_t ret; 38310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project ret = read(child->up_pipe[0], &tmp, sizeof(size_t)); 38410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project if (ret == sizeof(size_t)) 38510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project break; 3865bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng if ((ret < 0 && errno != EINTR) || ret == 0 ) { 3875bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng perror("Failed to read child pipe"); 38810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project exit(EXIT_FAILURE); 38910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project } 39010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project } 39110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project printf("Perfmon child up on CPU%d\n", (int)tmp); 39210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project fflush(stdout); 39310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 39410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project close(child->up_pipe[0]); 39510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project} 39610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 39710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Projectstatic struct child* xen_ctx; 39810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 39910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Projectvoid perfmon_init(void) 40010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project{ 40110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project size_t i; 40210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project long nr; 40310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 40410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project if (cpu_type == CPU_TIMER_INT) 40510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project return; 40610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 40710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project if (!no_xen) { 40810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project xen_ctx = xmalloc(sizeof(struct child)); 40910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project xen_ctx->pid = getpid(); 41010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project xen_ctx->up_pipe[0] = -1; 41110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project xen_ctx->up_pipe[1] = -1; 41210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project xen_ctx->sigusr1 = 0; 41310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project xen_ctx->sigusr2 = 0; 41410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project xen_ctx->sigterm = 0; 41510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 41610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project create_context(xen_ctx); 41710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 41810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project write_pmu(xen_ctx); 41910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 42010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project load_context(xen_ctx); 42110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project return; 42210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project } 42310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 42410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 42510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project nr = sysconf(_SC_NPROCESSORS_ONLN); 42610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project if (nr == -1) { 42710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project fprintf(stderr, "Couldn't determine number of CPUs.\n"); 42810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project exit(EXIT_FAILURE); 42910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project } 43010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 43110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project nr_cpus = nr; 43210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 43310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project children = xmalloc(sizeof(struct child) * nr_cpus); 4345bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng bzero(children, sizeof(struct child) * nr_cpus); 43510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 43610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project for (i = 0; i < nr_cpus; ++i) { 43710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project int ret; 43810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 43910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project if (pipe(children[i].up_pipe)) { 4405bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng perror("Couldn't create child pipe"); 44110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project exit(EXIT_FAILURE); 44210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project } 44310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 44410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project ret = fork(); 44510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project if (ret == -1) { 4465bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng perror("Couldn't fork perfmon child"); 44710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project exit(EXIT_FAILURE); 44810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project } else if (ret == 0) { 4495bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng close(children[i].up_pipe[0]); 45010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project run_child(i); 45110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project } else { 45210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project children[i].pid = ret; 4535bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng close(children[i].up_pipe[1]); 45410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project printf("Waiting on CPU%d\n", (int)i); 45510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project wait_for_child(&children[i]); 45610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project } 45710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project } 45810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project} 45910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 46010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 46110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Projectvoid perfmon_exit(void) 46210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project{ 46310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project size_t i; 46410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 46510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project if (cpu_type == CPU_TIMER_INT) 46610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project return; 46710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 46810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project if (!no_xen) 46910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project return; 47010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 47110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project for (i = 0; i < nr_cpus; ++i) { 4725bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng if (children[i].pid) { 4735bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng int c_pid = children[i].pid; 4745bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng children[i].pid = 0; 4755bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng if (kill(c_pid, SIGKILL)==0) 4765bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng waitpid(c_pid, NULL, 0); 4775bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng } 47810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project } 47910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project} 48010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 48110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 48210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Projectvoid perfmon_start(void) 48310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project{ 48410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project size_t i; 48510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 48610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project if (cpu_type == CPU_TIMER_INT) 48710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project return; 48810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 48910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project if (!no_xen) { 49010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project perfmon_start_child(xen_ctx->ctx_fd); 49110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project return; 49210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project } 49310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 4945bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng for (i = 0; i < nr_cpus; ++i) { 4955bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng if (kill(children[i].pid, SIGUSR1)) { 4965bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng perror("Unable to start perfmon"); 4975bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng exit(EXIT_FAILURE); 4985bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng } 4995bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng } 50010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project} 50110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 50210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 50310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Projectvoid perfmon_stop(void) 50410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project{ 50510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project size_t i; 50610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 50710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project if (cpu_type == CPU_TIMER_INT) 50810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project return; 50910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 51010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project if (!no_xen) { 51110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project perfmon_stop_child(xen_ctx->ctx_fd); 51210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project return; 51310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project } 51410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 51510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project for (i = 0; i < nr_cpus; ++i) 5165bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng if (kill(children[i].pid, SIGUSR2)) { 5175bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng perror("Unable to stop perfmon"); 5185bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng exit(EXIT_FAILURE); 5195bbbe460405564a1aed8a67a13c43e9356ffc656Ben Cheng } 52010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project} 52110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project 52210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project#endif /* __ia64__ */ 523