diff options
author | hunt <hunt> | 2007-03-14 16:13:33 +0000 |
---|---|---|
committer | hunt <hunt> | 2007-03-14 16:13:33 +0000 |
commit | 8c235ce57600584d3126ad86520b4fb44765c8ec (patch) | |
tree | 4a7ee542bda895a54edbb5863d68bce19d4f135f /runtime/bench2/itest.c | |
parent | fbbb89fffb3533a3b4fb63c15eaeaae6956391eb (diff) | |
download | systemtap-steved-8c235ce57600584d3126ad86520b4fb44765c8ec.tar.gz systemtap-steved-8c235ce57600584d3126ad86520b4fb44765c8ec.tar.xz systemtap-steved-8c235ce57600584d3126ad86520b4fb44765c8ec.zip |
2007-03-14 Martin Hunt <hunt@redhat.com>
* bench2/bench.rb: Updated to work with new transport
and new itest.c.
* bench2/Makefile: Updated for new itest.c
* bench2/itest.c: Rewritten to use multiple threads
and automatically divide the workload among the threads.
* print.c (_stp_print_flush): Move to print_new.c and
print_old.c.
* print_new.c: New file containing _stp_print_flush()
for the new transport.
* print_old.c: Ditto for old transport.
* runtime.h (STP_OLD_TRANSPORT): Define
(errk): Define.
(MAXSTRINGLEN): Define if not already defined.
* io.c (_stp_vlog): Use _stp_ctl_write().
Diffstat (limited to 'runtime/bench2/itest.c')
-rw-r--r-- | runtime/bench2/itest.c | 121 |
1 files changed, 111 insertions, 10 deletions
diff --git a/runtime/bench2/itest.c b/runtime/bench2/itest.c index efba623a..0578cf40 100644 --- a/runtime/bench2/itest.c +++ b/runtime/bench2/itest.c @@ -1,3 +1,13 @@ +/* + * itest - timed test program for use with bench2 + * Copyright (C) 2007 Red Hat Inc. + * + * This file is part of systemtap, and is free software. You can + * redistribute it and/or modify it under the terms of the GNU General + * Public License (GPL); either version 2, or (at your option) any + * later version. + */ + #include <stdio.h> #include <sys/types.h> #include <sys/stat.h> @@ -6,11 +16,18 @@ #include <stdlib.h> #include <sys/resource.h> #include <unistd.h> +#include <pthread.h> +#include <semaphore.h> +#include <sched.h> typedef unsigned long long uint64; struct timeval tstart, tstop; +pthread_t tester[256]; +sem_t go; +int ncpus; +int iterations; -void start() +void start(void) { gettimeofday (&tstart, NULL); } @@ -20,7 +37,7 @@ uint64 usecs (struct timeval *tv) return tv->tv_sec * 1000000 + tv->tv_usec; } -uint64 stop() +uint64 stop(void) { gettimeofday (&tstop, NULL); return usecs(&tstop) - usecs(&tstart); @@ -28,31 +45,115 @@ uint64 stop() void usage(char *name) { - printf ("Usage %s [num_threads]\nitest will call sys_getuid() 1000000/num_threads times.\n", name); - exit(1); + printf ("Usage %s [num_threads] [total_iterations]\n", name); + printf("%s will call sys_getuid() total_iterations [default 2,000,000]\n", name); + printf("times divided across num_threads [default 1].\n\n"); + exit(1); +} + + +void *null_thread (void *data) +{ + int cpu; + cpu_set_t cpu_mask; + int thread_num = (int)(long)data; + + cpu = thread_num % ncpus; + CPU_ZERO(&cpu_mask); + CPU_SET(cpu, &cpu_mask); + if( sched_setaffinity( 0, sizeof(cpu_mask), &cpu_mask ) < 0 ) { + perror("sched_setaffinity"); + } + + + // fprintf(stderr, "starting thread %d on cpu %d num=%d\n", thread_num, cpu, iterations); + while (sem_wait(&go) == -1) ; + + return NULL; +} + +void *caller_thread (void *data) +{ + int i, cpu; + cpu_set_t cpu_mask; + int thread_num = (int)(long)data; + + /* Force threads to be distributed across all cpus. */ + /* The scheduler would probably do the right thing without this. */ + cpu = thread_num % ncpus; + CPU_ZERO(&cpu_mask); + CPU_SET(cpu, &cpu_mask); + if( sched_setaffinity( 0, sizeof(cpu_mask), &cpu_mask ) < 0 ) { + perror("sched_setaffinity"); + } + + // fprintf(stderr, "starting thread %d on cpu %d num=%d\n", thread_num, cpu, iterations); + while (sem_wait(&go) == -1) ; + + for (i = 0; i < iterations; i++) + getuid(); + + return NULL; } int main(int argc, char *argv[]) { int i, n = 1; - uint64 nsecs; + uint64 nsecs, null_usecs, caller_usecs; + int total_iterations = 2000000; - if (argc > 2) + if (argc > 3) usage(argv[0]); - if (argc == 2) { + if (argc >= 2) { n = strtol(argv[1], NULL, 10); if (n <= 0) usage(argv[0]); } + if (argc > 2) { + total_iterations = strtol(argv[2], NULL, 10); + if (total_iterations < 100000) + usage(argv[0]); + } + + ncpus = sysconf(_SC_NPROCESSORS_ONLN); + sem_init (&go, 0, 0); + iterations = total_iterations/n; + + for (i = 0; i < n; i++) { + if (pthread_create(&tester[i], NULL, null_thread, (void *)(long)i) < 0) { + perror("Error creating thread"); + return -1; + } + } start(); - for (i = 0; i < 1000000/n; i++) - getuid(); + for (i = 0; i < n; i++) + sem_post (&go); + + for (i = 0; i < n; i++) + pthread_join(tester[i], NULL); + + null_usecs = stop(); - nsecs = stop() * n / 1000; + for (i = 0; i < n; i++) { + if (pthread_create(&tester[i], NULL, caller_thread, (void *)(long)i) < 0) { + perror("Error creating thread"); + return -1; + } + } + + start(); + for (i = 0; i < n; i++) + sem_post (&go); + + for (i = 0; i < n; i++) + pthread_join(tester[i], NULL); + caller_usecs = stop(); + /* returns nanosecs per call */ + nsecs = ((caller_usecs - null_usecs) * 1000LL) / ((uint64)(n * iterations)); printf("%lld\n", nsecs); return 0; } |