Changeset 5225 in vbox for trunk/src/VBox/Runtime/r0drv/linux/semevent-r0drv-linux.c
- Timestamp:
- Oct 10, 2007 3:06:48 PM (17 years ago)
- File:
-
- 1 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/r0drv/linux/semevent-r0drv-linux.c
r5219 r5225 1 1 /* $Id$ */ 2 2 /** @file 3 * innotek Portable Runtime - S emaphores, Ring-0 Driver, Linux.3 * innotek Portable Runtime - Single Release Event Semaphores, Ring-0 Driver, Linux. 4 4 */ 5 5 … … 48 48 49 49 50 /**51 * Linux mutex semaphore.52 */53 typedef struct RTSEMMUTEXINTERNAL54 {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 RTSEMFASTMUTEXINTERNAL70 {71 /** Magic value (RTSEMFASTMUTEX_MAGIC). */72 uint32_t u32Magic;73 /** the linux semaphore. */74 struct semaphore Semaphore;75 } RTSEMFASTMUTEXINTERNAL, *PRTSEMFASTMUTEXINTERNAL;76 77 78 79 50 80 51 RTDECL(int) RTSemEventCreate(PRTSEMEVENT pEventSem) … … 233 204 } 234 205 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 ( !pMutexInt287 || 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 else312 {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 ( !pMutexInt371 || 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 else391 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 ( !pFastInt445 || 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 ( !pFastInt463 || 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.