Changeset 5225 in vbox for trunk/src/VBox/Runtime/r0drv
- Timestamp:
- Oct 10, 2007 3:06:48 PM (17 years ago)
- 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 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 -
trunk/src/VBox/Runtime/r0drv/linux/semfastmutex-r0drv-linux.c
r5219 r5225 1 1 /* $Id$ */ 2 2 /** @file 3 * innotek Portable Runtime - Semaphores, Ring-0 Driver, Linux.3 * innotek Portable Runtime - Fast Mutex Semaphores, Ring-0 Driver, Linux. 4 4 */ 5 5 … … 35 35 *******************************************************************************/ 36 36 /** 37 * Linux event semaphore.38 */39 typedef struct RTSEMEVENTINTERNAL40 {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 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 37 * Wrapper for the linux semaphore structure. 68 38 */ … … 74 44 struct semaphore Semaphore; 75 45 } 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 ( !pEventInt129 || 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 ( !pEventInt206 || 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 ( !pEventInt224 || 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 ( !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 46 397 47 -
trunk/src/VBox/Runtime/r0drv/linux/semmutex-r0drv-linux.c
r5219 r5225 1 1 /* $Id$ */ 2 2 /** @file 3 * innotek Portable Runtime - Semaphores, Ring-0 Driver, Linux.3 * innotek Portable Runtime - Mutex Semaphores, Ring-0 Driver, Linux. 4 4 */ 5 5 … … 35 35 *******************************************************************************/ 36 36 /** 37 * Linux event semaphore.38 */39 typedef struct RTSEMEVENTINTERNAL40 {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 37 * Linux mutex semaphore. 52 38 */ … … 62 48 void * volatile pOwner; 63 49 } 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 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 ( !pEventInt129 || 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 ( !pEventInt206 || 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 ( !pEventInt224 || 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 50 235 51 … … 394 210 } 395 211 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.