VirtualBox

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

semaphore-r0drv-lnx.c split.

File:
1 copied

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