VirtualBox

Ignore:
Timestamp:
Oct 6, 2010 2:21:29 PM (14 years ago)
Author:
vboxsync
Message:

iprt/semaphore.h: Started adding RTSem*<Wait|Request>Ex[Debug].

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/testcase/tstSemEvent.cpp

    r28800 r32946  
    2525 */
    2626
     27
    2728/*******************************************************************************
    2829*   Header Files                                                               *
    2930*******************************************************************************/
    3031#include <iprt/semaphore.h>
    31 #include <iprt/string.h>
    32 #include <iprt/thread.h>
    33 #include <iprt/stream.h>
    34 #include <iprt/time.h>
    35 #include <iprt/initterm.h>
    36 #include <iprt/rand.h>
     32
    3733#include <iprt/asm.h>
    3834#include <iprt/assert.h>
     35#include <iprt/rand.h>
     36#include <iprt/stream.h>
     37#include <iprt/string.h>
     38#include <iprt/test.h>
     39#include <iprt/thread.h>
     40#include <iprt/time.h>
    3941
    4042
     
    4244*   Global Variables                                                           *
    4345*******************************************************************************/
    44 static RTSEMEVENTMULTI      g_hSemEM = NIL_RTSEMEVENTMULTI;
    45 static uint32_t volatile    g_cErrors;
    46 
    47 
    48 int PrintError(const char *pszFormat, ...)
    49 {
    50     ASMAtomicIncU32(&g_cErrors);
    51 
    52     RTPrintf("tstSemEvent: FAILURE - ");
    53     va_list va;
    54     va_start(va, pszFormat);
    55     RTPrintfV(pszFormat, va);
    56     va_end(va);
    57 
    58     return 1;
    59 }
    60 
    61 
    62 int ThreadTest1(RTTHREAD ThreadSelf, void *pvUser)
    63 {
    64     int rc;
    65     rc = RTSemEventMultiWait(g_hSemEM, 1000);
    66     if (rc != VERR_TIMEOUT)
    67     {
    68         PrintError("Thread 1: unexpected result of first RTSemEventMultiWait %Rrc\n", rc);
    69         return VINF_SUCCESS;
    70     }
    71 
    72     rc = RTSemEventMultiWait(g_hSemEM, 1000);
    73     if (RT_FAILURE(rc))
    74     {
    75         PrintError("Thread 1: unexpected result of second RTSemEventMultiWait %Rrc\n", rc);
    76         return VINF_SUCCESS;
    77     }
    78 
    79     RTPrintf("tstSemEvent: Thread 1 normal exit...\n");
     46/** The test handle. */
     47static RTTEST  g_hTest;
     48
     49
     50static DECLCALLBACK(int) test1Thread1(RTTHREAD ThreadSelf, void *pvUser)
     51{
     52    RTSEMEVENTMULTI hSem = *(PRTSEMEVENTMULTI)pvUser;
     53
     54    uint64_t u64 = RTTimeSystemMilliTS();
     55    RTTEST_CHECK_RC_RET(g_hTest, RTSemEventMultiWait(hSem, 1000), VERR_TIMEOUT, rcCheck);
     56    u64 = RTTimeSystemMilliTS() - u64;
     57    RTTEST_CHECK_MSG(g_hTest, u64 < 1500 && u64 > 950, (g_hTest, "u64=%llu\n", u64));
     58
     59    RTTEST_CHECK_RC_RET(g_hTest, RTSemEventMultiWait(hSem, 2000), VINF_SUCCESS, rcCheck);
    8060    return VINF_SUCCESS;
    8161}
    8262
    8363
    84 int ThreadTest2(RTTHREAD ThreadSelf, void *pvUser)
    85 {
    86     int rc;
    87     rc = RTSemEventMultiWait(g_hSemEM, RT_INDEFINITE_WAIT);
    88     if (RT_FAILURE(rc))
    89     {
    90         PrintError("Thread 2: unexpected result of RTSemEventMultiWait %Rrc\n", rc);
    91         return VINF_SUCCESS;
    92     }
    93 
    94     RTPrintf("tstSemEvent: Thread 2 normal exit...\n");
     64static DECLCALLBACK(int) test1Thread2(RTTHREAD ThreadSelf, void *pvUser)
     65{
     66    RTSEMEVENTMULTI hSem = *(PRTSEMEVENTMULTI)pvUser;
     67    RTTEST_CHECK_RC_RET(g_hTest, RTSemEventMultiWait(hSem, RT_INDEFINITE_WAIT), VINF_SUCCESS, rcCheck);
    9568    return VINF_SUCCESS;
    9669}
    9770
    9871
    99 static int Test1()
    100 {
    101     int rc;
    102     RTTHREAD Thread1, Thread2;
    103 
    104     rc = RTSemEventMultiCreate(&g_hSemEM);
    105     if (RT_FAILURE(rc))
    106         return PrintError("RTSemEventMultiCreate failed (rc=%Rrc)\n", rc);
     72static void test1(void)
     73{
     74    RTTestISub("Three threads");
    10775
    10876    /*
    10977     * Create the threads and let them block on the event multi semaphore.
    11078     */
    111     rc = RTSemEventMultiReset(g_hSemEM);
    112     if (RT_FAILURE(rc))
    113         return PrintError("RTSemEventMultiReset failed (rc=%Rrc)\n", rc);
    114 
    115     rc = RTThreadCreate(&Thread2, ThreadTest2, NULL, 0, RTTHREADTYPE_DEFAULT, RTTHREADFLAGS_WAITABLE, "test2");
    116     if (RT_FAILURE(rc))
    117         return PrintError("RTThreadCreate failed for thread 2 (rc=%Rrc)\n", rc);
     79    RTSEMEVENTMULTI hSem;
     80    RTTESTI_CHECK_RC_RETV(RTSemEventMultiCreate(&hSem), VINF_SUCCESS);
     81
     82    RTTHREAD hThread2;
     83    RTTESTI_CHECK_RC_RETV(RTThreadCreate(&hThread2, test1Thread2, &hSem, 0, RTTHREADTYPE_DEFAULT, RTTHREADFLAGS_WAITABLE, "test2"), VINF_SUCCESS);
    11884    RTThreadSleep(100);
    11985
    120     rc = RTThreadCreate(&Thread1, ThreadTest1, NULL, 0, RTTHREADTYPE_DEFAULT, RTTHREADFLAGS_WAITABLE, "test1");
    121     if (RT_FAILURE(rc))
    122         return PrintError("RTThreadCreate failed for thread 1 (rc=%Rrc)\n", rc);
     86    RTTHREAD hThread1;
     87    RTTESTI_CHECK_RC_RETV(RTThreadCreate(&hThread1, test1Thread1, &hSem, 0, RTTHREADTYPE_DEFAULT, RTTHREADFLAGS_WAITABLE, "test1"), VINF_SUCCESS);
    12388
    12489    /* Force first thread (which has a timeout of 1 second) to timeout in the
    12590     * first wait, and the second wait will succeed. */
    126     RTThreadSleep(1500);
    127     rc = RTSemEventMultiSignal(g_hSemEM);
    128     if (RT_FAILURE(rc))
    129         PrintError("RTSemEventMultiSignal failed (rc=%Rrc)\n", rc);
    130 
    131     rc = RTThreadWait(Thread1, 5000, NULL);
    132     if (RT_FAILURE(rc))
    133         PrintError("RTThreadWait failed for thread 1 (rc=%Rrc)\n", rc);
    134 
    135     rc = RTThreadWait(Thread2, 5000, NULL);
    136     if (RT_FAILURE(rc))
    137         PrintError("RTThreadWait failed for thread 2 (rc=%Rrc)\n", rc);
    138 
    139     rc = RTSemEventMultiDestroy(g_hSemEM);
    140     if (RT_FAILURE(rc))
    141         PrintError("RTSemEventMultiDestroy failed - %Rrc\n", rc);
    142     g_hSemEM = NIL_RTSEMEVENTMULTI;
    143     if (g_cErrors)
    144         RTThreadSleep(100);
    145     return 0;
     91    RTTESTI_CHECK_RC(RTThreadSleep(1500), VINF_SUCCESS);
     92    RTTESTI_CHECK_RC(RTSemEventMultiSignal(hSem), VINF_SUCCESS);
     93    RTTESTI_CHECK_RC(RTThreadWait(hThread1, 5000, NULL), VINF_SUCCESS);
     94    RTTESTI_CHECK_RC(RTThreadWait(hThread2, 5000, NULL), VINF_SUCCESS);
     95    RTTESTI_CHECK_RC(RTSemEventMultiDestroy(hSem), VINF_SUCCESS);
     96}
     97
     98
     99static void testBasicsWaitTimeout(RTSEMEVENTMULTI hSem, unsigned i)
     100{
     101    RTTESTI_CHECK_RC_RETV(RTSemEventMultiWait(hSem, 0), VERR_TIMEOUT);
     102#if 1
     103    RTTESTI_CHECK_RC_RETV(RTSemEventMultiWaitNoResume(hSem, 0), VERR_TIMEOUT);
     104#else
     105    RTTESTI_CHECK_RC_RETV(RTSemEventMultiWaitEx(hSem,
     106                                                RTSEMWAIT_FLAGS_RESUME | RTSEMWAIT_FLAGS_NANOSECS | RTSEMWAIT_FLAGS_RELATIVE,
     107                                                0),
     108                          VERR_TIMEOUT);
     109    RTTESTI_CHECK_RC_RETV(RTSemEventMultiWaitEx(hSem,
     110                                                RTSEMWAIT_FLAGS_RESUME | RTSEMWAIT_FLAGS_NANOSECS | RTSEMWAIT_FLAGS_ABSOLUTE,
     111                                                RTTimeSystemNanoTS() + 1000*i),
     112                          VERR_TIMEOUT);
     113    RTTESTI_CHECK_RC_RETV(RTSemEventMultiWaitEx(hSem,
     114                                                RTSEMWAIT_FLAGS_RESUME | RTSEMWAIT_FLAGS_NANOSECS | RTSEMWAIT_FLAGS_ABSOLUTE,
     115                                                RTTimeNanoTS() + 1000*i),
     116                          VERR_TIMEOUT);
     117
     118    RTTESTI_CHECK_RC_RETV(RTSemEventMultiWaitEx(hSem,
     119                                                RTSEMWAIT_FLAGS_RESUME | RTSEMWAIT_FLAGS_MILLISECS | RTSEMWAIT_FLAGS_RELATIVE,
     120                                                0),
     121                          VERR_TIMEOUT);
     122#endif
     123}
     124
     125
     126static void testBasicsWaitSuccess(RTSEMEVENTMULTI hSem, unsigned i)
     127{
     128    RTTESTI_CHECK_RC_RETV(RTSemEventMultiWait(hSem, 0), VINF_SUCCESS);
     129    RTTESTI_CHECK_RC_RETV(RTSemEventMultiWait(hSem, RT_INDEFINITE_WAIT), VINF_SUCCESS);
     130#if 1
     131    RTTESTI_CHECK_RC_RETV(RTSemEventMultiWaitNoResume(hSem, 0), VINF_SUCCESS);
     132    RTTESTI_CHECK_RC_RETV(RTSemEventMultiWaitNoResume(hSem, RT_INDEFINITE_WAIT), VINF_SUCCESS);
     133#else
     134    RTTESTI_CHECK_RC_RETV(RTSemEventMultiWaitEx(hSem,
     135                                                RTSEMWAIT_FLAGS_RESUME | RTSEMWAIT_FLAGS_NANOSECS | RTSEMWAIT_FLAGS_RELATIVE,
     136                                                0),
     137                          VINF_SUCCESS);
     138    RTTESTI_CHECK_RC_RETV(RTSemEventMultiWaitEx(hSem, RTSEMWAIT_FLAGS_RESUME   | RTSEMWAIT_FLAGS_INDEFINITE, 0), VINF_SUCCESS);
     139    RTTESTI_CHECK_RC_RETV(RTSemEventMultiWaitEx(hSem, RTSEMWAIT_FLAGS_NORESUME | RTSEMWAIT_FLAGS_INDEFINITE, 0), VINF_SUCCESS);
     140    RTTESTI_CHECK_RC_RETV(RTSemEventMultiWaitEx(hSem,
     141                                                RTSEMWAIT_FLAGS_RESUME | RTSEMWAIT_FLAGS_NANOSECS | RTSEMWAIT_FLAGS_ABSOLUTE,
     142                                                RTTimeSystemNanoTS() + 1000*i),
     143                          VINF_SUCCESS);
     144    RTTESTI_CHECK_RC_RETV(RTSemEventMultiWaitEx(hSem,
     145                                                RTSEMWAIT_FLAGS_RESUME | RTSEMWAIT_FLAGS_NANOSECS | RTSEMWAIT_FLAGS_ABSOLUTE,
     146                                                RTTimeNanoTS() + 1000*i),
     147                          VINF_SUCCESS);
     148    RTTESTI_CHECK_RC_RETV(RTSemEventMultiWaitEx(hSem,
     149                                                RTSEMWAIT_FLAGS_RESUME | RTSEMWAIT_FLAGS_NANOSECS | RTSEMWAIT_FLAGS_ABSOLUTE,
     150                                                0),
     151                          VINF_SUCCESS);
     152    RTTESTI_CHECK_RC_RETV(RTSemEventMultiWaitEx(hSem,
     153                                                RTSEMWAIT_FLAGS_RESUME | RTSEMWAIT_FLAGS_NANOSECS | RTSEMWAIT_FLAGS_ABSOLUTE,
     154                                                _1G),
     155                          VINF_SUCCESS);
     156    RTTESTI_CHECK_RC_RETV(RTSemEventMultiWaitEx(hSem,
     157                                                RTSEMWAIT_FLAGS_RESUME | RTSEMWAIT_FLAGS_NANOSECS | RTSEMWAIT_FLAGS_ABSOLUTE,
     158                                                UINT64_MAX),
     159                          VINF_SUCCESS);
     160
     161
     162    RTTESTI_CHECK_RC_RETV(RTSemEventMultiWaitEx(hSem,
     163                                                RTSEMWAIT_FLAGS_RESUME | RTSEMWAIT_FLAGS_MILLISECS | RTSEMWAIT_FLAGS_ABSOLUTE,
     164                                                RTTimeSystemMilliTS() + 1000*i),
     165                          VINF_SUCCESS);
     166    RTTESTI_CHECK_RC_RETV(RTSemEventMultiWaitEx(hSem,
     167                                                RTSEMWAIT_FLAGS_RESUME | RTSEMWAIT_FLAGS_MILLISECS | RTSEMWAIT_FLAGS_ABSOLUTE,
     168                                                RTTimeMilliTS() + 1000*i),
     169                          VINF_SUCCESS);
     170    RTTESTI_CHECK_RC_RETV(RTSemEventMultiWaitEx(hSem,
     171                                                RTSEMWAIT_FLAGS_RESUME | RTSEMWAIT_FLAGS_MILLISECS | RTSEMWAIT_FLAGS_ABSOLUTE,
     172                                                0),
     173                          VINF_SUCCESS);
     174    RTTESTI_CHECK_RC_RETV(RTSemEventMultiWaitEx(hSem,
     175                                                RTSEMWAIT_FLAGS_RESUME | RTSEMWAIT_FLAGS_MILLISECS | RTSEMWAIT_FLAGS_ABSOLUTE,
     176                                                _1M),
     177                          VINF_SUCCESS);
     178    RTTESTI_CHECK_RC_RETV(RTSemEventMultiWaitEx(hSem,
     179                                                RTSEMWAIT_FLAGS_RESUME | RTSEMWAIT_FLAGS_MILLISECS | RTSEMWAIT_FLAGS_ABSOLUTE,
     180                                                UINT64_MAX),
     181                          VINF_SUCCESS);
     182#endif
     183}
     184
     185
     186static void testBasics(void)
     187{
     188    RTTestISub("Basics");
     189
     190    RTSEMEVENTMULTI hSem;
     191    RTTESTI_CHECK_RC_RETV(RTSemEventMultiCreate(&hSem), VINF_SUCCESS);
     192
     193    /* The semaphore is created in a reset state, calling reset explicitly
     194       shouldn't make any difference. */
     195    testBasicsWaitTimeout(hSem, 0);
     196    RTTESTI_CHECK_RC_RETV(RTSemEventMultiReset(hSem), VINF_SUCCESS);
     197    testBasicsWaitTimeout(hSem, 1);
     198    if (RTTestIErrorCount())
     199        return;
     200
     201    /* When signalling the semaphore all successive wait calls shall
     202       succeed, signalling it again should make no difference. */
     203    RTTESTI_CHECK_RC_RETV(RTSemEventMultiSignal(hSem), VINF_SUCCESS);
     204    testBasicsWaitSuccess(hSem, 2);
     205    if (RTTestIErrorCount())
     206        return;
     207
     208    /* After resetting it we should time out again. */
     209    RTTESTI_CHECK_RC_RETV(RTSemEventMultiReset(hSem), VINF_SUCCESS);
     210    testBasicsWaitTimeout(hSem, 3);
     211    if (RTTestIErrorCount())
     212        return;
     213
     214    /* The number of resets or signal calls shouldn't matter. */
     215    RTTESTI_CHECK_RC_RETV(RTSemEventMultiReset(hSem), VINF_SUCCESS);
     216    RTTESTI_CHECK_RC_RETV(RTSemEventMultiReset(hSem), VINF_SUCCESS);
     217    RTTESTI_CHECK_RC_RETV(RTSemEventMultiReset(hSem), VINF_SUCCESS);
     218    testBasicsWaitTimeout(hSem, 4);
     219
     220    RTTESTI_CHECK_RC_RETV(RTSemEventMultiSignal(hSem), VINF_SUCCESS);
     221    RTTESTI_CHECK_RC_RETV(RTSemEventMultiSignal(hSem), VINF_SUCCESS);
     222    RTTESTI_CHECK_RC_RETV(RTSemEventMultiSignal(hSem), VINF_SUCCESS);
     223    RTTESTI_CHECK_RC_RETV(RTSemEventMultiSignal(hSem), VINF_SUCCESS);
     224    RTTESTI_CHECK_RC_RETV(RTSemEventMultiSignal(hSem), VINF_SUCCESS);
     225    testBasicsWaitSuccess(hSem, 5);
     226
     227    RTTESTI_CHECK_RC_RETV(RTSemEventMultiReset(hSem), VINF_SUCCESS);
     228    testBasicsWaitTimeout(hSem, 6);
     229
     230    /* Destroy it. */
     231    RTTESTI_CHECK_RC_RETV(RTSemEventMultiDestroy(hSem), VINF_SUCCESS);
     232    RTTESTI_CHECK_RC_RETV(RTSemEventMultiDestroy(NIL_RTSEMEVENTMULTI), VINF_SUCCESS);
     233
     234    /* Whether it is reset (above), signalled or not used shouldn't matter.  */
     235    RTTESTI_CHECK_RC_RETV(RTSemEventMultiCreate(&hSem), VINF_SUCCESS);
     236    RTTESTI_CHECK_RC_RETV(RTSemEventMultiSignal(hSem), VINF_SUCCESS);
     237    RTTESTI_CHECK_RC_RETV(RTSemEventMultiDestroy(hSem), VINF_SUCCESS);
     238
     239    RTTESTI_CHECK_RC_RETV(RTSemEventMultiCreate(&hSem), VINF_SUCCESS);
     240    RTTESTI_CHECK_RC_RETV(RTSemEventMultiDestroy(hSem), VINF_SUCCESS);
     241
     242    RTTestISubDone();
    146243}
    147244
     
    149246int main(int argc, char **argv)
    150247{
    151     int rc = RTR3Init();
    152     if (RT_FAILURE(rc))
     248    RTEXITCODE rcExit = RTTestInitAndCreate("tstSemEventMulti", &g_hTest);
     249    if (rcExit != RTEXITCODE_SUCCESS)
     250        return rcExit;
     251
     252    testBasics();
     253    if (!RTTestErrorCount(g_hTest))
    153254    {
    154         RTPrintf("tstSemEvent: RTR3Init failed (rc=%Rrc)\n", rc);
    155         return 1;
     255        test1();
    156256    }
    157     RTPrintf("tstSemEvent: TESTING...\n");
    158     Test1();
    159 
    160     if (!g_cErrors)
    161         RTPrintf("tstSemEvent: SUCCESS\n");
    162     else
    163         RTPrintf("tstSemEvent: FAILURE - %u errors\n", g_cErrors);
    164     return g_cErrors != 0;
    165 }
    166 
     257
     258    return RTTestSummaryAndDestroy(g_hTest);
     259}
     260
Note: See TracChangeset for help on using the changeset viewer.

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