VirtualBox

Changeset 28472 in vbox for trunk/src/VBox/Runtime


Ignore:
Timestamp:
Apr 19, 2010 2:59:33 PM (15 years ago)
Author:
vboxsync
Message:

tstRTR0SemMutex: More tests.

Location:
trunk/src/VBox/Runtime/testcase
Files:
3 edited

Legend:

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

    r28462 r28472  
    3535
    3636#include <iprt/err.h>
     37#include <VBox/sup.h>
     38#include <iprt/string.h>
    3739#include <iprt/time.h>
    38 #include <iprt/string.h>
    39 #include <VBox/sup.h>
     40#include <iprt/thread.h>
    4041#include "tstRTR0SemMutex.h"
     42
     43
     44/*******************************************************************************
     45*   Global Variables                                                           *
     46*******************************************************************************/
     47/** The mutex used in test #2. */
     48static RTSEMMUTEX g_hMtxTest2 = NIL_RTSEMMUTEX;
    4149
    4250
     
    5361                                             uint64_t u64Arg, PSUPR0SERVICEREQHDR pReqHdr)
    5462{
    55     if (u64Arg)
    56         return VERR_INVALID_PARAMETER;
    5763    if (!VALID_PTR(pReqHdr))
    5864        return VERR_INVALID_PARAMETER;
     
    7480        }
    7581
     82    /*
     83     * Set up test timeout (when applicable).
     84     */
     85    if (u64Arg > 120)
     86    {
     87        SET_ERROR1("Timeout is too large (max 120): %lld",  u64Arg);
     88        return VINF_SUCCESS;
     89    }
     90    uint64_t const  StartTS = RTTimeSystemMilliTS();
     91    uint32_t const  cMsMax  = (uint32_t)u64Arg * 1000;
    7692
    7793    /*
    7894     * The big switch.
    7995     */
    80     RTSEMMUTEX  hMtx;
    81     int         rc;
     96    RTSEMMUTEX      hMtx;
     97    int             rc;
    8298    switch (uOperation)
    8399    {
     
    178194            break;
    179195
     196        case TSTRTR0SEMMUTEX_TEST2_SETUP:
     197        case TSTRTR0SEMMUTEX_TEST3_SETUP:
     198        case TSTRTR0SEMMUTEX_TEST4_SETUP:
     199            rc = RTSemMutexCreate(&g_hMtxTest2);
     200            CHECK_RC_BREAK(rc, VINF_SUCCESS, "RTSemMutexCreate");
     201            break;
     202
     203        case TSTRTR0SEMMUTEX_TEST2_DO:
     204            for (unsigned i = 0; i < 200; i++)
     205            {
     206                if (i & 1)
     207                {
     208                    rc = RTSemMutexRequestNoResume(g_hMtxTest2, RT_INDEFINITE_WAIT);
     209                    CHECK_RC_BREAK(rc, VINF_SUCCESS, "RTSemMutexRequestNoResume(,indef_wait)");
     210                }
     211                else
     212                {
     213                    rc = RTSemMutexRequestNoResume(g_hMtxTest2, 30000);
     214                    CHECK_RC_BREAK(rc, VINF_SUCCESS, "RTSemMutexRequestNoResume(,30000)");
     215                }
     216                RTThreadSleep(1);
     217                rc = RTSemMutexRelease(g_hMtxTest2);
     218                CHECK_RC_BREAK(rc, VINF_SUCCESS, "RTSemMutexRelease");
     219
     220                if ((i % 16) == 15 && RTTimeSystemMilliTS() - StartTS >= cMsMax)
     221                    break;
     222            }
     223            break;
     224
     225
     226        case TSTRTR0SEMMUTEX_TEST3_DO:
     227            for (unsigned i = 0; i < 1000000; i++)
     228            {
     229                if (i & 1)
     230                {
     231                    rc = RTSemMutexRequestNoResume(g_hMtxTest2, RT_INDEFINITE_WAIT);
     232                    CHECK_RC_BREAK(rc, VINF_SUCCESS, "RTSemMutexRequestNoResume(,indef_wait)");
     233                }
     234                else
     235                {
     236                    rc = RTSemMutexRequestNoResume(g_hMtxTest2, 30000);
     237                    CHECK_RC_BREAK(rc, VINF_SUCCESS, "RTSemMutexRequestNoResume(,30000)");
     238                }
     239                rc = RTSemMutexRelease(g_hMtxTest2);
     240                CHECK_RC_BREAK(rc, VINF_SUCCESS, "RTSemMutexRelease");
     241
     242                if ((i % 256) == 255 && RTTimeSystemMilliTS() - StartTS >= cMsMax)
     243                    break;
     244            }
     245            break;
     246
     247        case TSTRTR0SEMMUTEX_TEST4_DO:
     248            for (unsigned i = 0; i < 1024; i++)
     249            {
     250                rc = RTSemMutexRequestNoResume(g_hMtxTest2, (i % 32));
     251                if (rc != VERR_TIMEOUT)
     252                {
     253                    CHECK_RC_BREAK(rc, VINF_SUCCESS, "RTSemMutexRequestNoResume");
     254                    RTThreadSleep(1000);
     255
     256                    rc = RTSemMutexRelease(g_hMtxTest2);
     257                    CHECK_RC_BREAK(rc, VINF_SUCCESS, "RTSemMutexRelease");
     258                }
     259
     260                if (RTTimeSystemMilliTS() - StartTS >= cMsMax)
     261                    break;
     262            }
     263            break;
     264
     265        case TSTRTR0SEMMUTEX_TEST2_CLEANUP:
     266        case TSTRTR0SEMMUTEX_TEST3_CLEANUP:
     267        case TSTRTR0SEMMUTEX_TEST4_CLEANUP:
     268            rc = RTSemMutexDestroy(g_hMtxTest2);
     269            CHECK_RC_BREAK(rc, VINF_SUCCESS, "RTSemMutexCreate");
     270            g_hMtxTest2 = NIL_RTSEMMUTEX;
     271            break;
     272
     273
    180274        default:
    181275            SET_ERROR1("Unknown test #%d", uOperation);
  • trunk/src/VBox/Runtime/testcase/tstRTR0SemMutex.h

    r28462 r28472  
    4040    TSTRTR0SEMMUTEX_SANITY_OK = 1,
    4141    TSTRTR0SEMMUTEX_SANITY_FAILURE,
    42     TSTRTR0SEMMUTEX_BASIC
     42    TSTRTR0SEMMUTEX_BASIC,
     43    TSTRTR0SEMMUTEX_TEST2_SETUP,
     44    TSTRTR0SEMMUTEX_TEST2_DO,
     45    TSTRTR0SEMMUTEX_TEST2_CLEANUP,
     46    TSTRTR0SEMMUTEX_TEST3_SETUP,
     47    TSTRTR0SEMMUTEX_TEST3_DO,
     48    TSTRTR0SEMMUTEX_TEST3_CLEANUP,
     49    TSTRTR0SEMMUTEX_TEST4_SETUP,
     50    TSTRTR0SEMMUTEX_TEST4_DO,
     51    TSTRTR0SEMMUTEX_TEST4_CLEANUP
    4352} TSTRTR0SEMMUTEX;
    4453
  • trunk/src/VBox/Runtime/testcase/tstRTR0SemMutexDriver.cpp

    r28462 r28472  
    4646#endif
    4747
     48/*******************************************************************************
     49*   Structures and Typedefs                                                    *
     50*******************************************************************************/
     51typedef struct TSTRTR0SEMMUTEXREQ
     52{
     53    SUPR0SERVICEREQHDR  Hdr;
     54    char                szMsg[256];
     55} TSTRTR0SEMMUTEXREQ;
     56typedef TSTRTR0SEMMUTEXREQ *PTSTRTR0SEMMUTEXREQ;
     57
     58
     59/*******************************************************************************
     60*   Global Variables                                                           *
     61*******************************************************************************/
     62static RTTEST g_hTest;
     63
     64
     65/**
     66 * Thread function employed by tstDoThreadedTest.
     67 *
     68 * @returns IPRT status code.
     69 * @param   hThreadSelf         The thread.
     70 * @param   pvUser              The operation to perform.
     71 */
     72static DECLCALLBACK(int) tstThreadFn(RTTHREAD hThreadSelf, void *pvUser)
     73{
     74    uint32_t            u32   = (uint32_t)(uintptr_t)pvUser;
     75    TSTRTR0SEMMUTEX     enmDo = (TSTRTR0SEMMUTEX)RT_LOWORD(u32);
     76    uint32_t            cSecs = RT_HIWORD(u32);
     77    TSTRTR0SEMMUTEXREQ Req;
     78    RT_ZERO(Req);
     79    Req.Hdr.u32Magic = SUPR0SERVICEREQHDR_MAGIC;
     80    Req.Hdr.cbReq = sizeof(Req);
     81    Req.szMsg[0] = '\0';
     82    RTTEST_CHECK_RC_RET(g_hTest, SUPR3CallR0Service("tstRTR0SemMutex", sizeof("tstRTR0SemMutex") - 1,
     83                                                    enmDo, cSecs, &Req.Hdr),
     84                        VINF_SUCCESS,
     85                        rcCheck);
     86    return VINF_SUCCESS;
     87}
     88
     89/**
     90 * Performs a threaded test.
     91 *
     92 * @returns true on succes, false on failure.
     93 * @param   enmSetup            The setup operation number.
     94 * @param   enmDo               The do-it operation number.
     95 * @param   enmCleanup          The cleanup operation number.
     96 * @param   cThreads            The number of threads.
     97 * @param   pReq                The request structure.
     98 * @param   pszTest             The test name.
     99 */
     100static bool tstDoThreadedTest(TSTRTR0SEMMUTEX enmSetup, TSTRTR0SEMMUTEX enmDo, TSTRTR0SEMMUTEX enmCleanup,
     101                              unsigned cThreads, unsigned cSecs, PTSTRTR0SEMMUTEXREQ pReq, const char *pszTest)
     102{
     103    RTTestSubF(g_hTest, "%s - %u threads", pszTest, cThreads);
     104    RTTHREAD ahThreads[32];
     105    RTTESTI_CHECK_RET(cThreads <= RT_ELEMENTS(ahThreads), false);
     106
     107    /*
     108     * Setup.
     109     */
     110    pReq->Hdr.u32Magic = SUPR0SERVICEREQHDR_MAGIC;
     111    pReq->Hdr.cbReq = sizeof(*pReq);
     112    pReq->szMsg[0] = '\0';
     113    RTTESTI_CHECK_RC_RET(SUPR3CallR0Service("tstRTR0SemMutex", sizeof("tstRTR0SemMutex") - 1, enmSetup, 0, &pReq->Hdr),
     114                         VINF_SUCCESS, false);
     115    if (pReq->szMsg[0] == '!')
     116        return RTTestIFailedRc(false, "%s", &pReq->szMsg[1]);
     117    if (pReq->szMsg[0])
     118        RTTestIPrintf(RTTESTLVL_ALWAYS, "%s", pReq->szMsg);
     119
     120    /*
     121     * Test execution.
     122     */
     123    for (unsigned i = 0; i < RT_ELEMENTS(ahThreads); i++)
     124        ahThreads[i] = NIL_RTTHREAD;
     125
     126    int rc = VINF_SUCCESS;
     127    for (unsigned i = 0; i < cThreads && RT_SUCCESS(rc); i++)
     128        rc = RTThreadCreateF(&ahThreads[i], tstThreadFn, (void *)(uintptr_t)RT_MAKE_U32(enmDo, cSecs), 0, RTTHREADTYPE_DEFAULT,
     129                             RTTHREADFLAGS_WAITABLE, "test-%u", i);
     130
     131    for (unsigned i = 0; i < cThreads; i++)
     132        if (ahThreads[i] != NIL_RTTHREAD)
     133        {
     134            int rcThread = VINF_SUCCESS;
     135            int rc2 = RTThreadWait(ahThreads[i], 3600*1000, &rcThread);
     136            if (RT_SUCCESS(rc2))
     137            {
     138                ahThreads[i] = NIL_RTTHREAD;
     139                if (RT_FAILURE(rcThread) && RT_SUCCESS(rc2))
     140                    rc = rcThread;
     141            }
     142            else if (RT_SUCCESS(rc))
     143                rc = rc2;
     144        }
     145
     146    /*
     147     * Cleanup.
     148     */
     149    pReq->Hdr.u32Magic = SUPR0SERVICEREQHDR_MAGIC;
     150    pReq->Hdr.cbReq = sizeof(*pReq);
     151    pReq->szMsg[0] = '\0';
     152    RTTESTI_CHECK_RC_RET(rc = SUPR3CallR0Service("tstRTR0SemMutex", sizeof("tstRTR0SemMutex") - 1, enmCleanup, 0, &pReq->Hdr),
     153                         VINF_SUCCESS, false);
     154    if (pReq->szMsg[0] == '!')
     155        return RTTestIFailedRc(false, "%s", &pReq->szMsg[1]);
     156    if (pReq->szMsg[0])
     157        RTTestIPrintf(RTTESTLVL_ALWAYS, "%s", pReq->szMsg);
     158
     159    if (RT_FAILURE(rc))
     160        for (unsigned i = 0; i < cThreads; i++)
     161            if (ahThreads[i] != NIL_RTTHREAD)
     162                RTThreadWait(ahThreads[i], 1000, NULL);
     163
     164    return RT_SUCCESS(rc);
     165}
     166
    48167
    49168int main(int argc, char **argv)
     
    57176     */
    58177    RTTEST hTest;
    59     int rc = RTTestInitAndCreate("tstR0SemMutex", &hTest);
     178    int rc = RTTestInitAndCreate("tstRTR0SemMutex", &hTest);
    60179    if (rc)
    61180        return rc;
     
    73192    rc = RTPathExecDir(szPath, sizeof(szPath));
    74193    if (RT_SUCCESS(rc))
    75         rc = RTPathAppend(szPath, sizeof(szPath), "tstR0SemMutex.r0");
     194        rc = RTPathAppend(szPath, sizeof(szPath), "tstRTR0SemMutex.r0");
    76195    if (RT_FAILURE(rc))
    77196    {
     
    81200
    82201    void *pvImageBase;
    83     rc = SUPR3LoadServiceModule(szPath, "tstR0SemMutex",
     202    rc = SUPR3LoadServiceModule(szPath, "tstRTR0SemMutex",
    84203                                "TSTRTR0SemMutexSrvReqHandler",
    85204                                &pvImageBase);
     
    91210
    92211    /* test request */
    93     struct
    94     {
    95         SUPR0SERVICEREQHDR  Hdr;
    96         char                szMsg[256];
    97     } Req;
     212    TSTRTR0SEMMUTEXREQ Req;
    98213
    99214    /*
     
    104219    Req.Hdr.cbReq = sizeof(Req);
    105220    Req.szMsg[0] = '\0';
    106     RTTESTI_CHECK_RC(rc = SUPR3CallR0Service("tstR0SemMutex", sizeof("tstR0SemMutex") - 1,
     221    RTTESTI_CHECK_RC(rc = SUPR3CallR0Service("tstRTR0SemMutex", sizeof("tstRTR0SemMutex") - 1,
    107222                                             TSTRTR0SEMMUTEX_SANITY_OK, 0, &Req.Hdr), VINF_SUCCESS);
    108223    if (RT_FAILURE(rc))
     
    115230    Req.Hdr.cbReq = sizeof(Req);
    116231    Req.szMsg[0] = '\0';
    117     RTTESTI_CHECK_RC(rc = SUPR3CallR0Service("tstR0SemMutex", sizeof("tstR0SemMutex") - 1,
     232    RTTESTI_CHECK_RC(rc = SUPR3CallR0Service("tstRTR0SemMutex", sizeof("tstRTR0SemMutex") - 1,
    118233                                             TSTRTR0SEMMUTEX_SANITY_FAILURE, 0, &Req.Hdr), VINF_SUCCESS);
    119234    if (RT_FAILURE(rc))
     
    130245    Req.Hdr.cbReq = sizeof(Req);
    131246    Req.szMsg[0] = '\0';
    132     RTTESTI_CHECK_RC(rc = SUPR3CallR0Service("tstR0SemMutex", sizeof("tstR0SemMutex") - 1,
     247    RTTESTI_CHECK_RC(rc = SUPR3CallR0Service("tstRTR0SemMutex", sizeof("tstRTR0SemMutex") - 1,
    133248                                             TSTRTR0SEMMUTEX_BASIC, 0, &Req.Hdr), VINF_SUCCESS);
    134249    if (RT_FAILURE(rc))
     
    143258
    144259    /*
    145      * More to come
    146      */
     260     * Tests with multiple threads for bugs in the contention part of the code.
     261     *     Test #2: Try to hold the semaphore for 1 ms.
     262     *     Test #3: Grab and release immediately.
     263     *     Test #4: Timeout checks. Try grab it for 0-32 ms and hold it for 1 s.
     264     */
     265    tstDoThreadedTest(TSTRTR0SEMMUTEX_TEST2_SETUP, TSTRTR0SEMMUTEX_TEST2_DO, TSTRTR0SEMMUTEX_TEST2_CLEANUP, 1, 1, &Req, "test #2");
     266    tstDoThreadedTest(TSTRTR0SEMMUTEX_TEST2_SETUP, TSTRTR0SEMMUTEX_TEST2_DO, TSTRTR0SEMMUTEX_TEST2_CLEANUP, 2, 3, &Req, "test #2");
     267    tstDoThreadedTest(TSTRTR0SEMMUTEX_TEST2_SETUP, TSTRTR0SEMMUTEX_TEST2_DO, TSTRTR0SEMMUTEX_TEST2_CLEANUP, 3, 3, &Req, "test #2");
     268    tstDoThreadedTest(TSTRTR0SEMMUTEX_TEST2_SETUP, TSTRTR0SEMMUTEX_TEST2_DO, TSTRTR0SEMMUTEX_TEST2_CLEANUP, 9, 3, &Req, "test #2");
     269
     270    tstDoThreadedTest(TSTRTR0SEMMUTEX_TEST3_SETUP, TSTRTR0SEMMUTEX_TEST3_DO, TSTRTR0SEMMUTEX_TEST3_CLEANUP, 1, 1, &Req, "test #3");
     271    tstDoThreadedTest(TSTRTR0SEMMUTEX_TEST3_SETUP, TSTRTR0SEMMUTEX_TEST3_DO, TSTRTR0SEMMUTEX_TEST3_CLEANUP, 2, 3, &Req, "test #3");
     272    tstDoThreadedTest(TSTRTR0SEMMUTEX_TEST3_SETUP, TSTRTR0SEMMUTEX_TEST3_DO, TSTRTR0SEMMUTEX_TEST3_CLEANUP, 3, 3, &Req, "test #3");
     273    tstDoThreadedTest(TSTRTR0SEMMUTEX_TEST3_SETUP, TSTRTR0SEMMUTEX_TEST3_DO, TSTRTR0SEMMUTEX_TEST3_CLEANUP, 9, 3, &Req, "test #3");
     274
     275    tstDoThreadedTest(TSTRTR0SEMMUTEX_TEST4_SETUP, TSTRTR0SEMMUTEX_TEST4_DO, TSTRTR0SEMMUTEX_TEST4_CLEANUP, 1, 1, &Req, "test #4");
     276    tstDoThreadedTest(TSTRTR0SEMMUTEX_TEST4_SETUP, TSTRTR0SEMMUTEX_TEST4_DO, TSTRTR0SEMMUTEX_TEST4_CLEANUP, 2, 3, &Req, "test #4");
     277    tstDoThreadedTest(TSTRTR0SEMMUTEX_TEST4_SETUP, TSTRTR0SEMMUTEX_TEST4_DO, TSTRTR0SEMMUTEX_TEST4_CLEANUP, 3, 3, &Req, "test #4");
     278    tstDoThreadedTest(TSTRTR0SEMMUTEX_TEST4_SETUP, TSTRTR0SEMMUTEX_TEST4_DO, TSTRTR0SEMMUTEX_TEST4_CLEANUP, 9, 3, &Req, "test #4");
    147279
    148280    /*
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