locks: drop _INIT macros
[platform/upstream/glib.git] / glib / tests / rec-mutex.c
1 /* Unit tests for GRecMutex
2  * Copyright (C) 2011 Red Hat, Inc
3  * Author: Matthias Clasen
4  *
5  * This work is provided "as is"; redistribution and modification
6  * in whole or in part, in any medium, physical or electronic is
7  * permitted without restriction.
8  *
9  * This work is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12  *
13  * In no event shall the authors or contributors be liable for any
14  * direct, indirect, incidental, special, exemplary, or consequential
15  * damages (including, but not limited to, procurement of substitute
16  * goods or services; loss of use, data, or profits; or business
17  * interruption) however caused and on any theory of liability, whether
18  * in contract, strict liability, or tort (including negligence or
19  * otherwise) arising in any way out of the use of this software, even
20  * if advised of the possibility of such damage.
21  */
22
23 #include <glib.h>
24
25 static void
26 test_rec_mutex1 (void)
27 {
28   GRecMutex mutex;
29
30   g_rec_mutex_init (&mutex);
31   g_rec_mutex_lock (&mutex);
32   g_rec_mutex_unlock (&mutex);
33   g_rec_mutex_lock (&mutex);
34   g_rec_mutex_unlock (&mutex);
35   g_rec_mutex_clear (&mutex);
36 }
37
38 static void
39 test_rec_mutex2 (void)
40 {
41   static GRecMutex mutex;
42
43   g_rec_mutex_lock (&mutex);
44   g_rec_mutex_unlock (&mutex);
45   g_rec_mutex_lock (&mutex);
46   g_rec_mutex_unlock (&mutex);
47 }
48
49 static void
50 test_rec_mutex3 (void)
51 {
52   static GRecMutex mutex;
53   gboolean ret;
54
55   ret = g_rec_mutex_trylock (&mutex);
56   g_assert (ret);
57
58   ret = g_rec_mutex_trylock (&mutex);
59   g_assert (ret);
60
61   g_rec_mutex_unlock (&mutex);
62   g_rec_mutex_unlock (&mutex);
63 }
64
65 #define LOCKS      48
66 #define ITERATIONS 10000
67 #define THREADS    100
68
69
70 GThread   *owners[LOCKS];
71 GRecMutex  locks[LOCKS];
72
73 static void
74 acquire (gint nr)
75 {
76   GThread *self;
77
78   self = g_thread_self ();
79
80   if (owners[nr] != NULL && owners[nr] != self)
81     {
82       if (g_test_verbose ())
83         g_print ("thread %p going to block on lock %d\n", self, nr);
84     }
85
86   g_rec_mutex_lock (&locks[nr]);
87
88   g_assert (owners[nr] == NULL);   /* hopefully nobody else is here */
89   owners[nr] = self;
90
91   /* let some other threads try to ruin our day */
92   g_thread_yield ();
93   g_thread_yield ();
94
95   g_assert (owners[nr] == self);   /* hopefully this is still us... */
96
97   if (g_test_verbose ())
98     g_print ("thread %p recursively taking lock %d\n", self, nr);
99
100   g_rec_mutex_lock (&locks[nr]);  /* we're recursive, after all */
101
102   g_assert (owners[nr] == self);   /* hopefully this is still us... */
103
104   g_rec_mutex_unlock (&locks[nr]);
105
106   g_thread_yield ();
107   g_thread_yield ();
108
109   g_assert (owners[nr] == self);   /* hopefully this is still us... */
110   owners[nr] = NULL;               /* make way for the next guy */
111
112   g_rec_mutex_unlock (&locks[nr]);
113 }
114
115 static gpointer
116 thread_func (gpointer data)
117 {
118   gint i;
119   GRand *rand;
120
121   rand = g_rand_new ();
122
123   for (i = 0; i < ITERATIONS; i++)
124     acquire (g_rand_int_range (rand, 0, LOCKS));
125
126   g_rand_free (rand);
127
128   return NULL;
129 }
130
131 static void
132 test_rec_mutex4 (void)
133 {
134   gint i;
135   GThread *threads[THREADS];
136
137   for (i = 0; i < LOCKS; i++)
138     g_rec_mutex_init (&locks[i]);
139
140   for (i = 0; i < THREADS; i++)
141     threads[i] = g_thread_create (thread_func, NULL, TRUE, NULL);
142
143   for (i = 0; i < THREADS; i++)
144     g_thread_join (threads[i]);
145
146   for (i = 0; i < LOCKS; i++)
147     g_rec_mutex_clear (&locks[i]);
148
149   for (i = 0; i < LOCKS; i++)
150     g_assert (owners[i] == NULL);
151 }
152
153 int
154 main (int argc, char *argv[])
155 {
156   g_test_init (&argc, &argv, NULL);
157
158   g_test_add_func ("/thread/rec-mutex1", test_rec_mutex1);
159   g_test_add_func ("/thread/rec-mutex2", test_rec_mutex2);
160   g_test_add_func ("/thread/rec-mutex3", test_rec_mutex3);
161   g_test_add_func ("/thread/rec-mutex4", test_rec_mutex4);
162
163   return g_test_run ();
164 }