diff options
author | vboxsync <vboxsync@cfe28804-0f27-0410-a406-dd0f0b0b656f> | 2023-05-09 17:01:36 +0000 |
---|---|---|
committer | vboxsync <vboxsync@cfe28804-0f27-0410-a406-dd0f0b0b656f> | 2023-05-09 17:01:36 +0000 |
commit | 6a8a935afa1ddac57a55c69e819416f2454bfa73 (patch) | |
tree | a639b7ccf0ee9ca885cc89cdd0ff9d1d3df1fdb1 | |
parent | 0df60991e041246f2ac63b0c1ea89056ab039bc3 (diff) | |
download | VirtualBox-svn-6a8a935afa1ddac57a55c69e819416f2454bfa73.tar.gz |
Runtime/testcase/tstRTSemEvent: test1() queues up two threads behind a
condition variable and then sends a signal to the condition variable and
verifies that the first thread queued was awakened. This fails on
Solaris since the order in which multiple threads blocked on a condition
variable are awakened is unspecified in the default scheduling class
(SCHED_OTHER). Fixed by simplifying the test for Solaris systems to
simply send two signals and then check that both of the waiting threads
have been awakened.
git-svn-id: https://www.virtualbox.org/svn/vbox/trunk@99704 cfe28804-0f27-0410-a406-dd0f0b0b656f
-rw-r--r-- | src/VBox/Runtime/testcase/tstRTSemEvent.cpp | 31 |
1 files changed, 30 insertions, 1 deletions
diff --git a/src/VBox/Runtime/testcase/tstRTSemEvent.cpp b/src/VBox/Runtime/testcase/tstRTSemEvent.cpp index 569325f4d9f..63f7cd5f2aa 100644 --- a/src/VBox/Runtime/testcase/tstRTSemEvent.cpp +++ b/src/VBox/Runtime/testcase/tstRTSemEvent.cpp @@ -165,7 +165,7 @@ static DECLCALLBACK(int) test1Thread(RTTHREAD hThreadSelf, void *pvUser) static void test1(void) { - RTTestISub("Three threads"); + RTTestISub("Two threads"); /* * Create the threads and let them block on the event semaphore one @@ -184,6 +184,34 @@ static void test1(void) RTTESTI_CHECK_RC_RETV(RTThreadUserWait(hThread2, RT_MS_30SEC), VINF_SUCCESS); RTThreadSleep(256); +#if defined(RT_OS_SOLARIS) + /* + * The Single UNIX Specification v2 states: "If more than one thread is blocked on a + * condition variable, the scheduling policy determines the order in which threads + * are unblocked." On Solaris, the default scheduling policy, SCHED_OTHER, does not + * specify the order in which multiple threads blocked on a condition variable are + * awakened. Thus we can't guarantee which thread will wake up when the condition + * variable is signalled so instead of verifying the order of thread wakeup we + * simply verify that two signals wake both threads. + */ + /* Signal twice to wake up both threads */ + RTTESTI_CHECK_RC(RTSemEventSignal(hSem), VINF_SUCCESS); + RTThreadSleep(256); + RTTESTI_CHECK_RC(RTSemEventSignal(hSem), VINF_SUCCESS); + + RTTESTI_CHECK_RC(RTThreadWait(hThread1, 5000, NULL), VINF_SUCCESS); + RTTESTI_CHECK_RC(RTThreadWait(hThread2, 5000, NULL), VINF_SUCCESS); +#else + /* + * The Linux sched(7) man page states: "SCHED_OTHER is the standard Linux + * time-sharing scheduler ... the thread chosen to run is based on a dynamic + * priority that ... is based on the nice value and is increased for each time + * quantum the thread is ready to run, but denied to run by the scheduler." This + * means that in practice the thread blocked longest on the condition variable will + * be awakened first and thus we can verify the ordering below. FreeBSD and macOS + * don't seem to document their implementations for this scenario but empirically + * they behave similar to Linux. + */ /* Signal once, hopefully waking up thread1: */ RTTESTI_CHECK_RC(RTSemEventSignal(hSem), VINF_SUCCESS); RTTESTI_CHECK_RC(RTThreadWait(hThread1, 5000, NULL), VINF_SUCCESS); @@ -191,6 +219,7 @@ static void test1(void) /* Signal once more, hopefully waking up thread2: */ RTTESTI_CHECK_RC(RTSemEventSignal(hSem), VINF_SUCCESS); RTTESTI_CHECK_RC(RTThreadWait(hThread2, 5000, NULL), VINF_SUCCESS); +#endif RTTESTI_CHECK_RC(RTSemEventDestroy(hSem), VINF_SUCCESS); } |