VirtualBox

Changeset 33011 in vbox


Ignore:
Timestamp:
Oct 8, 2010 3:42:24 PM (14 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
66526
Message:

IPRT,SUPDrv,VBoxGuest: Reimplemented RTSemEventWait* so that it can make use of high resoultion timers when present (2.6.28).

Location:
trunk
Files:
11 edited

Legend:

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

    r32946 r33011  
    350350 * @param   hEventMultiSem      The multiple release event semaphore.
    351351 * @param   cMillies            Number of milliseconds to wait.
     352 * @todo    Rename to RTSemEventMultiWaitIntr since it is mainly for
     353 *          ring-0 consumption.
    352354 */
    353355RTDECL(int)  RTSemEventMultiWaitNoResume(RTSEMEVENTMULTI hEventMultiSem, RTMSINTERVAL cMillies);
  • trunk/src/VBox/Additions/common/VBoxGuest/linux/Makefile

    r32183 r33011  
    119119        generic/RTLogWriteStdErr-stub-generic.o \
    120120        generic/RTLogWriteStdOut-stub-generic.o \
     121        generic/RTSemEventMultiWait-2-ex-generic.o \
     122        generic/RTSemEventMultiWaitNoResume-2-ex-generic.o \
    121123        VBox/log-vbox.o \
    122124        VBox/logbackdoor.o
  • trunk/src/VBox/Additions/common/VBoxGuest/linux/files_vboxguest

    r32449 r33011  
    123123    ${PATH_ROOT}/src/VBox/Runtime/generic/RTLogWriteStdErr-stub-generic.cpp=>generic/RTLogWriteStdErr-stub-generic.c \
    124124    ${PATH_ROOT}/src/VBox/Runtime/generic/RTLogWriteStdOut-stub-generic.cpp=>generic/RTLogWriteStdOut-stub-generic.c \
     125    ${PATH_ROOT}/src/VBox/Runtime/generic/RTSemEventMultiWait-2-ex-generic.cpp=>generic/RTSemEventMultiWait-2-ex-generic.c \
     126    ${PATH_ROOT}/src/VBox/Runtime/generic/RTSemEventMultiWaitNoResume-2-ex-generic.cpp=>generic/RTSemEventMultiWaitNoResume-2-ex-generic.c \
    125127    ${PATH_ROOT}/src/VBox/Runtime/r0drv/alloc-r0drv.cpp=>r0drv/alloc-r0drv.c \
    126128    ${PATH_ROOT}/src/VBox/Runtime/r0drv/alloc-r0drv.h=>r0drv/alloc-r0drv.h \
     
    147149    ${PATH_ROOT}/src/VBox/Runtime/r0drv/linux/thread-r0drv-linux.c=>r0drv/linux/thread-r0drv-linux.c \
    148150    ${PATH_ROOT}/src/VBox/Runtime/r0drv/linux/time-r0drv-linux.c=>r0drv/linux/time-r0drv-linux.c \
     151    ${PATH_ROOT}/src/VBox/Runtime/r0drv/linux/waitqueue-r0drv-linux.h=>r0drv/linux/waitqueue-r0drv-linux.h \
    149152    ${PATH_ROOT}/src/VBox/Runtime/r0drv/linux/RTLogWriteDebugger-r0drv-linux.c=>r0drv/linux/RTLogWriteDebugger-r0drv-linux.c \
    150153    ${PATH_ROOT}/src/VBox/Runtime/r0drv/generic/semspinmutex-r0drv-generic.c=>r0drv/generic/semspinmutex-r0drv-generic.c \
  • trunk/src/VBox/HostDrivers/Support/linux/Makefile

    r32572 r33011  
    131131        generic/RTLogWriteUser-generic.o \
    132132        generic/RTMpGetArraySize-generic.o \
     133        generic/RTSemEventMultiWait-2-ex-generic.o \
     134        generic/RTSemEventMultiWaitNoResume-2-ex-generic.o \
    133135        generic/RTTimerCreate-generic.o \
    134136        generic/uuid-generic.o \
  • trunk/src/VBox/HostDrivers/Support/linux/files_vboxdrv

    r32572 r33011  
    129129    ${PATH_ROOT}/src/VBox/Runtime/generic/RTLogWriteUser-generic.cpp=>generic/RTLogWriteUser-generic.c \
    130130    ${PATH_ROOT}/src/VBox/Runtime/generic/RTMpGetArraySize-generic.cpp=>generic/RTMpGetArraySize-generic.c \
     131    ${PATH_ROOT}/src/VBox/Runtime/generic/RTSemEventMultiWait-2-ex-generic.cpp=>generic/RTSemEventMultiWait-2-ex-generic.c \
     132    ${PATH_ROOT}/src/VBox/Runtime/generic/RTSemEventMultiWaitNoResume-2-ex-generic.cpp=>generic/RTSemEventMultiWaitNoResume-2-ex-generic.c \
    131133    ${PATH_ROOT}/src/VBox/Runtime/generic/RTTimerCreate-generic.cpp=>generic/RTTimerCreate-generic.c \
    132134    ${PATH_ROOT}/src/VBox/Runtime/generic/uuid-generic.cpp=>generic/uuid-generic.c \
     
    158160    ${PATH_ROOT}/src/VBox/Runtime/r0drv/linux/time-r0drv-linux.c=>r0drv/linux/time-r0drv-linux.c \
    159161    ${PATH_ROOT}/src/VBox/Runtime/r0drv/linux/timer-r0drv-linux.c=>r0drv/linux/timer-r0drv-linux.c \
     162    ${PATH_ROOT}/src/VBox/Runtime/r0drv/linux/waitqueue-r0drv-linux.h=>r0drv/linux/waitqueue-r0drv-linux.h \
    160163    ${PATH_ROOT}/src/VBox/Runtime/r0drv/generic/semspinmutex-r0drv-generic.c=>r0drv/generic/semspinmutex-r0drv-generic.c \
    161164    ${PATH_ROOT}/src/VBox/Runtime/r0drv/memobj-r0drv.cpp=>r0drv/memobj-r0drv.c \
  • trunk/src/VBox/HostDrivers/Support/testcase/tstSupSem.cpp

    r32431 r33011  
    111111    RTTESTI_CHECK_RC(SUPSemEventCreate(pSession, &hEvent),          VINF_SUCCESS);
    112112    RTTESTI_CHECK_RC(SUPSemEventWaitNoResume(pSession, hEvent, 0),  VERR_TIMEOUT);
     113    RTTESTI_CHECK_RC(SUPSemEventWaitNoResume(pSession, hEvent, 1),  VERR_TIMEOUT);
     114    RTTESTI_CHECK_RC(SUPSemEventWaitNoResume(pSession, hEvent, 2),  VERR_TIMEOUT);
     115    RTTESTI_CHECK_RC(SUPSemEventWaitNoResume(pSession, hEvent, 8),  VERR_TIMEOUT);
    113116    RTTESTI_CHECK_RC(SUPSemEventWaitNoResume(pSession, hEvent,20),  VERR_TIMEOUT);
    114117    RTTESTI_CHECK_RC(SUPSemEventSignal(pSession, hEvent),           VINF_SUCCESS);
    115118    RTTESTI_CHECK_RC(SUPSemEventWaitNoResume(pSession, hEvent, 0),  VINF_SUCCESS);
    116119    RTTESTI_CHECK_RC(SUPSemEventSignal(pSession, hEvent),           VINF_SUCCESS);
    117     RTTESTI_CHECK_RC(SUPSemEventWaitNoResume(pSession, hEvent,20),  VINF_SUCCESS);
     120    RTTESTI_CHECK_RC(SUPSemEventWaitNoResume(pSession, hEvent, 1),  VINF_SUCCESS);
     121    RTTESTI_CHECK_RC(SUPSemEventSignal(pSession, hEvent),           VINF_SUCCESS);
     122    RTTESTI_CHECK_RC(SUPSemEventWaitNoResume(pSession, hEvent, 2),  VINF_SUCCESS);
     123    RTTESTI_CHECK_RC(SUPSemEventSignal(pSession, hEvent),           VINF_SUCCESS);
     124    RTTESTI_CHECK_RC(SUPSemEventWaitNoResume(pSession, hEvent, 8),  VINF_SUCCESS);
     125    RTTESTI_CHECK_RC(SUPSemEventSignal(pSession, hEvent),           VINF_SUCCESS);
     126    RTTESTI_CHECK_RC(SUPSemEventWaitNoResume(pSession, hEvent, 20), VINF_SUCCESS);
     127    RTTESTI_CHECK_RC(SUPSemEventSignal(pSession, hEvent),           VINF_SUCCESS);
     128    RTTESTI_CHECK_RC(SUPSemEventWaitNoResume(pSession, hEvent,1000),VINF_SUCCESS);
    118129    RTTESTI_CHECK_RC(SUPSemEventSignal(pSession, hEvent),           VINF_SUCCESS);
    119130    RTTESTI_CHECK_RC(SUPSemEventSignal(pSession, hEvent),           VINF_SUCCESS);
    120131    RTTESTI_CHECK_RC(SUPSemEventWaitNoResume(pSession, hEvent, 0),  VINF_SUCCESS);
    121132    RTTESTI_CHECK_RC(SUPSemEventWaitNoResume(pSession, hEvent, 0),  VERR_TIMEOUT);
     133    RTTESTI_CHECK_RC(SUPSemEventWaitNoResume(pSession, hEvent, 1),  VERR_TIMEOUT);
     134    RTTESTI_CHECK_RC(SUPSemEventWaitNoResume(pSession, hEvent, 2),  VERR_TIMEOUT);
     135    RTTESTI_CHECK_RC(SUPSemEventWaitNoResume(pSession, hEvent, 8),  VERR_TIMEOUT);
    122136    RTTESTI_CHECK_RC(SUPSemEventWaitNoResume(pSession, hEvent,20),  VERR_TIMEOUT);
    123137    RTTESTI_CHECK_RC(SUPSemEventClose(pSession, hEvent),            VINF_OBJECT_DESTROYED);
     
    129143    RTTESTI_CHECK_RC(SUPSemEventMultiCreate(pSession, &hEventMulti),            VINF_SUCCESS);
    130144    RTTESTI_CHECK_RC(SUPSemEventMultiWaitNoResume(pSession, hEventMulti, 0),    VERR_TIMEOUT);
     145    RTTESTI_CHECK_RC(SUPSemEventMultiWaitNoResume(pSession, hEventMulti, 1),    VERR_TIMEOUT);
     146    RTTESTI_CHECK_RC(SUPSemEventMultiWaitNoResume(pSession, hEventMulti, 2),    VERR_TIMEOUT);
     147    RTTESTI_CHECK_RC(SUPSemEventMultiWaitNoResume(pSession, hEventMulti, 8),    VERR_TIMEOUT);
    131148    RTTESTI_CHECK_RC(SUPSemEventMultiWaitNoResume(pSession, hEventMulti,20),    VERR_TIMEOUT);
    132149    RTTESTI_CHECK_RC(SUPSemEventMultiSignal(pSession, hEventMulti),             VINF_SUCCESS);
     
    134151    RTTESTI_CHECK_RC(SUPSemEventMultiWaitNoResume(pSession, hEventMulti, 0),    VINF_SUCCESS);
    135152    RTTESTI_CHECK_RC(SUPSemEventMultiWaitNoResume(pSession, hEventMulti, 0),    VINF_SUCCESS);
     153    RTTESTI_CHECK_RC(SUPSemEventMultiWaitNoResume(pSession, hEventMulti, 1),    VINF_SUCCESS);
     154    RTTESTI_CHECK_RC(SUPSemEventMultiWaitNoResume(pSession, hEventMulti, 2),    VINF_SUCCESS);
     155    RTTESTI_CHECK_RC(SUPSemEventMultiWaitNoResume(pSession, hEventMulti, 8),    VINF_SUCCESS);
     156    RTTESTI_CHECK_RC(SUPSemEventMultiWaitNoResume(pSession, hEventMulti,20),    VINF_SUCCESS);
     157    RTTESTI_CHECK_RC(SUPSemEventMultiWaitNoResume(pSession, hEventMulti,1000),  VINF_SUCCESS);
    136158    RTTESTI_CHECK_RC(SUPSemEventMultiSignal(pSession, hEventMulti),             VINF_SUCCESS);
    137159    RTTESTI_CHECK_RC(SUPSemEventMultiSignal(pSession, hEventMulti),             VINF_SUCCESS);
     
    139161    RTTESTI_CHECK_RC(SUPSemEventMultiReset(pSession, hEventMulti),              VINF_SUCCESS);
    140162    RTTESTI_CHECK_RC(SUPSemEventMultiWaitNoResume(pSession, hEventMulti, 0),    VERR_TIMEOUT);
     163    RTTESTI_CHECK_RC(SUPSemEventMultiWaitNoResume(pSession, hEventMulti, 1),    VERR_TIMEOUT);
     164    RTTESTI_CHECK_RC(SUPSemEventMultiWaitNoResume(pSession, hEventMulti, 2),    VERR_TIMEOUT);
     165    RTTESTI_CHECK_RC(SUPSemEventMultiWaitNoResume(pSession, hEventMulti, 8),    VERR_TIMEOUT);
    141166    RTTESTI_CHECK_RC(SUPSemEventMultiWaitNoResume(pSession, hEventMulti,20),    VERR_TIMEOUT);
    142167    RTTESTI_CHECK_RC(SUPSemEventMultiSignal(pSession, hEventMulti),             VINF_SUCCESS);
    143168    RTTESTI_CHECK_RC(SUPSemEventMultiWaitNoResume(pSession, hEventMulti, 0),    VINF_SUCCESS);
     169    RTTESTI_CHECK_RC(SUPSemEventMultiWaitNoResume(pSession, hEventMulti, 1),    VINF_SUCCESS);
     170    RTTESTI_CHECK_RC(SUPSemEventMultiWaitNoResume(pSession, hEventMulti, 2),    VINF_SUCCESS);
     171    RTTESTI_CHECK_RC(SUPSemEventMultiWaitNoResume(pSession, hEventMulti, 8),    VINF_SUCCESS);
     172    RTTESTI_CHECK_RC(SUPSemEventMultiWaitNoResume(pSession, hEventMulti, 20),   VINF_SUCCESS);
     173    RTTESTI_CHECK_RC(SUPSemEventMultiWaitNoResume(pSession, hEventMulti,1000),  VINF_SUCCESS);
    144174    RTTESTI_CHECK_RC(SUPSemEventMultiClose(pSession, hEventMulti),              VINF_OBJECT_DESTROYED);
    145175    RTTESTI_CHECK_RC(SUPSemEventMultiClose(pSession, hEventMulti),              VERR_INVALID_HANDLE);
  • trunk/src/VBox/Runtime/Makefile.kmk

    r32997 r33011  
    14301430        generic/RTAssertShouldPanic-generic.cpp \
    14311431        generic/RTLogWriteStdOut-stub-generic.cpp \
     1432        generic/RTSemEventMultiWait-2-ex-generic.cpp \
     1433        generic/RTSemEventMultiWaitNoResume-2-ex-generic.cpp \
    14321434        generic/mppresent-generic.cpp \
    14331435        r0drv/linux/alloc-r0drv-linux.c \
  • trunk/src/VBox/Runtime/r0drv/linux/memobj-r0drv-linux.c

    r33006 r33011  
    175175 * @param   enmType     The object type.
    176176 * @param   cb          The number of bytes to allocate.
    177  * @param   uAlignment  The alignment of the phyiscal memory.
     177 * @param   uAlignment  The alignment of the physical memory.
    178178 *                      Only valid if fContiguous == true, ignored otherwise.
    179179 * @param   fFlagsLnx   The page allocation flags (GPFs).
  • trunk/src/VBox/Runtime/r0drv/linux/semeventmulti-r0drv-linux.c

    r29661 r33011  
    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
     
    3232#include "internal/iprt.h"
    3333#include <iprt/semaphore.h>
    34 #include <iprt/alloc.h>
     34
    3535#include <iprt/assert.h>
    3636#include <iprt/asm.h>
    3737#include <iprt/err.h>
    38 
     38#include <iprt/mem.h>
     39#include <iprt/lockvalidator.h>
     40
     41#include "waitqueue-r0drv-linux.h"
    3942#include "internal/magics.h"
    4043
     44
     45/*******************************************************************************
     46*   Defined Constants And Macros                                               *
     47*******************************************************************************/
     48/** @name fStateAndGen values
     49 * @{ */
     50/** The state bit number. */
     51#define RTSEMEVENTMULTILNX_STATE_BIT        0
     52/** The state mask. */
     53#define RTSEMEVENTMULTILNX_STATE_MASK       RT_BIT_32(RTSEMEVENTMULTILNX_STATE_BIT)
     54/** The generation mask. */
     55#define RTSEMEVENTMULTILNX_GEN_MASK         ~RTSEMEVENTMULTILNX_STATE_MASK
     56/** The generation shift. */
     57#define RTSEMEVENTMULTILNX_GEN_SHIFT        1
     58/** The initial variable value. */
     59#define RTSEMEVENTMULTILNX_STATE_GEN_INIT   UINT32_C(0xfffffffc)
     60/** @}  */
    4161
    4262/*******************************************************************************
     
    5070    /** Magic value (RTSEMEVENTMULTI_MAGIC). */
    5171    uint32_t volatile   u32Magic;
    52     /** The object status - !0 when signaled and 0 when reset. */
    53     uint32_t volatile   fState;
     72    /** The object state bit and generation counter.
     73     * The generation counter is incremented every time the object is   */
     74    uint32_t volatile   fStateAndGen;
     75    /** Reference counter. */
     76    uint32_t volatile   cRefs;
    5477    /** The wait queue. */
    5578    wait_queue_head_t   Head;
    5679} RTSEMEVENTMULTIINTERNAL, *PRTSEMEVENTMULTIINTERNAL;
     80
     81
    5782
    5883
     
    7398    if (pThis)
    7499    {
    75         pThis->u32Magic = RTSEMEVENTMULTI_MAGIC;
    76         pThis->fState   = 0;
     100        pThis->u32Magic     = RTSEMEVENTMULTI_MAGIC;
     101        pThis->fStateAndGen = RTSEMEVENTMULTILNX_STATE_GEN_INIT;
     102        pThis->cRefs        = 1;
    77103        init_waitqueue_head(&pThis->Head);
    78104
     
    83109}
    84110RT_EXPORT_SYMBOL(RTSemEventMultiCreate);
     111
     112
     113/**
     114 * Retain a reference to the semaphore.
     115 *
     116 * @param   pThis       The semaphore.
     117 */
     118DECLINLINE(void) rtR0SemEventMultiLnxRetain(PRTSEMEVENTMULTIINTERNAL pThis)
     119{
     120    uint32_t cRefs = ASMAtomicIncU32(&pThis->cRefs);
     121    Assert(cRefs && cRefs < 100000);
     122}
     123
     124
     125/**
     126 * Release a reference, destroy the thing if necessary.
     127 *
     128 * @param   pThis       The semaphore.
     129 */
     130DECLINLINE(void) rtR0SemEventMultiLnxRelease(PRTSEMEVENTMULTIINTERNAL pThis)
     131{
     132    if (RT_UNLIKELY(ASMAtomicDecU32(&pThis->cRefs) == 0))
     133    {
     134        Assert(pThis->u32Magic != RTSEMEVENTMULTI_MAGIC);
     135        RTMemFree(pThis);
     136    }
     137}
    85138
    86139
     
    95148    AssertPtrReturn(pThis, VERR_INVALID_PARAMETER);
    96149    AssertMsgReturn(pThis->u32Magic == RTSEMEVENTMULTI_MAGIC, ("%p u32Magic=%RX32\n", pThis, pThis->u32Magic), VERR_INVALID_PARAMETER);
     150    Assert(pThis->cRefs > 0);
    97151
    98152    /*
     
    100154     */
    101155    ASMAtomicWriteU32(&pThis->u32Magic, ~RTSEMEVENTMULTI_MAGIC);
    102     ASMAtomicXchgU32(&pThis->fState, 0);
     156    ASMAtomicAndU32(&pThis->fStateAndGen, RTSEMEVENTMULTILNX_GEN_MASK);
    103157    Assert(!waitqueue_active(&pThis->Head));
    104158    wake_up_all(&pThis->Head);
    105     RTMemFree(pThis);
    106159    return VINF_SUCCESS;
    107160}
     
    111164RTDECL(int) RTSemEventMultiSignal(RTSEMEVENTMULTI hEventMultiSem)
    112165{
     166    uint32_t fNew;
     167    uint32_t fOld;
     168
    113169    /*
    114170     * Validate input.
     
    119175    AssertPtrReturn(pThis, VERR_INVALID_PARAMETER);
    120176    AssertMsgReturn(pThis->u32Magic == RTSEMEVENTMULTI_MAGIC, ("%p u32Magic=%RX32\n", pThis, pThis->u32Magic), VERR_INVALID_PARAMETER);
    121 
    122     /*
    123      * Signal the event object.
    124      */
    125     ASMAtomicXchgU32(&pThis->fState, 1);
     177    rtR0SemEventMultiLnxRetain(pThis);
     178
     179    /*
     180     * Signal the event object.  The cause of the parnoia here is racing to try
     181     * deal with racing RTSemEventMultiSignal calls (should probably be
     182     * forbidden, but it's relatively easy to handle).
     183     */
     184    do
     185    {
     186        fNew = fOld = ASMAtomicUoReadU32(&pThis->fStateAndGen);
     187        fNew += 1 << RTSEMEVENTMULTILNX_GEN_SHIFT;
     188        fNew |= RTSEMEVENTMULTILNX_STATE_MASK;
     189    }
     190    while (!ASMAtomicCmpXchgU32(&pThis->fStateAndGen, fNew, fOld));
     191
    126192    wake_up_all(&pThis->Head);
     193
     194    rtR0SemEventMultiLnxRelease(pThis);
    127195    return VINF_SUCCESS;
    128196}
     
    140208    AssertPtrReturn(pThis, VERR_INVALID_PARAMETER);
    141209    AssertMsgReturn(pThis->u32Magic == RTSEMEVENTMULTI_MAGIC, ("%p u32Magic=%RX32\n", pThis, pThis->u32Magic), VERR_INVALID_PARAMETER);
     210    rtR0SemEventMultiLnxRetain(pThis);
    142211
    143212    /*
    144213     * Reset it.
    145214     */
    146     ASMAtomicXchgU32(&pThis->fState, 0);
     215    ASMAtomicAndU32(&pThis->fStateAndGen, ~RTSEMEVENTMULTILNX_STATE_MASK);
     216
     217    rtR0SemEventMultiLnxRelease(pThis);
    147218    return VINF_SUCCESS;
    148219}
     
    151222
    152223/**
    153  * Worker for RTSemEventMulti and RTSemEventMultiNoResume.
     224 * Worker for RTSemEventMultiWaitEx and RTSemEventMultiWaitExDebug.
    154225 *
    155226 * @returns VBox status code.
    156227 * @param   pThis           The event semaphore.
    157  * @param   cMillies            The number of milliseconds to wait.
    158  * @param   fInterruptible      Whether it's an interruptible wait or not.
    159  */
    160 static int rtSemEventMultiWait(PRTSEMEVENTMULTIINTERNAL pThis, RTMSINTERVAL cMillies, bool fInterruptible)
    161 {
    162     /*
    163      * Ok wait for it.
    164      */
    165     DEFINE_WAIT(Wait);
    166     int     rc       = VINF_SUCCESS;
    167     long    lTimeout = cMillies == RT_INDEFINITE_WAIT ? MAX_SCHEDULE_TIMEOUT : msecs_to_jiffies(cMillies);
    168     IPRT_DEBUG_SEMS_STATE(pThis, 'E');
    169     for (;;)
     228 */
     229static int rtR0SemEventMultiLnxWait(PRTSEMEVENTMULTIINTERNAL pThis, uint32_t fFlags, uint64_t uTimeout,
     230                                    PCRTLOCKVALSRCPOS pSrcPos)
     231{
     232    uint32_t    fOrgStateAndGen;
     233    int         rc;
     234
     235    /*
     236     * Validate the input.
     237     */
     238    AssertPtrReturn(pThis, VERR_INVALID_PARAMETER);
     239    AssertMsgReturn(pThis->u32Magic == RTSEMEVENTMULTI_MAGIC, ("%p u32Magic=%RX32\n", pThis, pThis->u32Magic), VERR_INVALID_PARAMETER);
     240    rtR0SemEventMultiLnxRetain(pThis);
     241
     242    /*
     243     * Is the event already signalled or do we have to wait?
     244     */
     245    fOrgStateAndGen = ASMAtomicUoReadU32(&pThis->fStateAndGen);
     246    if (fOrgStateAndGen & RTSEMEVENTMULTILNX_STATE_MASK)
     247        rc = VINF_SUCCESS;
     248    else
    170249    {
    171         /* make everything thru schedule() atomic scheduling wise. */
    172         prepare_to_wait(&pThis->Head, &Wait, fInterruptible ? TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE);
    173 
    174         /* check the condition. */
    175         if (pThis->fState)
    176             break;
    177 
    178         /* check for pending signals. */
    179         if (fInterruptible && signal_pending(current))
     250        /*
     251         * We have to wait.
     252         */
     253        RTR0SEMLNXWAIT Wait;
     254        rc = rtR0SemLnxWaitInit(&Wait, fFlags, uTimeout, &pThis->Head);
     255        if (RT_SUCCESS(rc))
    180256        {
    181             rc = VERR_INTERRUPTED;
    182             break;
    183         }
    184 
    185         /* wait */
    186         lTimeout = schedule_timeout(lTimeout);
    187 
    188         after_wait(&Wait);
    189 
    190         /* Check if someone destroyed the semaphore while we were waiting. */
    191         if (pThis->u32Magic != RTSEMEVENTMULTI_MAGIC)
    192         {
    193             rc = VERR_SEM_DESTROYED;
    194             break;
    195         }
    196 
    197         /* check for timeout. */
    198         if (!lTimeout)
    199         {
    200             rc = VERR_TIMEOUT;
    201             break;
     257            IPRT_DEBUG_SEMS_STATE(pThis, 'E');
     258            for (;;)
     259            {
     260                /* The destruction test. */
     261                if (RT_UNLIKELY(pThis->u32Magic != RTSEMEVENTMULTI_MAGIC))
     262                    rc = VERR_SEM_DESTROYED;
     263                else
     264                {
     265                    rtR0SemLnxWaitPrepare(&Wait);
     266
     267                    /* Check the exit conditions. */
     268                    if (RT_UNLIKELY(pThis->u32Magic != RTSEMEVENTMULTI_MAGIC))
     269                        rc = VERR_SEM_DESTROYED;
     270                    else if (ASMAtomicUoReadU32(&pThis->fStateAndGen) != fOrgStateAndGen)
     271                        rc = VINF_SUCCESS;
     272                    else if (rtR0SemLnxWaitHasTimedOut(&Wait))
     273                        rc = VERR_TIMEOUT;
     274                    else if (rtR0SemLnxWaitWasInterrupted(&Wait))
     275                        rc = VERR_INTERRUPTED;
     276                    else
     277                    {
     278                        /* Do the wait and then recheck the conditions. */
     279                        rtR0SemLnxWaitDoIt(&Wait);
     280                        continue;
     281                    }
     282                }
     283                break;
     284            }
     285
     286            rtR0SemLnxWaitDelete(&Wait);
     287            IPRT_DEBUG_SEMS_STATE_RC(pThis, 'E', rc);
    202288        }
    203289    }
    204290
    205     finish_wait(&pThis->Head, &Wait);
    206     IPRT_DEBUG_SEMS_STATE_RC(pThis, 'E', rc);
     291    rtR0SemEventMultiLnxRelease(pThis);
    207292    return rc;
    208293}
    209294
    210295
    211 RTDECL(int) RTSemEventMultiWait(RTSEMEVENTMULTI hEventMultiSem, RTMSINTERVAL cMillies)
    212 {
    213     PRTSEMEVENTMULTIINTERNAL pThis = (PRTSEMEVENTMULTIINTERNAL)hEventMultiSem;
    214     if (!pThis)
    215         return VERR_INVALID_PARAMETER;
    216     AssertPtrReturn(pThis, VERR_INVALID_PARAMETER);
    217     AssertMsgReturn(pThis->u32Magic == RTSEMEVENTMULTI_MAGIC, ("%p u32Magic=%RX32\n", pThis, pThis->u32Magic), VERR_INVALID_PARAMETER);
    218 
    219     if (pThis->fState)
    220         return VINF_SUCCESS;
    221     return rtSemEventMultiWait(pThis, cMillies, false /* fInterruptible */);
    222 }
    223 RT_EXPORT_SYMBOL(RTSemEventMultiWait);
    224 
    225 
    226 RTDECL(int) RTSemEventMultiWaitNoResume(RTSEMEVENTMULTI hEventMultiSem, RTMSINTERVAL cMillies)
    227 {
    228     PRTSEMEVENTMULTIINTERNAL pThis = (PRTSEMEVENTMULTIINTERNAL)hEventMultiSem;
    229     if (!pThis)
    230         return VERR_INVALID_PARAMETER;
    231     AssertPtrReturn(pThis, VERR_INVALID_PARAMETER);
    232     AssertMsgReturn(pThis->u32Magic == RTSEMEVENTMULTI_MAGIC, ("%p u32Magic=%RX32\n", pThis, pThis->u32Magic), VERR_INVALID_PARAMETER);
    233 
    234     if (pThis->fState)
    235         return VINF_SUCCESS;
    236     return rtSemEventMultiWait(pThis, cMillies, true /* fInterruptible */);
    237 }
    238 RT_EXPORT_SYMBOL(RTSemEventMultiWaitNoResume);
    239 
     296#undef RTSemEventMultiWaitEx
     297RTDECL(int)  RTSemEventMultiWaitEx(RTSEMEVENTMULTI hEventMultiSem, uint32_t fFlags, uint64_t uTimeout)
     298{
     299#ifndef RTSEMEVENT_STRICT
     300    return rtR0SemEventMultiLnxWait(hEventMultiSem, fFlags, uTimeout, NULL);
     301#else
     302    RTLOCKVALSRCPOS SrcPos = RTLOCKVALSRCPOS_INIT_NORMAL_API();
     303    return rtR0SemEventMultiLnxWait(hEventMultiSem, fFlags, uTimeout, &SrcPos);
     304#endif
     305}
     306RT_EXPORT_SYMBOL(RTSemEventMultiWaitEx);
     307
     308
     309RTDECL(int)  RTSemEventMultiWaitExDebug(RTSEMEVENTMULTI hEventMultiSem, uint32_t fFlags, uint64_t uTimeout,
     310                                        RTHCUINTPTR uId, RT_SRC_POS_DECL)
     311{
     312    RTLOCKVALSRCPOS SrcPos = RTLOCKVALSRCPOS_INIT_DEBUG_API();
     313    return rtR0SemEventMultiLnxWait(hEventMultiSem, fFlags, uTimeout, &SrcPos);
     314}
     315RT_EXPORT_SYMBOL(RTSemEventMultiWaitExDebug);
     316
  • trunk/src/VBox/Runtime/r0drv/linux/the-linux-kernel.h

    r29648 r33011  
    347347#endif
    348348
    349 #endif
    350 
     349/*
     350 * Some global indicator macros.
     351 */
     352/** @def IPRT_LINUX_HAS_HRTIMER
     353 * Whether the kernel support high resolution timers (Linux kernel versions
     354 * 2.6.28 and later (hrtimer_add_expires_ns() & schedule_hrtimeout). */
     355#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28)
     356# define IPRT_LINUX_HAS_HRTIMER
     357#endif
     358
     359
     360#endif
     361
  • trunk/src/VBox/Runtime/r0drv/linux/timer-r0drv-linux.c

    r32757 r33011  
    4444#include "internal/magics.h"
    4545
    46 /** @def RTTIMER_LINUX_HAVE_HRTIMER
    47  * Whether the kernel support high resolution timers (Linux kernel versions
    48  * 2.6.28 and later (hrtimer_add_expires_ns()). */
    49 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28)
    50 # define RTTIMER_LINUX_HAVE_HRTIMER
    51 #endif
    52 
    5346/** @def RTTIMER_LINUX_WITH_HRTIMER
    5447 * Whether to use high resolution timers.  */
    5548#if !defined(RTTIMER_LINUX_WITH_HRTIMER) \
    56     && defined(RTTIMER_LINUX_HAVE_HRTIMER)
     49    && defined(IPRT_LINUX_HAS_HRTIMER)
    5750# define RTTIMER_LINUX_WITH_HRTIMER
    5851#endif
Note: See TracChangeset for help on using the changeset viewer.

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