make tsmread.c more robust
[tridge/junkcode.git] / locker.c
1 /*
2   a simple demonsration of a scaling problem in byte range locks on solaris
3
4   try this as 'locker 800 1' and compare to 'locker 800 0'
5
6   tridge@samba.org, July 2002
7 */
8
9 #include <stdio.h>
10 #include <fcntl.h>
11 #include <unistd.h>
12 #include <stdlib.h>
13 #include <errno.h>
14 #include <string.h>
15 #include <signal.h>
16 #include <sys/wait.h>
17
18 static int brlock(int fd, off_t offset, int rw_type, int lck_type)
19 {
20         struct flock fl;
21         int ret;
22
23         fl.l_type = rw_type;
24         fl.l_whence = SEEK_SET;
25         fl.l_start = offset;
26         fl.l_len = 1;
27         fl.l_pid = 0;
28
29         ret = fcntl(fd,lck_type,&fl);
30
31         if (ret == -1) {
32                 printf("brlock failed offset=%d rw_type=%d lck_type=%d : %s\n", 
33                        (int)offset, rw_type, lck_type, strerror(errno));
34         }
35         return 0;
36 }
37
38 static void slave(int fd, int nlocks)
39 {
40         int i;
41         for (i=1; i<nlocks+1; i++) {
42                 brlock(fd, i, F_RDLCK, F_SETLKW);
43                 usleep(1); /* essentially just a yield() */
44         }
45
46         /* this last lock will block until the master unlocks it */
47         brlock(fd, 0, F_WRLCK, F_SETLKW);
48         brlock(fd, 0, F_UNLCK, F_SETLKW);
49 }
50
51 int main(int argc, char *argv[])
52 {
53         int i, fd;
54         int nproc, nlocks;
55         const char *fname = "locker.dat";
56         char c;
57
58         if (argc < 3) {
59                 printf("Usage: locker <nproc> <nlocks>\n");
60                 exit(1);
61         }
62
63         nproc = atoi(argv[1]);
64         nlocks = atoi(argv[2]);
65         setpgrp();
66
67         fd = open(fname, O_RDWR | O_CREAT | O_TRUNC, 0600);
68         if (fd == -1) {
69                 perror(fname);
70                 exit(1);
71         }
72
73         /* set the master lock - this stops the children exiting */
74         brlock(fd, 0, F_WRLCK, F_SETLKW);
75
76         for (i=0;i<nproc;i++) {
77                 switch (fork()) {
78                 case 0:
79                         slave(fd, nlocks);
80                         exit(0);
81                 case -1:
82                         perror("fork");
83                         kill(0, SIGTERM);
84                         exit(1);
85                 }
86         }
87
88         printf("hit enter to continue\n");
89         read(0, &c, 1);
90
91         printf("unlocking ....\n");
92         brlock(fd, 0, F_UNLCK, F_SETLKW);
93
94         while (waitpid(0, NULL, 0) > 0 || errno != ECHILD) /* noop */ ;
95
96         printf("done\n");
97
98         return 0;
99 }