2 * Lease performance test 2
4 * Fork off a given number of children who each open their own
5 * file. Then have each child take a read lease and release the lease
6 * for the given number of times.
8 * Time this to measure lease performance for lease heavy workloads where the
9 * locks are generally uncontended.
14 #endif /* HAVE_CONFIG_H */
17 #include <sys/types.h>
22 #include <sys/types.h>
31 #define NRLOCK (20480)
33 static struct timespec *diff;
36 leaseunlease(int nrlock, struct timespec *slot)
40 char name[10]; /* big enough for pid_t in hex + NULL */
41 struct timespec start, end;
43 ret = snprintf(name, sizeof(name), "%x", pid);
44 if (ret >= (int)sizeof(name)) {
49 fd = open(name, O_CREAT|O_RDONLY, 0644);
55 ret = clock_gettime(CLOCK_MONOTONIC_RAW, &start);
57 perror("clock_gettime");
61 for (i = 0; i < nrlock; ++i) {
62 ret = fcntl(fd, F_SETLEASE, F_RDLCK);
67 ret = fcntl(fd, F_SETLEASE, F_UNLCK);
74 ret = clock_gettime(CLOCK_MONOTONIC_RAW, &end);
76 perror("clock_gettime");
81 *slot = timespec_sub(end, start);
88 printf("usage: %s [-n nr_procs] [-l nr_locks] directory\n", prog);
92 main(int argc, char **argv)
94 int i, opt, valid = 0;
99 struct timespec total = { .tv_sec = 0,
102 while ((opt = getopt(argc, argv, "l:n:")) != -1) {
105 nlock = atoi(optarg);
108 nproc = atoi(optarg);
116 dirname = argv[optind];
122 if (mkdir(dirname, S_IRWXU)) {
127 if (chdir(dirname)) {
132 pids = calloc(nproc, sizeof(pid_t));
134 fprintf(stderr, "Unable to allocate pids array!");
138 diff = mmap(0, nproc * sizeof(*diff), PROT_READ | PROT_WRITE,
139 MAP_ANONYMOUS | MAP_SHARED, -1, 0);
140 if (diff == (struct timespec *)-1) {
141 fprintf(stderr, "Unable to allocate timespec array!");
145 for (i = 0; i < nproc; ++i) {
148 return leaseunlease(nlock, &diff[i]);
151 for (i = 0; i < nproc; ++i) {
155 fprintf(stderr, "process %d failed to fork\n", i);
158 if (waitpid(pids[i], &status, 0) < 0) {
159 fprintf(stderr, "unable to reap pid %d\n", pids[i]);
162 if (!WIFEXITED(status) || WEXITSTATUS(status)) {
163 fprintf(stderr, "pid %d exited abnormally(0x%x)\n", pids[i],status);
166 total = timespec_add(total, diff[i]);
170 if (valid != nproc) {
171 fprintf(stderr, "Some children didn't run properly -- "
172 "requested %d but only got %d\n", nproc, valid);
176 printf("%ld.%09ld\n", total.tv_sec, total.tv_nsec);