~ubuntu-branches/ubuntu/natty/evolution-data-server/natty

« back to all changes in this revision

Viewing changes to libdb/mutex/tm.c

  • Committer: Bazaar Package Importer
  • Author(s): Didier Roche
  • Date: 2010-05-17 17:02:06 UTC
  • mfrom: (1.1.79 upstream) (1.6.12 experimental)
  • Revision ID: james.westby@ubuntu.com-20100517170206-4ufr52vwrhh26yh0
Tags: 2.30.1-1ubuntu1
* Merge from debian experimental. Remaining change:
  (LP: #42199, #229669, #173703, #360344, #508494)
  + debian/control:
    - add Vcs-Bzr tag
    - don't use libgnome
    - Use Breaks instead of Conflicts against evolution 2.25 and earlier.
  + debian/evolution-data-server.install,
    debian/patches/45_libcamel_providers_version.patch:
    - use the upstream versioning, not a Debian-specific one 
  + debian/libedata-book1.2-dev.install, debian/libebackend-1.2-dev.install,
    debian/libcamel1.2-dev.install, debian/libedataserverui1.2-dev.install:
    - install html documentation
  + debian/rules:
    - don't build documentation it's shipped with the tarball

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * Standalone mutex tester for Berkeley DB mutexes.
3
 
 */
4
 
#include "db_config.h"
5
 
 
6
 
#include <sys/types.h>
7
 
#include <sys/mman.h>
8
 
#include <sys/stat.h>
9
 
#include <sys/wait.h>
10
 
 
11
 
#include <errno.h>
12
 
#include <fcntl.h>
13
 
#include <stdio.h>
14
 
#include <stdlib.h>
15
 
#include <string.h>
16
 
#include <unistd.h>
17
 
 
18
 
#if defined(HAVE_MUTEX_PTHREADS) || defined(BUILD_PTHREADS_ANYWAY)
19
 
#include <pthread.h>
20
 
#endif
21
 
 
22
 
#include "db_int.h"
23
 
 
24
 
void  exec_proc();
25
 
void  tm_file_init();
26
 
void  map_file();
27
 
void  run_proc();
28
 
void *run_thread();
29
 
void *run_thread_wake();
30
 
void  tm_mutex_destroy();
31
 
void  tm_mutex_init();
32
 
void  tm_mutex_stats();
33
 
void  unmap_file();
34
 
 
35
 
#define MUTEX_WAKEME    0x80                    /* Wake-me flag. */
36
 
 
37
 
DB_ENV   dbenv;                                 /* Fake out DB. */
38
 
size_t   len;                                   /* Backing file size. */
39
 
int      align;                                 /* Mutex alignment in file. */
40
 
int      quit;                                  /* End-of-test flag. */
41
 
char    *file = "mutex.file";                   /* Backing file. */
42
 
 
43
 
int      maxlocks = 20;                         /* -l: Backing locks. */
44
 
int      nlocks = 10000;                        /* -n: Locks per processes. */
45
 
int      nprocs = 20;                           /* -p: Processes. */
46
 
int      child;                                 /* -s: Slave. */
47
 
int      nthreads = 1;                          /* -t: Threads. */
48
 
int      verbose;                               /* -v: Verbosity. */
49
 
 
50
 
int
51
 
main(argc, argv)
52
 
        int argc;
53
 
        char *argv[];
54
 
{
55
 
        extern int optind;
56
 
        extern char *optarg;
57
 
        pid_t pid;
58
 
        int ch, eval, i, status;
59
 
        char *tmpath;
60
 
 
61
 
        tmpath = argv[0];
62
 
        while ((ch = getopt(argc, argv, "l:n:p:st:v")) != EOF)
63
 
                switch(ch) {
64
 
                case 'l':
65
 
                        maxlocks = atoi(optarg);
66
 
                        break;
67
 
                case 'n':
68
 
                        nlocks = atoi(optarg);
69
 
                        break;
70
 
                case 'p':
71
 
                        nprocs = atoi(optarg);
72
 
                        break;
73
 
                case 's':
74
 
                        child = 1;
75
 
                        break;
76
 
                case 't':
77
 
                        nthreads = atoi(optarg);
78
 
#if !defined(HAVE_MUTEX_PTHREADS) && !defined(BUILD_PTHREADS_ANYWAY)
79
 
                        if (nthreads != 1) {
80
 
                                (void)fprintf(stderr,
81
 
        "tm: pthreads not available or not compiled for this platform.\n");
82
 
                                return (EXIT_FAILURE);
83
 
                        }
84
 
#endif
85
 
                        break;
86
 
                case 'v':
87
 
                        verbose = 1;
88
 
                        break;
89
 
                case '?':
90
 
                default:
91
 
                        (void)fprintf(stderr,
92
 
    "usage: tm [-v] [-l maxlocks] [-n locks] [-p procs] [-t threads]\n");
93
 
                        return (EXIT_FAILURE);
94
 
                }
95
 
        argc -= optind;
96
 
        argv += optind;
97
 
 
98
 
        /*
99
 
         * The file layout:
100
 
         *      DB_MUTEX[1]             per-thread mutex array lock
101
 
         *      DB_MUTEX[nthreads]      per-thread mutex array
102
 
         *      DB_MUTEX[maxlocks]      per-lock mutex array
103
 
         *      u_long[maxlocks][2]     per-lock ID array
104
 
         */
105
 
        align = ALIGN(sizeof(DB_MUTEX) * 2, MUTEX_ALIGN);
106
 
        len =
107
 
            align * (1 + nthreads +  maxlocks) + sizeof(u_long) * maxlocks * 2;
108
 
        printf(
109
 
    "mutex alignment %d, structure alignment %d, backing file %lu bytes\n",
110
 
            MUTEX_ALIGN, align, (u_long)len);
111
 
 
112
 
        if (child) {
113
 
                run_proc();
114
 
                return (EXIT_SUCCESS);
115
 
        }
116
 
 
117
 
        tm_file_init();
118
 
        tm_mutex_init();
119
 
 
120
 
        printf(
121
 
            "%d proc, %d threads/proc, %d lock requests from %d locks:\n",
122
 
            nprocs, nthreads, nlocks, maxlocks);
123
 
        for (i = 0; i < nprocs; ++i)
124
 
                switch (fork()) {
125
 
                case -1:
126
 
                        perror("fork");
127
 
                        return (EXIT_FAILURE);
128
 
                case 0:
129
 
                        exec_proc(tmpath);
130
 
                        break;
131
 
                default:
132
 
                        break;
133
 
                }
134
 
 
135
 
        eval = EXIT_SUCCESS;
136
 
        while ((pid = wait(&status)) != (pid_t)-1) {
137
 
                fprintf(stderr,
138
 
                    "%lu: exited %d\n", (u_long)pid, WEXITSTATUS(status));
139
 
                if (WEXITSTATUS(status) != 0)
140
 
                        eval = EXIT_FAILURE;
141
 
        }
142
 
 
143
 
        tm_mutex_stats();
144
 
        tm_mutex_destroy();
145
 
 
146
 
        printf("tm: exit status: %s\n",
147
 
            eval == EXIT_SUCCESS ? "success" : "failed!");
148
 
        return (eval);
149
 
}
150
 
 
151
 
void
152
 
exec_proc(tmpath)
153
 
        char *tmpath;
154
 
{
155
 
        char *argv[10], **ap, b_l[10], b_n[10], b_t[10];
156
 
 
157
 
        ap = &argv[0];
158
 
        *ap++ = "tm";
159
 
        sprintf(b_l, "-l%d", maxlocks);
160
 
        *ap++ = b_l;
161
 
        sprintf(b_n, "-n%d", nlocks);
162
 
        *ap++ = b_n;
163
 
        *ap++ = "-s";
164
 
        sprintf(b_t, "-t%d", nthreads);
165
 
        *ap++ = b_t;
166
 
        if (verbose)
167
 
                *ap++ = "-v";
168
 
 
169
 
        *ap = NULL;
170
 
        execvp(tmpath, argv);
171
 
 
172
 
        fprintf(stderr, "%s: %s\n", tmpath, strerror(errno));
173
 
        exit(EXIT_FAILURE);
174
 
}
175
 
 
176
 
void
177
 
run_proc()
178
 
{
179
 
#if defined(HAVE_MUTEX_PTHREADS) || defined(BUILD_PTHREADS_ANYWAY)
180
 
        pthread_t *kidsp, wakep;
181
 
        int i, status;
182
 
        void *retp;
183
 
#endif
184
 
        __os_sleep(&dbenv, 3, 0);               /* Let everyone catch up. */
185
 
 
186
 
        srand((u_int)time(NULL) / getpid());    /* Initialize random numbers. */
187
 
 
188
 
        if (nthreads == 1)                      /* Simple case. */
189
 
                exit((int)run_thread((void *)0));
190
 
 
191
 
#if defined(HAVE_MUTEX_PTHREADS) || defined(BUILD_PTHREADS_ANYWAY)
192
 
        /*
193
 
         * Spawn off threads.  We have nthreads all locking and going to
194
 
         * sleep, and one other thread cycling through and waking them up.
195
 
         */
196
 
        if ((kidsp =
197
 
            (pthread_t *)calloc(sizeof(pthread_t), nthreads)) == NULL) {
198
 
                fprintf(stderr, "tm: %s\n", strerror(errno));
199
 
                exit(EXIT_FAILURE);
200
 
        }
201
 
        for (i = 0; i < nthreads; i++)
202
 
                if ((errno = pthread_create(
203
 
                    &kidsp[i], NULL, run_thread, (void *)i)) != 0) {
204
 
                        fprintf(stderr, "tm: failed spawning thread %d: %s\n",
205
 
                            i, strerror(errno));
206
 
                        exit(EXIT_FAILURE);
207
 
                }
208
 
 
209
 
        if ((errno = pthread_create(
210
 
            &wakep, NULL, run_thread_wake, (void *)0)) != 0) {
211
 
                fprintf(stderr, "tm: failed spawning wakeup thread: %s\n",
212
 
                    strerror(errno));
213
 
                exit(EXIT_FAILURE);
214
 
        }
215
 
 
216
 
        /* Wait for the threads to exit. */
217
 
        status = 0;
218
 
        for (i = 0; i < nthreads; i++) {
219
 
                pthread_join(kidsp[i], &retp);
220
 
                if (retp != NULL) {
221
 
                        fprintf(stderr,
222
 
                            "tm: thread %d exited with error\n", i);
223
 
                        status = EXIT_FAILURE;
224
 
                }
225
 
        }
226
 
        free(kidsp);
227
 
 
228
 
        /* Signal wakeup thread to stop. */
229
 
        quit = 1;
230
 
        pthread_join(wakep, &retp);
231
 
        if (retp != NULL) {
232
 
                fprintf(stderr, "tm: wakeup thread exited with error\n");
233
 
                status = EXIT_FAILURE;
234
 
        }
235
 
 
236
 
        exit(status);
237
 
#endif
238
 
}
239
 
 
240
 
void *
241
 
run_thread(arg)
242
 
        void *arg;
243
 
{
244
 
        DB_MUTEX *gm_addr, *lm_addr, *tm_addr, *mp;
245
 
        u_long gid1, gid2, *id_addr;
246
 
        int fd, i, lock, id, nl, remap;
247
 
 
248
 
        /* Set local and global per-thread ID. */
249
 
        id = (int)arg;
250
 
        gid1 = (u_long)getpid();
251
 
#if defined(HAVE_MUTEX_PTHREADS) || defined(BUILD_PTHREADS_ANYWAY)
252
 
        gid2 = (u_long)pthread_self();
253
 
#else
254
 
        gid2 = 0;
255
 
#endif
256
 
        printf("\tPID: %lu; TID: %lx; ID: %d\n", gid1, gid2, id);
257
 
 
258
 
        nl = nlocks;
259
 
        for (gm_addr = NULL, remap = 0;;) {
260
 
                /* Map in the file as necessary. */
261
 
                if (gm_addr == NULL) {
262
 
                        map_file(&gm_addr, &tm_addr, &lm_addr, &id_addr, &fd);
263
 
                        remap = (rand() % 100) + 35;
264
 
                }
265
 
 
266
 
                /* Select and acquire a data lock. */
267
 
                lock = rand() % maxlocks;
268
 
                mp = (DB_MUTEX *)((u_int8_t *)lm_addr + lock * align);
269
 
                if (verbose)
270
 
                        printf("%lu/%lx: %03d\n", gid1, gid2, lock);
271
 
 
272
 
                if (__db_mutex_lock(&dbenv, mp)) {
273
 
                        fprintf(stderr,
274
 
                            "%lu/%lx: never got lock\n", gid1, gid2);
275
 
                        return ((void *)EXIT_FAILURE);
276
 
                }
277
 
                if (id_addr[lock * 2] != 0) {
278
 
                        fprintf(stderr,
279
 
                            "RACE! (%lu/%lx granted lock %d held by %lu/%lx)\n",
280
 
                            gid1, gid2,
281
 
                            lock, id_addr[lock * 2], id_addr[lock * 2 + 1]);
282
 
                        return ((void *)EXIT_FAILURE);
283
 
                }
284
 
                id_addr[lock * 2] = gid1;
285
 
                id_addr[lock * 2 + 1] = gid2;
286
 
 
287
 
                /*
288
 
                 * Pretend to do some work, periodically checking to see if
289
 
                 * we still hold the mutex.
290
 
                 */
291
 
                for (i = 0; i < 3; ++i) {
292
 
                        __os_sleep(&dbenv, 0, rand() % 3);
293
 
                        if (id_addr[lock * 2] != gid1 ||
294
 
                            id_addr[lock * 2 + 1] != gid2) {
295
 
                                fprintf(stderr,
296
 
                            "RACE! (%lu/%lx stole lock %d from %lu/%lx)\n",
297
 
                                    id_addr[lock * 2],
298
 
                                    id_addr[lock * 2 + 1], lock, gid1, gid2);
299
 
                                return ((void *)EXIT_FAILURE);
300
 
                        }
301
 
                }
302
 
 
303
 
#if defined(HAVE_MUTEX_PTHREADS) || defined(BUILD_PTHREADS_ANYWAY)
304
 
                /*
305
 
                 * Test self-blocking and unlocking by other threads/processes:
306
 
                 *
307
 
                 *      acquire the global lock
308
 
                 *      set our wakeup flag
309
 
                 *      release the global lock
310
 
                 *      acquire our per-thread lock
311
 
                 *
312
 
                 * The wakeup thread will wake us up.
313
 
                 */
314
 
                if (__db_mutex_lock(&dbenv, gm_addr)) {
315
 
                        fprintf(stderr, "%lu/%lx: global lock\n", gid1, gid2);
316
 
                        return ((void *)EXIT_FAILURE);
317
 
                }
318
 
                mp = (DB_MUTEX *)((u_int8_t *)tm_addr + id * align);
319
 
                F_SET(mp, MUTEX_WAKEME);
320
 
                if (__db_mutex_unlock(&dbenv, gm_addr)) {
321
 
                        fprintf(stderr,
322
 
                            "%lu/%lx: per-thread wakeup failed\n", gid1, gid2);
323
 
                        return ((void *)EXIT_FAILURE);
324
 
                }
325
 
                if (__db_mutex_lock(&dbenv, mp)) {
326
 
                        fprintf(stderr,
327
 
                            "%lu/%lx: per-thread lock\n", gid1, gid2);
328
 
                        return ((void *)EXIT_FAILURE);
329
 
                }
330
 
                /* Time passes... */
331
 
                if (F_ISSET(mp, MUTEX_WAKEME)) {
332
 
                        fprintf(stderr, "%lu/%lx: %03d wakeup flag still set\n",
333
 
                            gid1, gid2, id);
334
 
                        return ((void *)EXIT_FAILURE);
335
 
                }
336
 
#endif
337
 
 
338
 
                /* Release the data lock. */
339
 
                id_addr[lock * 2] = id_addr[lock * 2 + 1] = 0;
340
 
                mp = (DB_MUTEX *)((u_int8_t *)lm_addr + lock * align);
341
 
                if (__db_mutex_unlock(&dbenv, mp)) {
342
 
                        fprintf(stderr, "%lu/%lx: wakeup failed\n", gid1, gid2);
343
 
                        return ((void *)EXIT_FAILURE);
344
 
                }
345
 
 
346
 
                if (--nl % 100 == 0)
347
 
                        fprintf(stderr, "%lu/%lx: %d\n", gid1, gid2, nl);
348
 
 
349
 
                if (nl == 0 || --remap == 0) {
350
 
                        unmap_file((void *)gm_addr, fd);
351
 
                        gm_addr = NULL;
352
 
 
353
 
                        if (nl == 0)
354
 
                                break;
355
 
 
356
 
                        __os_sleep(&dbenv, rand() % 3, 0);
357
 
                }
358
 
        }
359
 
 
360
 
        return (NULL);
361
 
}
362
 
 
363
 
#if defined(HAVE_MUTEX_PTHREADS) || defined(BUILD_PTHREADS_ANYWAY)
364
 
/*
365
 
 * run_thread_wake --
366
 
 *      Thread to wake up other threads that are sleeping.
367
 
 */
368
 
void *
369
 
run_thread_wake(arg)
370
 
        void *arg;
371
 
{
372
 
        DB_MUTEX *gm_addr, *tm_addr, *mp;
373
 
        int fd, id;
374
 
 
375
 
        arg = NULL;
376
 
        map_file(&gm_addr, &tm_addr, NULL, NULL, &fd);
377
 
 
378
 
        /* Loop, waking up sleepers and periodically sleeping ourselves. */
379
 
        while (!quit) {
380
 
                id = 0;
381
 
 
382
 
                /* Acquire the global lock. */
383
 
retry:          if (__db_mutex_lock(&dbenv, gm_addr)) {
384
 
                        fprintf(stderr, "wt: global lock failed\n");
385
 
                        return ((void *)EXIT_FAILURE);
386
 
                }
387
 
 
388
 
next:           mp = (DB_MUTEX *)((u_int8_t *)tm_addr + id * align);
389
 
                if (F_ISSET(mp, MUTEX_WAKEME)) {
390
 
                        F_CLR(mp, MUTEX_WAKEME);
391
 
                        if (__db_mutex_unlock(&dbenv, mp)) {
392
 
                                fprintf(stderr, "wt: wakeup failed\n");
393
 
                                return ((void *)EXIT_FAILURE);
394
 
                        }
395
 
                }
396
 
 
397
 
                if (++id < nthreads && id % 3 != 0)
398
 
                        goto next;
399
 
 
400
 
                if (__db_mutex_unlock(&dbenv, gm_addr)) {
401
 
                        fprintf(stderr, "wt: global unlock failed\n");
402
 
                        return ((void *)EXIT_FAILURE);
403
 
                }
404
 
 
405
 
                __os_sleep(&dbenv, 0, 500);
406
 
 
407
 
                if (id < nthreads)
408
 
                        goto retry;
409
 
        }
410
 
        return (NULL);
411
 
}
412
 
#endif
413
 
 
414
 
/*
415
 
 * tm_file_init --
416
 
 *      Initialize the backing file.
417
 
 */
418
 
void
419
 
tm_file_init()
420
 
{
421
 
        int fd;
422
 
 
423
 
 
424
 
        /* Initialize the backing file. */
425
 
        printf("Create the backing file...\n");
426
 
#ifdef  HAVE_QNX
427
 
        (void)shm_unlink(file);
428
 
        if ((fd = shm_open(file, O_CREAT | O_RDWR | O_TRUNC,
429
 
#else
430
 
        (void)remove(file);
431
 
        if ((fd = open(file, O_CREAT | O_RDWR | O_TRUNC,
432
 
#endif
433
 
 
434
 
            S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH)) == -1) {
435
 
                (void)fprintf(stderr, "%s: open: %s\n", file, strerror(errno));
436
 
                exit(EXIT_FAILURE);
437
 
        }
438
 
        if (lseek(fd, (off_t)len, SEEK_SET) != len || write(fd, &fd, 1) != 1) {
439
 
                (void)fprintf(stderr,
440
 
                    "%s: seek/write: %s\n", file, strerror(errno));
441
 
                exit(EXIT_FAILURE);
442
 
        }
443
 
        (void)close(fd);
444
 
}
445
 
 
446
 
/*
447
 
 * tm_mutex_init --
448
 
 *      Initialize the mutexes.
449
 
 */
450
 
void
451
 
tm_mutex_init()
452
 
{
453
 
        DB_MUTEX *gm_addr, *lm_addr, *mp, *tm_addr;
454
 
        int fd, i;
455
 
 
456
 
        map_file(&gm_addr, &tm_addr, &lm_addr, NULL, &fd);
457
 
 
458
 
        printf("Initialize the global mutex...\n");
459
 
        if (__db_mutex_init_int(&dbenv, gm_addr, 0, 0)) {
460
 
                fprintf(stderr,
461
 
                    "__db_mutex_init (global): %s\n", strerror(errno));
462
 
                exit(EXIT_FAILURE);
463
 
        }
464
 
 
465
 
        printf("Initialize the per-thread mutexes...\n");
466
 
        for (i = 1, mp = tm_addr;
467
 
            i <= nthreads; ++i, mp = (DB_MUTEX *)((u_int8_t *)mp + align)) {
468
 
                if (__db_mutex_init_int(&dbenv, mp, 0, MUTEX_SELF_BLOCK)) {
469
 
                        fprintf(stderr, "__db_mutex_init (per-thread %d): %s\n",
470
 
                            i, strerror(errno));
471
 
                        exit(EXIT_FAILURE);
472
 
                }
473
 
                if (__db_mutex_lock(&dbenv, mp)) {
474
 
                        fprintf(stderr,
475
 
                            "__db_mutex_init (per-thread %d) lock: %s\n",
476
 
                            i, strerror(errno));
477
 
                        exit(EXIT_FAILURE);
478
 
                }
479
 
        }
480
 
 
481
 
        printf("Initialize the per-lock mutexes...\n");
482
 
        for (i = 1, mp = lm_addr;
483
 
            i <= maxlocks; ++i, mp = (DB_MUTEX *)((u_int8_t *)mp + align))
484
 
                if (__db_mutex_init_int(&dbenv, mp, 0, 0)) {
485
 
                        fprintf(stderr, "__db_mutex_init (per-lock: %d): %s\n",
486
 
                            i, strerror(errno));
487
 
                        exit(EXIT_FAILURE);
488
 
                }
489
 
 
490
 
        unmap_file((void *)gm_addr, fd);
491
 
}
492
 
 
493
 
/*
494
 
 * tm_mutex_destroy --
495
 
 *      Destroy the mutexes.
496
 
 */
497
 
void
498
 
tm_mutex_destroy()
499
 
{
500
 
        DB_MUTEX *gm_addr, *lm_addr, *mp, *tm_addr;
501
 
        int fd, i;
502
 
 
503
 
        map_file(&gm_addr, &tm_addr, &lm_addr, NULL, &fd);
504
 
 
505
 
        printf("Destroy the global mutex...\n");
506
 
        if (__db_mutex_destroy(gm_addr)) {
507
 
                fprintf(stderr,
508
 
                    "__db_mutex_destroy (global): %s\n", strerror(errno));
509
 
                exit(EXIT_FAILURE);
510
 
        }
511
 
 
512
 
        printf("Destroy the per-thread mutexes...\n");
513
 
        for (i = 1, mp = tm_addr;
514
 
            i <= nthreads; ++i, mp = (DB_MUTEX *)((u_int8_t *)mp + align)) {
515
 
                if (__db_mutex_destroy(mp)) {
516
 
                        fprintf(stderr,
517
 
                            "__db_mutex_destroy (per-thread %d): %s\n",
518
 
                            i, strerror(errno));
519
 
                        exit(EXIT_FAILURE);
520
 
                }
521
 
        }
522
 
 
523
 
        printf("Destroy the per-lock mutexes...\n");
524
 
        for (i = 1, mp = lm_addr;
525
 
            i <= maxlocks; ++i, mp = (DB_MUTEX *)((u_int8_t *)mp + align))
526
 
                if (__db_mutex_destroy(mp)) {
527
 
                        fprintf(stderr,
528
 
                            "__db_mutex_destroy (per-lock: %d): %s\n",
529
 
                            i, strerror(errno));
530
 
                        exit(EXIT_FAILURE);
531
 
                }
532
 
 
533
 
        unmap_file((void *)gm_addr, fd);
534
 
#ifdef HAVE_QNX
535
 
        (void)shm_unlink(file);
536
 
#endif
537
 
}
538
 
 
539
 
/*
540
 
 * tm_mutex_stats --
541
 
 *      Display mutex statistics.
542
 
 */
543
 
void
544
 
tm_mutex_stats()
545
 
{
546
 
        DB_MUTEX *gm_addr, *lm_addr, *mp;
547
 
        int fd, i;
548
 
 
549
 
        map_file(&gm_addr, NULL, &lm_addr, NULL, &fd);
550
 
 
551
 
        printf("Per-lock mutex statistics...\n");
552
 
        for (i = 1, mp = lm_addr;
553
 
            i <= maxlocks; ++i, mp = (DB_MUTEX *)((u_int8_t *)mp + align))
554
 
                printf("mutex %2d: wait: %lu; no wait %lu\n", i,
555
 
                    (u_long)mp->mutex_set_wait, (u_long)mp->mutex_set_nowait);
556
 
 
557
 
        unmap_file((void *)gm_addr, fd);
558
 
}
559
 
 
560
 
/*
561
 
 * map_file --
562
 
 *      Map in the backing file.
563
 
 */
564
 
void
565
 
map_file(gm_addrp, tm_addrp, lm_addrp, id_addrp, fdp)
566
 
        DB_MUTEX **gm_addrp, **tm_addrp, **lm_addrp;
567
 
        u_long **id_addrp;
568
 
        int *fdp;
569
 
{
570
 
        void *maddr;
571
 
        int fd;
572
 
 
573
 
#ifndef MAP_FAILED
574
 
#define MAP_FAILED      (void *)-1
575
 
#endif
576
 
#ifndef MAP_FILE
577
 
#define MAP_FILE        0
578
 
#endif
579
 
#ifdef  HAVE_QNX
580
 
        if ((fd = shm_open(file, O_RDWR, 0)) == -1) {
581
 
#else
582
 
        if ((fd = open(file, O_RDWR, 0)) == -1) {
583
 
#endif
584
 
                fprintf(stderr, "%s: open %s\n", file, strerror(errno));
585
 
                exit(EXIT_FAILURE);
586
 
        }
587
 
 
588
 
        maddr = mmap(NULL, len,
589
 
            PROT_READ | PROT_WRITE, MAP_FILE | MAP_SHARED, fd, (off_t)0);
590
 
        if (maddr == MAP_FAILED) {
591
 
                fprintf(stderr, "%s: mmap: %s\n", file, strerror(errno));
592
 
                exit(EXIT_FAILURE);
593
 
        }
594
 
 
595
 
        if (gm_addrp != NULL)
596
 
                *gm_addrp = (DB_MUTEX *)maddr;
597
 
        maddr = (u_int8_t *)maddr + align;
598
 
        if (tm_addrp != NULL)
599
 
                *tm_addrp = (DB_MUTEX *)maddr;
600
 
        maddr = (u_int8_t *)maddr + align * nthreads;
601
 
        if (lm_addrp != NULL)
602
 
                *lm_addrp = (DB_MUTEX *)maddr;
603
 
        maddr = (u_int8_t *)maddr + align * maxlocks;
604
 
        if (id_addrp != NULL)
605
 
                *id_addrp = (u_long *)maddr;
606
 
        if (fdp != NULL)
607
 
                *fdp = fd;
608
 
}
609
 
 
610
 
/*
611
 
 * unmap_file --
612
 
 *      Discard backing file map.
613
 
 */
614
 
void
615
 
unmap_file(maddr, fd)
616
 
        void *maddr;
617
 
        int fd;
618
 
{
619
 
        if (munmap(maddr, len) != 0) {
620
 
                fprintf(stderr, "munmap: %s\n", strerror(errno));
621
 
                exit(EXIT_FAILURE);
622
 
        }
623
 
        if (close(fd) != 0) {
624
 
                fprintf(stderr, "close: %s\n", strerror(errno));
625
 
                exit(EXIT_FAILURE);
626
 
        }
627
 
}