diff options
author | Michael Adam <obnox@samba.org> | 2009-04-29 17:50:38 +0200 |
---|---|---|
committer | Ronnie Sahlberg <ronniesahlberg@gmail.com> | 2009-05-06 10:39:19 +1000 |
commit | bc6c3d03e83b28c866ea8498468f19e3516373ca (patch) | |
tree | 115664ad3af9be80d7d1c2dccbccaf0e82580a29 | |
parent | 9300933b6a95011f0700e1e27ad1c8104c408da7 (diff) | |
download | samba-bc6c3d03e83b28c866ea8498468f19e3516373ca.tar.gz samba-bc6c3d03e83b28c866ea8498468f19e3516373ca.tar.xz samba-bc6c3d03e83b28c866ea8498468f19e3516373ca.zip |
add tridge's ping_pong.c to the utils folder
Michael
(This used to be ctdb commit fe59ecb697fb4686ad8ea2fe4ec1cc7b4629e74f)
-rw-r--r-- | ctdb/utils/ping_pong/ping_pong.c | 176 |
1 files changed, 176 insertions, 0 deletions
diff --git a/ctdb/utils/ping_pong/ping_pong.c b/ctdb/utils/ping_pong/ping_pong.c new file mode 100644 index 00000000000..8511d957e5f --- /dev/null +++ b/ctdb/utils/ping_pong/ping_pong.c @@ -0,0 +1,176 @@ +/* + this measures the ping-pong byte range lock latency. It is + especially useful on a cluster of nodes sharing a common lock + manager as it will give some indication of the lock managers + performance under stress + + tridge@samba.org, February 2002 + +*/ + +#include <stdio.h> +#include <stdlib.h> +#include <sys/time.h> +#include <time.h> +#include <errno.h> +#include <string.h> +#include <unistd.h> +#include <fcntl.h> +#include <getopt.h> +#include <sys/mman.h> + +static struct timeval tp1,tp2; + +static int do_reads, do_writes, use_mmap; + +static void start_timer() +{ + gettimeofday(&tp1,NULL); +} + +static double end_timer() +{ + gettimeofday(&tp2,NULL); + return (tp2.tv_sec + (tp2.tv_usec*1.0e-6)) - + (tp1.tv_sec + (tp1.tv_usec*1.0e-6)); +} + +/* lock a byte range in a open file */ +static int lock_range(int fd, int offset, int len) +{ + struct flock lock; + + lock.l_type = F_WRLCK; + lock.l_whence = SEEK_SET; + lock.l_start = offset; + lock.l_len = len; + lock.l_pid = 0; + + return fcntl(fd,F_SETLKW,&lock); +} + +/* unlock a byte range in a open file */ +static int unlock_range(int fd, int offset, int len) +{ + struct flock lock; + + lock.l_type = F_UNLCK; + lock.l_whence = SEEK_SET; + lock.l_start = offset; + lock.l_len = len; + lock.l_pid = 0; + + return fcntl(fd,F_SETLKW,&lock); +} + +/* run the ping pong test on fd */ +static void ping_pong(int fd, int num_locks) +{ + unsigned count = 0; + int i=0, loops=0; + unsigned char *val; + unsigned char incr=0, last_incr=0; + unsigned char *p = NULL; + + ftruncate(fd, num_locks+1); + + if (use_mmap) { + p = mmap(NULL, num_locks+1, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); + } + + val = (unsigned char *)calloc(num_locks+1, sizeof(unsigned char)); + + start_timer(); + + lock_range(fd, 0, 1); + i = 0; + + while (1) { + if (lock_range(fd, (i+1) % num_locks, 1) != 0) { + printf("lock at %d failed! - %s\n", + (i+1) % num_locks, strerror(errno)); + } + if (do_reads) { + unsigned char c; + if (use_mmap) { + c = p[i]; + } if (pread(fd, &c, 1, i) != 1) { + printf("read failed at %d\n", i); + } + incr = c - val[i]; + val[i] = c; + } + if (do_writes) { + char c = val[i] + 1; + if (use_mmap) { + p[i] = c; + } else if (pwrite(fd, &c, 1, i) != 1) { + printf("write failed at %d\n", i); + } + } + if (unlock_range(fd, i, 1) != 0) { + printf("unlock at %d failed! - %s\n", + i, strerror(errno)); + } + i = (i+1) % num_locks; + count++; + if (loops > num_locks && incr != last_incr) { + last_incr = incr; + printf("data increment = %u\n", incr); + fflush(stdout); + } + if (end_timer() > 1.0) { + printf("%8u locks/sec\r", + (unsigned)(2*count/end_timer())); + fflush(stdout); + start_timer(); + count=0; + } + loops++; + } +} + +int main(int argc, char *argv[]) +{ + char *fname; + int fd, num_locks; + int c; + + while ((c = getopt(argc, argv, "rwm")) != -1) { + switch (c){ + case 'w': + do_writes = 1; + break; + case 'r': + do_reads = 1; + break; + case 'm': + use_mmap = 1; + break; + default: + fprintf(stderr, "Unknown option '%c'\n", c); + exit(1); + } + } + + argv += optind; + argc -= optind; + + if (argc < 2) { + printf("ping_pong [options] <file> <num_locks>\n"); + printf(" -r do reads\n"); + printf(" -w do writes\n"); + printf(" -m use mmap\n"); + exit(1); + } + + fname = argv[0]; + num_locks = atoi(argv[1]); + + fd = open(fname, O_CREAT|O_RDWR, 0600); + if (fd == -1) exit(1); + + ping_pong(fd, num_locks); + + return 0; +} |