VirtualBox

Changeset 32946 in vbox


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].

Location:
trunk
Files:
2 added
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/iprt/semaphore.h

    r31155 r32946  
    4646 * @{
    4747 */
     48
     49
     50/** @name Generic Semaphore Wait Flags.
     51 *
     52 * @remarks Exactly one of RTSEMWAIT_FLAGS_RELATIVE and
     53 *          RTSEMWAIT_FLAGS_ABSOLUTE must be set, unless
     54 *          RTSEMWAIT_FLAGS_INDEFINITE is used.
     55 *
     56 *          Exactly one of RTSEMWAIT_FLAGS_NANOSECS and
     57 *          RTSEMWAIT_FLAGS_MILLISECS must be set, unless
     58 *          RTSEMWAIT_FLAGS_INDEFINITE is used.
     59 *
     60 *          Exactly one of RTSEMWAIT_FLAGS_RESUME and RTSEMWAIT_FLAGS_NORESUME
     61 *          must be set.
     62 *
     63 *          The interruptible vs resume stuff is ring-0 vs ring-3 semantics.
     64 *
     65 * @{ */
     66/** The timeout is relative. */
     67#define RTSEMWAIT_FLAGS_RELATIVE            RT_BIT_32(0)
     68/** The timeout is absolute. */
     69#define RTSEMWAIT_FLAGS_ABSOLUTE            RT_BIT_32(1)
     70/** The timeout is specified in nanoseconds. */
     71#define RTSEMWAIT_FLAGS_NANOSECS            RT_BIT_32(2)
     72/** The timeout is specified in milliseconds. */
     73#define RTSEMWAIT_FLAGS_MILLISECS           RT_BIT_32(3)
     74/** Indefinite wait.
     75 * The relative/absolute and nano-/millisecond flags are ignored. */
     76#define RTSEMWAIT_FLAGS_INDEFINITE          RT_BIT_32(4)
     77/** Mask covering the time related bits. */
     78#define RTSEMWAIT_FLAGS_TIME_MASK           UINT32_C(0x0000001f)
     79
     80/** Interruptible wait. */
     81#define RTSEMWAIT_FLAGS_INTERRUPTIBLE       RT_BIT_32(5)
     82/** No automatic resume, same as interruptible. */
     83#define RTSEMWAIT_FLAGS_NORESUME            RTSEMWAIT_FLAGS_INTERRUPTIBLE
     84/** Uninterruptible wait. */
     85#define RTSEMWAIT_FLAGS_UNINTERRUPTIBLE     RT_BIT_32(6)
     86/** Resume on interrupt, same as uninterruptible. */
     87#define RTSEMWAIT_FLAGS_RESUME              RTSEMWAIT_FLAGS_UNINTERRUPTIBLE
     88
     89/** Macro for validate the flags. */
     90#define RTSEMWAIT_FLAGS_ARE_VALID(fFlags) \
     91    (   !((fFlags) & UINT32_C(0xffffff80)) \
     92     &&  (  ((fFlags) & RTSEMWAIT_FLAGS_INDEFINITE) \
     93          ? ( (((fFlags) & UINT32_C(0x20))) ^ (((fFlags) >> 1) & UINT32_C(0x20)) ) == UINT32_C(0x20) \
     94          : ( (((fFlags) & UINT32_C(0x25))) ^ (((fFlags) >> 1) & UINT32_C(0x25)) ) == UINT32_C(0x25) ))
     95/** @}  */
     96
    4897
    4998
     
    94143 *
    95144 * @returns iprt status code.
    96  * @param   hEventSem           Handle of the event sempahore.  NIL_RTSEMEVENT
     145 * @param   hEventSem           Handle of the event semaphore.  NIL_RTSEMEVENT
    97146 *                              is quitely ignored (VINF_SUCCESS).
    98147 */
     
    138187 */
    139188RTDECL(int)  RTSemEventWaitNoResume(RTSEMEVENT hEventSem, RTMSINTERVAL cMillies);
     189
     190/**
     191 * Extended API for waiting on an event semaphore to be signaled.
     192 *
     193 * @returns IPRT status code.
     194 * @param   hEventSem           The event semaphore to wait on.
     195 * @param   fFlags              Combination of RTSEMWAIT_FLAGS_XXX.
     196 * @param   uTimeout            The timeout, ignored if
     197 *                              RTSEMWAIT_FLAGS_INDEFINITE is set in @a flags.
     198 *                              Whether this is absolute or relative,
     199 *                              milliseconds or nanoseconds depends on the @a
     200 *                              fFlags value.  Do not pass RT_INDEFINITE_WAIT
     201 *                              here, use RTSEMWAIT_FLAGS_INDEFINITE instead.
     202 */
     203RTDECL(int)  RTSemEventWaitEx(RTSEMEVENT hEventSem, uint32_t fFlags, uint64_t uTimeout);
     204
     205/**
     206 * Debug version of RTSemEventWaitEx that tracks the location.
     207 *
     208 * @returns IPRT status code, see RTSemEventWaitEx.
     209 * @param   hEventSem           The event semaphore to wait on.
     210 * @param   fFlags              See RTSemEventWaitEx.
     211 * @param   uTimeout            See RTSemEventWaitEx.
     212 * @param   uId                 Some kind of locking location ID.  Typically a
     213 *                              return address up the stack.  Optional (0).
     214 * @param   pszFile             The file where the lock is being acquired from.
     215 *                              Optional.
     216 * @param   iLine               The line number in that file.  Optional (0).
     217 * @param   pszFunction         The function where the lock is being acquired
     218 *                              from.  Optional.
     219 */
     220RTDECL(int)  RTSemEventWaitExDebug(RTSEMEVENT hEventSem, uint32_t fFlags, uint64_t uTimeout,
     221                                   RTHCUINTPTR uId, RT_SRC_POS_DECL);
    140222
    141223/**
     
    222304 *
    223305 * @returns iprt status code.
    224  * @param   hEventMultiSem      The multiple release event sempahore.  NIL is
     306 * @param   hEventMultiSem      The multiple release event semaphore.  NIL is
    225307 *                              quietly ignored (VINF_SUCCESS).
    226308 */
     
    231313 *
    232314 * @returns iprt status code.
    233  * @param   hEventMultiSem      The multiple release event sempahore.
     315 * @param   hEventMultiSem      The multiple release event semaphore.
    234316 *
    235317 * @remarks ring-0: This works when preemption is disabled.  However it is
     
    243325 *
    244326 * @returns iprt status code.
    245  * @param   hEventMultiSem      The multiple release event sempahore.
     327 * @param   hEventMultiSem      The multiple release event semaphore.
    246328 */
    247329RTDECL(int)  RTSemEventMultiReset(RTSEMEVENTMULTI hEventMultiSem);
     
    255337 * @returns iprt status code.
    256338 *          Will not return VERR_INTERRUPTED.
    257  * @param   hEventMultiSem      The multiple release event sempahore.
     339 * @param   hEventMultiSem      The multiple release event semaphore.
    258340 * @param   cMillies            Number of milliseconds to wait.
    259341 */
    260342RTDECL(int)  RTSemEventMultiWait(RTSEMEVENTMULTI hEventMultiSem, RTMSINTERVAL cMillies);
    261343
    262 
    263344/**
    264345 * Wait for the event multi semaphore to be signaled, return on interruption.
     
    267348 *
    268349 * @returns iprt status code.
    269  * @param   hEventMultiSem      The multiple release event sempahore.
     350 * @param   hEventMultiSem      The multiple release event semaphore.
    270351 * @param   cMillies            Number of milliseconds to wait.
    271352 */
    272353RTDECL(int)  RTSemEventMultiWaitNoResume(RTSEMEVENTMULTI hEventMultiSem, RTMSINTERVAL cMillies);
     354
     355/**
     356 * Extended API for waiting on an event semaphore to be signaled.
     357 *
     358 * @returns IPRT status code.
     359 * @param   hEventMultiSem      The multiple release event semaphore to wait
     360 *                              on.
     361 * @param   fFlags              Combination of the RTSEMWAIT_FLAGS_XXX.
     362 * @param   uTimeout            The timeout, ignored if
     363 *                              RTSEMWAIT_FLAGS_INDEFINITE is set in @a flags.
     364 *                              Whether this is absolute or relative,
     365 *                              milliseconds or nanoseconds depends on the @a
     366 *                              fFlags value.  Do not pass RT_INDEFINITE_WAIT
     367 *                              here, use RTSEMWAIT_FLAGS_INDEFINITE instead.
     368 */
     369RTDECL(int)  RTSemEventMultiWaitEx(RTSEMEVENTMULTI hEventMultiSem, uint32_t fFlags, uint64_t uTimeout);
     370
     371/**
     372 * Debug version of RTSemEventMultiWaitEx that tracks the location.
     373
     374 * @returns IPRT status code, see RTSemEventMultiWaitEx.
     375 * @param   hEventMultiSem      The multiple release event semaphore handle.
     376 * @param   fFlags              See RTSemEventMultiWaitEx.
     377 * @param   uTimeout            See RTSemEventMultiWaitEx.
     378 * @param   uId                 Some kind of locking location ID.  Typically a
     379 *                              return address up the stack.  Optional (0).
     380 * @param   pszFile             The file where the lock is being acquired from.
     381 *                              Optional.
     382 * @param   iLine               The line number in that file.  Optional (0).
     383 * @param   pszFunction         The function where the lock is being acquired
     384 *                              from.  Optional.
     385 */
     386RTDECL(int)  RTSemEventMultiWaitExDebug(RTSEMEVENTMULTI hEventMultiSem, uint32_t fFlags, uint64_t uTimeout,
     387                                        RTHCUINTPTR uId, RT_SRC_POS_DECL);
    273388
    274389/**
     
    370485 * Changes the lock validator sub-class of the mutex semaphore.
    371486 *
    372  * It is recommended to try make sure that nobody is using this sempahore while
     487 * It is recommended to try make sure that nobody is using this semaphore while
    373488 * changing the value.
    374489 *
     
    425540 *                              Optional.
    426541 * @param   iLine               The line number in that file.  Optional (0).
    427  * @param   pszFunction         The functionn where the lock is being acquired
     542 * @param   pszFunction         The function where the lock is being acquired
    428543 *                              from.  Optional.
    429544 */
     
    441556 *                              Optional.
    442557 * @param   iLine               The line number in that file.  Optional (0).
    443  * @param   pszFunction         The functionn where the lock is being acquired
     558 * @param   pszFunction         The function where the lock is being acquired
    444559 *                              from.  Optional.
    445560 */
    446561RTDECL(int)  RTSemMutexRequestNoResumeDebug(RTSEMMUTEX hMutexSem, RTMSINTERVAL cMillies, RTHCUINTPTR uId, RT_SRC_POS_DECL);
     562
     563/**
     564 * Request ownership of a mutex semaphore, extended edition.
     565 *
     566 * The same thread may request a mutex semaphore multiple times,
     567 * a nested counter is kept to make sure it's released on the right
     568 * RTSemMutexRelease() call.
     569 *
     570 * @returns iprt status code.
     571 * @param   hMutexSem           The mutex semaphore to request ownership over.
     572 * @param   fFlags              Combination of the RTSEMWAIT_FLAGS_XXX.
     573 * @param   uTimeout            The timeout, ignored if
     574 *                              RTSEMWAIT_FLAGS_INDEFINITE is set in @a flags.
     575 *                              Whether this is absolute or relative,
     576 *                              milliseconds or nanoseconds depends on the @a
     577 *                              fFlags value.  Do not pass RT_INDEFINITE_WAIT
     578 *                              here, use RTSEMWAIT_FLAGS_INDEFINITE instead.
     579 */
     580RTDECL(int)  RTSemMutexRequestEx(RTSEMMUTEX hMutexSem, uint32_t fFlags, uint64_t uTimeout);
     581
     582/**
     583 * Debug version of RTSemMutexRequestEx that tracks the location.
     584 *
     585 * @returns iprt status code.
     586 * @param   hMutexSem           The mutex semaphore to request ownership over.
     587 * @param   fFlags              See RTSemMutexRequestEx.
     588 * @param   uTimeout            See RTSemMutexRequestEx.
     589 * @param   uId                 Some kind of locking location ID.  Typically a
     590 *                              return address up the stack.  Optional (0).
     591 * @param   pszFile             The file where the lock is being acquired from.
     592 *                              Optional.
     593 * @param   iLine               The line number in that file.  Optional (0).
     594 * @param   pszFunction         The function where the lock is being acquired
     595 *                              from.  Optional.
     596 */
     597RTDECL(int)  RTSemMutexRequestExDebug(RTSEMMUTEX hMutexSem, uint32_t fFlags, uint64_t uTimeout,
     598                                      RTHCUINTPTR uId, RT_SRC_POS_DECL);
    447599
    448600/**
     
    467619#ifdef RT_STRICT
    468620# ifdef ___iprt_asm_h
    469 #  define RTSemMutexRequest(pCritSect, cMillies)            RTSemMutexRequestDebug((pCritSect), (cMillies), (uintptr_t)ASMReturnAddress(), RT_SRC_POS)
    470 #  define RTSemMutexRequestNoResume(pCritSect, cMillies)    RTSemMutexRequestNoResumeDebug((pCritSect), (cMillies), (uintptr_t)ASMReturnAddress(), RT_SRC_POS)
     621#  define RTSemMutexRequest(hMutexSem, cMillies)            RTSemMutexRequestDebug((hMutexSem), (cMillies), (uintptr_t)ASMReturnAddress(), RT_SRC_POS)
     622#  define RTSemMutexRequestNoResume(hMutexSem, cMillies)    RTSemMutexRequestNoResumeDebug((hMutexSem), (cMillies), (uintptr_t)ASMReturnAddress(), RT_SRC_POS)
     623#  define RTSemMutexRequestEx(hMutexSem, fFlags, uTimeout)  RTSemMutexRequestExDebug((hMutexSem), (fFlags), (uTimeout), (uintptr_t)ASMReturnAddress(), RT_SRC_POS)
    471624# else
    472 #  define RTSemMutexRequest(pCritSect, cMillies)            RTSemMutexRequestDebug((pCritSect), (cMillies), 0, RT_SRC_POS)
    473 #  define RTSemMutexRequestNoResume(pCritSect, cMillies)    RTSemMutexRequestNoResumeDebug((pCritSect), (cMillies), 0, RT_SRC_POS)
     625#  define RTSemMutexRequest(hMutexSem, cMillies)            RTSemMutexRequestDebug((hMutexSem), (cMillies), 0, RT_SRC_POS)
     626#  define RTSemMutexRequestNoResume(hMutexSem, cMillies)    RTSemMutexRequestNoResumeDebug((hMutexSem), (cMillies), 0, RT_SRC_POS)
     627#  define RTSemMutexRequestEx(hMutexSem, fFlags, uTimeout)  RTSemMutexRequestExDebug((hMutexSem), (fFlags), (uTimeout), 0, RT_SRC_POS)
    474628# endif
    475629#endif
     
    691845 * Changes the lock validator sub-class of the read/write semaphore.
    692846 *
    693  * It is recommended to try make sure that nobody is using this sempahore while
     847 * It is recommended to try make sure that nobody is using this semaphore while
    694848 * changing the value.
    695849 *
     
    743897 *                              Optional.
    744898 * @param   iLine               The line number in that file.  Optional (0).
    745  * @param   pszFunction         The functionn where the lock is being acquired
     899 * @param   pszFunction         The function where the lock is being acquired
    746900 *                              from.  Optional.
    747901 */
     
    763917 *                              Optional.
    764918 * @param   iLine               The line number in that file.  Optional (0).
    765  * @param   pszFunction         The functionn where the lock is being acquired
     919 * @param   pszFunction         The function where the lock is being acquired
    766920 *                              from.  Optional.
    767921 */
    768922RTDECL(int)   RTSemRWRequestReadNoResumeDebug(RTSEMRW hRWSem, RTMSINTERVAL cMillies, RTHCUINTPTR uId, RT_SRC_POS_DECL);
     923
     924/**
     925 * Request read access to a read/write semaphore, extended edition.
     926 *
     927 * @returns iprt status code.
     928 * @retval  VINF_SUCCESS on success.
     929 * @retval  VERR_INTERRUPT if the wait was interrupted.
     930 * @retval  VERR_TIMEOUT if the wait timed out.
     931 * @retval  VERR_INVALID_HANDLE if hRWSem is invalid.
     932 *
     933 * @param   hRWSem              Handle to the read/write semaphore.
     934 * @param   fFlags              Combination of the RTSEMWAIT_FLAGS_XXX.
     935 * @param   uTimeout            The timeout, ignored if
     936 *                              RTSEMWAIT_FLAGS_INDEFINITE is set in @a flags.
     937 *                              Whether this is absolute or relative,
     938 *                              milliseconds or nanoseconds depends on the @a
     939 *                              fFlags value.  Do not pass RT_INDEFINITE_WAIT
     940 *                              here, use RTSEMWAIT_FLAGS_INDEFINITE instead.
     941 */
     942RTDECL(int)   RTSemRWRequestReadEx(RTSEMRW hRWSem, uint32_t fFlags, uint64_t uTimeout);
     943
     944
     945/**
     946 * Debug version of RTSemRWRequestReadEx that tracks the location.
     947 *
     948 * @returns iprt status code.
     949 * @retval  VINF_SUCCESS on success.
     950 * @retval  VERR_INTERRUPT if the wait was interrupted.
     951 * @retval  VERR_TIMEOUT if the wait timed out.
     952 * @retval  VERR_INVALID_HANDLE if hRWSem is invalid.
     953 *
     954 * @param   hRWSem              Handle to the read/write semaphore.
     955 * @param   fFlags              See RTSemRWRequestReadEx.
     956 * @param   uTimeout            See RTSemRWRequestReadEx.
     957 * @param   uId                 Some kind of locking location ID.  Typically a
     958 *                              return address up the stack.  Optional (0).
     959 * @param   pszFile             The file where the lock is being acquired from.
     960 *                              Optional.
     961 * @param   iLine               The line number in that file.  Optional (0).
     962 * @param   pszFunction         The function where the lock is being acquired
     963 *                              from.  Optional.
     964 */
     965RTDECL(int)   RTSemRWRequestReadExDebug(RTSEMRW hRWSem, uint32_t fFlags, uint64_t uTimeout,
     966                                        RTHCUINTPTR uId, RT_SRC_POS_DECL);
    769967
    770968/**
     
    8161014 *                              Optional.
    8171015 * @param   iLine               The line number in that file.  Optional (0).
    818  * @param   pszFunction         The functionn where the lock is being acquired
     1016 * @param   pszFunction         The function where the lock is being acquired
    8191017 *                              from.  Optional.
    8201018 */
     
    8321030 *                              Optional.
    8331031 * @param   iLine               The line number in that file.  Optional (0).
    834  * @param   pszFunction         The functionn where the lock is being acquired
     1032 * @param   pszFunction         The function where the lock is being acquired
    8351033 *                              from.  Optional.
    8361034 */
    8371035RTDECL(int)  RTSemRWRequestWriteNoResumeDebug(RTSEMRW hRWSem, RTMSINTERVAL cMillies, RTHCUINTPTR uId, RT_SRC_POS_DECL);
     1036
     1037/**
     1038 * Request write access to a read/write semaphore, extended edition.
     1039 *
     1040 * @returns iprt status code.
     1041 * @retval  VINF_SUCCESS on success.
     1042 * @retval  VERR_INTERRUPTED if the wait was interrupted.
     1043 * @retval  VERR_TIMEOUT if the wait timed out.
     1044 * @retval  VERR_DEADLOCK if the caller owned the read lock.  Do not depend on
     1045 *          this as it is implementation specific.
     1046 * @retval  VERR_INVALID_HANDLE if hRWSem is invalid.
     1047 *
     1048 * @param   hRWSem              Handle to the read/write semaphore.
     1049 * @param   fFlags              Combination of the RTSEMWAIT_FLAGS_XXX.
     1050 * @param   uTimeout            The timeout, ignored if
     1051 *                              RTSEMWAIT_FLAGS_INDEFINITE is set in @a flags.
     1052 *                              Whether this is absolute or relative,
     1053 *                              milliseconds or nanoseconds depends on the @a
     1054 *                              fFlags value.  Do not pass RT_INDEFINITE_WAIT
     1055 *                              here, use RTSEMWAIT_FLAGS_INDEFINITE instead.
     1056 */
     1057RTDECL(int)   RTSemRWRequestWriteEx(RTSEMRW hRWSem, uint32_t fFlags, uint64_t uTimeout);
     1058
     1059/**
     1060 * Debug version of RTSemRWRequestWriteEx that tracks the location.
     1061 *
     1062 * @returns IPRT status code, see RTSemRWRequestWriteEx.
     1063 * @param   hRWSem              Handle to the read/write semaphore.
     1064 * @param   fFlags              See RTSemRWRequestWriteEx.
     1065 * @param   uTimeout            See RTSemRWRequestWriteEx.
     1066 * @param   uId                 Some kind of locking location ID.  Typically a
     1067 *                              return address up the stack.  Optional (0).
     1068 * @param   pszFile             The file where the lock is being acquired from.
     1069 *                              Optional.
     1070 * @param   iLine               The line number in that file.  Optional (0).
     1071 * @param   pszFunction         The function where the lock is being acquired
     1072 *                              from.  Optional.
     1073 */
     1074RTDECL(int)  RTSemRWRequestWriteExDebug(RTSEMRW hRWSem, uint32_t fFlags, uint64_t uTimeout,
     1075                                        RTHCUINTPTR uId, RT_SRC_POS_DECL);
    8381076
    8391077/**
     
    8561094
    8571095/**
    858  * Checks if the caller is one of the read owners of the sempahore.
     1096 * Checks if the caller is one of the read owners of the semaphore.
    8591097 *
    8601098 * @note    !CAUTION!  This API doesn't work reliably if lock validation isn't
     
    9061144#ifdef RT_STRICT
    9071145# ifdef ___iprt_asm_h
    908 #  define RTSemRWRequestRead(pCritSect, cMillies)           RTSemRWRequestReadDebug((pCritSect), (cMillies), (uintptr_t)ASMReturnAddress(), RT_SRC_POS)
    909 #  define RTSemRWRequestReadNoResume(pCritSect, cMillies)   RTSemRWRequestReadNoResumeDebug((pCritSect), (cMillies), (uintptr_t)ASMReturnAddress(), RT_SRC_POS)
    910 #  define RTSemRWRequestWrite(pCritSect, cMillies)          RTSemRWRequestWriteDebug((pCritSect), (cMillies), (uintptr_t)ASMReturnAddress(), RT_SRC_POS)
    911 #  define RTSemRWRequestWriteNoResume(pCritSect, cMillies)  RTSemRWRequestWriteNoResumeDebug((pCritSect), (cMillies), (uintptr_t)ASMReturnAddress(), RT_SRC_POS)
     1146#  define RTSemRWRequestRead(hRWSem, cMillies)              RTSemRWRequestReadDebug((hRWSem), (cMillies), (uintptr_t)ASMReturnAddress(), RT_SRC_POS)
     1147#  define RTSemRWRequestReadNoResume(hRWSem, cMillies)      RTSemRWRequestReadNoResumeDebug((hRWSem), (cMillies), (uintptr_t)ASMReturnAddress(), RT_SRC_POS)
     1148#  define RTSemRWRequestWrite(hRWSem, cMillies)             RTSemRWRequestWriteDebug((hRWSem), (cMillies), (uintptr_t)ASMReturnAddress(), RT_SRC_POS)
     1149#  define RTSemRWRequestWriteNoResume(hRWSem, cMillies)     RTSemRWRequestWriteNoResumeDebug((hRWSem), (cMillies), (uintptr_t)ASMReturnAddress(), RT_SRC_POS)
     1150#  define RTSemRWRequestWriteEx(hRWSem, fFlags, uTimeout)   RTSemRWRequestWriteExDebug((hRWSem), (fFlags), (uTimeout), (uintptr_t)ASMReturnAddress(), RT_SRC_POS)
    9121151# else
    913 #  define RTSemRWRequestRead(pCritSect, cMillies)           RTSemRWRequestReadDebug((pCritSect), (cMillies), 0, RT_SRC_POS)
    914 #  define RTSemRWRequestReadNoResume(pCritSect, cMillies)   RTSemRWRequestReadNoResumeDebug((pCritSect), (cMillies), 0, RT_SRC_POS)
    915 #  define RTSemRWRequestWrite(pCritSect, cMillies)          RTSemRWRequestWriteDebug((pCritSect), (cMillies), 0, RT_SRC_POS)
    916 #  define RTSemRWRequestWriteNoResume(pCritSect, cMillies)  RTSemRWRequestWriteNoResumeDebug((pCritSect), (cMillies), 0, RT_SRC_POS)
     1152#  define RTSemRWRequestRead(hRWSem, cMillies)              RTSemRWRequestReadDebug((hRWSem), (cMillies), 0, RT_SRC_POS)
     1153#  define RTSemRWRequestReadNoResume(hRWSem, cMillies)      RTSemRWRequestReadNoResumeDebug((hRWSem), (cMillies), 0, RT_SRC_POS)
     1154#  define RTSemRWRequestWrite(hRWSem, cMillies)             RTSemRWRequestWriteDebug((hRWSem), (cMillies), 0, RT_SRC_POS)
     1155#  define RTSemRWRequestWriteNoResume(hRWSem, cMillies)     RTSemRWRequestWriteNoResumeDebug((hRWSem), (cMillies), 0, RT_SRC_POS)
     1156#  define RTSemRWRequestWriteEx(hRWSem, fFlags, uTimeout)   RTSemRWRequestWriteExDebug((hRWSem), (fFlags), (uTimeout), 0, RT_SRC_POS)
    9171157# endif
    9181158#endif
  • trunk/src/VBox/Runtime/Makefile.kmk

    r32656 r32946  
    545545        r3/linux/semeventmulti-linux.cpp \
    546546        r3/linux/semmutex-linux.cpp
     547#       generic/RTSemEventMultiWait-2-ex-generic.cpp \
     548#       generic/RTSemEventMultiWaitNoResume-2-ex-generic.cpp
    547549else
    548550 RuntimeR3_SOURCES.linux.x86 += \
     
    553555        r3/linux/semevent-linux.cpp \
    554556        r3/linux/semeventmulti-linux.cpp
     557#       generic/RTSemEventMultiWait-2-ex-generic.cpp \
     558#       generic/RTSemEventMultiWaitNoResume-2-ex-generic.cpp
    555559 ifdef RT_NEW_LINUX_MUTEX_CODE
    556560  RuntimeR3_SOURCES.linux.amd64 += \
  • trunk/src/VBox/Runtime/r3/linux/semeventmulti-linux.cpp

    r28800 r32946  
    55
    66/*
    7  * Copyright (C) 2006-2007 Oracle Corporation
     7 * Copyright (C) 2006-2010 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    248248
    249249
    250 static int rtSemEventMultiWait(RTSEMEVENTMULTI hEventMultiSem, RTMSINTERVAL cMillies, bool fAutoResume)
    251 {
    252     PCRTLOCKVALSRCPOS pSrcPos = NULL;
    253 
     250
     251DECLINLINE(int) rtSemEventLnxMultiWait(struct RTSEMEVENTMULTIINTERNAL *pThis, uint32_t fFlags, uint64_t uTimeout,
     252                                       PCRTLOCKVALSRCPOS pSrcPos)
     253{
    254254    /*
    255255     * Validate input.
    256256     */
    257     struct RTSEMEVENTMULTIINTERNAL *pThis = hEventMultiSem;
    258     AssertReturn(VALID_PTR(pThis) && pThis->u32Magic == RTSEMEVENTMULTI_MAGIC,
    259                  VERR_INVALID_HANDLE);
     257    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
     258    AssertReturn(pThis->u32Magic == RTSEMEVENTMULTI_MAGIC, VERR_INVALID_HANDLE);
     259    AssertReturn(RTSEMWAIT_FLAGS_ARE_VALID(fFlags), VERR_INVALID_PARAMETER);
    260260
    261261    /*
     
    268268
    269269    /*
    270      * Convert the timeout value.
     270     * Check and convert the timeout value.
    271271     */
    272272    struct timespec ts;
    273273    struct timespec *pTimeout = NULL;
    274     uint64_t u64End = 0; /* shut up gcc */
    275     if (cMillies != RT_INDEFINITE_WAIT)
     274    uint64_t u64Deadline = 0; /* shut up gcc */
     275    if (!(fFlags & RTSEMWAIT_FLAGS_INDEFINITE))
    276276    {
    277277        /* If the timeout is zero, then we're done. */
    278         if (!cMillies)
     278        if (!uTimeout)
    279279            return VERR_TIMEOUT;
    280         ts.tv_sec  = cMillies / 1000;
    281         ts.tv_nsec = (cMillies % 1000) * UINT32_C(1000000);
    282         u64End = RTTimeSystemNanoTS() + cMillies * UINT64_C(1000000);
    283         pTimeout = &ts;
     280
     281        /* Convert it to a deadline + interval timespec. */
     282        if (fFlags & RTSEMWAIT_FLAGS_MILLISECS)
     283            uTimeout = uTimeout < UINT64_MAX / UINT32_C(1000000) * UINT32_C(1000000)
     284                     ? uTimeout * UINT32_C(1000000)
     285                     : UINT64_MAX;
     286        if (uTimeout != UINT64_MAX) /* unofficial way of indicating an indefinite wait */
     287        {
     288            if (fFlags & RTSEMWAIT_FLAGS_RELATIVE)
     289                u64Deadline = RTTimeSystemNanoTS();
     290            else
     291            {
     292                uint64_t u64Now = RTTimeSystemNanoTS();
     293                if (uTimeout <= u64Now)
     294                    return VERR_TIMEOUT;
     295                u64Deadline = uTimeout;
     296                uTimeout   -= u64Now;
     297            }
     298            if (   sizeof(ts.tv_sec) >= sizeof(uint64_t)
     299                || uTimeout <= UINT64_C(1000000000) * UINT32_MAX)
     300            {
     301                ts.tv_nsec = uTimeout % UINT32_C(1000000000);
     302                ts.tv_sec  = uTimeout / UINT32_C(1000000000);
     303                pTimeout = &ts;
     304            }
     305        }
    284306    }
    285307
     
    306328            if (pTimeout)
    307329            {
    308                 int64_t i64Diff = u64End - RTTimeSystemNanoTS();
     330                int64_t i64Diff = u64Deadline - RTTimeSystemNanoTS();
    309331                if (i64Diff < 1000)
    310332                    return VERR_TIMEOUT;
     
    316338            {
    317339                int rc9 = RTLockValidatorRecSharedCheckBlocking(&pThis->Signallers, hThreadSelf, pSrcPos, false,
    318                                                                 cMillies, RTTHREADSTATE_EVENT_MULTI, true);
     340                                                                uTimeout / UINT32_C(1000000), RTTHREADSTATE_EVENT_MULTI, true);
    319341                if (RT_FAILURE(rc9))
    320342                    return rc9;
     
    344366            else if (rc == -EINTR)
    345367            {
    346                 if (!fAutoResume)
     368                if (fFlags & RTSEMWAIT_FLAGS_NORESUME)
    347369                    return VERR_INTERRUPTED;
    348370            }
     
    360382
    361383
    362 RTDECL(int)  RTSemEventMultiWait(RTSEMEVENTMULTI hEventMultiSem, RTMSINTERVAL cMillies)
    363 {
    364     int rc = rtSemEventMultiWait(hEventMultiSem, cMillies, true);
    365     Assert(rc != VERR_INTERRUPTED);
    366     return rc;
    367 }
    368 
    369 
    370 RTDECL(int)  RTSemEventMultiWaitNoResume(RTSEMEVENTMULTI hEventMultiSem, RTMSINTERVAL cMillies)
    371 {
    372     return rtSemEventMultiWait(hEventMultiSem, cMillies, false);
     384#undef RTSemEventMultiWaitEx
     385RTDECL(int)  RTSemEventMultiWaitEx(RTSEMEVENTMULTI hEventMultiSem, uint32_t fFlags, uint64_t uTimeout)
     386{
     387#ifndef RTSEMEVENT_STRICT
     388    return rtSemEventLnxMultiWait(hEventMultiSem, fFlags, uTimeout, NULL);
     389#else
     390    RTLOCKVALSRCPOS SrcPos = RTLOCKVALSRCPOS_INIT_NORMAL_API();
     391    return rtSemEventLnxMultiWait(hEventMultiSem, fFlags, uTimeout, &SrcPos);
     392#endif
     393}
     394
     395
     396RTDECL(int)  RTSemEventMultiWaitExDebug(RTSEMEVENTMULTI hEventMultiSem, uint32_t fFlags, uint64_t uTimeout,
     397                                        RTHCUINTPTR uId, RT_SRC_POS_DECL)
     398{
     399    RTLOCKVALSRCPOS SrcPos = RTLOCKVALSRCPOS_INIT_DEBUG_API();
     400    return rtSemEventLnxMultiWait(hEventMultiSem, fFlags, uTimeout, &SrcPos);
    373401}
    374402
     
    411439}
    412440
     441#include "../../generic/RTSemEventMultiWait-2-ex-generic.cpp"
     442#include "../../generic/RTSemEventMultiWaitNoResume-2-ex-generic.cpp"
     443
    413444#endif /* glibc < 2.6 || IPRT_WITH_FUTEX_BASED_SEMS */
    414445
  • 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