PS2SDK
PS2 Homebrew Libraries
Loading...
Searching...
No Matches
tls-helper.c
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
11#include <ps2_osal.h>
12
13#ifdef F___keysUsed
14int *__keysUsed;
15#else
16extern int *__keysUsed;
17#endif
18
19#ifdef F___maxTlsValues
20int __maxTlsValues;
21#else
22extern int __maxTlsValues;
23#endif
24
25#ifdef F___globalTlsLock
26pte_osMutexHandle __globalTlsLock;
27#else
28extern pte_osMutexHandle __globalTlsLock;
29#endif
30
31/* Structure used to emulate TLS on non-POSIX threads.
32 * This limits us to one non-POSIX thread that can
33 * call pthread functions. */
34#ifdef F___globalTls
35void *__globalTls;
36#else
37extern void *__globalTls;
38#endif
39
40#ifdef F_pteTlsGlobalInit
41pte_osResult pteTlsGlobalInit(int maxEntries)
42{
43 int i;
44 pte_osResult result;
45
46 pte_osMutexCreate(&__globalTlsLock);
47 __keysUsed = (int *)malloc(maxEntries * sizeof(int));
48
49 if (__keysUsed != NULL) {
50 for (i = 0; i < maxEntries; i++) {
51 __keysUsed[i] = 0;
52 }
53
54 __maxTlsValues = maxEntries;
55 result = PTE_OS_OK;
56 } else {
57 result = PTE_OS_NO_RESOURCES;
58 }
59
60 return result;
61}
62#endif
63
64#ifdef F_pteTlsThreadInit
65void *pteTlsThreadInit(void)
66{
67 void **pTlsStruct;
68 int i;
69
70 pTlsStruct = (void **)malloc(__maxTlsValues * sizeof(void *));
71
72 // PTE library assumes that keys are initialized to zero
73 for (i = 0; i < __maxTlsValues; i++) {
74 pTlsStruct[i] = 0;
75 }
76
77 return (void *)pTlsStruct;
78}
79#endif
80
81#ifdef F___pteTlsAlloc
82pte_osResult __pteTlsAlloc(unsigned int *pKey)
83{
84 int i;
85 pte_osResult result = PTE_OS_NO_RESOURCES;
86
87 pte_osMutexLock(__globalTlsLock);
88
89 for (i = 0; i < __maxTlsValues; i++) {
90 if (__keysUsed[i] == 0) {
91 __keysUsed[i] = 1;
92
93 *pKey = i + 1;
94 result = PTE_OS_OK;
95 break;
96 }
97 }
98
99 pte_osMutexUnlock(__globalTlsLock);
100 return result;
101}
102#else
103pte_osResult __pteTlsAlloc(unsigned int *pKey);
104#endif
105
106#ifdef F_pteTlsGetValue
107void *pteTlsGetValue(void *pTlsThreadStruct, unsigned int index)
108{
109 void **pTls = (void **)pTlsThreadStruct;
110
111 if (__keysUsed[index - 1] && pTls != NULL) {
112 return pTls[index - 1];
113 } else {
114 return NULL;
115 }
116}
117#else
118void *pteTlsGetValue(void *pTlsThreadStruct, unsigned int index);
119#endif
120
121#ifdef F___pteTlsSetValue
122pte_osResult __pteTlsSetValue(void *pTlsThreadStruct, unsigned int index, void *value)
123{
124 pte_osResult result;
125 void **pTls = (void **)pTlsThreadStruct;
126
127 if (pTls != NULL) {
128 pTls[index - 1] = value;
129 result = PTE_OS_OK;
130 } else {
131 result = PTE_OS_INVALID_PARAM;
132 }
133
134 return result;
135}
136#else
137pte_osResult __pteTlsSetValue(void *pTlsThreadStruct, unsigned int index, void *value);
138#endif
139
140#ifdef F___getTlsStructFromThread
141void *__getTlsStructFromThread(s32 thid)
142{
143 struct OsalThreadInfo *threadInfo = &__threadInfo[thid];
144 void *pTls;
145
146 /* If we were called from a pthread, use the TLS allocated when the thread
147 * was created. Otherwise, we were called from a non-pthread, so use the
148 * "global". This is a pretty bad hack, but necessary due to lack of TLS on PS2.
149 */
150 if (threadInfo->tlsPtr) {
151 pTls = threadInfo->tlsPtr;
152 } else {
153 pTls = __globalTls;
154 }
155
156 return pTls;
157}
158#else
159void *__getTlsStructFromThread(s32 thid);
160#endif
161
162#ifdef F_pteTlsFree
163pte_osResult pteTlsFree(unsigned int index)
164{
165 pte_osResult result;
166
167 if (__keysUsed != NULL) {
168 pte_osMutexLock(__globalTlsLock);
169 __keysUsed[index - 1] = 0;
170 pte_osMutexUnlock(__globalTlsLock);
171
172 result = PTE_OS_OK;
173 } else {
174 result = PTE_OS_GENERAL_FAILURE;
175 }
176
177 return result;
178}
179#else
180pte_osResult pteTlsFree(unsigned int index);
181#endif
182
183#ifdef F_pteTlsThreadDestroy
184void pteTlsThreadDestroy(void *pTlsThreadStruct)
185{
186 free(pTlsThreadStruct);
187}
188#endif
189
190#ifdef F_pteTlsGlobalDestroy
191void pteTlsGlobalDestroy(void)
192{
193 pte_osMutexDelete(__globalTlsLock);
194 free(__keysUsed);
195}
196#endif
197
198#ifdef F_pte_osTlsSetValue
199pte_osResult pte_osTlsSetValue(unsigned int key, void * value)
200{
201 void *pTls;
202
203 pTls = __getTlsStructFromThread(GetThreadId());
204
205 return __pteTlsSetValue(pTls, key, value);
206}
207#endif
208
209#ifdef F_pte_osTlsGetValue
210void * pte_osTlsGetValue(unsigned int index)
211{
212 void *pTls;
213
214 pTls = __getTlsStructFromThread(GetThreadId());
215
216 return (void *) pteTlsGetValue(pTls, index);
217
218}
219#endif
220
221#ifdef F_pte_osTlsAlloc
222pte_osResult pte_osTlsAlloc(unsigned int *pKey)
223{
224 __getTlsStructFromThread(GetThreadId());
225
226 return __pteTlsAlloc(pKey);
227
228}
229#endif
230
231#ifdef F_pte_osTlsFree
232pte_osResult pte_osTlsFree(unsigned int index)
233{
234 return pteTlsFree(index);
235}
236#endif