/* Error with overflows and perf::perf_count_sw_cpu_clock */ /* This test will crash Linux 3.0.0 */ /* compile with gcc -O2 -o oflo_sw_cpu_clock_crash oflo_sw_cpu_clock_crash.c */ /* by Vince Weaver */ #define _GNU_SOURCE 1 #include #include #include #include #include #include #include #include #include #include #include #include #define MATRIX_SIZE 512 static double a[MATRIX_SIZE][MATRIX_SIZE]; static double b[MATRIX_SIZE][MATRIX_SIZE]; static double c[MATRIX_SIZE][MATRIX_SIZE]; static void naive_matrix_multiply(int quiet) { double s; int i,j,k; for(i=0;isi_fd; ioctl(fd , PERF_EVENT_IOC_DISABLE,0); total++; ioctl(fd , PERF_EVENT_IOC_REFRESH,1); } int perf_event_open(struct perf_event_attr *hw_event_uptr, pid_t pid, int cpu, int group_fd, unsigned long flags) { return syscall(__NR_perf_event_open,hw_event_uptr,pid,cpu,group_fd,flags); } int main( int argc, char **argv ) { int fd; void *blargh; struct perf_event_attr pe; struct sigaction sa; memset(&sa, 0, sizeof(struct sigaction)); sa.sa_sigaction=our_handler; sa.sa_flags=SA_SIGINFO; if (sigaction(SIGIO,&sa,NULL)<0) { fprintf(stderr,"Error setting up signal handler\n"); exit(1); } memset(&pe,0,sizeof(struct perf_event_attr)); pe.type=PERF_TYPE_SOFTWARE; pe.size=sizeof(struct perf_event_attr); pe.config=PERF_COUNT_SW_CPU_CLOCK; pe.sample_period=100000; pe.sample_type=PERF_SAMPLE_IP; pe.read_format=PERF_FORMAT_GROUP|PERF_FORMAT_ID; pe.disabled=1; pe.pinned=1; pe.exclude_kernel=1; pe.exclude_hv=1; pe.wakeup_events=1; fd=perf_event_open(&pe,0,-1,-1,0); if (fd<0) { printf("Error opening\n"); } blargh=mmap(NULL,(1+2)*4096,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0); fcntl(fd,F_SETFL,O_RDWR|O_NONBLOCK|O_ASYNC); fcntl(fd,F_SETSIG,SIGIO); fcntl(fd,F_SETOWN,getpid()); ioctl(fd,PERF_EVENT_IOC_RESET,0); ioctl(fd,PERF_EVENT_IOC_ENABLE,0); naive_matrix_multiply(0); ioctl(fd,PERF_EVENT_IOC_DISABLE,0); munmap(blargh,(1+2)*4096); close(fd); printf("Total overflows: %d\n",total); return 0; }