PS2SDK
PS2 Homebrew Libraries
Loading...
Searching...
No Matches
lock.c
Go to the documentation of this file.
1/*
2# _____ ___ ____ ___ ____
3# ____| | ____| | | |____|
4# | ___| |____ ___| ____| | \ PS2DEV Open Source Project.
5#-----------------------------------------------------------------------
6# Copyright 2001-2004, ps2dev - http://www.ps2dev.org
7# Licenced under Academic Free License version 2.0
8# Review ps2sdk README & LICENSE files for further details.
9*/
10
16#include <stdint.h>
17#include <stdio.h>
18#include <stdbool.h>
19#include <stdlib.h>
20#include <sys/lock.h>
21#include <kernel.h>
22
23// Structure representing the lock
24struct __lock {
25 int32_t sem_id;
26 int32_t thread_id;
27 int32_t count;
28};
29
30#ifdef F___lock___sfp_recursive_mutex
31struct __lock __lock___sfp_recursive_mutex;
32#endif
33
34#ifdef F___lock___atexit_recursive_mutex
35struct __lock __lock___atexit_recursive_mutex;
36#endif
37
38#ifdef F___lock___at_quick_exit_mutex
39struct __lock __lock___at_quick_exit_mutex;
40#endif
41
42#ifdef F___lock___malloc_recursive_mutex
43struct __lock __lock___malloc_recursive_mutex;
44#endif
45
46#ifdef F___lock___env_recursive_mutex
47struct __lock __lock___env_recursive_mutex;
48#endif
49
50#ifdef F___lock___tz_mutex
51struct __lock __lock___tz_mutex;
52#endif
53
54#ifdef F___lock___dd_hash_mutex
55struct __lock __lock___dd_hash_mutex;
56#endif
57
58#ifdef F___lock___arc4random_mutex
59struct __lock __lock___arc4random_mutex;
60#endif
61
62static inline void __common_lock_init(_LOCK_T lock)
63{
64 ee_sema_t sema;
65 sema.init_count = 1;
66 sema.max_count = 1;
67 sema.option = 0;
68 sema.attr = 0;
69 sema.wait_threads = 0;
70 lock->sem_id = CreateSema(&sema);
71 lock->count = -1;
72 lock->thread_id = -1;
73}
74
75static inline void __common_lock_init_recursive(_LOCK_T lock)
76{
77 ee_sema_t sema;
78 sema.init_count = 1;
79 sema.max_count = 1;
80 sema.option = 0;
81 sema.attr = 0;
82 sema.wait_threads = 0;
83 lock->sem_id = CreateSema(&sema);
84 lock->count = 0;
85 lock->thread_id = -1;
86}
87
88static inline void __common_lock_close(_LOCK_T lock)
89{
90 DeleteSema(lock->sem_id);
91}
92
93static inline void __common_lock_close_recursive(_LOCK_T lock)
94{
95 DeleteSema(lock->sem_id);
96}
97
98#ifdef F___retarget_lock_init
99void __retarget_lock_init(_LOCK_T *lock)
100{
101 _LOCK_T new_lock = (_LOCK_T)malloc(sizeof(struct __lock));
102 __common_lock_init(new_lock);
103 *lock = new_lock;
104}
105#endif
106
107#ifdef F___retarget_lock_init_recursive
108void __retarget_lock_init_recursive(_LOCK_T *lock)
109{
110 _LOCK_T new_lock = (_LOCK_T)malloc(sizeof(struct __lock));
111 __common_lock_init_recursive(new_lock);
112 *lock = new_lock;
113}
114#endif
115
116#ifdef F___retarget_lock_close
117void __retarget_lock_close(_LOCK_T lock)
118{
119 __common_lock_close(lock);
120 free(lock);
121}
122#endif
123
124#ifdef F___retarget_lock_close_recursive
125void __retarget_lock_close_recursive(_LOCK_T lock)
126{
127 __common_lock_close_recursive(lock);
128 free(lock);
129}
130#endif
131
132#ifdef F___retarget_lock_acquire
133void __retarget_lock_acquire(_LOCK_T lock)
134{
135 WaitSema(lock->sem_id);
136}
137#endif
138
139#ifdef F___retarget_lock_acquire_recursive
140void __retarget_lock_acquire_recursive(_LOCK_T lock)
141{
142 bool starting = false;
143 int32_t thread_id = GetThreadId();
144 starting = lock->count == 0;
145 if (starting) {
146 lock->thread_id = thread_id;
147 }
148 if (lock->thread_id == thread_id) {
149 lock->count++;
150 if (starting) {
151 WaitSema(lock->sem_id);
152 }
153 } else {
154 WaitSema(lock->sem_id);
155 // Reached here means that the lock was acquired by another thread
156 // so now we need to make it ours
157 // We can't put the lock->count++ before the WaitSema because it will
158 // cause a deadlock
159 lock->thread_id = thread_id;
160 lock->count++;
161 }
162}
163#endif
164
165#ifdef F___retarget_lock_try_acquire
166int __retarget_lock_try_acquire(_LOCK_T lock)
167{
168 return PollSema(lock->sem_id) > 0 ? 0 : 1;
169}
170#endif
171
172#ifdef F___retarget_lock_try_acquire_recursive
173int __retarget_lock_try_acquire_recursive(_LOCK_T lock)
174{
175 int res = 0;
176 bool starting = false;
177 int32_t thread_id = GetThreadId();
178 starting = lock->count == 0;
179 if (starting) {
180 lock->thread_id = thread_id;
181 }
182 if (lock->thread_id == thread_id) {
183 lock->count++;
184 if (starting) {
185 res = PollSema(lock->sem_id) > 0 ? 0 : 1;
186 }
187 } else {
188 res = PollSema(lock->sem_id) > 0 ? 0 : 1;
189 // Reached here means that the lock was acquired by another thread
190 // so now we need to make it ours
191 // We can't put the lock->count++ before the WaitSema because it will
192 // cause a deadlock
193 lock->thread_id = thread_id;
194 lock->count++;
195 }
196 return res;
197}
198#endif
199
200#ifdef F___retarget_lock_release
201void __retarget_lock_release(_LOCK_T lock)
202{
203 SignalSema(lock->sem_id);
204}
205#endif
206
207#ifdef F___retarget_lock_release_recursive
208void __retarget_lock_release_recursive(_LOCK_T lock)
209{
210 bool tobeRelease = false;
211 int32_t thread_id = GetThreadId();
212 if (lock->thread_id != thread_id) {
213 // error this shouldn't never happen
214 perror("Error: Trying to release a lock that was not acquired by the current thread");
215 exit(1);
216 }
217
218 tobeRelease = lock->count == 1;
219 lock->count--;
220 if (lock->count == 0) {
221 lock->thread_id = -1;
222 }
223 if (tobeRelease) {
224 SignalSema(lock->sem_id);
225 }
226}
227#endif
228
229#ifdef F___locks_init
230extern struct __lock __lock___malloc_recursive_mutex;
231extern struct __lock __lock___atexit_recursive_mutex;
232extern struct __lock __lock___at_quick_exit_mutex;
233extern struct __lock __lock___sfp_recursive_mutex;
234extern struct __lock __lock___env_recursive_mutex;
235extern struct __lock __lock___tz_mutex;
236extern struct __lock __lock___dd_hash_mutex;
237extern struct __lock __lock___arc4random_mutex;
238
239void __locks_init()
240{
241 _LOCK_T lock_malloc = &__lock___malloc_recursive_mutex;
242 _LOCK_T lock_atexit = &__lock___atexit_recursive_mutex;
243 _LOCK_T lock_quick_exit = &__lock___at_quick_exit_mutex;
244 _LOCK_T lock_sfp = &__lock___sfp_recursive_mutex;
245 _LOCK_T lock_env = &__lock___env_recursive_mutex;
246 _LOCK_T lock_tz = &__lock___tz_mutex;
247 _LOCK_T lock_dd_hash = &__lock___dd_hash_mutex;
248 _LOCK_T lock_arc4random = &__lock___arc4random_mutex;
249
250 __common_lock_init_recursive(lock_malloc);
251 __common_lock_init_recursive(lock_atexit);
252 __common_lock_init(lock_quick_exit);
253 __common_lock_init_recursive(lock_sfp);
254 __common_lock_init_recursive(lock_env);
255 __common_lock_init(lock_tz);
256 __common_lock_init(lock_dd_hash);
257 __common_lock_init(lock_arc4random);
258}
259#endif
260
261#ifdef F___locks_deinit
262extern struct __lock __lock___malloc_recursive_mutex;
263extern struct __lock __lock___atexit_recursive_mutex;
264extern struct __lock __lock___at_quick_exit_mutex;
265extern struct __lock __lock___sfp_recursive_mutex;
266extern struct __lock __lock___env_recursive_mutex;
267extern struct __lock __lock___tz_mutex;
268extern struct __lock __lock___dd_hash_mutex;
269extern struct __lock __lock___arc4random_mutex;
270
271void __locks_deinit()
272{
273 _LOCK_T lock_malloc = &__lock___malloc_recursive_mutex;
274 _LOCK_T lock_atexit = &__lock___atexit_recursive_mutex;
275 _LOCK_T lock_quick_exit = &__lock___at_quick_exit_mutex;
276 _LOCK_T lock_sfp = &__lock___sfp_recursive_mutex;
277 _LOCK_T lock_env = &__lock___env_recursive_mutex;
278 _LOCK_T lock_tz = &__lock___tz_mutex;
279 _LOCK_T lock_dd_hash = &__lock___dd_hash_mutex;
280 _LOCK_T lock_arc4random = &__lock___arc4random_mutex;
281
282
283 __common_lock_close_recursive(lock_malloc);
284 __common_lock_close_recursive(lock_atexit);
285 __common_lock_close(lock_quick_exit);
286 __common_lock_close_recursive(lock_sfp);
287 __common_lock_close_recursive(lock_env);
288 __common_lock_close(lock_tz);
289 __common_lock_close(lock_dd_hash);
290 __common_lock_close(lock_arc4random);
291}
292#endif
Definition lock.c:24