VirtualBox

source: vbox/trunk/src/VBox/Runtime/r0drv/linux/semmutex-r0drv-linux.c@ 21337

最後變更 在這個檔案從21337是 21337,由 vboxsync 提交於 16 年 前

IPRT,HostDrv,AddDrv: Export public IPRT symbols for the linux kernel (pain).

  • 屬性 svn:eol-style 設為 native
  • 屬性 svn:keywords 設為 Id
檔案大小: 6.8 KB
 
1/* $Id: semmutex-r0drv-linux.c 21337 2009-07-07 14:58:27Z vboxsync $ */
2/** @file
3 * IPRT - Mutex Semaphores, Ring-0 Driver, Linux.
4 */
5
6/*
7 * Copyright (C) 2006-2007 Sun Microsystems, Inc.
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.alldomusa.eu.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 *
17 * The contents of this file may alternatively be used under the terms
18 * of the Common Development and Distribution License Version 1.0
19 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
20 * VirtualBox OSE distribution, in which case the provisions of the
21 * CDDL are applicable instead of those of the GPL.
22 *
23 * You may elect to license modified versions of this file under the
24 * terms and conditions of either the GPL or the CDDL or both.
25 *
26 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
27 * Clara, CA 95054 USA or visit http://www.sun.com if you need
28 * additional information or have any questions.
29 */
30
31
32/*******************************************************************************
33* Header Files *
34*******************************************************************************/
35#include "the-linux-kernel.h"
36#include "internal/iprt.h"
37#include <iprt/semaphore.h>
38#include <iprt/alloc.h>
39#include <iprt/assert.h>
40#include <iprt/asm.h>
41#include <iprt/err.h>
42
43#include "internal/magics.h"
44
45
46/*******************************************************************************
47* Structures and Typedefs *
48*******************************************************************************/
49/**
50 * Linux mutex semaphore.
51 */
52typedef struct RTSEMMUTEXINTERNAL
53{
54 /** Magic value (RTSEMMUTEX_MAGIC). */
55 uint32_t volatile u32Magic;
56 /** Number of recursive locks - 0 if not owned by anyone, > 0 if owned. */
57 uint32_t volatile cRecursion;
58 /** The wait queue. */
59 wait_queue_head_t Head;
60 /** The current owner. */
61 void * volatile pOwner;
62} RTSEMMUTEXINTERNAL, *PRTSEMMUTEXINTERNAL;
63
64
65
66RTDECL(int) RTSemMutexCreate(PRTSEMMUTEX pMutexSem)
67{
68 PRTSEMMUTEXINTERNAL pMutexInt = (PRTSEMMUTEXINTERNAL)RTMemAlloc(sizeof(*pMutexInt));
69 if (pMutexInt)
70 {
71 pMutexInt->u32Magic = RTSEMMUTEX_MAGIC;
72 init_waitqueue_head(&pMutexInt->Head);
73 *pMutexSem = pMutexInt;
74AssertReleaseMsgFailed(("This mutex implementation is buggy, fix it!\n"));
75 return VINF_SUCCESS;
76 }
77 return VERR_NO_MEMORY;
78}
79RT_EXPORT_SYMBOL(RTSemMutexCreate);
80
81
82RTDECL(int) RTSemMutexDestroy(RTSEMMUTEX MutexSem)
83{
84 /*
85 * Validate input.
86 */
87 PRTSEMMUTEXINTERNAL pMutexInt = (PRTSEMMUTEXINTERNAL)MutexSem;
88 if (!pMutexInt)
89 return VERR_INVALID_PARAMETER;
90 if (pMutexInt->u32Magic != RTSEMMUTEX_MAGIC)
91 {
92 AssertMsgFailed(("pMutexInt->u32Magic=%RX32 pMutexInt=%p\n", pMutexInt->u32Magic, pMutexInt));
93 return VERR_INVALID_PARAMETER;
94 }
95
96 /*
97 * Invalidate it and signal the object just in case.
98 */
99 ASMAtomicIncU32(&pMutexInt->u32Magic);
100 ASMAtomicXchgU32(&pMutexInt->cRecursion, 0);
101 Assert(!waitqueue_active(&pMutexInt->Head));
102 wake_up_all(&pMutexInt->Head);
103 RTMemFree(pMutexInt);
104 return VINF_SUCCESS;
105}
106RT_EXPORT_SYMBOL(RTSemMutexDestroy);
107
108
109RTDECL(int) RTSemMutexRequest(RTSEMMUTEX MutexSem, unsigned cMillies)
110{
111 /*
112 * Validate input.
113 */
114 PRTSEMMUTEXINTERNAL pMutexInt = (PRTSEMMUTEXINTERNAL)MutexSem;
115 if (!pMutexInt)
116 return VERR_INVALID_PARAMETER;
117 if ( !pMutexInt
118 || pMutexInt->u32Magic != RTSEMMUTEX_MAGIC)
119 {
120 AssertMsgFailed(("pMutexInt->u32Magic=%RX32 pMutexInt=%p\n", pMutexInt ? pMutexInt->u32Magic : 0, pMutexInt));
121 return VERR_INVALID_PARAMETER;
122 }
123
124 /*
125 * Check for recursive request.
126 */
127 if (pMutexInt->pOwner == current)
128 {
129 Assert(pMutexInt->cRecursion < 1000);
130 ASMAtomicIncU32(&pMutexInt->cRecursion);
131 return VINF_SUCCESS;
132 }
133
134 /*
135 * Try aquire it.
136 */
137 if (ASMAtomicCmpXchgU32(&pMutexInt->cRecursion, 1, 0))
138 {
139 ASMAtomicXchgPtr(&pMutexInt->pOwner, current);
140 return VINF_SUCCESS;
141 }
142 else
143 {
144 /*
145 * Ok wait for it.
146 */
147 DEFINE_WAIT(Wait);
148 int rc = VINF_SUCCESS;
149 long lTimeout = cMillies == RT_INDEFINITE_WAIT ? MAX_SCHEDULE_TIMEOUT : msecs_to_jiffies(cMillies);
150 for (;;)
151 {
152 /* make everything thru schedule() atomic scheduling wise. */
153 prepare_to_wait(&pMutexInt->Head, &Wait, TASK_INTERRUPTIBLE);
154
155 /* check the condition. */
156 if (ASMAtomicCmpXchgU32(&pMutexInt->cRecursion, 1, 0))
157 {
158 ASMAtomicXchgPtr(&pMutexInt->pOwner, current);
159 break;
160 }
161
162 /* check for pending signals. */
163 if (signal_pending(current))
164 {
165 rc = VERR_INTERRUPTED; /** @todo VERR_INTERRUPTED isn't correct anylonger. please fix r0drv stuff! */
166 break;
167 }
168
169 /* wait */
170 lTimeout = schedule_timeout(lTimeout);
171
172 /* Check if someone destroyed the semaphore while we was waiting. */
173 if (pMutexInt->u32Magic != RTSEMMUTEX_MAGIC)
174 {
175 rc = VERR_SEM_DESTROYED;
176 break;
177 }
178
179 /* check for timeout. */
180 if (!lTimeout)
181 {
182 rc = VERR_TIMEOUT;
183 break;
184 }
185 }
186 finish_wait(&pMutexInt->Head, &Wait);
187 return rc;
188 }
189 return VINF_SUCCESS;
190}
191RT_EXPORT_SYMBOL(RTSemMutexRequest);
192
193
194RTDECL(int) RTSemMutexRelease(RTSEMMUTEX MutexSem)
195{
196 /*
197 * Validate input.
198 */
199 PRTSEMMUTEXINTERNAL pMutexInt = (PRTSEMMUTEXINTERNAL)MutexSem;
200 if (!pMutexInt)
201 return VERR_INVALID_PARAMETER;
202 if ( !pMutexInt
203 || pMutexInt->u32Magic != RTSEMMUTEX_MAGIC)
204 {
205 AssertMsgFailed(("pMutexInt->u32Magic=%RX32 pMutexInt=%p\n", pMutexInt ? pMutexInt->u32Magic : 0, pMutexInt));
206 return VERR_INVALID_PARAMETER;
207 }
208 if (pMutexInt->pOwner != current)
209 {
210 AssertMsgFailed(("Not owner, pOwner=%p current=%p\n", (void *)pMutexInt->pOwner, (void *)current));
211 return VERR_NOT_OWNER;
212 }
213
214 /*
215 * Release the mutex.
216 */
217 if (pMutexInt->cRecursion == 1)
218 {
219 ASMAtomicXchgPtr(&pMutexInt->pOwner, NULL);
220 ASMAtomicXchgU32(&pMutexInt->cRecursion, 0);
221 }
222 else
223 ASMAtomicDecU32(&pMutexInt->cRecursion);
224
225 return VINF_SUCCESS;
226}
227RT_EXPORT_SYMBOL(RTSemMutexRelease);
228
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette