VirtualBox

Changeset 45520 in vbox for trunk/src


Ignore:
Timestamp:
Apr 12, 2013 2:22:41 PM (12 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
84998
Message:

iprt/cpp/list.h,iprt/cpp/mtlist.h: Added assertions for index out of range conditions and tried to force those cases to have predictable non-destructive behavior. (Not possible when indexing an empty list, unfortunately.) Fixed RTMemRealloc bugs. Added missing read locking. Also changed the testcase to not wait forever in the multithreaded test2() function.

File:
1 edited

Legend:

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

    r37861 r45520  
    3434#include <iprt/rand.h>
    3535#include <iprt/thread.h>
     36#include <iprt/time.h>
    3637
    3738
     
    166167    L<T1, T2> testList;
    167168
    168     const size_t defCap = L<T1, T2>::DefaultCapacity;
     169    const size_t defCap = L<T1, T2>::kDefaultCapacity;
    169170    RTTESTI_CHECK(testList.isEmpty());
    170171    RTTESTI_CHECK(testList.size()     == 0);
     
    376377    RTTESTI_CHECK(testList5.capacity()  == 0);
    377378
     379    /*
     380     * Negative testing.
     381     */
     382    bool fMayPanic = RTAssertMayPanic();
     383    bool fQuiet    = RTAssertAreQuiet();
     384    RTAssertSetMayPanic(false);
     385    RTAssertSetQuiet(true);
     386
     387    L<T1, T2> testList6;
     388    for (size_t i = 0; i < cTestItems; ++i)
     389        testList6.insert(i, paTestData[i]);
     390    RTTESTI_CHECK(testList6.size() == cTestItems);
     391
     392    /* Insertion beyond the end of the array ends up at the end. */
     393    size_t cBefore = testList6.size();
     394    testList6.insert(cBefore + 3, paTestData[0]);
     395    RTTESTI_CHECK(testList6.size() == cBefore + 1);
     396    RTTESTI_CHECK(testList6.at(cBefore) == paTestData[0]);
     397
     398    cBefore = testList6.size();
     399    L<T1, T2> testList7(testList6);
     400    testList6.insert(testList6.size() + 42, testList7);
     401    RTTESTI_CHECK(testList6.size() == cBefore + testList7.size());
     402
     403    /* Inserting, appending or prepending a list to itself is not supported. */
     404    cBefore = testList6.size();
     405    testList6.insert(3, testList6);
     406    RTTESTI_CHECK(testList6.size() == cBefore);
     407
     408    cBefore = testList6.size();
     409    testList6.append(testList6);
     410    RTTESTI_CHECK(testList6.size() == cBefore);
     411
     412    cBefore = testList6.size();
     413    testList6.prepend(testList6);
     414    RTTESTI_CHECK(testList6.size() == cBefore);
     415
     416    /* Replace does nothing if the index is bad. */
     417    cBefore = testList6.size();
     418    testList6.replace(cBefore, testList6[6]);
     419    RTTESTI_CHECK(testList6.size() == cBefore);
     420
     421    cBefore = testList6.size();
     422    testList6.replace(cBefore + 64, testList6[6]);
     423    RTTESTI_CHECK(testList6.size() == cBefore);
     424
     425    /* Indexing beyond the array returns the last element. */
     426    cBefore = testList6.size();
     427    RTTESTI_CHECK(testList6[cBefore] == testList6.last());
     428    RTTESTI_CHECK(testList6[cBefore + 42] == testList6.last());
     429
     430    RTTESTI_CHECK(&testList6[cBefore]      == &testList6[cBefore - 1]);
     431    RTTESTI_CHECK(&testList6[cBefore + 42] == &testList6[cBefore - 1]);
     432
     433    /* removeAt does nothing if the index is bad. */
     434    cBefore = testList6.size();
     435    testList6.removeAt(cBefore);
     436    RTTESTI_CHECK(testList6.size() == cBefore);
     437
     438    cBefore = testList6.size();
     439    testList6.removeAt(cBefore + 42);
     440    RTTESTI_CHECK(testList6.size() == cBefore);
     441
     442    L<T1, T2> testListEmpty1; RTTESTI_CHECK(!testListEmpty1.size());
     443    testListEmpty1.removeFirst();
     444    RTTESTI_CHECK(!testListEmpty1.size());
     445
     446    testListEmpty1.removeLast();
     447    RTTESTI_CHECK(!testListEmpty1.size());
     448
     449    testListEmpty1.removeAt(128);
     450    RTTESTI_CHECK(!testListEmpty1.size());
     451
     452    /* removeRange interprets indexes beyond the end as the end of array (asserted). */
     453    testListEmpty1.removeRange(42, 128);
     454    RTTESTI_CHECK(!testListEmpty1.size());
     455
     456    cBefore = testList6.size();
     457    testList6.removeRange(cBefore, cBefore);
     458    RTTESTI_CHECK(testList6.size() == cBefore);
     459
     460    cBefore = testList6.size();
     461    testList6.removeRange(cBefore + 12, cBefore + 128);
     462    RTTESTI_CHECK(testList6.size() == cBefore);
     463
     464    /* If end is less or equal to the start, nothing is done. */
     465    testListEmpty1.removeRange(128, 0);
     466    RTTESTI_CHECK(!testListEmpty1.size());
     467
     468    cBefore = testList6.size();
     469    testList6.removeRange(cBefore, 0);
     470    RTTESTI_CHECK(testList6.size() == cBefore);
     471
     472    cBefore = testList6.size();
     473    testList6.removeRange(0, 0);
     474    RTTESTI_CHECK(testList6.size() == cBefore);
     475
     476    cBefore = testList6.size();
     477    testList6.removeRange(0, 0);
     478    RTTESTI_CHECK(testList6.size() == cBefore);
     479
     480    RTAssertSetQuiet(fQuiet);
     481    RTAssertSetMayPanic(fMayPanic);
    378482}
    379483
    380484/* define RTCList here to see what happens without MT support ;)
    381485 * (valgrind is the preferred tool to check). */
    382 #define MTTESTLISTTYPE RTCMTList
    383 #define MTTESTTYPE uint32_t
    384 #define MTTESTITEMS 1000
     486#define MTTESTLISTTYPE  RTCMTList
     487#define MTTESTTYPE      uint32_t
     488#define MTTESTITEMS     1000
    385489
    386490/**
     
    390494 * @param   pvUser      The provided user data.
    391495 */
    392 DECLCALLBACK(int) mttest1(RTTHREAD hSelf, void *pvUser)
     496static DECLCALLBACK(int) MtTest1ThreadProc(RTTHREAD hSelf, void *pvUser)
    393497{
    394498    MTTESTLISTTYPE<MTTESTTYPE> *pTestList = (MTTESTLISTTYPE<MTTESTTYPE> *)pvUser;
     
    407511 * @param   pvUser      The provided user data.
    408512 */
    409 DECLCALLBACK(int) mttest2(RTTHREAD hSelf, void *pvUser)
     513static DECLCALLBACK(int) MtTest2ThreadProc(RTTHREAD hSelf, void *pvUser)
    410514{
    411515    MTTESTLISTTYPE<MTTESTTYPE> *pTestList = (MTTESTLISTTYPE<MTTESTTYPE> *)pvUser;
     
    424528 * @param   pvUser      The provided user data.
    425529 */
    426 DECLCALLBACK(int) mttest3(RTTHREAD hSelf, void *pvUser)
     530static DECLCALLBACK(int) MtTest3ThreadProc(RTTHREAD hSelf, void *pvUser)
    427531{
    428532    MTTESTLISTTYPE<MTTESTTYPE> *pTestList = (MTTESTLISTTYPE<MTTESTTYPE> *)pvUser;
     
    441545 * @param   pvUser      The provided user data.
    442546 */
    443 DECLCALLBACK(int) mttest4(RTTHREAD hSelf, void *pvUser)
     547static DECLCALLBACK(int) MtTest4ThreadProc(RTTHREAD hSelf, void *pvUser)
    444548{
    445549    MTTESTLISTTYPE<MTTESTTYPE> *pTestList = (MTTESTLISTTYPE<MTTESTTYPE> *)pvUser;
     
    450554    {
    451555        /* Make sure there is at least one item in the list. */
    452         while (pTestList->isEmpty()) {};
     556        while (pTestList->isEmpty())
     557            RTThreadYield();
    453558        a = pTestList->at(RTRandU32Ex(0, (uint32_t)pTestList->size() - 1));
    454559    }
     
    463568 * @param   pvUser      The provided user data.
    464569 */
    465 DECLCALLBACK(int) mttest5(RTTHREAD hSelf, void *pvUser)
     570static DECLCALLBACK(int) MtTest5ThreadProc(RTTHREAD hSelf, void *pvUser)
    466571{
    467572    MTTESTLISTTYPE<MTTESTTYPE> *pTestList = (MTTESTLISTTYPE<MTTESTTYPE> *)pvUser;
     
    471576    {
    472577        /* Make sure there is at least one item in the list. */
    473         while (pTestList->isEmpty()) {};
     578        while (pTestList->isEmpty())
     579            RTThreadYield();
    474580        pTestList->replace(RTRandU32Ex(0, (uint32_t)pTestList->size() - 1), 0xFF00FF00);
    475581    }
     
    484590 * @param   pvUser      The provided user data.
    485591 */
    486 DECLCALLBACK(int) mttest6(RTTHREAD hSelf, void *pvUser)
     592static DECLCALLBACK(int) MtTest6ThreadProc(RTTHREAD hSelf, void *pvUser)
    487593{
    488594    MTTESTLISTTYPE<MTTESTTYPE> *pTestList = (MTTESTLISTTYPE<MTTESTTYPE> *)pvUser;
     
    492598    {
    493599        /* Make sure there is at least one item in the list. */
    494         while (pTestList->isEmpty()) {};
     600        while (pTestList->isEmpty())
     601            RTThreadYield();
    495602        pTestList->removeAt(RTRandU32Ex(0, (uint32_t)pTestList->size() - 1));
    496603    }
     
    508615    RTTestISubF("MT test with 6 threads (%u tests per thread).", MTTESTITEMS);
    509616
    510     RTTHREAD hThread1, hThread2, hThread3, hThread4, hThread5, hThread6;
    511     int rc = VINF_SUCCESS;
    512 
    513     MTTESTLISTTYPE<MTTESTTYPE> testList;
    514     rc = RTThreadCreate(&hThread1, &mttest1, &testList, 0, RTTHREADTYPE_DEFAULT, RTTHREADFLAGS_WAITABLE, "mttest1");
    515     AssertRC(rc);
    516     rc = RTThreadCreate(&hThread2, &mttest2, &testList, 0, RTTHREADTYPE_DEFAULT, RTTHREADFLAGS_WAITABLE, "mttest2");
    517     AssertRC(rc);
    518     rc = RTThreadCreate(&hThread3, &mttest3, &testList, 0, RTTHREADTYPE_DEFAULT, RTTHREADFLAGS_WAITABLE, "mttest3");
    519     AssertRC(rc);
    520     rc = RTThreadCreate(&hThread4, &mttest4, &testList, 0, RTTHREADTYPE_DEFAULT, RTTHREADFLAGS_WAITABLE, "mttest4");
    521     AssertRC(rc);
    522     rc = RTThreadCreate(&hThread5, &mttest5, &testList, 0, RTTHREADTYPE_DEFAULT, RTTHREADFLAGS_WAITABLE, "mttest5");
    523     AssertRC(rc);
    524     rc = RTThreadCreate(&hThread6, &mttest6, &testList, 0, RTTHREADTYPE_DEFAULT, RTTHREADFLAGS_WAITABLE, "mttest6");
    525     AssertRC(rc);
    526 
    527     rc = RTThreadWait(hThread1, RT_INDEFINITE_WAIT, 0);
    528     AssertRC(rc);
    529     rc = RTThreadWait(hThread2, RT_INDEFINITE_WAIT, 0);
    530     AssertRC(rc);
    531     rc = RTThreadWait(hThread3, RT_INDEFINITE_WAIT, 0);
    532     AssertRC(rc);
    533     rc = RTThreadWait(hThread4, RT_INDEFINITE_WAIT, 0);
    534     AssertRC(rc);
    535     rc = RTThreadWait(hThread5, RT_INDEFINITE_WAIT, 0);
    536     AssertRC(rc);
    537     rc = RTThreadWait(hThread6, RT_INDEFINITE_WAIT, 0);
    538     AssertRC(rc);
     617    int                         rc;
     618    MTTESTLISTTYPE<MTTESTTYPE>  testList;
     619    RTTHREAD                    ahThreads[6];
     620    static PFNRTTHREAD          apfnThreads[6] =
     621    {
     622        MtTest1ThreadProc, MtTest2ThreadProc, MtTest3ThreadProc, MtTest4ThreadProc, MtTest5ThreadProc, MtTest6ThreadProc
     623    };
     624
     625    for (unsigned i = 0; i < RT_ELEMENTS(ahThreads); i++)
     626    {
     627        RTTESTI_CHECK_RC_RETV(RTThreadCreateF(&ahThreads[i], apfnThreads[i], &testList, 0,
     628                                              RTTHREADTYPE_DEFAULT, RTTHREADFLAGS_WAITABLE, "mttest%u", i), VINF_SUCCESS);
     629    }
     630
     631    uint64_t tsMsDeadline = RTTimeMilliTS() + 60000;
     632    for (unsigned i = 0; i < RT_ELEMENTS(ahThreads); i++)
     633    {
     634        uint64_t tsNow = RTTimeMilliTS();
     635        uint32_t cWait = tsNow > tsMsDeadline ? 5000 : tsMsDeadline - tsNow;
     636        RTTESTI_CHECK_RC(RTThreadWait(ahThreads[i], tsNow, NULL), VINF_SUCCESS);
     637    }
    539638
    540639    RTTESTI_CHECK_RETV(testList.size() == MTTESTITEMS * 2);
     
    557656    RTTestBanner(hTest);
    558657
    559     /* Some host info. */
    560     RTTestIPrintf(RTTESTLVL_ALWAYS, "sizeof(void*)=%d", sizeof(void*));
    561 
    562     /*
    563      * The tests.
    564      */
    565 
    566658    /*
    567659     * Native types.
Note: See TracChangeset for help on using the changeset viewer.

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