VirtualBox

Ignore:
Timestamp:
Oct 10, 2007 3:35:11 PM (17 years ago)
Author:
vboxsync
Message:

Added r0drv/linux/semeventmulti-r0drv-linux.c

File:
1 copied

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/r0drv/linux/semeventmulti-r0drv-linux.c

    r5225 r5226  
    11/* $Id$ */
    22/** @file
    3  * innotek Portable Runtime - Single Release Event Semaphores, Ring-0 Driver, Linux.
     3 * innotek Portable Runtime - Multiple Release Event Semaphores, Ring-0 Driver, Linux.
    44 */
    55
     
    3737 * Linux event semaphore.
    3838 */
    39 typedef struct RTSEMEVENTINTERNAL
     39typedef struct RTSEMEVENTMULTIINTERNAL
    4040{
    4141    /** Magic value (RTSEMEVENT_MAGIC). */
     
    4545    /** The wait queue. */
    4646    wait_queue_head_t   Head;
    47 } RTSEMEVENTINTERNAL, *PRTSEMEVENTINTERNAL;
    48 
    49 
    50 
    51 RTDECL(int)  RTSemEventCreate(PRTSEMEVENT pEventSem)
    52 {
    53     PRTSEMEVENTINTERNAL pEventInt = (PRTSEMEVENTINTERNAL)RTMemAlloc(sizeof(*pEventInt));
    54     if (pEventInt)
     47} RTSEMEVENTMULTIINTERNAL, *PRTSEMEVENTMULTIINTERNAL;
     48
     49
     50
     51RTDECL(int) RTSemEventMultiCreate(PRTSEMEVENTMULTI pEventMultiSem)
     52{
     53    PRTSEMEVENTMULTIINTERNAL pThis = (PRTSEMEVENTMULTIINTERNAL)RTMemAlloc(sizeof(*pThis));
     54    if (pThis)
    5555    {
    56         pEventInt->u32Magic = RTSEMEVENT_MAGIC;
    57         init_waitqueue_head(&pEventInt->Head);
    58         *pEventSem = pEventInt;
     56        pThis->u32Magic = RTSEMEVENT_MAGIC;
     57        init_waitqueue_head(&pThis->Head);
     58        *pEventMultiSem = pThis;
    5959        return VINF_SUCCESS;
    6060    }
     
    6363
    6464
    65 RTDECL(int)  RTSemEventDestroy(RTSEMEVENT EventSem)
     65RTDECL(int) RTSemEventMultiDestroy(RTSEMEVENTMULTI EventMultiSem)
    6666{
    6767    /*
    6868     * Validate input.
    6969     */
    70     PRTSEMEVENTINTERNAL pEventInt = (PRTSEMEVENTINTERNAL)EventSem;
    71     if (!pEventInt)
    72         return VERR_INVALID_PARAMETER;
    73     if (pEventInt->u32Magic != RTSEMEVENT_MAGIC)
    74     {
    75         AssertMsgFailed(("pEventInt->u32Magic=%RX32 pEventInt=%p\n", pEventInt->u32Magic, pEventInt));
    76         return VERR_INVALID_PARAMETER;
    77     }
     70    PRTSEMEVENTMULTIINTERNAL pThis = (PRTSEMEVENTMULTIINTERNAL)EventMultiSem;
     71    if (!pThis)
     72        return VERR_INVALID_PARAMETER;
     73    AssertPtrReturn(pThis, VERR_INVALID_PARAMETER);
     74    AssertMsgReturn(pThis->u32Magic == RTSEMEVENT_MAGIC, ("%p u32Magic=%RX32\n", pThis, pThis->u32Magic), VERR_INVALID_PARAMETER);
    7875
    7976    /*
    8077     * Invalidate it and signal the object just in case.
    8178     */
    82     ASMAtomicIncU32(&pEventInt->u32Magic);
    83     ASMAtomicXchgU32(&pEventInt->fState, 0);
    84     Assert(!waitqueue_active(&pEventInt->Head));
    85     wake_up_all(&pEventInt->Head);
    86     RTMemFree(pEventInt);
     79    ASMAtomicIncU32(&pThis->u32Magic);
     80    ASMAtomicXchgU32(&pThis->fState, 0);
     81    Assert(!waitqueue_active(&pThis->Head));
     82    wake_up_all(&pThis->Head);
     83    RTMemFree(pThis);
    8784    return VINF_SUCCESS;
    8885}
    8986
    9087
    91 RTDECL(int)  RTSemEventSignal(RTSEMEVENT EventSem)
     88RTDECL(int) RTSemEventMultiSignal(RTSEMEVENTMULTI EventMultiSem)
    9289{
    9390    /*
    9491     * Validate input.
    9592     */
    96     PRTSEMEVENTINTERNAL pEventInt = (PRTSEMEVENTINTERNAL)EventSem;
    97     if (!pEventInt)
    98         return VERR_INVALID_PARAMETER;
    99     if (    !pEventInt
    100         ||  pEventInt->u32Magic != RTSEMEVENT_MAGIC)
    101     {
    102         AssertMsgFailed(("pEventInt->u32Magic=%RX32 pEventInt=%p\n", pEventInt ? pEventInt->u32Magic : 0, pEventInt));
    103         return VERR_INVALID_PARAMETER;
    104     }
     93    PRTSEMEVENTMULTIINTERNAL pThis = (PRTSEMEVENTMULTIINTERNAL)EventMultiSem;
     94    if (!pThis)
     95        return VERR_INVALID_PARAMETER;
     96    AssertPtrReturn(pThis, VERR_INVALID_PARAMETER);
     97    AssertMsgReturn(pThis->u32Magic == RTSEMEVENT_MAGIC, ("%p u32Magic=%RX32\n", pThis, pThis->u32Magic), VERR_INVALID_PARAMETER);
    10598
    10699    /*
    107100     * Signal the event object.
    108101     */
    109     ASMAtomicXchgU32(&pEventInt->fState, 1);
    110     wake_up(&pEventInt->Head);
    111 
     102    ASMAtomicXchgU32(&pThis->fState, 1);
     103    wake_up_all(&pThis->Head);
    112104    return VINF_SUCCESS;
    113105}
    114106
    115107
     108RTDECL(int) RTSemEventMultiReset(RTSEMEVENTMULTI EventMultiSem)
     109{
     110    /*
     111     * Validate input.
     112     */
     113    PRTSEMEVENTMULTIINTERNAL pThis = (PRTSEMEVENTMULTIINTERNAL)EventMultiSem;
     114    if (!pThis)
     115        return VERR_INVALID_PARAMETER;
     116    AssertPtrReturn(pThis, VERR_INVALID_PARAMETER);
     117    AssertMsgReturn(pThis->u32Magic == RTSEMEVENT_MAGIC, ("%p u32Magic=%RX32\n", pThis, pThis->u32Magic), VERR_INVALID_PARAMETER);
     118
     119    /*
     120     * Reset it.
     121     */
     122    ASMAtomicXchgU32(&pThis->fState, 0);
     123    return VINF_SUCCESS;
     124}
     125
     126
    116127/**
    117  * Worker for RTSemEvent and RTSemEventNoResume.
     128 * Worker for RTSemEventMulti and RTSemEventMultiNoResume.
    118129 *
    119130 * @returns VBox status code.
    120  * @param   pEventInt           The event semaphore.
     131 * @param   pThis           The event semaphore.
    121132 * @param   cMillies            The number of milliseconds to wait.
    122133 * @param   fInterruptible      Whether it's an interruptible wait or not.
    123134 */
    124 static int rtSemEventWait(PRTSEMEVENTINTERNAL pEventInt, unsigned cMillies, bool fInterruptible)
     135static int rtSemEventWait(PRTSEMEVENTMULTIINTERNAL pThis, unsigned cMillies, bool fInterruptible)
    125136{
    126137    /*
     
    133144    {
    134145        /* make everything thru schedule() atomic scheduling wise. */
    135         prepare_to_wait(&pEventInt->Head, &Wait, fInterruptible ? TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE);
     146        prepare_to_wait(&pThis->Head, &Wait, fInterruptible ? TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE);
    136147
    137148        /* check the condition. */
    138         if (ASMAtomicCmpXchgU32(&pEventInt->fState, 0, 1))
     149        if (pThis->fState)
    139150            break;
    140151
     
    150161
    151162        /* Check if someone destroyed the semaphore while we were waiting. */
    152         if (pEventInt->u32Magic != RTSEMEVENT_MAGIC)
     163        if (pThis->u32Magic != RTSEMEVENT_MAGIC)
    153164        {
    154165            rc = VERR_SEM_DESTROYED;
     
    164175    }
    165176
    166     finish_wait(&pEventInt->Head, &Wait);
     177    finish_wait(&pThis->Head, &Wait);
    167178    return rc;
    168179}
    169180
    170181
    171 RTDECL(int) RTSemEventWait(RTSEMEVENT EventSem, unsigned cMillies)
    172 {
    173     PRTSEMEVENTINTERNAL pEventInt = (PRTSEMEVENTINTERNAL)EventSem;
    174     if (!pEventInt)
    175         return VERR_INVALID_PARAMETER;
    176     if (    !pEventInt
    177         ||  pEventInt->u32Magic != RTSEMEVENT_MAGIC)
    178     {
    179         AssertMsgFailed(("pEventInt->u32Magic=%RX32 pEventInt=%p\n", pEventInt ? pEventInt->u32Magic : 0, pEventInt));
    180         return VERR_INVALID_PARAMETER;
    181     }
    182 
    183     if (ASMAtomicCmpXchgU32(&pEventInt->fState, 0, 1))
     182RTDECL(int) RTSemEventMultiWait(RTSEMEVENTMULTI EventMultiSem, unsigned cMillies)
     183{
     184    PRTSEMEVENTMULTIINTERNAL pThis = (PRTSEMEVENTMULTIINTERNAL)EventMultiSem;
     185    if (!pThis)
     186        return VERR_INVALID_PARAMETER;
     187    AssertPtrReturn(pThis, VERR_INVALID_PARAMETER);
     188    AssertMsgReturn(pThis->u32Magic == RTSEMEVENT_MAGIC, ("%p u32Magic=%RX32\n", pThis, pThis->u32Magic), VERR_INVALID_PARAMETER);
     189
     190    if (pThis->fState)
    184191        return VINF_SUCCESS;
    185     return rtSemEventWait(pEventInt, cMillies, false /* fInterruptible */);
    186 }
    187 
    188 
    189 RTDECL(int) RTSemEventWaitNoResume(RTSEMEVENT EventSem, unsigned cMillies)
    190 {
    191     PRTSEMEVENTINTERNAL pEventInt = (PRTSEMEVENTINTERNAL)EventSem;
    192     if (!pEventInt)
    193         return VERR_INVALID_PARAMETER;
    194     if (    !pEventInt
    195         ||  pEventInt->u32Magic != RTSEMEVENT_MAGIC)
    196     {
    197         AssertMsgFailed(("pEventInt->u32Magic=%RX32 pEventInt=%p\n", pEventInt ? pEventInt->u32Magic : 0, pEventInt));
    198         return VERR_INVALID_PARAMETER;
    199     }
    200 
    201     if (ASMAtomicCmpXchgU32(&pEventInt->fState, 0, 1))
     192    return rtSemEventWait(pThis, cMillies, false /* fInterruptible */);
     193}
     194
     195
     196RTDECL(int) RTSemEventMultiWaitNoResume(RTSEMEVENTMULTI EventMultiSem, unsigned cMillies)
     197{
     198    PRTSEMEVENTMULTIINTERNAL pThis = (PRTSEMEVENTMULTIINTERNAL)EventMultiSem;
     199    if (!pThis)
     200        return VERR_INVALID_PARAMETER;
     201    AssertPtrReturn(pThis, VERR_INVALID_PARAMETER);
     202    AssertMsgReturn(pThis->u32Magic == RTSEMEVENT_MAGIC, ("%p u32Magic=%RX32\n", pThis, pThis->u32Magic), VERR_INVALID_PARAMETER);
     203
     204    if (pThis->fState)
    202205        return VINF_SUCCESS;
    203     return rtSemEventWait(pEventInt, cMillies, true /* fInterruptible */);
    204 }
    205 
     206    return rtSemEventWait(pThis, cMillies, true /* fInterruptible */);
     207}
     208
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