VirtualBox

source: vbox/trunk/src/VBox/Runtime/testcase/tstRTSemEventMulti.cpp@ 80721

Last change on this file since 80721 was 76553, checked in by vboxsync, 6 years ago

scm --update-copyright-year

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Revision
File size: 11.7 KB
Line 
1/* $Id: tstRTSemEventMulti.cpp 76553 2019-01-01 01:45:53Z vboxsync $ */
2/** @file
3 * IPRT Testcase - Multiple Release Event Semaphores.
4 */
5
6/*
7 * Copyright (C) 2009-2019 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 *
17 * The contents of this file may alternatively be used under the terms
18 * of the Common Development and Distribution License Version 1.0
19 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
20 * VirtualBox OSE distribution, in which case the provisions of the
21 * CDDL are applicable instead of those of the GPL.
22 *
23 * You may elect to license modified versions of this file under the
24 * terms and conditions of either the GPL or the CDDL or both.
25 */
26
27
28/*********************************************************************************************************************************
29* Header Files *
30*********************************************************************************************************************************/
31#include <iprt/semaphore.h>
32
33#include <iprt/asm.h>
34#include <iprt/assert.h>
35#include <iprt/errcore.h>
36#include <iprt/rand.h>
37#include <iprt/stream.h>
38#include <iprt/string.h>
39#include <iprt/test.h>
40#include <iprt/thread.h>
41#include <iprt/time.h>
42
43
44/*********************************************************************************************************************************
45* Global Variables *
46*********************************************************************************************************************************/
47/** The test handle. */
48static RTTEST g_hTest;
49
50
51static DECLCALLBACK(int) test1Thread1(RTTHREAD ThreadSelf, void *pvUser)
52{
53 RTSEMEVENTMULTI hSem = *(PRTSEMEVENTMULTI)pvUser;
54 RT_NOREF_PV(ThreadSelf);
55
56 uint64_t u64 = RTTimeSystemMilliTS();
57 RTTEST_CHECK_RC(g_hTest, RTSemEventMultiWait(hSem, 1000), VERR_TIMEOUT);
58 u64 = RTTimeSystemMilliTS() - u64;
59 RTTEST_CHECK_MSG(g_hTest, u64 < 1500 && u64 > 950, (g_hTest, "u64=%llu\n", u64));
60
61 RTTEST_CHECK_RC(g_hTest, RTSemEventMultiWait(hSem, 2000), VINF_SUCCESS);
62 return VINF_SUCCESS;
63}
64
65
66static DECLCALLBACK(int) test1Thread2(RTTHREAD ThreadSelf, void *pvUser)
67{
68 RTSEMEVENTMULTI hSem = *(PRTSEMEVENTMULTI)pvUser;
69 RT_NOREF_PV(ThreadSelf);
70
71 RTTEST_CHECK_RC(g_hTest, RTSemEventMultiWait(hSem, RT_INDEFINITE_WAIT), VINF_SUCCESS);
72 return VINF_SUCCESS;
73}
74
75
76static void test1(void)
77{
78 RTTestISub("Three threads");
79
80 /*
81 * Create the threads and let them block on the event multi semaphore.
82 */
83 RTSEMEVENTMULTI hSem;
84 RTTESTI_CHECK_RC_RETV(RTSemEventMultiCreate(&hSem), VINF_SUCCESS);
85
86 RTTHREAD hThread2;
87 RTTESTI_CHECK_RC_RETV(RTThreadCreate(&hThread2, test1Thread2, &hSem, 0, RTTHREADTYPE_DEFAULT, RTTHREADFLAGS_WAITABLE, "test2"), VINF_SUCCESS);
88 RTThreadSleep(100);
89
90 RTTHREAD hThread1;
91 RTTESTI_CHECK_RC_RETV(RTThreadCreate(&hThread1, test1Thread1, &hSem, 0, RTTHREADTYPE_DEFAULT, RTTHREADFLAGS_WAITABLE, "test1"), VINF_SUCCESS);
92
93 /* Force first thread (which has a timeout of 1 second) to timeout in the
94 * first wait, and the second wait will succeed. */
95 RTTESTI_CHECK_RC(RTThreadSleep(1500), VINF_SUCCESS);
96 RTTESTI_CHECK_RC(RTSemEventMultiSignal(hSem), VINF_SUCCESS);
97 RTTESTI_CHECK_RC(RTThreadWait(hThread1, 5000, NULL), VINF_SUCCESS);
98 RTTESTI_CHECK_RC(RTThreadWait(hThread2, 5000, NULL), VINF_SUCCESS);
99 RTTESTI_CHECK_RC(RTSemEventMultiDestroy(hSem), VINF_SUCCESS);
100}
101
102
103static void testBasicsWaitTimeout(RTSEMEVENTMULTI hSem, unsigned i)
104{
105 RTTESTI_CHECK_RC_RETV(RTSemEventMultiWait(hSem, 0), VERR_TIMEOUT);
106#if 0
107 RTTESTI_CHECK_RC_RETV(RTSemEventMultiWaitNoResume(hSem, 0), VERR_TIMEOUT);
108#else
109 RTTESTI_CHECK_RC_RETV(RTSemEventMultiWaitEx(hSem,
110 RTSEMWAIT_FLAGS_RESUME | RTSEMWAIT_FLAGS_NANOSECS | RTSEMWAIT_FLAGS_RELATIVE,
111 0),
112 VERR_TIMEOUT);
113 RTTESTI_CHECK_RC_RETV(RTSemEventMultiWaitEx(hSem,
114 RTSEMWAIT_FLAGS_RESUME | RTSEMWAIT_FLAGS_NANOSECS | RTSEMWAIT_FLAGS_ABSOLUTE,
115 RTTimeSystemNanoTS() + 1000*i),
116 VERR_TIMEOUT);
117 RTTESTI_CHECK_RC_RETV(RTSemEventMultiWaitEx(hSem,
118 RTSEMWAIT_FLAGS_RESUME | RTSEMWAIT_FLAGS_NANOSECS | RTSEMWAIT_FLAGS_ABSOLUTE,
119 RTTimeNanoTS() + 1000*i),
120 VERR_TIMEOUT);
121
122 RTTESTI_CHECK_RC_RETV(RTSemEventMultiWaitEx(hSem,
123 RTSEMWAIT_FLAGS_RESUME | RTSEMWAIT_FLAGS_MILLISECS | RTSEMWAIT_FLAGS_RELATIVE,
124 0),
125 VERR_TIMEOUT);
126#endif
127}
128
129
130static void testBasicsWaitSuccess(RTSEMEVENTMULTI hSem, unsigned i)
131{
132 RTTESTI_CHECK_RC_RETV(RTSemEventMultiWait(hSem, 0), VINF_SUCCESS);
133 RTTESTI_CHECK_RC_RETV(RTSemEventMultiWait(hSem, RT_INDEFINITE_WAIT), VINF_SUCCESS);
134#if 0
135 RTTESTI_CHECK_RC_RETV(RTSemEventMultiWaitNoResume(hSem, 0), VINF_SUCCESS);
136 RTTESTI_CHECK_RC_RETV(RTSemEventMultiWaitNoResume(hSem, RT_INDEFINITE_WAIT), VINF_SUCCESS);
137#else
138 RTTESTI_CHECK_RC_RETV(RTSemEventMultiWaitEx(hSem,
139 RTSEMWAIT_FLAGS_RESUME | RTSEMWAIT_FLAGS_NANOSECS | RTSEMWAIT_FLAGS_RELATIVE,
140 0),
141 VINF_SUCCESS);
142 RTTESTI_CHECK_RC_RETV(RTSemEventMultiWaitEx(hSem, RTSEMWAIT_FLAGS_RESUME | RTSEMWAIT_FLAGS_INDEFINITE, 0), VINF_SUCCESS);
143 RTTESTI_CHECK_RC_RETV(RTSemEventMultiWaitEx(hSem, RTSEMWAIT_FLAGS_NORESUME | RTSEMWAIT_FLAGS_INDEFINITE, 0), VINF_SUCCESS);
144 RTTESTI_CHECK_RC_RETV(RTSemEventMultiWaitEx(hSem,
145 RTSEMWAIT_FLAGS_RESUME | RTSEMWAIT_FLAGS_NANOSECS | RTSEMWAIT_FLAGS_ABSOLUTE,
146 RTTimeSystemNanoTS() + 1000*i),
147 VINF_SUCCESS);
148 RTTESTI_CHECK_RC_RETV(RTSemEventMultiWaitEx(hSem,
149 RTSEMWAIT_FLAGS_RESUME | RTSEMWAIT_FLAGS_NANOSECS | RTSEMWAIT_FLAGS_ABSOLUTE,
150 RTTimeNanoTS() + 1000*i),
151 VINF_SUCCESS);
152 RTTESTI_CHECK_RC_RETV(RTSemEventMultiWaitEx(hSem,
153 RTSEMWAIT_FLAGS_RESUME | RTSEMWAIT_FLAGS_NANOSECS | RTSEMWAIT_FLAGS_ABSOLUTE,
154 0),
155 VINF_SUCCESS);
156 RTTESTI_CHECK_RC_RETV(RTSemEventMultiWaitEx(hSem,
157 RTSEMWAIT_FLAGS_RESUME | RTSEMWAIT_FLAGS_NANOSECS | RTSEMWAIT_FLAGS_ABSOLUTE,
158 _1G),
159 VINF_SUCCESS);
160 RTTESTI_CHECK_RC_RETV(RTSemEventMultiWaitEx(hSem,
161 RTSEMWAIT_FLAGS_RESUME | RTSEMWAIT_FLAGS_NANOSECS | RTSEMWAIT_FLAGS_ABSOLUTE,
162 UINT64_MAX),
163 VINF_SUCCESS);
164
165
166 RTTESTI_CHECK_RC_RETV(RTSemEventMultiWaitEx(hSem,
167 RTSEMWAIT_FLAGS_RESUME | RTSEMWAIT_FLAGS_MILLISECS | RTSEMWAIT_FLAGS_ABSOLUTE,
168 RTTimeSystemMilliTS() + 1000*i),
169 VINF_SUCCESS);
170 RTTESTI_CHECK_RC_RETV(RTSemEventMultiWaitEx(hSem,
171 RTSEMWAIT_FLAGS_RESUME | RTSEMWAIT_FLAGS_MILLISECS | RTSEMWAIT_FLAGS_ABSOLUTE,
172 RTTimeMilliTS() + 1000*i),
173 VINF_SUCCESS);
174 RTTESTI_CHECK_RC_RETV(RTSemEventMultiWaitEx(hSem,
175 RTSEMWAIT_FLAGS_RESUME | RTSEMWAIT_FLAGS_MILLISECS | RTSEMWAIT_FLAGS_ABSOLUTE,
176 0),
177 VINF_SUCCESS);
178 RTTESTI_CHECK_RC_RETV(RTSemEventMultiWaitEx(hSem,
179 RTSEMWAIT_FLAGS_RESUME | RTSEMWAIT_FLAGS_MILLISECS | RTSEMWAIT_FLAGS_ABSOLUTE,
180 _1M),
181 VINF_SUCCESS);
182 RTTESTI_CHECK_RC_RETV(RTSemEventMultiWaitEx(hSem,
183 RTSEMWAIT_FLAGS_RESUME | RTSEMWAIT_FLAGS_MILLISECS | RTSEMWAIT_FLAGS_ABSOLUTE,
184 UINT64_MAX),
185 VINF_SUCCESS);
186#endif
187}
188
189
190static void testBasics(void)
191{
192 RTTestISub("Basics");
193
194 RTSEMEVENTMULTI hSem;
195 RTTESTI_CHECK_RC_RETV(RTSemEventMultiCreate(&hSem), VINF_SUCCESS);
196
197 /* The semaphore is created in a reset state, calling reset explicitly
198 shouldn't make any difference. */
199 testBasicsWaitTimeout(hSem, 0);
200 RTTESTI_CHECK_RC_RETV(RTSemEventMultiReset(hSem), VINF_SUCCESS);
201 testBasicsWaitTimeout(hSem, 1);
202 if (RTTestIErrorCount())
203 return;
204
205 /* When signalling the semaphore all successive wait calls shall
206 succeed, signalling it again should make no difference. */
207 RTTESTI_CHECK_RC_RETV(RTSemEventMultiSignal(hSem), VINF_SUCCESS);
208 testBasicsWaitSuccess(hSem, 2);
209 if (RTTestIErrorCount())
210 return;
211
212 /* After resetting it we should time out again. */
213 RTTESTI_CHECK_RC_RETV(RTSemEventMultiReset(hSem), VINF_SUCCESS);
214 testBasicsWaitTimeout(hSem, 3);
215 if (RTTestIErrorCount())
216 return;
217
218 /* The number of resets or signal calls shouldn't matter. */
219 RTTESTI_CHECK_RC_RETV(RTSemEventMultiReset(hSem), VINF_SUCCESS);
220 RTTESTI_CHECK_RC_RETV(RTSemEventMultiReset(hSem), VINF_SUCCESS);
221 RTTESTI_CHECK_RC_RETV(RTSemEventMultiReset(hSem), VINF_SUCCESS);
222 testBasicsWaitTimeout(hSem, 4);
223
224 RTTESTI_CHECK_RC_RETV(RTSemEventMultiSignal(hSem), VINF_SUCCESS);
225 RTTESTI_CHECK_RC_RETV(RTSemEventMultiSignal(hSem), VINF_SUCCESS);
226 RTTESTI_CHECK_RC_RETV(RTSemEventMultiSignal(hSem), VINF_SUCCESS);
227 RTTESTI_CHECK_RC_RETV(RTSemEventMultiSignal(hSem), VINF_SUCCESS);
228 RTTESTI_CHECK_RC_RETV(RTSemEventMultiSignal(hSem), VINF_SUCCESS);
229 testBasicsWaitSuccess(hSem, 5);
230
231 RTTESTI_CHECK_RC_RETV(RTSemEventMultiReset(hSem), VINF_SUCCESS);
232 testBasicsWaitTimeout(hSem, 6);
233
234 /* Destroy it. */
235 RTTESTI_CHECK_RC_RETV(RTSemEventMultiDestroy(hSem), VINF_SUCCESS);
236 RTTESTI_CHECK_RC_RETV(RTSemEventMultiDestroy(NIL_RTSEMEVENTMULTI), VINF_SUCCESS);
237
238 /* Whether it is reset (above), signalled or not used shouldn't matter. */
239 RTTESTI_CHECK_RC_RETV(RTSemEventMultiCreate(&hSem), VINF_SUCCESS);
240 RTTESTI_CHECK_RC_RETV(RTSemEventMultiSignal(hSem), VINF_SUCCESS);
241 RTTESTI_CHECK_RC_RETV(RTSemEventMultiDestroy(hSem), VINF_SUCCESS);
242
243 RTTESTI_CHECK_RC_RETV(RTSemEventMultiCreate(&hSem), VINF_SUCCESS);
244 RTTESTI_CHECK_RC_RETV(RTSemEventMultiDestroy(hSem), VINF_SUCCESS);
245
246 RTTestISubDone();
247}
248
249
250int main(int argc, char **argv)
251{
252 RT_NOREF_PV(argc); RT_NOREF_PV(argv);
253
254 RTEXITCODE rcExit = RTTestInitAndCreate("tstRTSemEventMulti", &g_hTest);
255 if (rcExit != RTEXITCODE_SUCCESS)
256 return rcExit;
257
258 testBasics();
259 if (!RTTestErrorCount(g_hTest))
260 {
261 test1();
262 }
263
264 return RTTestSummaryAndDestroy(g_hTest);
265}
266
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette