VirtualBox

source: vbox/trunk/src/VBox/Runtime/r0drv/freebsd/semmutex-r0drv-freebsd.c

Last change on this file was 98103, checked in by vboxsync, 17 months ago

Copyright year updates by scm.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 7.1 KB
Line 
1/* $Id: semmutex-r0drv-freebsd.c 98103 2023-01-17 14:15:46Z vboxsync $ */
2/** @file
3 * IPRT - Mutex Semaphores, Ring-0 Driver, FreeBSD.
4 */
5
6/*
7 * Copyright (C) 2010-2023 Oracle and/or its affiliates.
8 *
9 * This file is part of VirtualBox base platform packages, as
10 * available from https://www.virtualbox.org.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation, in version 3 of the
15 * License.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, see <https://www.gnu.org/licenses>.
24 *
25 * The contents of this file may alternatively be used under the terms
26 * of the Common Development and Distribution License Version 1.0
27 * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included
28 * in the VirtualBox distribution, in which case the provisions of the
29 * CDDL are applicable instead of those of the GPL.
30 *
31 * You may elect to license modified versions of this file under the
32 * terms and conditions of either the GPL or the CDDL or both.
33 *
34 * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0
35 */
36
37
38/*********************************************************************************************************************************
39* Header Files *
40*********************************************************************************************************************************/
41#define RTSEMMUTEX_WITHOUT_REMAPPING
42#include "the-freebsd-kernel.h"
43#include "internal/iprt.h"
44#include <iprt/semaphore.h>
45
46#include <iprt/asm.h>
47#include <iprt/assert.h>
48#include <iprt/errcore.h>
49#include <iprt/mem.h>
50#include <iprt/thread.h>
51#include <iprt/time.h>
52
53#include "internal/magics.h"
54
55
56/*********************************************************************************************************************************
57* Structures and Typedefs *
58*********************************************************************************************************************************/
59/**
60 * Wrapper for the FreeBSD (sleep) mutex.
61 */
62typedef struct RTSEMMUTEXINTERNAL
63{
64 /** Magic value (RTSEMMUTEX_MAGIC). */
65 uint32_t u32Magic;
66 /** The FreeBSD shared/exclusive lock mutex. */
67 struct sx SxLock;
68} RTSEMMUTEXINTERNAL, *PRTSEMMUTEXINTERNAL;
69
70
71RTDECL(int) RTSemMutexCreate(PRTSEMMUTEX phMutexSem)
72{
73 AssertCompile(sizeof(RTSEMMUTEXINTERNAL) > sizeof(void *));
74 AssertPtrReturn(phMutexSem, VERR_INVALID_POINTER);
75
76 PRTSEMMUTEXINTERNAL pThis = (PRTSEMMUTEXINTERNAL)RTMemAllocZ(sizeof(*pThis));
77 if (pThis)
78 {
79 pThis->u32Magic = RTSEMMUTEX_MAGIC;
80 sx_init_flags(&pThis->SxLock, "IPRT Mutex Semaphore", SX_RECURSE);
81
82 *phMutexSem = pThis;
83 return VINF_SUCCESS;
84 }
85 return VERR_NO_MEMORY;
86}
87
88
89RTDECL(int) RTSemMutexDestroy(RTSEMMUTEX hMutexSem)
90{
91 PRTSEMMUTEXINTERNAL pThis = hMutexSem;
92 if (pThis == NIL_RTSEMMUTEX)
93 return VINF_SUCCESS;
94 AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
95 AssertMsgReturn(pThis->u32Magic == RTSEMMUTEX_MAGIC, ("%p: u32Magic=%RX32\n", pThis, pThis->u32Magic), VERR_INVALID_HANDLE);
96
97 AssertReturn(ASMAtomicCmpXchgU32(&pThis->u32Magic, RTSEMMUTEX_MAGIC_DEAD, RTSEMMUTEX_MAGIC), VERR_INVALID_HANDLE);
98
99 sx_destroy(&pThis->SxLock);
100 RTMemFree(pThis);
101
102 return VINF_SUCCESS;
103}
104
105
106RTDECL(int) RTSemMutexRequest(RTSEMMUTEX hMutexSem, RTMSINTERVAL cMillies)
107{
108 PRTSEMMUTEXINTERNAL pThis = hMutexSem;
109 int rc;
110 AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
111 AssertMsgReturn(pThis->u32Magic == RTSEMMUTEX_MAGIC, ("%p: u32Magic=%RX32\n", pThis, pThis->u32Magic), VERR_INVALID_HANDLE);
112
113 if (cMillies == RT_INDEFINITE_WAIT)
114 {
115 sx_xlock(&pThis->SxLock);
116 rc = VINF_SUCCESS;
117 }
118 else if (!cMillies)
119 {
120 if (sx_try_xlock(&pThis->SxLock))
121 rc = VINF_SUCCESS;
122 else
123 rc = VERR_TIMEOUT;
124 }
125 /*
126 * GROSS HACK: poll implementation of timeout.
127 */
128 /** @todo Implement timeouts in RTSemMutexRequest. */
129 else if (sx_try_xlock(&pThis->SxLock))
130 rc = VINF_SUCCESS;
131 else
132 {
133 uint64_t StartTS = RTTimeSystemMilliTS();
134 rc = VERR_TIMEOUT;
135 do
136 {
137 RTThreadSleep(1);
138 if (sx_try_xlock(&pThis->SxLock))
139 {
140 rc = VINF_SUCCESS;
141 break;
142 }
143 } while (RTTimeSystemMilliTS() - StartTS < cMillies);
144 }
145
146 return VINF_SUCCESS;
147}
148
149
150RTDECL(int) RTSemMutexRequestDebug(RTSEMMUTEX hMutexSem, RTMSINTERVAL cMillies, RTHCUINTPTR uId, RT_SRC_POS_DECL)
151{
152 return RTSemMutexRequest(hMutexSem, cMillies);
153}
154
155
156RTDECL(int) RTSemMutexRequestNoResume(RTSEMMUTEX hMutexSem, RTMSINTERVAL cMillies)
157{
158 PRTSEMMUTEXINTERNAL pThis = hMutexSem;
159 int rc;
160 AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
161 AssertMsgReturn(pThis->u32Magic == RTSEMMUTEX_MAGIC, ("%p: u32Magic=%RX32\n", pThis, pThis->u32Magic), VERR_INVALID_HANDLE);
162
163 if (cMillies == RT_INDEFINITE_WAIT)
164 {
165 if (!sx_xlock_sig(&pThis->SxLock))
166 rc = VINF_SUCCESS;
167 else
168 rc = VERR_INTERRUPTED;
169 }
170 else if (!cMillies)
171 {
172 if (sx_try_xlock(&pThis->SxLock))
173 rc = VINF_SUCCESS;
174 else
175 rc = VERR_TIMEOUT;
176 }
177 /*
178 * GROSS HACK: poll implementation of timeout.
179 */
180 /** @todo Implement timeouts and interrupt checks in
181 * RTSemMutexRequestNoResume. */
182 else if (sx_try_xlock(&pThis->SxLock))
183 rc = VINF_SUCCESS;
184 else
185 {
186 uint64_t StartTS = RTTimeSystemMilliTS();
187 rc = VERR_TIMEOUT;
188 do
189 {
190 RTThreadSleep(1);
191 if (sx_try_xlock(&pThis->SxLock))
192 {
193 rc = VINF_SUCCESS;
194 break;
195 }
196 } while (RTTimeSystemMilliTS() - StartTS < cMillies);
197 }
198
199 return VINF_SUCCESS;
200}
201
202
203RTDECL(int) RTSemMutexRequestNoResumeDebug(RTSEMMUTEX hMutexSem, RTMSINTERVAL cMillies, RTHCUINTPTR uId, RT_SRC_POS_DECL)
204{
205 return RTSemMutexRequestNoResume(hMutexSem, cMillies);
206}
207
208
209RTDECL(int) RTSemMutexRelease(RTSEMMUTEX hMutexSem)
210{
211 PRTSEMMUTEXINTERNAL pThis = hMutexSem;
212 AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
213 AssertMsgReturn(pThis->u32Magic == RTSEMMUTEX_MAGIC, ("%p: u32Magic=%RX32\n", pThis, pThis->u32Magic), VERR_INVALID_HANDLE);
214
215 sx_xunlock(&pThis->SxLock);
216 return VINF_SUCCESS;
217}
218
219
220
221RTDECL(bool) RTSemMutexIsOwned(RTSEMMUTEX hMutexSem)
222{
223 PRTSEMMUTEXINTERNAL pThis = hMutexSem;
224 AssertPtrReturn(pThis, false);
225 AssertMsgReturn(pThis->u32Magic == RTSEMMUTEX_MAGIC, ("%p: u32Magic=%RX32\n", pThis, pThis->u32Magic), false);
226
227 return sx_xlocked(&pThis->SxLock);
228}
229
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use