summaryrefslogtreecommitdiffstats
path: root/c_pgms
diff options
context:
space:
mode:
authorRaghavendra Bhat <raghavendrabhat@gluster.com>2011-09-21 16:43:23 +0530
committerRaghavendra Bhat <raghavendrabhat@gluster.com>2011-09-21 16:43:23 +0530
commite14e0edae6a48908da53a78eec0d008fc3e20c3d (patch)
tree1d20a2a7f9bf6542ac3315ed990b618c9f2d22f5 /c_pgms
parent6aebc171a47f6c1fe1c9a4ea0a799e8ee38b1e70 (diff)
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.
Diffstat (limited to 'c_pgms')
-rw-r--r--c_pgms/INFO6
-rw-r--r--c_pgms/ping_pong.c206
2 files changed, 211 insertions, 1 deletions
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 <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;
+
+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] <file> <num_locks> [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;
+}