Changeset 5225 in vbox for trunk/src/VBox/Runtime/r0drv/linux/semmutex-r0drv-linux.c
- Timestamp:
- Oct 10, 2007 3:06:48 PM (18 years ago)
- svn:sync-xref-src-repo-rev:
- 25161
- File:
-
- 1 copied
Legend:
- Unmodified
- Added
- Removed
-
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.