1/** Hold several types of synchronization objects locked as long as specified.
2 */
3
4#define _GNU_SOURCE 1
5
6#include <assert.h>
7#include <pthread.h>
8#include <stdio.h>
9#include <stdlib.h>
10#include <time.h>
11#include <unistd.h>
12
13
14static void delay_ms(const int ms)
15{
16  struct timespec ts;
17
18  assert(ms >= 0);
19  ts.tv_sec = ms / 1000;
20  ts.tv_nsec = (ms % 1000) * 1000 * 1000;
21  nanosleep(&ts, 0);
22}
23
24int main(int argc, char** argv)
25{
26  int interval = 0;
27  int optchar;
28  pthread_mutex_t     mutex;
29  pthread_mutexattr_t mutexattr;
30  pthread_rwlock_t    rwlock;
31
32  while ((optchar = getopt(argc, argv, "i:")) != EOF)
33  {
34    switch (optchar)
35    {
36    case 'i':
37      interval = atoi(optarg);
38      break;
39    default:
40      fprintf(stderr, "Usage: %s [-i <interval time in ms>].\n", argv[0]);
41      break;
42    }
43  }
44
45  fprintf(stderr, "Locking mutex ...\n");
46
47  pthread_mutexattr_init(&mutexattr);
48  pthread_mutexattr_settype(&mutexattr, PTHREAD_MUTEX_RECURSIVE);
49  pthread_mutex_init(&mutex, &mutexattr);
50  pthread_mutexattr_destroy(&mutexattr);
51  pthread_mutex_lock(&mutex);
52  delay_ms(interval);
53  pthread_mutex_lock(&mutex);
54  pthread_mutex_unlock(&mutex);
55  pthread_mutex_unlock(&mutex);
56  pthread_mutex_destroy(&mutex);
57
58  fprintf(stderr, "Locking rwlock exclusively ...\n");
59
60  pthread_rwlock_init(&rwlock, 0);
61  pthread_rwlock_wrlock(&rwlock);
62  delay_ms(interval);
63  pthread_rwlock_unlock(&rwlock);
64  pthread_rwlock_destroy(&rwlock);
65
66  fprintf(stderr, "Locking rwlock shared ...\n");
67
68  pthread_rwlock_init(&rwlock, 0);
69  pthread_rwlock_rdlock(&rwlock);
70  delay_ms(interval);
71  pthread_rwlock_rdlock(&rwlock);
72  pthread_rwlock_unlock(&rwlock);
73  pthread_rwlock_unlock(&rwlock);
74  pthread_rwlock_destroy(&rwlock);
75
76  fprintf(stderr, "Done.\n");
77
78  return 0;
79}
80