Branch data Line data Source code
1 : : /* refcount.c: Tests for reference counting types
2 : : *
3 : : * Copyright 2018 Emmanuele Bassi
4 : : *
5 : : * SPDX-License-Identifier: LGPL-2.1-or-later
6 : : *
7 : : * This library is free software; you can redistribute it and/or
8 : : * modify it under the terms of the GNU Lesser General Public
9 : : * License as published by the Free Software Foundation; either
10 : : * version 2.1 of the License, or (at your option) any later version.
11 : : *
12 : : * This library is distributed in the hope that it will be useful,
13 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 : : * Lesser General Public License for more details.
16 : : *
17 : : * You should have received a copy of the GNU Lesser General Public
18 : : * License along with this library; if not, see <http://www.gnu.org/licenses/>.
19 : : */
20 : :
21 : : #include <stdlib.h>
22 : : #include <glib.h>
23 : :
24 : : /* test_grefcount: test the behavior of the grefcount API */
25 : : static void
26 : 2 : test_grefcount (void)
27 : : {
28 : : grefcount a, b;
29 : :
30 : : /* init(a): 1 */
31 : 2 : g_ref_count_init (&a);
32 [ - + ]: 2 : if (g_test_verbose ())
33 : 0 : g_test_message ("init(a) := %d\n", (int) a);
34 : 2 : g_assert_true (g_ref_count_compare (&a, 1));
35 : :
36 : : /* inc(a): 2 */
37 [ + - ]: 2 : g_ref_count_inc (&a);
38 [ - + ]: 2 : if (g_test_verbose ())
39 : 0 : g_test_message ("inc(a) := %d\n", (int) a);
40 : 2 : g_assert_false (g_ref_count_compare (&a, 1));
41 : 2 : g_assert_false (g_ref_count_compare (&a, G_MAXINT));
42 : :
43 : : /* b = a = 2 */
44 : 2 : b = a;
45 [ - + ]: 2 : if (g_test_verbose ())
46 : 0 : g_test_message ("a := %d, b := %d\n", (int) a, (int) b);
47 : :
48 : : /* inc(a): 3 */
49 [ + - ]: 2 : g_ref_count_inc (&a);
50 [ - + ]: 2 : if (g_test_verbose ())
51 : 0 : g_test_message ("inc(a) := %d\n", (int) a);
52 : :
53 : : /* dec(b) = 1 */
54 [ - + ]: 2 : if (g_test_verbose ())
55 : 0 : g_test_message ("dec(b) := %d + 1\n", (int) b);
56 : 2 : g_assert_false (g_ref_count_dec (&b));
57 : :
58 : : /* dec(a) = 2 */
59 [ - + ]: 2 : if (g_test_verbose ())
60 : 0 : g_test_message ("dec(a) := %d + 1\n", (int) a);
61 : 2 : g_assert_false (g_ref_count_dec (&a));
62 : :
63 : : /* dec(b) = 0 */
64 [ - + ]: 2 : if (g_test_verbose ())
65 : 0 : g_test_message ("dec(b) := %d + 1\n", (int) b);
66 : 2 : g_assert_true (g_ref_count_dec (&b));
67 : :
68 : : /* dec(a) = 1 */
69 [ - + ]: 2 : if (g_test_verbose ())
70 : 0 : g_test_message ("dec(a) := %d + 1\n", (int) a);
71 : 2 : g_assert_false (g_ref_count_dec (&a));
72 : :
73 : : /* dec(a) = 0 */
74 [ - + ]: 2 : if (g_test_verbose ())
75 : 0 : g_test_message ("dec(a) := %d + 1\n", (int) a);
76 : 2 : g_assert_true (g_ref_count_dec (&a));
77 : 2 : }
78 : :
79 : : /* test_grefcount_saturation: Saturating a grefcount counter
80 : : * does not cause an overflow; additionally, if we're building
81 : : * with checks enabled or with non-GCC compilers, it'll cause a
82 : : * warning
83 : : */
84 : : static void
85 : 3 : test_grefcount_saturation (void)
86 : : {
87 [ + + ]: 3 : if (g_test_subprocess ())
88 : : {
89 : : grefcount a;
90 : :
91 : : /* We're breaking abstraction here for convenience */
92 : 1 : a = G_MININT + 1;
93 : :
94 [ + - ]: 1 : g_ref_count_inc (&a);
95 : 1 : g_assert_true (a == G_MININT);
96 : :
97 [ - + ]: 1 : g_ref_count_inc (&a);
98 : 1 : g_assert_true (a == G_MININT);
99 : :
100 : 1 : exit (0);
101 : : }
102 : :
103 : 2 : g_test_trap_subprocess (NULL, 0, G_TEST_SUBPROCESS_DEFAULT);
104 : :
105 : : #if defined (G_DISABLE_CHECKS) && defined (__GNUC__)
106 : : /* With checks disabled we don't get any warning */
107 : 1 : g_test_trap_assert_passed ();
108 : : #else
109 : : /* Ensure that we got a warning when building with checks or with
110 : : * non-GCC compilers; the test will fail because of the critical
111 : : * warning being caught by GTest
112 : : */
113 : 1 : g_test_trap_assert_failed ();
114 : 1 : g_test_trap_assert_stderr ("*saturation*");
115 : : #endif
116 : 2 : }
117 : :
118 : : /* test_gatomicrefcount: test the behavior of the gatomicrefcount API */
119 : : static void
120 : 2 : test_gatomicrefcount (void)
121 : : {
122 : : gatomicrefcount a, b;
123 : :
124 : : /* init(a): 1 */
125 : 2 : g_atomic_ref_count_init (&a);
126 [ - + ]: 2 : if (g_test_verbose ())
127 : 0 : g_test_message ("init(a) := %d\n", (int) a);
128 : 2 : g_assert_true (g_atomic_ref_count_compare (&a, 1));
129 : :
130 : : /* inc(a): 2 */
131 [ + - ]: 2 : g_atomic_ref_count_inc (&a);
132 [ - + ]: 2 : if (g_test_verbose ())
133 : 0 : g_test_message ("inc(a) := %d\n", (int) a);
134 : 2 : g_assert_false (g_atomic_ref_count_compare (&a, 1));
135 : 2 : g_assert_false (g_atomic_ref_count_compare (&a, G_MAXINT));
136 : :
137 : : /* b = a = 2 */
138 : 2 : b = a;
139 [ - + ]: 2 : if (g_test_verbose ())
140 : 0 : g_test_message ("a := %d, b := %d\n", (int) a, (int) b);
141 : :
142 : : /* inc(a): 3 */
143 [ + - ]: 2 : g_atomic_ref_count_inc (&a);
144 [ - + ]: 2 : if (g_test_verbose ())
145 : 0 : g_test_message ("inc(a) := %d\n", (int) a);
146 : :
147 : : /* dec(b) = 1 */
148 [ - + ]: 2 : if (g_test_verbose ())
149 : 0 : g_test_message ("dec(b) := %d + 1\n", (int) b);
150 : 2 : g_assert_false (g_atomic_ref_count_dec (&b));
151 : :
152 : : /* dec(a) = 2 */
153 [ - + ]: 2 : if (g_test_verbose ())
154 : 0 : g_test_message ("dec(a) := %d + 1\n", (int) a);
155 : 2 : g_assert_false (g_atomic_ref_count_dec (&a));
156 : :
157 : : /* dec(b) = 0 */
158 [ - + ]: 2 : if (g_test_verbose ())
159 : 0 : g_test_message ("dec(b) := %d + 1\n", (int) b);
160 : 2 : g_assert_true (g_atomic_ref_count_dec (&b));
161 : :
162 : : /* dec(a) = 1 */
163 [ - + ]: 2 : if (g_test_verbose ())
164 : 0 : g_test_message ("dec(a) := %d + 1\n", (int) a);
165 : 2 : g_assert_false (g_atomic_ref_count_dec (&a));
166 : :
167 : : /* dec(a) = 0 */
168 [ - + ]: 2 : if (g_test_verbose ())
169 : 0 : g_test_message ("dec(a) := %d + 1\n", (int) a);
170 : 2 : g_assert_true (g_atomic_ref_count_dec (&a));
171 : 2 : }
172 : :
173 : : /* test_gatomicrefcount_saturation: Saturating a gatomicrefcount counter
174 : : * does not cause an overflow; additionally, if we're building with
175 : : * checks enabled or with non-GCC compilers, it'll cause a warning
176 : : */
177 : : static void
178 : 3 : test_gatomicrefcount_saturation (void)
179 : : {
180 [ + + ]: 3 : if (g_test_subprocess ())
181 : : {
182 : : gatomicrefcount a;
183 : :
184 : : /* We're breaking abstraction here for convenience */
185 : 1 : a = G_MAXINT - 1;
186 : :
187 [ + - ]: 1 : g_atomic_ref_count_inc (&a);
188 : 1 : g_assert_true (a == G_MAXINT);
189 : :
190 [ - + ]: 1 : g_atomic_ref_count_inc (&a);
191 : 1 : g_assert_true (a == G_MAXINT);
192 : :
193 : 1 : exit (0);
194 : : }
195 : :
196 : 2 : g_test_trap_subprocess (NULL, 0, G_TEST_SUBPROCESS_DEFAULT);
197 : :
198 : : #if defined (G_DISABLE_CHECKS) && defined (__GNUC__)
199 : : /* With checks disabled we don't get any warning */
200 : 1 : g_test_trap_assert_passed ();
201 : : #else
202 : : /* Ensure that we got a warning when building with checks or with
203 : : * non-GCC compilers; the test will fail because of the critical
204 : : * warning being caught by GTest
205 : : */
206 : 1 : g_test_trap_assert_failed ();
207 : 1 : g_test_trap_assert_stderr ("*saturation*");
208 : : #endif
209 : 2 : }
210 : :
211 : : int
212 : 4 : main (int argc,
213 : : char *argv[])
214 : : {
215 : 4 : g_test_init (&argc, &argv, NULL);
216 : :
217 : 4 : g_test_add_func ("/refcount/grefcount", test_grefcount);
218 : 4 : g_test_add_func ("/refcount/grefcount/saturation", test_grefcount_saturation);
219 : :
220 : 4 : g_test_add_func ("/refcount/gatomicrefcount", test_gatomicrefcount);
221 : 4 : g_test_add_func ("/refcount/gatomicrefcount/saturation", test_gatomicrefcount_saturation);
222 : :
223 : 4 : return g_test_run ();
224 : : }
|