VirtualBox

Changeset 5225 in vbox for trunk/src/VBox/Runtime/r0drv


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

semaphore-r0drv-lnx.c split.

Location:
trunk/src/VBox/Runtime/r0drv/linux
Files:
2 copied
1 moved

Legend:

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

    r5219 r5225  
    11/* $Id$ */
    22/** @file
    3  * innotek Portable Runtime - Semaphores, Ring-0 Driver, Linux.
     3 * innotek Portable Runtime - Single Release Event Semaphores, Ring-0 Driver, Linux.
    44 */
    55
     
    4848
    4949
    50 /**
    51  * Linux mutex semaphore.
    52  */
    53 typedef struct RTSEMMUTEXINTERNAL
    54 {
    55     /** Magic value (RTSEMMUTEX_MAGIC). */
    56     uint32_t volatile   u32Magic;
    57     /** Number of recursive locks - 0 if not owned by anyone, > 0 if owned. */
    58     uint32_t volatile   cRecursion;
    59     /** The wait queue. */
    60     wait_queue_head_t   Head;
    61     /** The current owner. */
    62     void * volatile     pOwner;
    63 } RTSEMMUTEXINTERNAL, *PRTSEMMUTEXINTERNAL;
    64 
    65 
    66 /**
    67  * Wrapper for the linux semaphore structure.
    68  */
    69 typedef struct RTSEMFASTMUTEXINTERNAL
    70 {
    71     /** Magic value (RTSEMFASTMUTEX_MAGIC). */
    72     uint32_t            u32Magic;
    73     /** the linux semaphore. */
    74     struct semaphore    Semaphore;
    75 } RTSEMFASTMUTEXINTERNAL, *PRTSEMFASTMUTEXINTERNAL;
    76 
    77 
    78 
    7950
    8051RTDECL(int)  RTSemEventCreate(PRTSEMEVENT pEventSem)
     
    233204}
    234205
    235 
    236 
    237 RTDECL(int)  RTSemMutexCreate(PRTSEMMUTEX pMutexSem)
    238 {
    239     PRTSEMMUTEXINTERNAL pMutexInt = (PRTSEMMUTEXINTERNAL)RTMemAlloc(sizeof(*pMutexInt));
    240     if (pMutexInt)
    241     {
    242         pMutexInt->u32Magic = RTSEMMUTEX_MAGIC;
    243         init_waitqueue_head(&pMutexInt->Head);
    244         *pMutexSem = pMutexInt;
    245 AssertReleaseMsgFailed(("This mutex implementation is buggy, fix it!\n"));
    246         return VINF_SUCCESS;
    247     }
    248     return VERR_NO_MEMORY;
    249 }
    250 
    251 
    252 RTDECL(int)  RTSemMutexDestroy(RTSEMMUTEX MutexSem)
    253 {
    254     /*
    255      * Validate input.
    256      */
    257     PRTSEMMUTEXINTERNAL pMutexInt = (PRTSEMMUTEXINTERNAL)MutexSem;
    258     if (!pMutexInt)
    259         return VERR_INVALID_PARAMETER;
    260     if (pMutexInt->u32Magic != RTSEMMUTEX_MAGIC)
    261     {
    262         AssertMsgFailed(("pMutexInt->u32Magic=%RX32 pMutexInt=%p\n", pMutexInt->u32Magic, pMutexInt));
    263         return VERR_INVALID_PARAMETER;
    264     }
    265 
    266     /*
    267      * Invalidate it and signal the object just in case.
    268      */
    269     ASMAtomicIncU32(&pMutexInt->u32Magic);
    270     ASMAtomicXchgU32(&pMutexInt->cRecursion, 0);
    271     Assert(!waitqueue_active(&pMutexInt->Head));
    272     wake_up_all(&pMutexInt->Head);
    273     RTMemFree(pMutexInt);
    274     return VINF_SUCCESS;
    275 }
    276 
    277 
    278 RTDECL(int)  RTSemMutexRequest(RTSEMMUTEX MutexSem, unsigned cMillies)
    279 {
    280     /*
    281      * Validate input.
    282      */
    283     PRTSEMMUTEXINTERNAL pMutexInt = (PRTSEMMUTEXINTERNAL)MutexSem;
    284     if (!pMutexInt)
    285         return VERR_INVALID_PARAMETER;
    286     if (    !pMutexInt
    287         ||  pMutexInt->u32Magic != RTSEMMUTEX_MAGIC)
    288     {
    289         AssertMsgFailed(("pMutexInt->u32Magic=%RX32 pMutexInt=%p\n", pMutexInt ? pMutexInt->u32Magic : 0, pMutexInt));
    290         return VERR_INVALID_PARAMETER;
    291     }
    292 
    293     /*
    294      * Check for recursive request.
    295      */
    296     if (pMutexInt->pOwner == current)
    297     {
    298         Assert(pMutexInt->cRecursion < 1000);
    299         ASMAtomicIncU32(&pMutexInt->cRecursion);
    300         return VINF_SUCCESS;
    301     }
    302 
    303     /*
    304      * Try aquire it.
    305      */
    306     if (ASMAtomicCmpXchgU32(&pMutexInt->cRecursion, 1, 0))
    307     {
    308         ASMAtomicXchgPtr(&pMutexInt->pOwner, current);
    309         return VINF_SUCCESS;
    310     }
    311     else
    312     {
    313         /*
    314          * Ok wait for it.
    315          */
    316         DEFINE_WAIT(Wait);
    317         int     rc       = VINF_SUCCESS;
    318         long    lTimeout = cMillies == RT_INDEFINITE_WAIT ? MAX_SCHEDULE_TIMEOUT : msecs_to_jiffies(cMillies);
    319         for (;;)
    320         {
    321             /* make everything thru schedule() atomic scheduling wise. */
    322             prepare_to_wait(&pMutexInt->Head, &Wait, TASK_INTERRUPTIBLE);
    323 
    324             /* check the condition. */
    325             if (ASMAtomicCmpXchgU32(&pMutexInt->cRecursion, 1, 0))
    326             {
    327                 ASMAtomicXchgPtr(&pMutexInt->pOwner, current);
    328                 break;
    329             }
    330 
    331             /* check for pending signals. */
    332             if (signal_pending(current))
    333             {
    334                 rc = VERR_INTERRUPTED; /** @todo VERR_INTERRUPTED isn't correct anylonger. please fix r0drv stuff! */
    335                 break;
    336             }
    337 
    338             /* wait */
    339             lTimeout = schedule_timeout(lTimeout);
    340 
    341             /* Check if someone destroyed the semaphore while we was waiting. */
    342             if (pMutexInt->u32Magic != RTSEMMUTEX_MAGIC)
    343             {
    344                 rc = VERR_SEM_DESTROYED;
    345                 break;
    346             }
    347 
    348             /* check for timeout. */
    349             if (!lTimeout)
    350             {
    351                 rc = VERR_TIMEOUT;
    352                 break;
    353             }
    354         }
    355         finish_wait(&pMutexInt->Head, &Wait);
    356         return rc;
    357     }
    358     return VINF_SUCCESS;
    359 }
    360 
    361 
    362 RTDECL(int)  RTSemMutexRelease(RTSEMMUTEX MutexSem)
    363 {
    364     /*
    365      * Validate input.
    366      */
    367     PRTSEMMUTEXINTERNAL pMutexInt = (PRTSEMMUTEXINTERNAL)MutexSem;
    368     if (!pMutexInt)
    369         return VERR_INVALID_PARAMETER;
    370     if (    !pMutexInt
    371         ||  pMutexInt->u32Magic != RTSEMMUTEX_MAGIC)
    372     {
    373         AssertMsgFailed(("pMutexInt->u32Magic=%RX32 pMutexInt=%p\n", pMutexInt ? pMutexInt->u32Magic : 0, pMutexInt));
    374         return VERR_INVALID_PARAMETER;
    375     }
    376     if (pMutexInt->pOwner != current)
    377     {
    378         AssertMsgFailed(("Not owner, pOwner=%p current=%p\n", (void *)pMutexInt->pOwner, (void *)current));
    379         return VERR_NOT_OWNER;
    380     }
    381 
    382     /*
    383      * Release the mutex.
    384      */
    385     if (pMutexInt->cRecursion == 1)
    386     {
    387         ASMAtomicXchgPtr(&pMutexInt->pOwner, NULL);
    388         ASMAtomicXchgU32(&pMutexInt->cRecursion, 0);
    389     }
    390     else
    391         ASMAtomicDecU32(&pMutexInt->cRecursion);
    392 
    393     return VINF_SUCCESS;
    394 }
    395 
    396 
    397 
    398 RTDECL(int)  RTSemFastMutexCreate(PRTSEMFASTMUTEX pMutexSem)
    399 {
    400     /*
    401      * Allocate.
    402      */
    403     PRTSEMFASTMUTEXINTERNAL pFastInt;
    404     pFastInt = (PRTSEMFASTMUTEXINTERNAL)RTMemAlloc(sizeof(*pFastInt));
    405     if (!pFastInt)
    406         return VERR_NO_MEMORY;
    407 
    408     /*
    409      * Initialize.
    410      */
    411     pFastInt->u32Magic = RTSEMFASTMUTEX_MAGIC;
    412     sema_init(&pFastInt->Semaphore, 1);
    413     *pMutexSem = pFastInt;
    414     return VINF_SUCCESS;
    415 }
    416 
    417 
    418 RTDECL(int)  RTSemFastMutexDestroy(RTSEMFASTMUTEX MutexSem)
    419 {
    420     /*
    421      * Validate.
    422      */
    423     PRTSEMFASTMUTEXINTERNAL pFastInt = (PRTSEMFASTMUTEXINTERNAL)MutexSem;
    424     if (!pFastInt)
    425         return VERR_INVALID_PARAMETER;
    426     if (pFastInt->u32Magic != RTSEMFASTMUTEX_MAGIC)
    427     {
    428         AssertMsgFailed(("pFastInt->u32Magic=%RX32 pMutexInt=%p\n", pFastInt->u32Magic, pFastInt));
    429         return VERR_INVALID_PARAMETER;
    430     }
    431 
    432     ASMAtomicIncU32(&pFastInt->u32Magic);
    433     RTMemFree(pFastInt);
    434     return VINF_SUCCESS;
    435 }
    436 
    437 
    438 RTDECL(int)  RTSemFastMutexRequest(RTSEMFASTMUTEX MutexSem)
    439 {
    440     /*
    441      * Validate.
    442      */
    443     PRTSEMFASTMUTEXINTERNAL pFastInt = (PRTSEMFASTMUTEXINTERNAL)MutexSem;
    444     if (    !pFastInt
    445         ||  pFastInt->u32Magic != RTSEMFASTMUTEX_MAGIC)
    446     {
    447         AssertMsgFailed(("pFastInt->u32Magic=%RX32 pMutexInt=%p\n", pFastInt ? pFastInt->u32Magic : 0, pFastInt));
    448         return VERR_INVALID_PARAMETER;
    449     }
    450 
    451     down(&pFastInt->Semaphore);
    452     return VINF_SUCCESS;
    453 }
    454 
    455 
    456 RTDECL(int)  RTSemFastMutexRelease(RTSEMFASTMUTEX MutexSem)
    457 {
    458     /*
    459      * Validate.
    460      */
    461     PRTSEMFASTMUTEXINTERNAL pFastInt = (PRTSEMFASTMUTEXINTERNAL)MutexSem;
    462     if (    !pFastInt
    463         ||  pFastInt->u32Magic != RTSEMFASTMUTEX_MAGIC)
    464     {
    465         AssertMsgFailed(("pFastInt->u32Magic=%RX32 pMutexInt=%p\n", pFastInt ? pFastInt->u32Magic : 0, pFastInt));
    466         return VERR_INVALID_PARAMETER;
    467     }
    468 
    469     up(&pFastInt->Semaphore);
    470     return VINF_SUCCESS;
    471 }
    472 
  • trunk/src/VBox/Runtime/r0drv/linux/semfastmutex-r0drv-linux.c

    r5219 r5225  
    11/* $Id$ */
    22/** @file
    3  * innotek Portable Runtime - Semaphores, Ring-0 Driver, Linux.
     3 * innotek Portable Runtime - Fast Mutex Semaphores, Ring-0 Driver, Linux.
    44 */
    55
     
    3535*******************************************************************************/
    3636/**
    37  * Linux event semaphore.
    38  */
    39 typedef struct RTSEMEVENTINTERNAL
    40 {
    41     /** Magic value (RTSEMEVENT_MAGIC). */
    42     uint32_t volatile   u32Magic;
    43     /** The object status - !0 when signaled and 0 when reset. */
    44     uint32_t volatile   fState;
    45     /** The wait queue. */
    46     wait_queue_head_t   Head;
    47 } RTSEMEVENTINTERNAL, *PRTSEMEVENTINTERNAL;
    48 
    49 
    50 /**
    51  * Linux mutex semaphore.
    52  */
    53 typedef struct RTSEMMUTEXINTERNAL
    54 {
    55     /** Magic value (RTSEMMUTEX_MAGIC). */
    56     uint32_t volatile   u32Magic;
    57     /** Number of recursive locks - 0 if not owned by anyone, > 0 if owned. */
    58     uint32_t volatile   cRecursion;
    59     /** The wait queue. */
    60     wait_queue_head_t   Head;
    61     /** The current owner. */
    62     void * volatile     pOwner;
    63 } RTSEMMUTEXINTERNAL, *PRTSEMMUTEXINTERNAL;
    64 
    65 
    66 /**
    6737 * Wrapper for the linux semaphore structure.
    6838 */
     
    7444    struct semaphore    Semaphore;
    7545} RTSEMFASTMUTEXINTERNAL, *PRTSEMFASTMUTEXINTERNAL;
    76 
    77 
    78 
    79 
    80 RTDECL(int)  RTSemEventCreate(PRTSEMEVENT pEventSem)
    81 {
    82     PRTSEMEVENTINTERNAL pEventInt = (PRTSEMEVENTINTERNAL)RTMemAlloc(sizeof(*pEventInt));
    83     if (pEventInt)
    84     {
    85         pEventInt->u32Magic = RTSEMEVENT_MAGIC;
    86         init_waitqueue_head(&pEventInt->Head);
    87         *pEventSem = pEventInt;
    88         return VINF_SUCCESS;
    89     }
    90     return VERR_NO_MEMORY;
    91 }
    92 
    93 
    94 RTDECL(int)  RTSemEventDestroy(RTSEMEVENT EventSem)
    95 {
    96     /*
    97      * Validate input.
    98      */
    99     PRTSEMEVENTINTERNAL pEventInt = (PRTSEMEVENTINTERNAL)EventSem;
    100     if (!pEventInt)
    101         return VERR_INVALID_PARAMETER;
    102     if (pEventInt->u32Magic != RTSEMEVENT_MAGIC)
    103     {
    104         AssertMsgFailed(("pEventInt->u32Magic=%RX32 pEventInt=%p\n", pEventInt->u32Magic, pEventInt));
    105         return VERR_INVALID_PARAMETER;
    106     }
    107 
    108     /*
    109      * Invalidate it and signal the object just in case.
    110      */
    111     ASMAtomicIncU32(&pEventInt->u32Magic);
    112     ASMAtomicXchgU32(&pEventInt->fState, 0);
    113     Assert(!waitqueue_active(&pEventInt->Head));
    114     wake_up_all(&pEventInt->Head);
    115     RTMemFree(pEventInt);
    116     return VINF_SUCCESS;
    117 }
    118 
    119 
    120 RTDECL(int)  RTSemEventSignal(RTSEMEVENT EventSem)
    121 {
    122     /*
    123      * Validate input.
    124      */
    125     PRTSEMEVENTINTERNAL pEventInt = (PRTSEMEVENTINTERNAL)EventSem;
    126     if (!pEventInt)
    127         return VERR_INVALID_PARAMETER;
    128     if (    !pEventInt
    129         ||  pEventInt->u32Magic != RTSEMEVENT_MAGIC)
    130     {
    131         AssertMsgFailed(("pEventInt->u32Magic=%RX32 pEventInt=%p\n", pEventInt ? pEventInt->u32Magic : 0, pEventInt));
    132         return VERR_INVALID_PARAMETER;
    133     }
    134 
    135     /*
    136      * Signal the event object.
    137      */
    138     ASMAtomicXchgU32(&pEventInt->fState, 1);
    139     wake_up(&pEventInt->Head);
    140 
    141     return VINF_SUCCESS;
    142 }
    143 
    144 
    145 /**
    146  * Worker for RTSemEvent and RTSemEventNoResume.
    147  *
    148  * @returns VBox status code.
    149  * @param   pEventInt           The event semaphore.
    150  * @param   cMillies            The number of milliseconds to wait.
    151  * @param   fInterruptible      Whether it's an interruptible wait or not.
    152  */
    153 static int rtSemEventWait(PRTSEMEVENTINTERNAL pEventInt, unsigned cMillies, bool fInterruptible)
    154 {
    155     /*
    156      * Ok wait for it.
    157      */
    158     DEFINE_WAIT(Wait);
    159     int     rc       = VINF_SUCCESS;
    160     long    lTimeout = cMillies == RT_INDEFINITE_WAIT ? MAX_SCHEDULE_TIMEOUT : msecs_to_jiffies(cMillies);
    161     for (;;)
    162     {
    163         /* make everything thru schedule() atomic scheduling wise. */
    164         prepare_to_wait(&pEventInt->Head, &Wait, fInterruptible ? TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE);
    165 
    166         /* check the condition. */
    167         if (ASMAtomicCmpXchgU32(&pEventInt->fState, 0, 1))
    168             break;
    169 
    170         /* check for pending signals. */
    171         if (fInterruptible && signal_pending(current))
    172         {
    173             rc = VERR_INTERRUPTED;
    174             break;
    175         }
    176 
    177         /* wait */
    178         lTimeout = schedule_timeout(lTimeout);
    179 
    180         /* Check if someone destroyed the semaphore while we were waiting. */
    181         if (pEventInt->u32Magic != RTSEMEVENT_MAGIC)
    182         {
    183             rc = VERR_SEM_DESTROYED;
    184             break;
    185         }
    186 
    187         /* check for timeout. */
    188         if (!lTimeout)
    189         {
    190             rc = VERR_TIMEOUT;
    191             break;
    192         }
    193     }
    194 
    195     finish_wait(&pEventInt->Head, &Wait);
    196     return rc;
    197 }
    198 
    199 
    200 RTDECL(int) RTSemEventWait(RTSEMEVENT EventSem, unsigned cMillies)
    201 {
    202     PRTSEMEVENTINTERNAL pEventInt = (PRTSEMEVENTINTERNAL)EventSem;
    203     if (!pEventInt)
    204         return VERR_INVALID_PARAMETER;
    205     if (    !pEventInt
    206         ||  pEventInt->u32Magic != RTSEMEVENT_MAGIC)
    207     {
    208         AssertMsgFailed(("pEventInt->u32Magic=%RX32 pEventInt=%p\n", pEventInt ? pEventInt->u32Magic : 0, pEventInt));
    209         return VERR_INVALID_PARAMETER;
    210     }
    211 
    212     if (ASMAtomicCmpXchgU32(&pEventInt->fState, 0, 1))
    213         return VINF_SUCCESS;
    214     return rtSemEventWait(pEventInt, cMillies, false /* fInterruptible */);
    215 }
    216 
    217 
    218 RTDECL(int) RTSemEventWaitNoResume(RTSEMEVENT EventSem, unsigned cMillies)
    219 {
    220     PRTSEMEVENTINTERNAL pEventInt = (PRTSEMEVENTINTERNAL)EventSem;
    221     if (!pEventInt)
    222         return VERR_INVALID_PARAMETER;
    223     if (    !pEventInt
    224         ||  pEventInt->u32Magic != RTSEMEVENT_MAGIC)
    225     {
    226         AssertMsgFailed(("pEventInt->u32Magic=%RX32 pEventInt=%p\n", pEventInt ? pEventInt->u32Magic : 0, pEventInt));
    227         return VERR_INVALID_PARAMETER;
    228     }
    229 
    230     if (ASMAtomicCmpXchgU32(&pEventInt->fState, 0, 1))
    231         return VINF_SUCCESS;
    232     return rtSemEventWait(pEventInt, cMillies, true /* fInterruptible */);
    233 }
    234 
    235 
    236 
    237 RTDECL(int)  RTSemMutexCreate(PRTSEMMUTEX pMutexSem)
    238 {
    239     PRTSEMMUTEXINTERNAL pMutexInt = (PRTSEMMUTEXINTERNAL)RTMemAlloc(sizeof(*pMutexInt));
    240     if (pMutexInt)
    241     {
    242         pMutexInt->u32Magic = RTSEMMUTEX_MAGIC;
    243         init_waitqueue_head(&pMutexInt->Head);
    244         *pMutexSem = pMutexInt;
    245 AssertReleaseMsgFailed(("This mutex implementation is buggy, fix it!\n"));
    246         return VINF_SUCCESS;
    247     }
    248     return VERR_NO_MEMORY;
    249 }
    250 
    251 
    252 RTDECL(int)  RTSemMutexDestroy(RTSEMMUTEX MutexSem)
    253 {
    254     /*
    255      * Validate input.
    256      */
    257     PRTSEMMUTEXINTERNAL pMutexInt = (PRTSEMMUTEXINTERNAL)MutexSem;
    258     if (!pMutexInt)
    259         return VERR_INVALID_PARAMETER;
    260     if (pMutexInt->u32Magic != RTSEMMUTEX_MAGIC)
    261     {
    262         AssertMsgFailed(("pMutexInt->u32Magic=%RX32 pMutexInt=%p\n", pMutexInt->u32Magic, pMutexInt));
    263         return VERR_INVALID_PARAMETER;
    264     }
    265 
    266     /*
    267      * Invalidate it and signal the object just in case.
    268      */
    269     ASMAtomicIncU32(&pMutexInt->u32Magic);
    270     ASMAtomicXchgU32(&pMutexInt->cRecursion, 0);
    271     Assert(!waitqueue_active(&pMutexInt->Head));
    272     wake_up_all(&pMutexInt->Head);
    273     RTMemFree(pMutexInt);
    274     return VINF_SUCCESS;
    275 }
    276 
    277 
    278 RTDECL(int)  RTSemMutexRequest(RTSEMMUTEX MutexSem, unsigned cMillies)
    279 {
    280     /*
    281      * Validate input.
    282      */
    283     PRTSEMMUTEXINTERNAL pMutexInt = (PRTSEMMUTEXINTERNAL)MutexSem;
    284     if (!pMutexInt)
    285         return VERR_INVALID_PARAMETER;
    286     if (    !pMutexInt
    287         ||  pMutexInt->u32Magic != RTSEMMUTEX_MAGIC)
    288     {
    289         AssertMsgFailed(("pMutexInt->u32Magic=%RX32 pMutexInt=%p\n", pMutexInt ? pMutexInt->u32Magic : 0, pMutexInt));
    290         return VERR_INVALID_PARAMETER;
    291     }
    292 
    293     /*
    294      * Check for recursive request.
    295      */
    296     if (pMutexInt->pOwner == current)
    297     {
    298         Assert(pMutexInt->cRecursion < 1000);
    299         ASMAtomicIncU32(&pMutexInt->cRecursion);
    300         return VINF_SUCCESS;
    301     }
    302 
    303     /*
    304      * Try aquire it.
    305      */
    306     if (ASMAtomicCmpXchgU32(&pMutexInt->cRecursion, 1, 0))
    307     {
    308         ASMAtomicXchgPtr(&pMutexInt->pOwner, current);
    309         return VINF_SUCCESS;
    310     }
    311     else
    312     {
    313         /*
    314          * Ok wait for it.
    315          */
    316         DEFINE_WAIT(Wait);
    317         int     rc       = VINF_SUCCESS;
    318         long    lTimeout = cMillies == RT_INDEFINITE_WAIT ? MAX_SCHEDULE_TIMEOUT : msecs_to_jiffies(cMillies);
    319         for (;;)
    320         {
    321             /* make everything thru schedule() atomic scheduling wise. */
    322             prepare_to_wait(&pMutexInt->Head, &Wait, TASK_INTERRUPTIBLE);
    323 
    324             /* check the condition. */
    325             if (ASMAtomicCmpXchgU32(&pMutexInt->cRecursion, 1, 0))
    326             {
    327                 ASMAtomicXchgPtr(&pMutexInt->pOwner, current);
    328                 break;
    329             }
    330 
    331             /* check for pending signals. */
    332             if (signal_pending(current))
    333             {
    334                 rc = VERR_INTERRUPTED; /** @todo VERR_INTERRUPTED isn't correct anylonger. please fix r0drv stuff! */
    335                 break;
    336             }
    337 
    338             /* wait */
    339             lTimeout = schedule_timeout(lTimeout);
    340 
    341             /* Check if someone destroyed the semaphore while we was waiting. */
    342             if (pMutexInt->u32Magic != RTSEMMUTEX_MAGIC)
    343             {
    344                 rc = VERR_SEM_DESTROYED;
    345                 break;
    346             }
    347 
    348             /* check for timeout. */
    349             if (!lTimeout)
    350             {
    351                 rc = VERR_TIMEOUT;
    352                 break;
    353             }
    354         }
    355         finish_wait(&pMutexInt->Head, &Wait);
    356         return rc;
    357     }
    358     return VINF_SUCCESS;
    359 }
    360 
    361 
    362 RTDECL(int)  RTSemMutexRelease(RTSEMMUTEX MutexSem)
    363 {
    364     /*
    365      * Validate input.
    366      */
    367     PRTSEMMUTEXINTERNAL pMutexInt = (PRTSEMMUTEXINTERNAL)MutexSem;
    368     if (!pMutexInt)
    369         return VERR_INVALID_PARAMETER;
    370     if (    !pMutexInt
    371         ||  pMutexInt->u32Magic != RTSEMMUTEX_MAGIC)
    372     {
    373         AssertMsgFailed(("pMutexInt->u32Magic=%RX32 pMutexInt=%p\n", pMutexInt ? pMutexInt->u32Magic : 0, pMutexInt));
    374         return VERR_INVALID_PARAMETER;
    375     }
    376     if (pMutexInt->pOwner != current)
    377     {
    378         AssertMsgFailed(("Not owner, pOwner=%p current=%p\n", (void *)pMutexInt->pOwner, (void *)current));
    379         return VERR_NOT_OWNER;
    380     }
    381 
    382     /*
    383      * Release the mutex.
    384      */
    385     if (pMutexInt->cRecursion == 1)
    386     {
    387         ASMAtomicXchgPtr(&pMutexInt->pOwner, NULL);
    388         ASMAtomicXchgU32(&pMutexInt->cRecursion, 0);
    389     }
    390     else
    391         ASMAtomicDecU32(&pMutexInt->cRecursion);
    392 
    393     return VINF_SUCCESS;
    394 }
    395 
    39646
    39747
  • trunk/src/VBox/Runtime/r0drv/linux/semmutex-r0drv-linux.c

    r5219 r5225  
    11/* $Id$ */
    22/** @file
    3  * innotek Portable Runtime - Semaphores, Ring-0 Driver, Linux.
     3 * innotek Portable Runtime - Mutex Semaphores, Ring-0 Driver, Linux.
    44 */
    55
     
    3535*******************************************************************************/
    3636/**
    37  * Linux event semaphore.
    38  */
    39 typedef struct RTSEMEVENTINTERNAL
    40 {
    41     /** Magic value (RTSEMEVENT_MAGIC). */
    42     uint32_t volatile   u32Magic;
    43     /** The object status - !0 when signaled and 0 when reset. */
    44     uint32_t volatile   fState;
    45     /** The wait queue. */
    46     wait_queue_head_t   Head;
    47 } RTSEMEVENTINTERNAL, *PRTSEMEVENTINTERNAL;
    48 
    49 
    50 /**
    5137 * Linux mutex semaphore.
    5238 */
     
    6248    void * volatile     pOwner;
    6349} RTSEMMUTEXINTERNAL, *PRTSEMMUTEXINTERNAL;
    64 
    65 
    66 /**
    67  * Wrapper for the linux semaphore structure.
    68  */
    69 typedef struct RTSEMFASTMUTEXINTERNAL
    70 {
    71     /** Magic value (RTSEMFASTMUTEX_MAGIC). */
    72     uint32_t            u32Magic;
    73     /** the linux semaphore. */
    74     struct semaphore    Semaphore;
    75 } RTSEMFASTMUTEXINTERNAL, *PRTSEMFASTMUTEXINTERNAL;
    76 
    77 
    78 
    79 
    80 RTDECL(int)  RTSemEventCreate(PRTSEMEVENT pEventSem)
    81 {
    82     PRTSEMEVENTINTERNAL pEventInt = (PRTSEMEVENTINTERNAL)RTMemAlloc(sizeof(*pEventInt));
    83     if (pEventInt)
    84     {
    85         pEventInt->u32Magic = RTSEMEVENT_MAGIC;
    86         init_waitqueue_head(&pEventInt->Head);
    87         *pEventSem = pEventInt;
    88         return VINF_SUCCESS;
    89     }
    90     return VERR_NO_MEMORY;
    91 }
    92 
    93 
    94 RTDECL(int)  RTSemEventDestroy(RTSEMEVENT EventSem)
    95 {
    96     /*
    97      * Validate input.
    98      */
    99     PRTSEMEVENTINTERNAL pEventInt = (PRTSEMEVENTINTERNAL)EventSem;
    100     if (!pEventInt)
    101         return VERR_INVALID_PARAMETER;
    102     if (pEventInt->u32Magic != RTSEMEVENT_MAGIC)
    103     {
    104         AssertMsgFailed(("pEventInt->u32Magic=%RX32 pEventInt=%p\n", pEventInt->u32Magic, pEventInt));
    105         return VERR_INVALID_PARAMETER;
    106     }
    107 
    108     /*
    109      * Invalidate it and signal the object just in case.
    110      */
    111     ASMAtomicIncU32(&pEventInt->u32Magic);
    112     ASMAtomicXchgU32(&pEventInt->fState, 0);
    113     Assert(!waitqueue_active(&pEventInt->Head));
    114     wake_up_all(&pEventInt->Head);
    115     RTMemFree(pEventInt);
    116     return VINF_SUCCESS;
    117 }
    118 
    119 
    120 RTDECL(int)  RTSemEventSignal(RTSEMEVENT EventSem)
    121 {
    122     /*
    123      * Validate input.
    124      */
    125     PRTSEMEVENTINTERNAL pEventInt = (PRTSEMEVENTINTERNAL)EventSem;
    126     if (!pEventInt)
    127         return VERR_INVALID_PARAMETER;
    128     if (    !pEventInt
    129         ||  pEventInt->u32Magic != RTSEMEVENT_MAGIC)
    130     {
    131         AssertMsgFailed(("pEventInt->u32Magic=%RX32 pEventInt=%p\n", pEventInt ? pEventInt->u32Magic : 0, pEventInt));
    132         return VERR_INVALID_PARAMETER;
    133     }
    134 
    135     /*
    136      * Signal the event object.
    137      */
    138     ASMAtomicXchgU32(&pEventInt->fState, 1);
    139     wake_up(&pEventInt->Head);
    140 
    141     return VINF_SUCCESS;
    142 }
    143 
    144 
    145 /**
    146  * Worker for RTSemEvent and RTSemEventNoResume.
    147  *
    148  * @returns VBox status code.
    149  * @param   pEventInt           The event semaphore.
    150  * @param   cMillies            The number of milliseconds to wait.
    151  * @param   fInterruptible      Whether it's an interruptible wait or not.
    152  */
    153 static int rtSemEventWait(PRTSEMEVENTINTERNAL pEventInt, unsigned cMillies, bool fInterruptible)
    154 {
    155     /*
    156      * Ok wait for it.
    157      */
    158     DEFINE_WAIT(Wait);
    159     int     rc       = VINF_SUCCESS;
    160     long    lTimeout = cMillies == RT_INDEFINITE_WAIT ? MAX_SCHEDULE_TIMEOUT : msecs_to_jiffies(cMillies);
    161     for (;;)
    162     {
    163         /* make everything thru schedule() atomic scheduling wise. */
    164         prepare_to_wait(&pEventInt->Head, &Wait, fInterruptible ? TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE);
    165 
    166         /* check the condition. */
    167         if (ASMAtomicCmpXchgU32(&pEventInt->fState, 0, 1))
    168             break;
    169 
    170         /* check for pending signals. */
    171         if (fInterruptible && signal_pending(current))
    172         {
    173             rc = VERR_INTERRUPTED;
    174             break;
    175         }
    176 
    177         /* wait */
    178         lTimeout = schedule_timeout(lTimeout);
    179 
    180         /* Check if someone destroyed the semaphore while we were waiting. */
    181         if (pEventInt->u32Magic != RTSEMEVENT_MAGIC)
    182         {
    183             rc = VERR_SEM_DESTROYED;
    184             break;
    185         }
    186 
    187         /* check for timeout. */
    188         if (!lTimeout)
    189         {
    190             rc = VERR_TIMEOUT;
    191             break;
    192         }
    193     }
    194 
    195     finish_wait(&pEventInt->Head, &Wait);
    196     return rc;
    197 }
    198 
    199 
    200 RTDECL(int) RTSemEventWait(RTSEMEVENT EventSem, unsigned cMillies)
    201 {
    202     PRTSEMEVENTINTERNAL pEventInt = (PRTSEMEVENTINTERNAL)EventSem;
    203     if (!pEventInt)
    204         return VERR_INVALID_PARAMETER;
    205     if (    !pEventInt
    206         ||  pEventInt->u32Magic != RTSEMEVENT_MAGIC)
    207     {
    208         AssertMsgFailed(("pEventInt->u32Magic=%RX32 pEventInt=%p\n", pEventInt ? pEventInt->u32Magic : 0, pEventInt));
    209         return VERR_INVALID_PARAMETER;
    210     }
    211 
    212     if (ASMAtomicCmpXchgU32(&pEventInt->fState, 0, 1))
    213         return VINF_SUCCESS;
    214     return rtSemEventWait(pEventInt, cMillies, false /* fInterruptible */);
    215 }
    216 
    217 
    218 RTDECL(int) RTSemEventWaitNoResume(RTSEMEVENT EventSem, unsigned cMillies)
    219 {
    220     PRTSEMEVENTINTERNAL pEventInt = (PRTSEMEVENTINTERNAL)EventSem;
    221     if (!pEventInt)
    222         return VERR_INVALID_PARAMETER;
    223     if (    !pEventInt
    224         ||  pEventInt->u32Magic != RTSEMEVENT_MAGIC)
    225     {
    226         AssertMsgFailed(("pEventInt->u32Magic=%RX32 pEventInt=%p\n", pEventInt ? pEventInt->u32Magic : 0, pEventInt));
    227         return VERR_INVALID_PARAMETER;
    228     }
    229 
    230     if (ASMAtomicCmpXchgU32(&pEventInt->fState, 0, 1))
    231         return VINF_SUCCESS;
    232     return rtSemEventWait(pEventInt, cMillies, true /* fInterruptible */);
    233 }
    23450
    23551
     
    394210}
    395211
    396 
    397 
    398 RTDECL(int)  RTSemFastMutexCreate(PRTSEMFASTMUTEX pMutexSem)
    399 {
    400     /*
    401      * Allocate.
    402      */
    403     PRTSEMFASTMUTEXINTERNAL pFastInt;
    404     pFastInt = (PRTSEMFASTMUTEXINTERNAL)RTMemAlloc(sizeof(*pFastInt));
    405     if (!pFastInt)
    406         return VERR_NO_MEMORY;
    407 
    408     /*
    409      * Initialize.
    410      */
    411     pFastInt->u32Magic = RTSEMFASTMUTEX_MAGIC;
    412     sema_init(&pFastInt->Semaphore, 1);
    413     *pMutexSem = pFastInt;
    414     return VINF_SUCCESS;
    415 }
    416 
    417 
    418 RTDECL(int)  RTSemFastMutexDestroy(RTSEMFASTMUTEX MutexSem)
    419 {
    420     /*
    421      * Validate.
    422      */
    423     PRTSEMFASTMUTEXINTERNAL pFastInt = (PRTSEMFASTMUTEXINTERNAL)MutexSem;
    424     if (!pFastInt)
    425         return VERR_INVALID_PARAMETER;
    426     if (pFastInt->u32Magic != RTSEMFASTMUTEX_MAGIC)
    427     {
    428         AssertMsgFailed(("pFastInt->u32Magic=%RX32 pMutexInt=%p\n", pFastInt->u32Magic, pFastInt));
    429         return VERR_INVALID_PARAMETER;
    430     }
    431 
    432     ASMAtomicIncU32(&pFastInt->u32Magic);
    433     RTMemFree(pFastInt);
    434     return VINF_SUCCESS;
    435 }
    436 
    437 
    438 RTDECL(int)  RTSemFastMutexRequest(RTSEMFASTMUTEX MutexSem)
    439 {
    440     /*
    441      * Validate.
    442      */
    443     PRTSEMFASTMUTEXINTERNAL pFastInt = (PRTSEMFASTMUTEXINTERNAL)MutexSem;
    444     if (    !pFastInt
    445         ||  pFastInt->u32Magic != RTSEMFASTMUTEX_MAGIC)
    446     {
    447         AssertMsgFailed(("pFastInt->u32Magic=%RX32 pMutexInt=%p\n", pFastInt ? pFastInt->u32Magic : 0, pFastInt));
    448         return VERR_INVALID_PARAMETER;
    449     }
    450 
    451     down(&pFastInt->Semaphore);
    452     return VINF_SUCCESS;
    453 }
    454 
    455 
    456 RTDECL(int)  RTSemFastMutexRelease(RTSEMFASTMUTEX MutexSem)
    457 {
    458     /*
    459      * Validate.
    460      */
    461     PRTSEMFASTMUTEXINTERNAL pFastInt = (PRTSEMFASTMUTEXINTERNAL)MutexSem;
    462     if (    !pFastInt
    463         ||  pFastInt->u32Magic != RTSEMFASTMUTEX_MAGIC)
    464     {
    465         AssertMsgFailed(("pFastInt->u32Magic=%RX32 pMutexInt=%p\n", pFastInt ? pFastInt->u32Magic : 0, pFastInt));
    466         return VERR_INVALID_PARAMETER;
    467     }
    468 
    469     up(&pFastInt->Semaphore);
    470     return VINF_SUCCESS;
    471 }
    472 
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