/* * Bench program to exercice multi threads using open()/close()/read()/lseek() calls. * Usage : * bench [-t XX] [-l len] * XX : number of threads * len : bench time in seconds * -s : small fdset : try to use embedded sruct fdtable */ #include #include #include #include #include #include #include #include #include #include static pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER; static pthread_cond_t cond = PTHREAD_COND_INITIALIZER; static int sflag; /* small fdset */ static int end_prog; static unsigned long work_done; static char onekilo[1024]; static void catch_alarm(int sig) { end_prog = 1; } static void *perform_work(void *arg) { int fd, i; unsigned long units = 0; int fds[64]; char filename[64]; char c; strcpy(filename, "/tmp/benchXXXXXX"); fd = mkstemp(filename); write(fd, onekilo, sizeof(onekilo)); close(fd); /* force this program to open more than 64 fds */ if (!sflag) for (i = 0 ; i < 64 ; i++) fds[i] = open("/dev/null", O_RDONLY); while (!end_prog) { fd = open(filename, O_RDONLY); read(fd, &c, 1); lseek(fd, 10, SEEK_SET); read(fd, &c, 1); lseek(fd, 20, SEEK_SET); read(fd, &c, 1); lseek(fd, 30, SEEK_SET); read(fd, &c, 1); lseek(fd, 40, SEEK_SET); read(fd, &c, 1); close(fd); units++; } unlink(filename); if (!sflag) for (i = 0 ; i < 64 ; i++) close(fds[i]); pthread_mutex_lock(&mut); work_done += units; pthread_mutex_unlock(&mut); return 0; } static void *idle_thread(void *arg) { pthread_mutex_lock(&mut); while (!end_prog) { pthread_cond_wait(&cond, &mut); } pthread_mutex_unlock(&mut); } static void usage(int code) { fprintf(stderr, "Usage : bench [-i] [-s] [-a affinity_mask] [-t threads] [-l duration]\n"); exit(code); } int main(int argc, char *argv[]) { int i, c; int nbthreads = 2; int iflag = 0; unsigned int length = 10; pthread_t *tid; struct sigaction sg; struct timeval t0, t1; long mask = 0; while ((c = getopt(argc, argv, "sit:l:a:")) != -1) { if (c == 't') nbthreads = atoi(optarg); else if (c == 'l') length = atoi(optarg); else if (c == 's') sflag = 1; else if (c == 'i') iflag = 1; else if (c == 'a') sscanf(optarg, "%li", &mask); else usage(1); } if (mask != 0) { int res = sched_setaffinity(0, &mask); if (res != 0) fprintf(stderr, "sched_affinity(0x%lx)->%d errno=%d\n", mask, res, errno); } tid = malloc(nbthreads*sizeof(pthread_t)); gettimeofday(&t0, NULL); for (i = 1 ; i < nbthreads; i++) pthread_create(tid + i, NULL, perform_work, NULL); if (iflag) pthread_create(tid, NULL, idle_thread, NULL); memset(&sg, 0, sizeof(sg)); sg.sa_handler = catch_alarm; sigaction(SIGALRM, &sg, NULL); alarm(length); perform_work(NULL); if (iflag) { pthread_cond_signal(&cond); pthread_join(tid[0], NULL); } for (i = 1 ; i < nbthreads; i++) pthread_join(tid[i], NULL); gettimeofday(&t1, NULL); t1.tv_sec -= t0.tv_sec; t1.tv_usec -= t0.tv_usec; if (t1.tv_usec < 0) { t1.tv_usec += 1000000; t1.tv_sec--; } pthread_mutex_lock(&mut); printf("%d threads, %d.%06d seconds, work_done=%lu\n", nbthreads, (int)t1.tv_sec, (int)t1.tv_usec, work_done); pthread_mutex_unlock(&mut); return 0; }