VirtualBox

Changeset 33167 in vbox for trunk


Ignore:
Timestamp:
Oct 15, 2010 6:16:59 PM (14 years ago)
Author:
vboxsync
Message:

SUPDrv,SUPLib: Expose the high resolution event semaphore APIs.

Location:
trunk
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/sup.h

    r32358 r33167  
    385385SUPDECL(int) SUPSemEventWaitNoResume(PSUPDRVSESSION pSession, SUPSEMEVENT hEvent, uint32_t cMillies);
    386386
     387/**
     388 * Waits on a single release event semaphore, interruptible.
     389 *
     390 * @returns VBox status code.
     391 * @param   pSession            The session handle of the caller.
     392 * @param   hEvent              The semaphore handle.
     393 * @param   uNsTimeout          The deadline given on the RTTimeNanoTS() clock.
     394 */
     395SUPDECL(int) SUPSemEventWaitNsAbsIntr(PSUPDRVSESSION pSession, SUPSEMEVENT hEvent, uint64_t uNsTimeout);
     396
     397/**
     398 * Waits on a single release event semaphore, interruptible.
     399 *
     400 * @returns VBox status code.
     401 * @param   pSession            The session handle of the caller.
     402 * @param   hEvent              The semaphore handle.
     403 * @param   cNsTimeout          The number of nanoseconds to wait.
     404 */
     405SUPDECL(int) SUPSemEventWaitNsRelIntr(PSUPDRVSESSION pSession, SUPSEMEVENT hEvent, uint64_t cNsTimeout);
     406
     407/**
     408 * Gets the best timeout resolution that SUPSemEventWaitNsAbsIntr and
     409 * SUPSemEventWaitNsAbsIntr can do.
     410 *
     411 * @returns The resolution in nanoseconds.
     412 * @param   pSession            The session handle of the caller.
     413 */
     414SUPDECL(uint32_t) SUPSemEventGetResolution(PSUPDRVSESSION pSession);
     415
    387416
    388417/** Multiple release event semaphore handle. Ring-0 / ring-3. */
     
    455484 */
    456485SUPDECL(int) SUPSemEventMultiWaitNoResume(PSUPDRVSESSION pSession, SUPSEMEVENTMULTI hEventMulti, uint32_t cMillies);
     486
     487/**
     488 * Waits on a multiple release event semaphore, interruptible.
     489 *
     490 * @returns VBox status code.
     491 * @param   pSession            The session handle of the caller.
     492 * @param   hEventMulti         The semaphore handle.
     493 * @param   uNsTimeout          The deadline given on the RTTimeNanoTS() clock.
     494 */
     495SUPDECL(int) SUPSemEventMultiWaitNsAbsIntr(PSUPDRVSESSION pSession, SUPSEMEVENTMULTI hEventMulti, uint64_t uNsTimeout);
     496
     497/**
     498 * Waits on a multiple release event semaphore, interruptible.
     499 *
     500 * @returns VBox status code.
     501 * @param   pSession            The session handle of the caller.
     502 * @param   hEventMulti         The semaphore handle.
     503 * @param   cNsTimeout          The number of nanoseconds to wait.
     504 */
     505SUPDECL(int) SUPSemEventMultiWaitNsRelIntr(PSUPDRVSESSION pSession, SUPSEMEVENTMULTI hEventMulti, uint64_t cNsTimeout);
     506
     507/**
     508 * Gets the best timeout resolution that SUPSemEventMultiWaitNsAbsIntr and
     509 * SUPSemEventMultiWaitNsRelIntr can do.
     510 *
     511 * @returns The resolution in nanoseconds.
     512 * @param   pSession            The session handle of the caller.
     513 */
     514SUPDECL(uint32_t) SUPSemEventMultiGetResolution(PSUPDRVSESSION pSession);
    457515
    458516
  • trunk/src/VBox/HostDrivers/Support/SUPDrv.c

    r32755 r33167  
    176176    { "SUPSemEventWait",                        (void *)SUPSemEventWait },
    177177    { "SUPSemEventWaitNoResume",                (void *)SUPSemEventWaitNoResume },
     178    { "SUPSemEventWaitNsAbsIntr",               (void *)SUPSemEventWaitNsAbsIntr },
     179    { "SUPSemEventWaitNsRelIntr",               (void *)SUPSemEventWaitNsRelIntr },
     180    { "SUPSemEventGetResolution",               (void *)SUPSemEventGetResolution },
    178181    { "SUPSemEventMultiCreate",                 (void *)SUPSemEventMultiCreate },
    179182    { "SUPSemEventMultiClose",                  (void *)SUPSemEventMultiClose },
     
    182185    { "SUPSemEventMultiWait",                   (void *)SUPSemEventMultiWait },
    183186    { "SUPSemEventMultiWaitNoResume",           (void *)SUPSemEventMultiWaitNoResume },
     187    { "SUPSemEventMultiWaitNsAbsIntr",          (void *)SUPSemEventMultiWaitNsAbsIntr },
     188    { "SUPSemEventMultiWaitNsRelIntr",          (void *)SUPSemEventMultiWaitNsRelIntr },
     189    { "SUPSemEventMultiGetResolution",          (void *)SUPSemEventMultiGetResolution },
    184190    { "SUPR0GetPagingMode",                     (void *)SUPR0GetPagingMode },
    185191    { "SUPR0EnableVTx",                         (void *)SUPR0EnableVTx },
     
    234240    { "RTSemEventWait",                         (void *)RTSemEventWait },
    235241    { "RTSemEventWaitNoResume",                 (void *)RTSemEventWaitNoResume },
     242    { "RTSemEventWaitEx",                       (void *)RTSemEventWaitEx },
     243    { "RTSemEventWaitExDebug",                  (void *)RTSemEventWaitExDebug },
     244    { "RTSemEventGetResolution",                (void *)RTSemEventGetResolution },
    236245    { "RTSemEventDestroy",                      (void *)RTSemEventDestroy },
    237246    { "RTSemEventMultiCreate",                  (void *)RTSemEventMultiCreate },
     
    240249    { "RTSemEventMultiWait",                    (void *)RTSemEventMultiWait },
    241250    { "RTSemEventMultiWaitNoResume",            (void *)RTSemEventMultiWaitNoResume },
     251    { "RTSemEventMultiWaitEx",                  (void *)RTSemEventMultiWaitEx },
     252    { "RTSemEventMultiWaitExDebug",             (void *)RTSemEventMultiWaitExDebug },
     253    { "RTSemEventMultiGetResolution",           (void *)RTSemEventMultiGetResolution },
    242254    { "RTSemEventMultiDestroy",                 (void *)RTSemEventMultiDestroy },
    243255    { "RTSpinlockCreate",                       (void *)RTSpinlockCreate },
     
    16281640        }
    16291641
     1642        case SUP_CTL_CODE_NO_SIZE(SUP_IOCTL_SEM_OP2):
     1643        {
     1644            /* validate */
     1645            PSUPSEMOP2 pReq = (PSUPSEMOP2)pReqHdr;
     1646            REQ_CHECK_SIZES_EX(SUP_IOCTL_SEM_OP2, SUP_IOCTL_SEM_OP2_SIZE_IN, SUP_IOCTL_SEM_OP2_SIZE_OUT);
     1647            REQ_CHECK_EXPR(SUP_IOCTL_SEM_OP2, pReq->u.In.uReserved == 0);
     1648
     1649            /* execute */
     1650            switch (pReq->u.In.uType)
     1651            {
     1652                case SUP_SEM_TYPE_EVENT:
     1653                {
     1654                    SUPSEMEVENT hEvent = (SUPSEMEVENT)(uintptr_t)pReq->u.In.hSem;
     1655                    switch (pReq->u.In.uOp)
     1656                    {
     1657                        case SUPSEMOP2_WAIT_MS_REL:
     1658                            pReq->Hdr.rc = SUPSemEventWaitNoResume(pSession, hEvent, pReq->u.In.uArg.cRelMsTimeout);
     1659                            break;
     1660                        case SUPSEMOP2_WAIT_NS_ABS:
     1661                            pReq->Hdr.rc = SUPSemEventWaitNsAbsIntr(pSession, hEvent, pReq->u.In.uArg.uAbsNsTimeout);
     1662                            break;
     1663                        case SUPSEMOP2_WAIT_NS_REL:
     1664                            pReq->Hdr.rc = SUPSemEventWaitNsRelIntr(pSession, hEvent, pReq->u.In.uArg.cRelNsTimeout);
     1665                            break;
     1666                        case SUPSEMOP2_SIGNAL:
     1667                            pReq->Hdr.rc = SUPSemEventSignal(pSession, hEvent);
     1668                            break;
     1669                        case SUPSEMOP2_CLOSE:
     1670                            pReq->Hdr.rc = SUPSemEventClose(pSession, hEvent);
     1671                            break;
     1672                        case SUPSEMOP2_RESET:
     1673                        default:
     1674                            pReq->Hdr.rc = VERR_INVALID_FUNCTION;
     1675                            break;
     1676                    }
     1677                    break;
     1678                }
     1679
     1680                case SUP_SEM_TYPE_EVENT_MULTI:
     1681                {
     1682                    SUPSEMEVENTMULTI hEventMulti = (SUPSEMEVENTMULTI)(uintptr_t)pReq->u.In.hSem;
     1683                    switch (pReq->u.In.uOp)
     1684                    {
     1685                        case SUPSEMOP2_WAIT_MS_REL:
     1686                            pReq->Hdr.rc = SUPSemEventMultiWaitNoResume(pSession, hEventMulti, pReq->u.In.uArg.cRelMsTimeout);
     1687                            break;
     1688                        case SUPSEMOP2_WAIT_NS_ABS:
     1689                            pReq->Hdr.rc = SUPSemEventMultiWaitNsAbsIntr(pSession, hEventMulti, pReq->u.In.uArg.uAbsNsTimeout);
     1690                            break;
     1691                        case SUPSEMOP2_WAIT_NS_REL:
     1692                            pReq->Hdr.rc = SUPSemEventMultiWaitNsRelIntr(pSession, hEventMulti, pReq->u.In.uArg.cRelNsTimeout);
     1693                            break;
     1694                        case SUPSEMOP2_SIGNAL:
     1695                            pReq->Hdr.rc = SUPSemEventMultiSignal(pSession, hEventMulti);
     1696                            break;
     1697                        case SUPSEMOP2_CLOSE:
     1698                            pReq->Hdr.rc = SUPSemEventMultiClose(pSession, hEventMulti);
     1699                            break;
     1700                        case SUPSEMOP2_RESET:
     1701                            pReq->Hdr.rc = SUPSemEventMultiReset(pSession, hEventMulti);
     1702                            break;
     1703                        default:
     1704                            pReq->Hdr.rc = VERR_INVALID_FUNCTION;
     1705                            break;
     1706                    }
     1707                    break;
     1708                }
     1709
     1710                default:
     1711                    pReq->Hdr.rc = VERR_INVALID_PARAMETER;
     1712                    break;
     1713            }
     1714            return 0;
     1715        }
     1716
     1717        case SUP_CTL_CODE_NO_SIZE(SUP_IOCTL_SEM_OP3):
     1718        {
     1719            /* validate */
     1720            PSUPSEMOP3 pReq = (PSUPSEMOP3)pReqHdr;
     1721            REQ_CHECK_SIZES_EX(SUP_IOCTL_SEM_OP3, SUP_IOCTL_SEM_OP3_SIZE_IN, SUP_IOCTL_SEM_OP3_SIZE_OUT);
     1722            REQ_CHECK_EXPR(SUP_IOCTL_SEM_OP3, pReq->u.In.u32Reserved == 0 && pReq->u.In.u64Reserved == 0);
     1723
     1724            /* execute */
     1725            switch (pReq->u.In.uType)
     1726            {
     1727                case SUP_SEM_TYPE_EVENT:
     1728                {
     1729                    SUPSEMEVENT hEvent = (SUPSEMEVENT)(uintptr_t)pReq->u.In.hSem;
     1730                    switch (pReq->u.In.uOp)
     1731                    {
     1732                        case SUPSEMOP3_CREATE:
     1733                            REQ_CHECK_EXPR(SUP_IOCTL_SEM_OP3, hEvent == NIL_SUPSEMEVENT);
     1734                            pReq->Hdr.rc = SUPSemEventCreate(pSession, &hEvent);
     1735                            pReq->u.Out.hSem = (uint32_t)(uintptr_t)hEvent;
     1736                            break;
     1737                        case SUPSEMOP3_GET_RESOLUTION:
     1738                            REQ_CHECK_EXPR(SUP_IOCTL_SEM_OP3, hEvent == NIL_SUPSEMEVENT);
     1739                            pReq->Hdr.rc = VINF_SUCCESS;
     1740                            pReq->Hdr.cbOut = sizeof(*pReq);
     1741                            pReq->u.Out.cNsResolution = SUPSemEventGetResolution(pSession);
     1742                            break;
     1743                        default:
     1744                            pReq->Hdr.rc = VERR_INVALID_FUNCTION;
     1745                            break;
     1746                    }
     1747                    break;
     1748                }
     1749
     1750                case SUP_SEM_TYPE_EVENT_MULTI:
     1751                {
     1752                    SUPSEMEVENTMULTI hEventMulti = (SUPSEMEVENTMULTI)(uintptr_t)pReq->u.In.hSem;
     1753                    switch (pReq->u.In.uOp)
     1754                    {
     1755                        case SUPSEMOP3_CREATE:
     1756                            REQ_CHECK_EXPR(SUP_IOCTL_SEM_OP3, hEventMulti == NIL_SUPSEMEVENTMULTI);
     1757                            pReq->Hdr.rc = SUPSemEventMultiCreate(pSession, &hEventMulti);
     1758                            pReq->u.Out.hSem = (uint32_t)(uintptr_t)hEventMulti;
     1759                            break;
     1760                        case SUPSEMOP3_GET_RESOLUTION:
     1761                            REQ_CHECK_EXPR(SUP_IOCTL_SEM_OP3, hEventMulti == NIL_SUPSEMEVENTMULTI);
     1762                            pReq->Hdr.rc = VINF_SUCCESS;
     1763                            pReq->u.Out.cNsResolution = SUPSemEventMultiGetResolution(pSession);
     1764                            break;
     1765                        default:
     1766                            pReq->Hdr.rc = VERR_INVALID_FUNCTION;
     1767                            break;
     1768                    }
     1769                    break;
     1770                }
     1771
     1772                default:
     1773                    pReq->Hdr.rc = VERR_INVALID_PARAMETER;
     1774                    break;
     1775            }
     1776            return 0;
     1777        }
     1778
    16301779        case SUP_CTL_CODE_NO_SIZE(SUP_IOCTL_VT_CAPS):
    16311780        {
  • trunk/src/VBox/HostDrivers/Support/SUPDrvIOC.h

    r32572 r33167  
    191191 *
    192192 * @todo Pending work on next major version change:
    193  *          - Nothing.
    194  */
    195 #define SUPDRV_IOC_VERSION                              0x00150003
     193 *          - Remove SUPSEMOP and SUPSEMCREATE.
     194 */
     195#define SUPDRV_IOC_VERSION                              0x00150004
    196196
    197197/** SUP_IOCTL_COOKIE. */
     
    10191019/** @name SUP_IOCTL_SEM_CREATE
    10201020 * Create a semaphore
     1021 * @todo remove this interface with the next major version change.
    10211022 * @{
    10221023 */
     
    10491050/** @name SUP_IOCTL_SEM_OP
    10501051 * Semaphore operations.
     1052 * @todo remove this interface with the next major version change.
    10511053 * @{
    10521054 */
     
    10751077} SUPSEMOP, *PSUPSEMOP;
    10761078
    1077 /** Wait for a number of millisecons. */
     1079/** Wait for a number of milliseconds. */
    10781080#define SUPSEMOP_WAIT       0
    10791081/** Signal the semaphore. */
     
    10861088/** @} */
    10871089
     1090/** @name SUP_IOCTL_SEM_OP2
     1091 * Semaphore operations.
     1092 * @remarks This replaces the old SUP_IOCTL_SEM_OP interface.
     1093 * @{
     1094 */
     1095#define SUP_IOCTL_SEM_OP2                               SUP_CTL_CODE_SIZE(27, SUP_IOCTL_SEM_OP2_SIZE)
     1096#define SUP_IOCTL_SEM_OP2_SIZE                          sizeof(SUPSEMOP2)
     1097#define SUP_IOCTL_SEM_OP2_SIZE_IN                       sizeof(SUPSEMOP2)
     1098#define SUP_IOCTL_SEM_OP2_SIZE_OUT                      sizeof(SUPREQHDR)
     1099typedef struct SUPSEMOP2
     1100{
     1101    /** The header. */
     1102    SUPREQHDR               Hdr;
     1103    union
     1104    {
     1105        struct
     1106        {
     1107            /** The semaphore type. */
     1108            uint32_t        uType;
     1109            /** The semaphore handle. */
     1110            uint32_t        hSem;
     1111            /** The operation. */
     1112            uint32_t        uOp;
     1113            /** Reserved, must be zero. */
     1114            uint32_t        uReserved;
     1115            /** The number of milliseconds to wait if it's a wait operation. */
     1116            union
     1117            {
     1118                /** Absolute timeout (RTTime[System]NanoTS).
     1119                 * Used by SUPSEMOP2_WAIT_NS_ABS. */
     1120                uint64_t    uAbsNsTimeout;
     1121                /** Relative nanosecond timeout.
     1122                 * Used by SUPSEMOP2_WAIT_NS_REL. */
     1123                uint64_t    cRelNsTimeout;
     1124                /** Relative millisecond timeout.
     1125                 * Used by SUPSEMOP2_WAIT_MS_REL. */
     1126                uint32_t    cRelMsTimeout;
     1127                /** Generic 64-bit accessor.
     1128                 * ASSUMES little endian!  */
     1129                uint64_t    u64;
     1130            } uArg;
     1131        } In;
     1132    } u;
     1133} SUPSEMOP2, *PSUPSEMOP2;
     1134
     1135/** Wait for a number of milliseconds. */
     1136#define SUPSEMOP2_WAIT_MS_REL       0
     1137/** Wait until the specified deadline is reached. */
     1138#define SUPSEMOP2_WAIT_NS_ABS       1
     1139/** Wait for a number of nanoseconds. */
     1140#define SUPSEMOP2_WAIT_NS_REL       2
     1141/** Signal the semaphore. */
     1142#define SUPSEMOP2_SIGNAL            3
     1143/** Reset the sempahore (only applicable to SUP_SEM_TYPE_EVENT_MULTI). */
     1144#define SUPSEMOP2_RESET             4
     1145/** Close the semaphore handle. */
     1146#define SUPSEMOP2_CLOSE             5
     1147/** @} */
     1148
     1149/** @name SUP_IOCTL_SEM_OP3
     1150 * Semaphore operations.
     1151 * @{
     1152 */
     1153#define SUP_IOCTL_SEM_OP3                               SUP_CTL_CODE_SIZE(28, SUP_IOCTL_SEM_OP3_SIZE)
     1154#define SUP_IOCTL_SEM_OP3_SIZE                          sizeof(SUPSEMOP3)
     1155#define SUP_IOCTL_SEM_OP3_SIZE_IN                       sizeof(SUPSEMOP3)
     1156#define SUP_IOCTL_SEM_OP3_SIZE_OUT                      sizeof(SUPSEMOP3)
     1157typedef struct SUPSEMOP3
     1158{
     1159    /** The header. */
     1160    SUPREQHDR               Hdr;
     1161    union
     1162    {
     1163        struct
     1164        {
     1165            /** The semaphore type. */
     1166            uint32_t        uType;
     1167            /** The semaphore handle. */
     1168            uint32_t        hSem;
     1169            /** The operation. */
     1170            uint32_t        uOp;
     1171            /** Reserved, must be zero. */
     1172            uint32_t        u32Reserved;
     1173            /** Reserved for future use. */
     1174            uint64_t        u64Reserved;
     1175        } In;
     1176        union
     1177        {
     1178            /** The handle of the created semaphore.
     1179             * Used by SUPSEMOP3_CREATE. */
     1180            uint32_t        hSem;
     1181            /** The semaphore resolution in nano seconds.
     1182             * Used by SUPSEMOP3_GET_RESOLUTION. */
     1183            uint32_t        cNsResolution;
     1184            /** The 32-bit view. */
     1185            uint32_t        u32;
     1186            /** Reserved some space for later expansion. */
     1187            uint64_t        u64Reserved;
     1188        } Out;
     1189    } u;
     1190} SUPSEMOP3, *PSUPSEMOP3;
     1191
     1192/** Get the wait resolution.  */
     1193#define SUPSEMOP3_CREATE            0
     1194/** Get the wait resolution.  */
     1195#define SUPSEMOP3_GET_RESOLUTION    1
     1196/** @} */
     1197
    10881198/** @name SUP_IOCTL_VT_CAPS
    10891199 * Get the VT-x/AMD-V capabilities.
  • trunk/src/VBox/HostDrivers/Support/SUPDrvSem.c

    r28800 r33167  
    156156
    157157
    158 SUPDECL(int) SUPSemEventWait(PSUPDRVSESSION pSession, SUPSEMEVENT hEvent, uint32_t cMillies)
     158static int supR0SemEventWaitEx(PSUPDRVSESSION pSession, SUPSEMEVENT hEvent, uint32_t fFlags, uint64_t uTimeout)
    159159{
    160160    int         rc;
     
    176176     * Do the job.
    177177     */
    178     rc = RTSemEventWait((RTSEMEVENT)pObj->pvUser1, cMillies);
     178    rc = RTSemEventWaitEx((RTSEMEVENT)pObj->pvUser1, fFlags, uTimeout);
    179179
    180180    SUPR0ObjRelease(pObj, pSession);
     
    183183
    184184
     185SUPDECL(int) SUPSemEventWait(PSUPDRVSESSION pSession, SUPSEMEVENT hEvent, uint32_t cMillies)
     186{
     187    uint32_t fFlags = RTSEMWAIT_FLAGS_RELATIVE | RTSEMWAIT_FLAGS_MILLISECS | RTSEMWAIT_FLAGS_UNINTERRUPTIBLE;
     188    if (cMillies == RT_INDEFINITE_WAIT)
     189        fFlags |= RTSEMWAIT_FLAGS_INDEFINITE;
     190    return supR0SemEventWaitEx(pSession, hEvent, fFlags, cMillies);
     191}
     192
     193
    185194SUPDECL(int) SUPSemEventWaitNoResume(PSUPDRVSESSION pSession, SUPSEMEVENT hEvent, uint32_t cMillies)
    186195{
    187     int         rc;
    188     uint32_t    h32;
    189     PSUPDRVOBJ  pObj;
    190 
    191     /*
    192      * Input validation.
    193      */
    194     AssertReturn(SUP_IS_SESSION_VALID(pSession), VERR_INVALID_PARAMETER);
    195     h32 = (uint32_t)(uintptr_t)hEvent;
    196     if (h32 != (uintptr_t)hEvent)
    197         return VERR_INVALID_HANDLE;
    198     pObj = (PSUPDRVOBJ)RTHandleTableLookupWithCtx(pSession->hHandleTable, h32, SUPDRV_HANDLE_CTX_EVENT);
    199     if (!pObj)
    200         return VERR_INVALID_HANDLE;
    201 
    202     /*
    203      * Do the job.
    204      */
    205     rc = RTSemEventWaitNoResume((RTSEMEVENT)pObj->pvUser1, cMillies);
    206 
    207     SUPR0ObjRelease(pObj, pSession);
    208     return rc;
     196    uint32_t fFlags = RTSEMWAIT_FLAGS_RELATIVE | RTSEMWAIT_FLAGS_MILLISECS | RTSEMWAIT_FLAGS_INTERRUPTIBLE;
     197    if (cMillies == RT_INDEFINITE_WAIT)
     198        fFlags |= RTSEMWAIT_FLAGS_INDEFINITE;
     199    return supR0SemEventWaitEx(pSession, hEvent, fFlags, cMillies);
     200}
     201
     202
     203SUPDECL(int) SUPSemEventWaitNsAbsIntr(PSUPDRVSESSION pSession, SUPSEMEVENT hEvent, uint64_t uNsTimeout)
     204{
     205    uint32_t fFlags = RTSEMWAIT_FLAGS_ABSOLUTE | RTSEMWAIT_FLAGS_NANOSECS | RTSEMWAIT_FLAGS_INTERRUPTIBLE;
     206    return supR0SemEventWaitEx(pSession, hEvent, fFlags, uNsTimeout);
     207}
     208
     209
     210SUPDECL(int) SUPSemEventWaitNsRelIntr(PSUPDRVSESSION pSession, SUPSEMEVENT hEvent, uint64_t cNsTimeout)
     211{
     212    uint32_t fFlags = RTSEMWAIT_FLAGS_RELATIVE | RTSEMWAIT_FLAGS_NANOSECS | RTSEMWAIT_FLAGS_INTERRUPTIBLE;
     213    return supR0SemEventWaitEx(pSession, hEvent, fFlags, cNsTimeout);
     214}
     215
     216
     217SUPDECL(uint32_t) SUPSemEventGetResolution(PSUPDRVSESSION pSession)
     218{
     219    Assert(SUP_IS_SESSION_VALID(pSession));
     220    return RTSemEventGetResolution();
    209221}
    210222
     
    343355
    344356
    345 SUPDECL(int) SUPSemEventMultiWait(PSUPDRVSESSION pSession, SUPSEMEVENTMULTI hEventMulti, uint32_t cMillies)
     357static int supR0SemEventMultiWaitEx(PSUPDRVSESSION pSession, SUPSEMEVENTMULTI hEventMulti, uint32_t fFlags, uint64_t uTimeout)
    346358{
    347359    int         rc;
     
    363375     * Do the job.
    364376     */
    365     rc = RTSemEventMultiWait((RTSEMEVENTMULTI)pObj->pvUser1, cMillies);
     377    rc = RTSemEventMultiWaitEx((RTSEMEVENTMULTI)pObj->pvUser1, fFlags, uTimeout);
    366378
    367379    SUPR0ObjRelease(pObj, pSession);
     
    369381}
    370382
     383SUPDECL(int) SUPSemEventMultiWait(PSUPDRVSESSION pSession, SUPSEMEVENTMULTI hEventMulti, uint32_t cMillies)
     384{
     385    uint32_t fFlags = RTSEMWAIT_FLAGS_RELATIVE | RTSEMWAIT_FLAGS_MILLISECS | RTSEMWAIT_FLAGS_UNINTERRUPTIBLE;
     386    if (cMillies == RT_INDEFINITE_WAIT)
     387        fFlags |= RTSEMWAIT_FLAGS_INDEFINITE;
     388    return supR0SemEventMultiWaitEx(pSession, hEventMulti, fFlags, cMillies);
     389}
     390
     391
    371392
    372393SUPDECL(int) SUPSemEventMultiWaitNoResume(PSUPDRVSESSION pSession, SUPSEMEVENTMULTI hEventMulti, uint32_t cMillies)
    373394{
    374     int         rc;
    375     uint32_t    h32;
    376     PSUPDRVOBJ  pObj;
    377 
    378     /*
    379      * Input validation.
    380      */
    381     AssertReturn(SUP_IS_SESSION_VALID(pSession), VERR_INVALID_PARAMETER);
    382     h32 = (uint32_t)(uintptr_t)hEventMulti;
    383     if (h32 != (uintptr_t)hEventMulti)
    384         return VERR_INVALID_HANDLE;
    385     pObj = (PSUPDRVOBJ)RTHandleTableLookupWithCtx(pSession->hHandleTable, h32, SUPDRV_HANDLE_CTX_EVENT_MULTI);
    386     if (!pObj)
    387         return VERR_INVALID_HANDLE;
    388 
    389     /*
    390      * Do the job.
    391      */
    392     rc = RTSemEventMultiWaitNoResume((RTSEMEVENTMULTI)pObj->pvUser1, cMillies);
    393 
    394     SUPR0ObjRelease(pObj, pSession);
    395     return rc;
    396 }
    397 
     395    uint32_t fFlags = RTSEMWAIT_FLAGS_RELATIVE | RTSEMWAIT_FLAGS_MILLISECS | RTSEMWAIT_FLAGS_INTERRUPTIBLE;
     396    if (cMillies == RT_INDEFINITE_WAIT)
     397        fFlags |= RTSEMWAIT_FLAGS_INDEFINITE;
     398    return supR0SemEventMultiWaitEx(pSession, hEventMulti, fFlags, cMillies);
     399}
     400
     401
     402SUPDECL(int) SUPSemEventMultiWaitNsAbsIntr(PSUPDRVSESSION pSession, SUPSEMEVENTMULTI hEventMulti, uint64_t uNsTimeout)
     403{
     404    uint32_t fFlags = RTSEMWAIT_FLAGS_ABSOLUTE | RTSEMWAIT_FLAGS_NANOSECS | RTSEMWAIT_FLAGS_INTERRUPTIBLE;
     405    return supR0SemEventMultiWaitEx(pSession, hEventMulti, fFlags, uNsTimeout);
     406}
     407
     408
     409SUPDECL(int) SUPSemEventMultiWaitNsRelIntr(PSUPDRVSESSION pSession, SUPSEMEVENTMULTI hEventMulti, uint64_t cNsTimeout)
     410{
     411    uint32_t fFlags = RTSEMWAIT_FLAGS_RELATIVE | RTSEMWAIT_FLAGS_NANOSECS | RTSEMWAIT_FLAGS_INTERRUPTIBLE;
     412    return supR0SemEventMultiWaitEx(pSession, hEventMulti, fFlags, cNsTimeout);
     413}
     414
     415
     416SUPDECL(uint32_t) SUPSemEventMultiGetResolution(PSUPDRVSESSION pSession)
     417{
     418    Assert(SUP_IS_SESSION_VALID(pSession));
     419    return RTSemEventMultiGetResolution();
     420}
     421
  • trunk/src/VBox/HostDrivers/Support/SUPLib.cpp

    r32572 r33167  
    269269        CookieReq.u.In.u32ReqVersion = SUPDRV_IOC_VERSION;
    270270        const uint32_t uMinVersion = (SUPDRV_IOC_VERSION & 0xffff0000) == 0x00150000
    271                                    ?  0x00150003
     271                                   ?  0x00150004
    272272                                   : SUPDRV_IOC_VERSION & 0xffff0000;
    273273        CookieReq.u.In.u32MinVersion = uMinVersion;
  • trunk/src/VBox/HostDrivers/Support/SUPLibSem.cpp

    r28800 r33167  
    4141
    4242/**
    43  * Worker that makes a SUP_IOCTL_SEM_OP request.
     43 * Worker that makes a SUP_IOCTL_SEM_OP2 request.
    4444 *
    4545 * @returns VBox status code.
     
    4848 * @param   hSem                The semaphore handle.
    4949 * @param   uOp                 The operation.
    50  * @param   cMillies            The timeout if applicable, otherwise 0.
    51  */
    52 DECLINLINE(int) supSemOp(PSUPDRVSESSION pSession, uint32_t uType, uintptr_t hSem, uint32_t uOp, uint32_t cMillies)
    53 {
    54     SUPSEMOP Req;
     50 * @param   u64Arg              The argument if applicable, otherwise 0.
     51 */
     52DECLINLINE(int) supSemOp2(PSUPDRVSESSION pSession, uint32_t uType, uintptr_t hSem, uint32_t uOp, uint64_t u64Arg)
     53{
     54    SUPSEMOP2 Req;
    5555    Req.Hdr.u32Cookie           = g_u32Cookie;
    5656    Req.Hdr.u32SessionCookie    = g_u32SessionCookie;
    57     Req.Hdr.cbIn                = SUP_IOCTL_SEM_OP_SIZE_IN;
    58     Req.Hdr.cbOut               = SUP_IOCTL_SEM_OP_SIZE_OUT;
     57    Req.Hdr.cbIn                = SUP_IOCTL_SEM_OP2_SIZE_IN;
     58    Req.Hdr.cbOut               = SUP_IOCTL_SEM_OP2_SIZE_OUT;
    5959    Req.Hdr.fFlags              = SUPREQHDR_FLAGS_DEFAULT;
    6060    Req.Hdr.rc                  = VERR_INTERNAL_ERROR;
     
    6363    AssertReturn(Req.u.In.hSem == hSem, VERR_INVALID_HANDLE);
    6464    Req.u.In.uOp                = uOp;
    65     Req.u.In.cMillies           = cMillies;
    66     int rc = suplibOsIOCtl(&g_supLibData, SUP_IOCTL_SEM_OP, &Req, sizeof(Req));
     65    Req.u.In.uReserved          = 0;
     66    Req.u.In.uArg.u64           = u64Arg;
     67    int rc = suplibOsIOCtl(&g_supLibData, SUP_IOCTL_SEM_OP2, &Req, sizeof(Req));
    6768    if (RT_SUCCESS(rc))
    6869        rc = Req.Hdr.rc;
     
    7273
    7374
     75/**
     76 * Worker that makes a SUP_IOCTL_SEM_OP3 request.
     77 *
     78 * @returns VBox status code.
     79 * @param   pSession            The session handle.
     80 * @param   uType               The semaphore type.
     81 * @param   hSem                The semaphore handle.
     82 * @param   uOp                 The operation.
     83 * @param   pReq                The request structure.  The caller should pick
     84 *                              the output data from it himself.
     85 */
     86DECLINLINE(int) supSemOp3(PSUPDRVSESSION pSession, uint32_t uType, uintptr_t hSem, uint32_t uOp, PSUPSEMOP3 pReq)
     87{
     88    pReq->Hdr.u32Cookie           = g_u32Cookie;
     89    pReq->Hdr.u32SessionCookie    = g_u32SessionCookie;
     90    pReq->Hdr.cbIn                = SUP_IOCTL_SEM_OP3_SIZE_IN;
     91    pReq->Hdr.cbOut               = SUP_IOCTL_SEM_OP3_SIZE_OUT;
     92    pReq->Hdr.fFlags              = SUPREQHDR_FLAGS_DEFAULT;
     93    pReq->Hdr.rc                  = VERR_INTERNAL_ERROR;
     94    pReq->u.In.uType              = uType;
     95    pReq->u.In.hSem               = (uint32_t)hSem;
     96    AssertReturn(pReq->u.In.hSem == hSem, VERR_INVALID_HANDLE);
     97    pReq->u.In.uOp                = uOp;
     98    pReq->u.In.u32Reserved        = 0;
     99    pReq->u.In.u64Reserved        = 0;
     100    int rc = suplibOsIOCtl(&g_supLibData, SUP_IOCTL_SEM_OP3, pReq, sizeof(*pReq));
     101    if (RT_SUCCESS(rc))
     102        rc = pReq->Hdr.rc;
     103
     104    return rc;
     105}
     106
     107
    74108SUPDECL(int) SUPSemEventCreate(PSUPDRVSESSION pSession, PSUPSEMEVENT phEvent)
    75109{
    76110    AssertPtrReturn(phEvent, VERR_INVALID_POINTER);
    77111
    78     SUPSEMCREATE Req;
    79     Req.Hdr.u32Cookie           = g_u32Cookie;
    80     Req.Hdr.u32SessionCookie    = g_u32SessionCookie;
    81     Req.Hdr.cbIn                = SUP_IOCTL_SEM_CREATE_SIZE_IN;
    82     Req.Hdr.cbOut               = SUP_IOCTL_SEM_CREATE_SIZE_OUT;
    83     Req.Hdr.fFlags              = SUPREQHDR_FLAGS_DEFAULT;
    84     Req.Hdr.rc                  = VERR_INTERNAL_ERROR;
    85     Req.u.In.uType              = SUP_SEM_TYPE_EVENT;
    86     int rc = suplibOsIOCtl(&g_supLibData, SUP_IOCTL_SEM_CREATE, &Req, sizeof(Req));
    87     if (RT_SUCCESS(rc))
    88     {
    89         rc = Req.Hdr.rc;
    90         if (RT_SUCCESS(rc))
    91             *phEvent = (SUPSEMEVENT)(uintptr_t)Req.u.Out.hSem;
    92     }
    93 
     112    SUPSEMOP3 Req;
     113    int rc = supSemOp3(pSession, SUP_SEM_TYPE_EVENT, (uintptr_t)NIL_SUPSEMEVENT, SUPSEMOP3_CREATE, &Req);
     114    if (RT_SUCCESS(rc))
     115        *phEvent = (SUPSEMEVENT)(uintptr_t)Req.u.Out.hSem;
    94116    return rc;
    95117}
     
    100122    if (hEvent == NIL_SUPSEMEVENT)
    101123        return VINF_SUCCESS;
    102     return supSemOp(pSession, SUP_SEM_TYPE_EVENT, (uintptr_t)hEvent, SUPSEMOP_CLOSE, 0);
     124    return supSemOp2(pSession, SUP_SEM_TYPE_EVENT, (uintptr_t)hEvent, SUPSEMOP2_CLOSE, 0);
    103125}
    104126
     
    106128SUPDECL(int) SUPSemEventSignal(PSUPDRVSESSION pSession, SUPSEMEVENT hEvent)
    107129{
    108     return supSemOp(pSession, SUP_SEM_TYPE_EVENT, (uintptr_t)hEvent, SUPSEMOP_SIGNAL, 0);
     130    return supSemOp2(pSession, SUP_SEM_TYPE_EVENT, (uintptr_t)hEvent, SUPSEMOP2_SIGNAL, 0);
    109131}
    110132
     
    112134SUPDECL(int) SUPSemEventWaitNoResume(PSUPDRVSESSION pSession, SUPSEMEVENT hEvent, uint32_t cMillies)
    113135{
    114     return supSemOp(pSession, SUP_SEM_TYPE_EVENT, (uintptr_t)hEvent, SUPSEMOP_WAIT, cMillies);
    115 }
     136    return supSemOp2(pSession, SUP_SEM_TYPE_EVENT, (uintptr_t)hEvent, SUPSEMOP2_WAIT_MS_REL, cMillies);
     137}
     138
     139
     140SUPDECL(int) SUPSemEventWaitNsAbsIntr(PSUPDRVSESSION pSession, SUPSEMEVENT hEvent, uint64_t uNsTimeout)
     141{
     142    return supSemOp2(pSession, SUP_SEM_TYPE_EVENT, (uintptr_t)hEvent, SUPSEMOP2_WAIT_NS_ABS, uNsTimeout);
     143}
     144
     145
     146SUPDECL(int) SUPSemEventWaitNsRelIntr(PSUPDRVSESSION pSession, SUPSEMEVENT hEvent, uint64_t cNsTimeout)
     147{
     148    return supSemOp2(pSession, SUP_SEM_TYPE_EVENT, (uintptr_t)hEvent, SUPSEMOP2_WAIT_NS_REL, cNsTimeout);
     149}
     150
     151
     152SUPDECL(uint32_t) SUPSemEventGetResolution(PSUPDRVSESSION pSession)
     153{
     154    SUPSEMOP3 Req;
     155    int rc = supSemOp3(pSession, SUP_SEM_TYPE_EVENT, (uintptr_t)NIL_SUPSEMEVENT, SUPSEMOP3_GET_RESOLUTION, &Req);
     156    if (RT_SUCCESS(rc))
     157        return Req.u.Out.cNsResolution;
     158    return 1000 / 100;
     159}
     160
     161
     162
     163
    116164
    117165SUPDECL(int) SUPSemEventMultiCreate(PSUPDRVSESSION pSession, PSUPSEMEVENTMULTI phEventMulti)
     
    119167    AssertPtrReturn(phEventMulti, VERR_INVALID_POINTER);
    120168
    121     SUPSEMCREATE Req;
    122     Req.Hdr.u32Cookie           = g_u32Cookie;
    123     Req.Hdr.u32SessionCookie    = g_u32SessionCookie;
    124     Req.Hdr.cbIn                = SUP_IOCTL_SEM_CREATE_SIZE_IN;
    125     Req.Hdr.cbOut               = SUP_IOCTL_SEM_CREATE_SIZE_OUT;
    126     Req.Hdr.fFlags              = SUPREQHDR_FLAGS_DEFAULT;
    127     Req.Hdr.rc                  = VERR_INTERNAL_ERROR;
    128     Req.u.In.uType              = SUP_SEM_TYPE_EVENT_MULTI;
    129     int rc = suplibOsIOCtl(&g_supLibData, SUP_IOCTL_SEM_CREATE, &Req, sizeof(Req));
    130     if (RT_SUCCESS(rc))
    131     {
    132         rc = Req.Hdr.rc;
    133         if (RT_SUCCESS(rc))
    134             *phEventMulti = (SUPSEMEVENTMULTI)(uintptr_t)Req.u.Out.hSem;
    135     }
    136 
     169    SUPSEMOP3 Req;
     170    int rc = supSemOp3(pSession, SUP_SEM_TYPE_EVENT_MULTI, (uintptr_t)NIL_SUPSEMEVENTMULTI, SUPSEMOP3_CREATE, &Req);
     171    if (RT_SUCCESS(rc))
     172        *phEventMulti = (SUPSEMEVENTMULTI)(uintptr_t)Req.u.Out.hSem;
    137173    return rc;
    138174}
     
    143179    if (hEventMulti == NIL_SUPSEMEVENTMULTI)
    144180        return VINF_SUCCESS;
    145     return supSemOp(pSession, SUP_SEM_TYPE_EVENT_MULTI, (uintptr_t)hEventMulti, SUPSEMOP_CLOSE, 0);
     181    return supSemOp2(pSession, SUP_SEM_TYPE_EVENT_MULTI, (uintptr_t)hEventMulti, SUPSEMOP2_CLOSE, 0);
    146182}
    147183
     
    149185SUPDECL(int) SUPSemEventMultiSignal(PSUPDRVSESSION pSession, SUPSEMEVENTMULTI hEventMulti)
    150186{
    151     return supSemOp(pSession, SUP_SEM_TYPE_EVENT_MULTI, (uintptr_t)hEventMulti, SUPSEMOP_SIGNAL, 0);
     187    return supSemOp2(pSession, SUP_SEM_TYPE_EVENT_MULTI, (uintptr_t)hEventMulti, SUPSEMOP2_SIGNAL, 0);
    152188}
    153189
     
    155191SUPDECL(int) SUPSemEventMultiReset(PSUPDRVSESSION pSession, SUPSEMEVENTMULTI hEventMulti)
    156192{
    157     return supSemOp(pSession, SUP_SEM_TYPE_EVENT_MULTI, (uintptr_t)hEventMulti, SUPSEMOP_RESET, 0);
     193    return supSemOp2(pSession, SUP_SEM_TYPE_EVENT_MULTI, (uintptr_t)hEventMulti, SUPSEMOP2_RESET, 0);
    158194}
    159195
     
    161197SUPDECL(int) SUPSemEventMultiWaitNoResume(PSUPDRVSESSION pSession, SUPSEMEVENTMULTI hEventMulti, uint32_t cMillies)
    162198{
    163     return supSemOp(pSession, SUP_SEM_TYPE_EVENT_MULTI, (uintptr_t)hEventMulti, SUPSEMOP_WAIT, cMillies);
    164 }
    165 
     199    return supSemOp2(pSession, SUP_SEM_TYPE_EVENT_MULTI, (uintptr_t)hEventMulti, SUPSEMOP2_WAIT_MS_REL, cMillies);
     200}
     201
     202
     203SUPDECL(int) SUPSemEventMultiWaitNsAbsIntr(PSUPDRVSESSION pSession, SUPSEMEVENTMULTI hEventMulti, uint64_t uNsTimeout)
     204{
     205    return supSemOp2(pSession, SUP_SEM_TYPE_EVENT_MULTI, (uintptr_t)hEventMulti, SUPSEMOP2_WAIT_NS_ABS, uNsTimeout);
     206}
     207
     208
     209SUPDECL(int) SUPSemEventMultiWaitNsRelIntr(PSUPDRVSESSION pSession, SUPSEMEVENTMULTI hEventMulti, uint64_t cNsTimeout)
     210{
     211    return supSemOp2(pSession, SUP_SEM_TYPE_EVENT_MULTI, (uintptr_t)hEventMulti, SUPSEMOP2_WAIT_NS_REL, cNsTimeout);
     212}
     213
     214
     215SUPDECL(uint32_t) SUPSemEventMultiGetResolution(PSUPDRVSESSION pSession)
     216{
     217    SUPSEMOP3 Req;
     218    int rc = supSemOp3(pSession, SUP_SEM_TYPE_EVENT_MULTI, (uintptr_t)NIL_SUPSEMEVENTMULTI, SUPSEMOP3_GET_RESOLUTION, &Req);
     219    if (RT_SUCCESS(rc))
     220        return Req.u.Out.cNsResolution;
     221    return 1000 / 100;
     222}
     223
  • trunk/src/VBox/HostDrivers/Support/SUPR0.def

    r32579 r33167  
    5656    SUPSemEventWait
    5757    SUPSemEventWaitNoResume
     58    SUPSemEventWaitNsAbsIntr
     59    SUPSemEventWaitNsRelIntr
     60    SUPSemEventGetResolution
    5861    SUPSemEventMultiCreate
    5962    SUPSemEventMultiClose
     
    6265    SUPSemEventMultiWait
    6366    SUPSemEventMultiWaitNoResume
     67    SUPSemEventMultiWaitNsAbsIntr
     68    SUPSemEventMultiWaitNsRelIntr
     69    SUPSemEventMultiGetResolution
    6470    SUPR0GetPagingMode
    6571    SUPR0EnableVTx
     
    101107    RTSemEventWait
    102108    RTSemEventWaitNoResume
     109    RTSemEventWaitEx
     110    RTSemEventWaitExDebug
     111    RTSemEventGetResolution
    103112    RTSemEventDestroy
    104113    RTSemEventMultiCreate
     
    107116    RTSemEventMultiWait
    108117    RTSemEventMultiWaitNoResume
     118    RTSemEventMultiWaitEx
     119    RTSemEventMultiWaitExDebug
     120    RTSemEventMultiGetResolution
    109121    RTSemEventMultiDestroy
    110122    RTSemFastMutexCreate
  • trunk/src/VBox/HostDrivers/Support/testcase/tstSupSem.cpp

    r33033 r33167  
    7070int main(int argc, char **argv)
    7171{
     72    bool fSys = true;
     73    bool fGip = false;
     74#if defined(RT_OS_WINDOWS) || defined(RT_OS_OS2)
     75    fGip = true;
     76#endif
     77
    7278    /*
    7379     * Init.
     
    283289#endif /* !OS2 && !WINDOWS */
    284290
    285     if (RTTestErrorCount(hTest) == 0)
    286291    {
    287         RTTestSub(hTest, "SRE Timeout Accuracy");
    288         RTTESTI_CHECK_RC(SUPSemEventCreate(pSession, &hEvent), VINF_SUCCESS);
    289 
    290292        static unsigned const s_acMsIntervals[] = { 0, 1, 2, 3, 4, 8, 10, 16, 32 };
    291         for (unsigned i = 0; i < RT_ELEMENTS(s_acMsIntervals); i++)
    292         {
    293             uint64_t cMs        = s_acMsIntervals[i];
    294             uint64_t cNsMinSys  = UINT64_MAX;
    295             uint64_t cNsMin     = UINT64_MAX;
    296             uint64_t cNsTotalSys= 0;
    297             uint64_t cNsTotal   = 0;
    298             for (unsigned j = 0; j < 10; j++)
     293        if (RTTestErrorCount(hTest) == 0)
     294        {
     295            RTTestSub(hTest, "SRE Timeout Accuracy (ms)");
     296            RTTESTI_CHECK_RC(SUPSemEventCreate(pSession, &hEvent), VINF_SUCCESS);
     297
     298            for (unsigned i = 0; i < RT_ELEMENTS(s_acMsIntervals); i++)
    299299            {
    300                 uint64_t u64StartSys = RTTimeSystemNanoTS();
    301                 uint64_t u64Start    = RTTimeNanoTS();
    302                 int rcX = SUPSemEventWaitNoResume(pSession, hEvent, cMs);
    303                 if (rc == VERR_TIMEOUT)
    304                     RTTestFailed(hTest, "%Rrc j=%u cMs=%u", rcX, j, cMs);
    305                 uint64_t cNsElapsedSys = RTTimeSystemNanoTS() - u64StartSys;
    306                 uint64_t cNsElapsed    = RTTimeNanoTS()       - u64Start;
    307                 if (cNsElapsedSys < cNsMinSys)
    308                     cNsMinSys = cNsElapsedSys;
    309                 if (cNsElapsed < cNsMin)
    310                     cNsMin = cNsElapsed;
    311                 cNsTotalSys += cNsElapsedSys;
    312                 cNsTotal    += cNsElapsed;
     300                uint64_t cMs        = s_acMsIntervals[i];
     301                uint64_t cNsMinSys  = UINT64_MAX;
     302                uint64_t cNsMin     = UINT64_MAX;
     303                uint64_t cNsTotalSys= 0;
     304                uint64_t cNsTotal   = 0;
     305                for (unsigned j = 0; j < 10; j++)
     306                {
     307                    uint64_t u64StartSys = RTTimeSystemNanoTS();
     308                    uint64_t u64Start    = RTTimeNanoTS();
     309                    int rcX = SUPSemEventWaitNoResume(pSession, hEvent, cMs);
     310                    if (rc == VERR_TIMEOUT)
     311                        RTTestFailed(hTest, "%Rrc j=%u cMs=%u", rcX, j, cMs);
     312                    uint64_t cNsElapsedSys = RTTimeSystemNanoTS() - u64StartSys;
     313                    uint64_t cNsElapsed    = RTTimeNanoTS()       - u64Start;
     314                    if (cNsElapsedSys < cNsMinSys)
     315                        cNsMinSys = cNsElapsedSys;
     316                    if (cNsElapsed < cNsMin)
     317                        cNsMin = cNsElapsed;
     318                    cNsTotalSys += cNsElapsedSys;
     319                    cNsTotal    += cNsElapsed;
     320                }
     321                if (fSys)
     322                {
     323                    RTTestValueF(hTest, cNsMinSys, RTTESTUNIT_NS,        "%u ms min (clock=sys)", cMs);
     324                    RTTestValueF(hTest, cNsTotalSys / 10, RTTESTUNIT_NS, "%u ms avg (clock=sys)", cMs);
     325                }
     326                if (fGip)
     327                {
     328                    RTTestValueF(hTest, cNsMin, RTTESTUNIT_NS,           "%u ms min (clock=gip)", cMs);
     329                    RTTestValueF(hTest, cNsTotal / 10, RTTESTUNIT_NS,    "%u ms avg (clock=gip)", cMs);
     330                }
    313331            }
    314             RTTestValueF(hTest, cNsMinSys, RTTESTUNIT_NS, "%u ms min (clock=sys)", cMs);
    315             RTTestValueF(hTest, cNsTotalSys / 10, RTTESTUNIT_NS, "%u ms avg - (clock=sys)", cMs);
    316             RTTestValueF(hTest, cNsMin, RTTESTUNIT_NS, "%u ms min (clock=gip)", cMs);
    317             RTTestValueF(hTest, cNsTotal / 10, RTTESTUNIT_NS, "%u ms avg - (clock=gip)", cMs);
     332
     333            RTTESTI_CHECK_RC(SUPSemEventClose(pSession, hEvent), VINF_OBJECT_DESTROYED);
    318334        }
    319335
    320         RTTESTI_CHECK_RC(SUPSemEventClose(pSession, hEvent), VINF_OBJECT_DESTROYED);
     336        if (RTTestErrorCount(hTest) == 0)
     337        {
     338            RTTestSub(hTest, "MRE Timeout Accuracy (ms)");
     339            RTTESTI_CHECK_RC(SUPSemEventMultiCreate(pSession, &hEvent), VINF_SUCCESS);
     340
     341            for (unsigned i = 0; i < RT_ELEMENTS(s_acMsIntervals); i++)
     342            {
     343                uint64_t cMs        = s_acMsIntervals[i];
     344                uint64_t cNsMinSys  = UINT64_MAX;
     345                uint64_t cNsMin     = UINT64_MAX;
     346                uint64_t cNsTotalSys= 0;
     347                uint64_t cNsTotal   = 0;
     348                for (unsigned j = 0; j < 10; j++)
     349                {
     350                    uint64_t u64StartSys = RTTimeSystemNanoTS();
     351                    uint64_t u64Start    = RTTimeNanoTS();
     352                    int rcX = SUPSemEventMultiWaitNoResume(pSession, hEvent, cMs);
     353                    if (rc == VERR_TIMEOUT)
     354                        RTTestFailed(hTest, "%Rrc j=%u cMs=%u", rcX, j, cMs);
     355                    uint64_t cNsElapsedSys = RTTimeSystemNanoTS() - u64StartSys;
     356                    uint64_t cNsElapsed    = RTTimeNanoTS()       - u64Start;
     357                    if (cNsElapsedSys < cNsMinSys)
     358                        cNsMinSys = cNsElapsedSys;
     359                    if (cNsElapsed < cNsMin)
     360                        cNsMin = cNsElapsed;
     361                    cNsTotalSys += cNsElapsedSys;
     362                    cNsTotal    += cNsElapsed;
     363                }
     364                if (fSys)
     365                {
     366                    RTTestValueF(hTest, cNsMinSys, RTTESTUNIT_NS,        "%u ms min (clock=sys)", cMs);
     367                    RTTestValueF(hTest, cNsTotalSys / 10, RTTESTUNIT_NS, "%u ms avg (clock=sys)", cMs);
     368                }
     369                if (fGip)
     370                {
     371                    RTTestValueF(hTest, cNsMin, RTTESTUNIT_NS,           "%u ms min (clock=gip)", cMs);
     372                    RTTestValueF(hTest, cNsTotal / 10, RTTESTUNIT_NS,    "%u ms avg (clock=gip)", cMs);
     373                }
     374            }
     375
     376            RTTESTI_CHECK_RC(SUPSemEventMultiClose(pSession, hEvent), VINF_OBJECT_DESTROYED);
     377        }
    321378    }
    322379
    323     if (RTTestErrorCount(hTest) == 0)
    324380    {
    325         RTTestSub(hTest, "MRE Timeout Accuracy");
    326         RTTESTI_CHECK_RC(SUPSemEventMultiCreate(pSession, &hEvent), VINF_SUCCESS);
    327 
    328         static unsigned const s_acMsIntervals[] = { 0, 1, 2, 3, 4, 8, 10, 16, 32 };
    329         for (unsigned i = 0; i < RT_ELEMENTS(s_acMsIntervals); i++)
    330         {
    331             uint64_t cMs        = s_acMsIntervals[i];
    332             uint64_t cNsMinSys  = UINT64_MAX;
    333             uint64_t cNsMin     = UINT64_MAX;
    334             uint64_t cNsTotalSys= 0;
    335             uint64_t cNsTotal   = 0;
    336             for (unsigned j = 0; j < 10; j++)
     381        static uint32_t const s_acNsIntervals[] =
     382        {
     383            0, 1000, 5000, 15000, 30000, 50000, 100000, 250000, 500000, 750000, 900000, 1500000, 2200000
     384        };
     385
     386        if (RTTestErrorCount(hTest) == 0)
     387        {
     388            RTTestSub(hTest, "SUPSemEventWaitNsRelIntr Accuracy");
     389            RTTestValueF(hTest, SUPSemEventGetResolution(pSession), RTTESTUNIT_NS, "SRE resolution");
     390            RTTESTI_CHECK_RC(SUPSemEventCreate(pSession, &hEvent), VINF_SUCCESS);
     391
     392            for (unsigned i = 0; i < RT_ELEMENTS(s_acNsIntervals); i++)
    337393            {
    338                 uint64_t u64StartSys = RTTimeSystemNanoTS();
    339                 uint64_t u64Start    = RTTimeNanoTS();
    340                 int rcX = SUPSemEventMultiWaitNoResume(pSession, hEvent, cMs);
    341                 if (rc == VERR_TIMEOUT)
    342                     RTTestFailed(hTest, "%Rrc j=%u cMs=%u", rcX, j, cMs);
    343                 uint64_t cNsElapsedSys = RTTimeSystemNanoTS() - u64StartSys;
    344                 uint64_t cNsElapsed    = RTTimeNanoTS()       - u64Start;
    345                 if (cNsElapsedSys < cNsMinSys)
    346                     cNsMinSys = cNsElapsedSys;
    347                 if (cNsElapsed < cNsMin)
    348                     cNsMin = cNsElapsed;
    349                 cNsTotalSys += cNsElapsedSys;
    350                 cNsTotal    += cNsElapsed;
     394                uint64_t cNs        = s_acNsIntervals[i];
     395                uint64_t cNsMinSys  = UINT64_MAX;
     396                uint64_t cNsMin     = UINT64_MAX;
     397                uint64_t cNsTotalSys= 0;
     398                uint64_t cNsTotal   = 0;
     399                for (unsigned j = 0; j < 10; j++)
     400                {
     401                    uint64_t u64StartSys = RTTimeSystemNanoTS();
     402                    uint64_t u64Start    = RTTimeNanoTS();
     403                    int rcX = SUPSemEventWaitNsRelIntr(pSession, hEvent, cNs);
     404                    if (rc == VERR_TIMEOUT)
     405                        RTTestFailed(hTest, "%Rrc j=%u cNs=%u", rcX, j, cNs);
     406                    uint64_t cNsElapsedSys = RTTimeSystemNanoTS() - u64StartSys;
     407                    uint64_t cNsElapsed    = RTTimeNanoTS()       - u64Start;
     408                    if (cNsElapsedSys < cNsMinSys)
     409                        cNsMinSys = cNsElapsedSys;
     410                    if (cNsElapsed < cNsMin)
     411                        cNsMin = cNsElapsed;
     412                    cNsTotalSys += cNsElapsedSys;
     413                    cNsTotal    += cNsElapsed;
     414                }
     415                if (fSys)
     416                {
     417                    RTTestValueF(hTest, cNsMinSys, RTTESTUNIT_NS,        "%'u ns min (clock=sys)", cNs);
     418                    RTTestValueF(hTest, cNsTotalSys / 10, RTTESTUNIT_NS, "%'u ns avg (clock=sys)", cNs);
     419                }
     420                if (fGip)
     421                {
     422                    RTTestValueF(hTest, cNsMin, RTTESTUNIT_NS,           "%'u ns min (clock=gip)", cNs);
     423                    RTTestValueF(hTest, cNsTotal / 10, RTTESTUNIT_NS,    "%'u ns avg (clock=gip)", cNs);
     424                }
    351425            }
    352             RTTestValueF(hTest, cNsMinSys, RTTESTUNIT_NS, "%u ms min (clock=sys)", cMs);
    353             RTTestValueF(hTest, cNsTotalSys / 10, RTTESTUNIT_NS, "%u ms avg - (clock=sys)", cMs);
    354             RTTestValueF(hTest, cNsMin, RTTESTUNIT_NS, "%u ms min (clock=gip)", cMs);
    355             RTTestValueF(hTest, cNsTotal / 10, RTTESTUNIT_NS, "%u ms avg - (clock=gip)", cMs);
     426
     427            RTTESTI_CHECK_RC(SUPSemEventClose(pSession, hEvent), VINF_OBJECT_DESTROYED);
    356428        }
    357429
    358         RTTESTI_CHECK_RC(SUPSemEventMultiClose(pSession, hEvent), VINF_OBJECT_DESTROYED);
     430        if (RTTestErrorCount(hTest) == 0)
     431        {
     432            RTTestSub(hTest, "SUPSemEventMultiWaitNsRelIntr Accuracy");
     433            RTTestValueF(hTest, SUPSemEventMultiGetResolution(pSession), RTTESTUNIT_NS, "MRE resolution");
     434            RTTESTI_CHECK_RC(SUPSemEventMultiCreate(pSession, &hEvent), VINF_SUCCESS);
     435
     436            for (unsigned i = 0; i < RT_ELEMENTS(s_acNsIntervals); i++)
     437            {
     438                uint64_t cNs        = s_acNsIntervals[i];
     439                uint64_t cNsMinSys  = UINT64_MAX;
     440                uint64_t cNsMin     = UINT64_MAX;
     441                uint64_t cNsTotalSys= 0;
     442                uint64_t cNsTotal   = 0;
     443                for (unsigned j = 0; j < 10; j++)
     444                {
     445                    uint64_t u64StartSys = RTTimeSystemNanoTS();
     446                    uint64_t u64Start    = RTTimeNanoTS();
     447                    int rcX = SUPSemEventMultiWaitNsRelIntr(pSession, hEvent, cNs);
     448                    if (rc == VERR_TIMEOUT)
     449                        RTTestFailed(hTest, "%Rrc j=%u cNs=%u", rcX, j, cNs);
     450                    uint64_t cNsElapsedSys = RTTimeSystemNanoTS() - u64StartSys;
     451                    uint64_t cNsElapsed    = RTTimeNanoTS()       - u64Start;
     452                    if (cNsElapsedSys < cNsMinSys)
     453                        cNsMinSys = cNsElapsedSys;
     454                    if (cNsElapsed < cNsMin)
     455                        cNsMin = cNsElapsed;
     456                    cNsTotalSys += cNsElapsedSys;
     457                    cNsTotal    += cNsElapsed;
     458                }
     459                if (fSys)
     460                {
     461                    RTTestValueF(hTest, cNsMinSys, RTTESTUNIT_NS,        "%'u ns min (clock=sys)", cNs);
     462                    RTTestValueF(hTest, cNsTotalSys / 10, RTTESTUNIT_NS, "%'u ns avg (clock=sys)", cNs);
     463                }
     464                if (fGip)
     465                {
     466                    RTTestValueF(hTest, cNsMin, RTTESTUNIT_NS,           "%'u ns min (clock=gip)", cNs);
     467                    RTTestValueF(hTest, cNsTotal / 10, RTTESTUNIT_NS,    "%'u ns avg (clock=gip)", cNs);
     468                }
     469            }
     470
     471            RTTESTI_CHECK_RC(SUPSemEventMultiClose(pSession, hEvent), VINF_OBJECT_DESTROYED);
     472        }
     473
     474        if (RTTestErrorCount(hTest) == 0)
     475        {
     476            RTTestSub(hTest, "SUPSemEventWaitNsAbsIntr Accuracy");
     477            RTTestValueF(hTest, SUPSemEventGetResolution(pSession), RTTESTUNIT_NS, "MRE resolution");
     478            RTTESTI_CHECK_RC(SUPSemEventCreate(pSession, &hEvent), VINF_SUCCESS);
     479
     480            for (unsigned i = 0; i < RT_ELEMENTS(s_acNsIntervals); i++)
     481            {
     482                uint64_t cNs        = s_acNsIntervals[i];
     483                uint64_t cNsMinSys  = UINT64_MAX;
     484                uint64_t cNsMin     = UINT64_MAX;
     485                uint64_t cNsTotalSys= 0;
     486                uint64_t cNsTotal   = 0;
     487                for (unsigned j = 0; j < 10; j++)
     488                {
     489                    uint64_t u64StartSys   = RTTimeSystemNanoTS();
     490                    uint64_t u64Start      = RTTimeNanoTS();
     491                    uint64_t uAbsDeadline  = (fGip ? u64Start : u64StartSys) + cNs;
     492                    int rcX = SUPSemEventWaitNsAbsIntr(pSession, hEvent, uAbsDeadline);
     493                    if (rc == VERR_TIMEOUT)
     494                        RTTestFailed(hTest, "%Rrc j=%u cNs=%u", rcX, j, cNs);
     495                    uint64_t cNsElapsedSys = RTTimeSystemNanoTS() - u64StartSys;
     496                    uint64_t cNsElapsed    = RTTimeNanoTS()       - u64Start;
     497                    if (cNsElapsedSys < cNsMinSys)
     498                        cNsMinSys = cNsElapsedSys;
     499                    if (cNsElapsed < cNsMin)
     500                        cNsMin = cNsElapsed;
     501                    cNsTotalSys += cNsElapsedSys;
     502                    cNsTotal    += cNsElapsed;
     503                }
     504                if (fSys)
     505                {
     506                    RTTestValueF(hTest, cNsMinSys, RTTESTUNIT_NS,        "%'u ns min (clock=sys)", cNs);
     507                    RTTestValueF(hTest, cNsTotalSys / 10, RTTESTUNIT_NS, "%'u ns avg (clock=sys)", cNs);
     508                }
     509                if (fGip)
     510                {
     511                    RTTestValueF(hTest, cNsMin, RTTESTUNIT_NS,           "%'u ns min (clock=gip)", cNs);
     512                    RTTestValueF(hTest, cNsTotal / 10, RTTESTUNIT_NS,    "%'u ns avg (clock=gip)", cNs);
     513                }
     514            }
     515
     516            RTTESTI_CHECK_RC(SUPSemEventClose(pSession, hEvent), VINF_OBJECT_DESTROYED);
     517        }
     518
     519
     520        if (RTTestErrorCount(hTest) == 0)
     521        {
     522            RTTestSub(hTest, "SUPSemEventMultiWaitNsAbsIntr Accuracy");
     523            RTTestValueF(hTest, SUPSemEventMultiGetResolution(pSession), RTTESTUNIT_NS, "MRE resolution");
     524            RTTESTI_CHECK_RC(SUPSemEventMultiCreate(pSession, &hEvent), VINF_SUCCESS);
     525
     526            for (unsigned i = 0; i < RT_ELEMENTS(s_acNsIntervals); i++)
     527            {
     528                uint64_t cNs        = s_acNsIntervals[i];
     529                uint64_t cNsMinSys  = UINT64_MAX;
     530                uint64_t cNsMin     = UINT64_MAX;
     531                uint64_t cNsTotalSys= 0;
     532                uint64_t cNsTotal   = 0;
     533                for (unsigned j = 0; j < 10; j++)
     534                {
     535                    uint64_t u64StartSys   = RTTimeSystemNanoTS();
     536                    uint64_t u64Start      = RTTimeNanoTS();
     537                    uint64_t uAbsDeadline  = (fGip ? u64Start : u64StartSys) + cNs;
     538                    int rcX = SUPSemEventMultiWaitNsAbsIntr(pSession, hEvent, uAbsDeadline);
     539                    if (rc == VERR_TIMEOUT)
     540                        RTTestFailed(hTest, "%Rrc j=%u cNs=%u", rcX, j, cNs);
     541                    uint64_t cNsElapsedSys = RTTimeSystemNanoTS() - u64StartSys;
     542                    uint64_t cNsElapsed    = RTTimeNanoTS()       - u64Start;
     543                    if (cNsElapsedSys < cNsMinSys)
     544                        cNsMinSys = cNsElapsedSys;
     545                    if (cNsElapsed < cNsMin)
     546                        cNsMin = cNsElapsed;
     547                    cNsTotalSys += cNsElapsedSys;
     548                    cNsTotal    += cNsElapsed;
     549                }
     550                if (fSys)
     551                {
     552                    RTTestValueF(hTest, cNsMinSys, RTTESTUNIT_NS,        "%'u ns min (clock=sys)", cNs);
     553                    RTTestValueF(hTest, cNsTotalSys / 10, RTTESTUNIT_NS, "%'u ns avg (clock=sys)", cNs);
     554                }
     555                if (fGip)
     556                {
     557                    RTTestValueF(hTest, cNsMin, RTTESTUNIT_NS,           "%'u ns min (clock=gip)", cNs);
     558                    RTTestValueF(hTest, cNsTotal / 10, RTTESTUNIT_NS,    "%'u ns avg (clock=gip)", cNs);
     559                }
     560            }
     561
     562            RTTESTI_CHECK_RC(SUPSemEventMultiClose(pSession, hEvent), VINF_OBJECT_DESTROYED);
     563        }
     564
    359565    }
    360566
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