From e14e0edae6a48908da53a78eec0d008fc3e20c3d Mon Sep 17 00:00:00 2001 From: Raghavendra Bhat Date: Wed, 21 Sep 2011 16:43:23 +0530 Subject: c_pgms/ping_pong: changes in ping_pong for giving running time as an argument ping_pong used to run indefinitely before. Now the locking functionality is made to run in a separate thread and the main thread sleeps for the number of seconds specified as a command line argument. By default it runs for 600 seconds. --- c_pgms/INFO | 6 +- c_pgms/ping_pong.c | 206 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 211 insertions(+), 1 deletion(-) create mode 100644 c_pgms/ping_pong.c diff --git a/c_pgms/INFO b/c_pgms/INFO index b4dccf4..b755c79 100644 --- a/c_pgms/INFO +++ b/c_pgms/INFO @@ -12,4 +12,8 @@ c_pgms/inotify.c ---> program which monitors a directory and sends mail whenever =============================================== c_pgms/trucate ---> programs which truncates a file based on both path as well as fd on a file. Can be enhanced in future to write some truncate based applications. Used to verify bug 3077. -c_pgms/new-ps-perf(new-fs-perf.c) -----> fs-perf test program modified. Now the number of files to be opened can be given as an argument. Default value is 30000 \ No newline at end of file +=============================================== +c_pgms/new-ps-perf(new-fs-perf.c) -----> fs-perf test program modified. Now the number of files to be opened can be given as an argument. Default value is 30000 + +=============================================== +c_pgms/ping_pong.c (ping_pong.c) -------> ping_pong program modified. Now the time duration for which ping_pong should execute can be given as an argument. By default it executed for 600 seconds. diff --git a/c_pgms/ping_pong.c b/c_pgms/ping_pong.c new file mode 100644 index 0000000..afd624c --- /dev/null +++ b/c_pgms/ping_pong.c @@ -0,0 +1,206 @@ +/* + 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static struct timeval tp1,tp2; + +static int do_reads, do_writes, use_mmap; + +struct file_info +{ + int fd; + int num_locks; +}; + +typedef struct file_info file_info_t; + +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(void *info) +{ + file_info_t *info_file = NULL; + unsigned count = 0; + int i=0, loops=0; + unsigned char *val; + unsigned char incr=0, last_incr=0; + unsigned char *p = NULL; + int fd = -1; + int num_locks = -1; + + info_file = (file_info_t *)info; + fd = info_file->fd; + num_locks = info_file->num_locks; + + 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]; + } else 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; + file_info_t info_file; + pthread_t thread; + int tid = -1; + int zzzz = 600; + + 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] [run_time]\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]); + if (argv[2]) + zzzz = atoi (argv[2]); + + if (zzzz <= 0) { + fprintf (stderr, "Cannot sleep for 0 or -ve seconds. Defaulting to 600"); + zzzz = 600; + } + + fd = open(fname, O_CREAT|O_RDWR, 0600); + if (fd == -1) exit(1); + + info_file.fd = fd; + info_file.num_locks = num_locks; + + tid = pthread_create (&thread, NULL, (void *)ping_pong, (void *)&info_file); + + sleep (zzzz); + return 0; +} -- cgit