VirtualBox

source: vbox/trunk/src/VBox/Runtime/r0drv/darwin/spinlock-r0drv-darwin.cpp@ 109128

Last change on this file since 109128 was 109128, checked in by vboxsync, 2 weeks ago

IPRT/r0drv: Build adjustments for darwin.arm64. jiraref:VBP-1653

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Revision
File size: 5.9 KB
Line 
1/* $Id: spinlock-r0drv-darwin.cpp 109128 2025-05-01 01:31:56Z vboxsync $ */
2/** @file
3 * IPRT - Spinlocks, Ring-0 Driver, Darwin.
4 */
5
6/*
7 * Copyright (C) 2006-2024 Oracle and/or its affiliates.
8 *
9 * This file is part of VirtualBox base platform packages, as
10 * available from https://www.215389.xyz.
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#include "the-darwin-kernel.h"
42#include "internal/iprt.h"
43#include <iprt/spinlock.h>
44
45#include <iprt/assert.h>
46#include <iprt/asm.h>
47#if defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86)
48# include <iprt/asm-amd64-x86.h>
49#elif defined(RT_ARCH_ARM64) || defined(RT_ARCH_ARM32)
50# include <iprt/asm-arm.h>
51#endif
52#include <iprt/errcore.h>
53#include <iprt/mem.h>
54#include <iprt/thread.h>
55
56#include "internal/magics.h"
57
58
59/*********************************************************************************************************************************
60* Structures and Typedefs *
61*********************************************************************************************************************************/
62/**
63 * Wrapper for the KSPIN_LOCK type.
64 */
65typedef struct RTSPINLOCKINTERNAL
66{
67 /** Spinlock magic value (RTSPINLOCK_MAGIC). */
68 uint32_t volatile u32Magic;
69 /** Saved interrupt flag. */
70 uint32_t volatile fIntSaved;
71 /** Creation flags. */
72 uint32_t fFlags;
73 /** The Darwin spinlock structure. */
74 lck_spin_t *pSpinLock;
75 /** The spinlock name. */
76 const char *pszName;
77} RTSPINLOCKINTERNAL, *PRTSPINLOCKINTERNAL;
78
79
80
81RTDECL(int) RTSpinlockCreate(PRTSPINLOCK pSpinlock, uint32_t fFlags, const char *pszName)
82{
83 RT_ASSERT_PREEMPTIBLE();
84 AssertReturn(fFlags == RTSPINLOCK_FLAGS_INTERRUPT_SAFE || fFlags == RTSPINLOCK_FLAGS_INTERRUPT_UNSAFE, VERR_INVALID_PARAMETER);
85 IPRT_DARWIN_SAVE_EFL_AC();
86
87 /*
88 * Allocate.
89 */
90 AssertCompile(sizeof(RTSPINLOCKINTERNAL) > sizeof(void *));
91 PRTSPINLOCKINTERNAL pThis = (PRTSPINLOCKINTERNAL)RTMemAlloc(sizeof(*pThis));
92 if (pThis)
93 {
94 /*
95 * Initialize & return.
96 */
97 pThis->u32Magic = RTSPINLOCK_MAGIC;
98 pThis->fIntSaved = 0;
99 pThis->fFlags = fFlags;
100 pThis->pszName = pszName;
101 Assert(g_pDarwinLockGroup);
102 pThis->pSpinLock = lck_spin_alloc_init(g_pDarwinLockGroup, LCK_ATTR_NULL);
103 if (pThis->pSpinLock)
104 {
105 *pSpinlock = pThis;
106 IPRT_DARWIN_RESTORE_EFL_AC();
107 return VINF_SUCCESS;
108 }
109
110 RTMemFree(pThis);
111 }
112 IPRT_DARWIN_RESTORE_EFL_AC();
113 return VERR_NO_MEMORY;
114}
115
116
117RTDECL(int) RTSpinlockDestroy(RTSPINLOCK Spinlock)
118{
119 /*
120 * Validate input.
121 */
122 PRTSPINLOCKINTERNAL pThis = (PRTSPINLOCKINTERNAL)Spinlock;
123 if (!pThis)
124 return VERR_INVALID_PARAMETER;
125 AssertMsgReturn(pThis->u32Magic == RTSPINLOCK_MAGIC,
126 ("Invalid spinlock %p magic=%#x\n", pThis, pThis->u32Magic),
127 VERR_INVALID_PARAMETER);
128
129 /*
130 * Make the lock invalid and release the memory.
131 */
132 ASMAtomicIncU32(&pThis->u32Magic);
133 IPRT_DARWIN_SAVE_EFL_AC();
134
135 Assert(g_pDarwinLockGroup);
136 lck_spin_free(pThis->pSpinLock, g_pDarwinLockGroup);
137 pThis->pSpinLock = NULL;
138
139 RTMemFree(pThis);
140
141 IPRT_DARWIN_RESTORE_EFL_AC();
142 return VINF_SUCCESS;
143}
144
145
146RTDECL(void) RTSpinlockAcquire(RTSPINLOCK Spinlock)
147{
148 PRTSPINLOCKINTERNAL pThis = (PRTSPINLOCKINTERNAL)Spinlock;
149 AssertPtr(pThis);
150 Assert(pThis->u32Magic == RTSPINLOCK_MAGIC);
151
152 if (pThis->fFlags & RTSPINLOCK_FLAGS_INTERRUPT_SAFE)
153 {
154 uint32_t fIntSaved = ASMGetFlags();
155 ASMIntDisable();
156 lck_spin_lock(pThis->pSpinLock);
157 pThis->fIntSaved = fIntSaved;
158 IPRT_DARWIN_RESTORE_EFL_ONLY_AC_EX(fIntSaved);
159 }
160 else
161 {
162 IPRT_DARWIN_SAVE_EFL_AC();
163 lck_spin_lock(pThis->pSpinLock);
164 IPRT_DARWIN_RESTORE_EFL_ONLY_AC();
165 }
166}
167
168
169RTDECL(void) RTSpinlockRelease(RTSPINLOCK Spinlock)
170{
171 PRTSPINLOCKINTERNAL pThis = (PRTSPINLOCKINTERNAL)Spinlock;
172 AssertPtr(pThis);
173 Assert(pThis->u32Magic == RTSPINLOCK_MAGIC);
174
175 if (pThis->fFlags & RTSPINLOCK_FLAGS_INTERRUPT_SAFE)
176 {
177 uint32_t fIntSaved = pThis->fIntSaved;
178 pThis->fIntSaved = 0;
179 lck_spin_unlock(pThis->pSpinLock);
180 ASMSetFlags(fIntSaved);
181 }
182 else
183 {
184 IPRT_DARWIN_SAVE_EFL_AC();
185 lck_spin_unlock(pThis->pSpinLock);
186 IPRT_DARWIN_RESTORE_EFL_ONLY_AC();
187 }
188}
189
Note: See TracBrowser for help on using the repository browser.

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