Merge "Implementation of following functionality" into connectivity-abstraction
[platform/upstream/iotivity.git] / resource / csdk / connectivity / lib / android / glib-master / gthread / tests / 1bit-mutex.c
1 /*
2  * Copyright © 2008 Ryan Lortie
3  * Copyright © 2010 Codethink Limited
4  *
5  * This program is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU Lesser General Public License as
7  * published by the Free Software Foundation; either version 2 of the
8  * License, or (at your option) any later version.
9  *
10  * See the included COPYING file for more information.
11  */
12
13 /* LOCKS should be more than the number of contention
14  * counters in gthread.c in order to ensure we exercise
15  * the case where they overlap.
16  */
17 #define LOCKS      48
18 #define ITERATIONS 10000
19 #define THREADS    100
20
21
22 #if TEST_EMULATED_FUTEX
23   /* this is defined for the 1bit-mutex-emufutex test.
24    *
25    * we want to test the emulated futex even if futex(2) is available.
26    */
27
28   /* side-step some glib build stuff */
29   #ifndef DISABLE_VISIBILITY
30   #define DISABLE_VISIBILITY
31   #endif
32   #define GLIB_COMPILATION
33
34   /* rebuild gbitlock.c without futex support,
35      defining our own version of the g_bit_*lock symbols
36    */
37   #define g_bit_lock            _emufutex_g_bit_lock
38   #define g_bit_trylock         _emufutex_g_bit_trylock
39   #define g_bit_unlock          _emufutex_g_bit_unlock
40   #define _g_futex_thread_init  _emufutex_g_futex_thread_init
41
42   #define G_BIT_LOCK_FORCE_FUTEX_EMULATION
43
44   #include <glib/gbitlock.c>
45 #endif
46
47 #include <glib.h>
48
49 volatile GThread *owners[LOCKS];
50 volatile gint     locks[LOCKS];
51 volatile gint     bits[LOCKS];
52
53 static void
54 acquire (int nr)
55 {
56   GThread *self;
57
58   self = g_thread_self ();
59
60   if (!g_bit_trylock (&locks[nr], bits[nr]))
61     {
62       if (g_test_verbose ())
63         g_print ("thread %p going to block on lock %d\n", self, nr);
64       g_bit_lock (&locks[nr], bits[nr]);
65     }
66
67   g_assert (owners[nr] == NULL);   /* hopefully nobody else is here */
68   owners[nr] = self;
69
70   /* let some other threads try to ruin our day */
71   g_thread_yield ();
72   g_thread_yield ();
73   g_thread_yield ();
74
75   g_assert (owners[nr] == self);   /* hopefully this is still us... */
76   owners[nr] = NULL;               /* make way for the next guy */
77   g_bit_unlock (&locks[nr], bits[nr]);
78 }
79
80 static gpointer
81 thread_func (gpointer data)
82 {
83   gint i;
84
85   for (i = 0; i < ITERATIONS; i++)
86     acquire (g_random_int () % LOCKS);
87
88   return NULL;
89 }
90
91 static void
92 testcase (void)
93 {
94   GThread *threads[THREADS];
95   int i;
96
97   g_thread_init (NULL);
98
99 #ifdef TEST_EMULATED_FUTEX
100   _g_futex_thread_init ();
101   #define SUFFIX "-emufutex"
102
103   /* ensure that we are using the emulated futex by checking
104    * (at compile-time) for the existance of 'g_futex_mutex'
105    */
106   g_assert (g_futex_mutex != NULL);
107 #else
108   #define SUFFIX ""
109 #endif
110
111   for (i = 0; i < LOCKS; i++)
112     bits[i] = g_random_int () % 32;
113
114   for (i = 0; i < THREADS; i++)
115     threads[i] = g_thread_create (thread_func, NULL, TRUE, NULL);
116
117   for (i = 0; i < THREADS; i++)
118     g_thread_join (threads[i]);
119
120   for (i = 0; i < LOCKS; i++)
121     {
122       g_assert (owners[i] == NULL);
123       g_assert (locks[i] == 0);
124     }
125 }
126
127 int
128 main (int argc, char **argv)
129 {
130   g_test_init (&argc, &argv, NULL);
131
132   g_test_add_func ("/glib/1bit-mutex" SUFFIX, testcase);
133
134   return g_test_run ();
135 }