#define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include int pid; int group_fd; void context_setup() { int ret; struct perf_event_attr attr = {0}; pid = getpid(); attr.type = PERF_TYPE_SOFTWARE; attr.config = PERF_COUNT_SW_CPU_CLOCK; attr.size = sizeof(attr); attr.exclude_kernel = 1; group_fd = syscall(__NR_perf_event_open, &attr, pid, 0, -1, 0); // group_fd = -1 // printf("group_fd: %d\n", group_fd); assert(group_fd != -1); //set_cpu(0); } void *func1(void *arg) { //set_cpu(2); struct perf_event_attr attr = {.size = sizeof(attr)}; attr.type = PERF_TYPE_SOFTWARE; attr.config = PERF_COUNT_SW_CPU_CLOCK; attr.exclude_kernel = 1; for(int i = 0; i < 0x20; i++) syscall(__NR_perf_event_open, &attr, pid, 0, group_fd, 0); } void *func2(void *arg) { //set_cpu(1); struct perf_event_attr attr = {.size = sizeof(attr)}; attr.type = PERF_TYPE_HARDWARE; attr.config = PERF_COUNT_HW_CPU_CYCLES; attr.exclude_kernel = 1; syscall(__NR_perf_event_open, &attr, pid, 0, group_fd, 0); } void execute_two() { pthread_t tid1, tid2; pthread_create(&tid1, NULL, func1, NULL); pthread_create(&tid2, NULL, func2, NULL); // set_cpu(0); pthread_join(tid1, NULL); pthread_join(tid2, NULL); } static void loop(void) { while(1) { if(!fork()) { context_setup(); execute_two(); exit(0); } wait(NULL); } } int main(void) { for(int i=0; i<16; i++) { if(!fork()) { loop(); } } sleep(100000000); return 0; }