1#include <stdio.h>
2#include <pthread.h>
3#include <stdlib.h>
4#define MANY 1000
5#define LEVEL 100
6typedef struct {
7   pthread_mutex_t m[MANY];
8   pthread_mutex_t d;
9} Level;
10
11static Level level[LEVEL];
12
13static int stat_mutex_init = 0;
14static int stat_mutex_lock = 0;
15static int stat_mutex_unlock = 0;
16static int stat_mutex_destroy = 0;
17
18/* t2t.c : test program for the laog data structure performance testing
19   and "shaking" : it creates, locks/unlocks and destroy mutex.
20
21   USAGE:  t2t [many] [level] [loops]
22   many (default 100) : how many locks are created/locked/unlocked at a certain level.
23   level (default 1)  : how many levels of "nested locks" are done
24   loops : how many times these locks are created and destroyed and locked/unlocked) */
25#define check if (ret != 0) printf("error %d at line %d\n", ret, __LINE__)
26int doit(int argc, char*argv[])
27{
28   int l, i;
29   int ret;
30
31   int clo_many = 100;
32   int clo_level = 1;
33
34   if (argc >= 2) clo_many = atoi(argv[1]);
35   if (argc >= 3) clo_level = atoi(argv[2]);
36
37   if (clo_many > MANY) {
38      printf("error argv[1] (many arg) %d > max MANY %d\n", clo_many, MANY);
39      exit(1);
40   }
41
42   if (clo_level > LEVEL) {
43      printf("error argv[2] (level arg) %d > max LEVEL %d\n", clo_level, LEVEL);
44      exit(1);
45   }
46
47   printf ("many %d level %d total_locks: %d\n",
48           clo_many, clo_level,
49           clo_many * clo_level + clo_level * (clo_level == 1 ? 0 : 1));
50
51   for (l = 0; l < clo_level; l++) {
52      printf ("init level %d\n", l);
53      for (i = 0; i < clo_many; i++) {
54         ret = pthread_mutex_init (&level[l].m[i], NULL);
55         check;
56         stat_mutex_init++;
57      }
58      if (clo_level > 1) {
59         ret = pthread_mutex_init (&level[l].d, NULL);
60         check;
61         stat_mutex_init++;
62      }
63   }
64
65   for (l = 0; l < clo_level; l++) {
66      printf ("locking level %d\n", l);
67      for (i = 0; i < clo_many; i++) {
68         ret = pthread_mutex_lock (&level[l].m[i]);
69         check;
70         stat_mutex_lock++;
71      }
72      if (clo_level > 1) {
73         ret = pthread_mutex_lock (&level[l].d);
74         check;
75         stat_mutex_lock++;
76      }
77   }
78
79   for (l = 0; l < clo_level; l++) {
80      printf ("unlocking level %d\n", l);
81      for (i = 0; i < clo_many; i++) {
82         ret = pthread_mutex_unlock (&level[l].m[i]);
83         check;
84         stat_mutex_unlock++;
85      }
86      if (clo_level > 1) {
87         ret = pthread_mutex_unlock (&level[l].d);
88         stat_mutex_unlock++;
89         check;
90      }
91   }
92
93   for (l = 0; l < clo_level; l++) {
94      printf ("deleting level %d\n", l);
95      if (clo_level > 1) {
96         ret = pthread_mutex_destroy (&level[l].d);
97         /// this tests the influence of the deletion in another order.
98         check;
99         stat_mutex_destroy++;
100      }
101      for (i = 0; i < clo_many; i++) {
102         ret = pthread_mutex_destroy (&level[l].m[i]);
103         check;
104         stat_mutex_destroy++;
105      }
106   }
107   return 0;
108}
109
110int main(int argc, char*argv[])
111{
112   int loops = 1;
113   int i;
114   if (argc >= 4) loops = atoi(argv[3]);
115
116   printf ("loops %d\n", loops);
117   for (i = 0; i < loops; i++)
118      doit(argc, argv);
119
120   printf ("stats: init %d lock %d unlock %d destroy %d\n",
121           stat_mutex_init, stat_mutex_lock,
122           stat_mutex_unlock, stat_mutex_destroy);
123   return 0;
124}
125
126