2 Copyright © 2017, The AROS Development Team. All rights reserved.
9 Exposes a Public resource on smp systems that allows user space code
10 to create (spin) locks, and exposes locking on exec Lists.
12 e.g. LDDemon uses this to lock access to the system lists
13 when scanning devices/libraries etc - since are not allowed
14 to directly call the kernel locking functions or access the exec locks.
19 #include <aros/config.h>
21 #if defined(__AROSEXEC_SMP__)
25 #include <aros/debug.h>
26 #include <proto/exec.h>
28 #include "exec_debug.h"
29 #include "exec_intern.h"
30 #include "exec_locks.h"
32 int ExecLock__InternObtainSystemLock(struct List
*systemList
, ULONG mode
, ULONG flags
)
34 spinlock_t
*sysListLock
= NULL
;
39 if (&SysBase
->ResourceList
== systemList
) {
40 D(name
="ResourceList");
41 sysListLock
= &PrivExecBase(SysBase
)->ResourceListSpinLock
;
43 else if (&SysBase
->DeviceList
== systemList
) {
45 sysListLock
= &PrivExecBase(SysBase
)->DeviceListSpinLock
;
47 else if (&SysBase
->IntrList
== systemList
) {
49 sysListLock
= &PrivExecBase(SysBase
)->IntrListSpinLock
;
51 else if (&SysBase
->LibList
== systemList
) {
53 sysListLock
= &PrivExecBase(SysBase
)->LibListSpinLock
;
55 else if (&SysBase
->PortList
== systemList
) {
57 sysListLock
= &PrivExecBase(SysBase
)->PortListSpinLock
;
59 else if (&SysBase
->SemaphoreList
== systemList
) {
60 D(name
="SemaphoreList");
61 sysListLock
= &PrivExecBase(SysBase
)->SemListSpinLock
;
64 D(bug("[Exec:Lock] %s(), List='%s' (%p), mode=%s, flags=%d\n", __func__
, name
, systemList
, mode
== SPINLOCK_MODE_WRITE
? "write":"read", flags
));
67 if (flags
&& LOCKF_DISABLE
)
69 if (flags
&& LOCKF_FORBID
)
72 EXEC_SPINLOCK_LOCK(sysListLock
, NULL
, mode
);
79 void ExecLock__InternReleaseSystemLock(struct List
*systemList
, ULONG flags
)
81 spinlock_t
*sysListLock
= NULL
;
86 if (&SysBase
->ResourceList
== systemList
) {
87 D(name
="ResourceList");
88 sysListLock
= &PrivExecBase(SysBase
)->ResourceListSpinLock
;
90 else if (&SysBase
->DeviceList
== systemList
) {
92 sysListLock
= &PrivExecBase(SysBase
)->DeviceListSpinLock
;
94 else if (&SysBase
->IntrList
== systemList
) {
96 sysListLock
= &PrivExecBase(SysBase
)->IntrListSpinLock
;
98 else if (&SysBase
->LibList
== systemList
) {
100 sysListLock
= &PrivExecBase(SysBase
)->LibListSpinLock
;
102 else if (&SysBase
->PortList
== systemList
) {
104 sysListLock
= &PrivExecBase(SysBase
)->PortListSpinLock
;
106 else if (&SysBase
->SemaphoreList
== systemList
) {
107 D(name
="SemaphoreList");
108 sysListLock
= &PrivExecBase(SysBase
)->SemListSpinLock
;
111 D(bug("[Exec:Lock] %s(), list='%s' (%p), flags=%d\n", __func__
, name
, systemList
, flags
));
114 EXEC_SPINLOCK_UNLOCK(sysListLock
);
116 if (flags
& LOCKF_FORBID
)
118 if (flags
& LOCKF_DISABLE
)
123 /* Locking mechanism for userspace */
124 void *ExecLock__AllocLock()
126 spinlock_t
*publicLock
;
128 D(bug("[Exec:Lock] %s()\n", __func__
));
130 if ((publicLock
= (spinlock_t
*)AllocMem(sizeof(spinlock_t
), MEMF_ANY
)) != NULL
)
132 EXEC_SPINLOCK_INIT(publicLock
);
137 void *ExecLock__ObtainLock(void *lock
, ULONG mode
)
139 D(bug("[Exec:Lock] %s()\n", __func__
));
143 EXEC_SPINLOCK_LOCK(lock
, NULL
, mode
);
149 void ExecLock__ReleaseLock(void *lock
)
151 D(bug("[Exec:Lock] %s()\n", __func__
));
155 EXEC_SPINLOCK_UNLOCK(lock
);
159 void ExecLock__FreeLock(void *lock
)
161 D(bug("[Exec:Lock] %s()\n", __func__
));
165 FreeMem(lock
, sizeof(spinlock_t
));
170 AROS_LH1 (struct ExecLockBase
*, ResourceOpen
,
171 AROS_LHA (ULONG
, version
, D0
),
172 struct ExecLockBase
*, ExecLockBase
, 1, ExecLock
177 D(bug("[Exec:Lock] %s()\n", __func__
));
179 ((struct Library
*)ExecLockBase
)->lib_OpenCnt
++;
180 ((struct Library
*)ExecLockBase
)->lib_Flags
&= ~LIBF_DELEXP
;
187 AROS_LH3 (int, ObtainSystemLock
,
188 AROS_LHA(struct List
*, systemList
, A0
),
189 AROS_LHA(ULONG
, mode
, D0
),
190 AROS_LHA(ULONG
, flags
, D1
),
191 struct ExecLockBase
*, ExecLockBase
, 5, ExecLock
196 D(bug("[Exec:Lock] %s()\n", __func__
));
198 return ExecLock__InternObtainSystemLock(systemList
, mode
, flags
);
203 AROS_LH2 (void, ReleaseSystemLock
,
204 AROS_LHA(struct List
*, systemList
, A0
),
205 AROS_LHA(ULONG
, flags
, D1
),
206 struct ExecLockBase
*, ExecLockBase
, 6, ExecLock
211 D(bug("[Exec:Lock] %s()\n", __func__
));
213 ExecLock__InternReleaseSystemLock(systemList
, flags
);
219 const APTR ExecLock__FuncTable
[]=
221 &AROS_SLIB_ENTRY(ResourceOpen
,ExecLock
,1),
226 &AROS_SLIB_ENTRY(ObtainSystemLock
,ExecLock
,5),
227 &AROS_SLIB_ENTRY(ReleaseSystemLock
,ExecLock
,6),
232 APTR
ExecLock__PrepareBase(struct MemHeader
*mh
)
234 APTR ExecLockResBase
;
235 struct ExecLockBase
*ExecLockBase
;
237 D(bug("[Exec:Lock] %s()\n", __func__
));
239 ExecLockResBase
= Allocate(mh
, sizeof(struct ExecLockBase
) + sizeof(*ExecLock__FuncTable
));
240 ExecLockBase
= (struct ExecLockBase
*)((IPTR
)ExecLockResBase
+ sizeof(*ExecLock__FuncTable
));
242 MakeFunctions(ExecLockBase
, ExecLock__FuncTable
, NULL
);
244 ExecLockBase
->el_Node
.ln_Name
= "execlock.resource";
245 ExecLockBase
->el_Node
.ln_Type
= NT_RESOURCE
;
246 ExecLockBase
->ObtainSystemLock
= ExecLock__InternObtainSystemLock
;
247 ExecLockBase
->ReleaseSystemLock
= ExecLock__InternReleaseSystemLock
;
249 AddResource(ExecLockBase
);