︙ | | | ︙ | |
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
|
# if defined(OF_HAVE_COMPILER_TLS)
static thread_local struct page *firstPage = NULL;
static thread_local struct page *lastPage = NULL;
static thread_local struct page **preallocatedPages = NULL;
static thread_local size_t numPreallocatedPages = 0;
# elif defined(OF_HAVE_THREADS)
static of_tlskey_t firstPageKey, lastPageKey;
static of_tlskey_t preallocatedPagesKey, numPreallocatedPagesKey;
# else
static struct page *firstPage = NULL;
static struct page *lastPage = NULL;
static struct page **preallocatedPages = NULL;
static size_t numPreallocatedPages = 0;
# endif
|
|
|
|
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
|
# if defined(OF_HAVE_COMPILER_TLS)
static thread_local struct page *firstPage = NULL;
static thread_local struct page *lastPage = NULL;
static thread_local struct page **preallocatedPages = NULL;
static thread_local size_t numPreallocatedPages = 0;
# elif defined(OF_HAVE_THREADS)
static OFTLSKey firstPageKey, lastPageKey;
static OFTLSKey preallocatedPagesKey, numPreallocatedPagesKey;
# else
static struct page *firstPage = NULL;
static struct page *lastPage = NULL;
static struct page **preallocatedPages = NULL;
static size_t numPreallocatedPages = 0;
# endif
|
︙ | | | ︙ | |
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
|
# if !defined(OF_HAVE_COMPILER_TLS) && defined(OF_HAVE_THREADS)
struct page *lastPage;
# endif
if (allowPreallocated) {
# if !defined(OF_HAVE_COMPILER_TLS) && defined(OF_HAVE_THREADS)
uintptr_t numPreallocatedPages =
(uintptr_t)of_tlskey_get(numPreallocatedPagesKey);
# endif
if (numPreallocatedPages > 0) {
# if !defined(OF_HAVE_COMPILER_TLS) && defined(OF_HAVE_THREADS)
struct page **preallocatedPages =
of_tlskey_get(preallocatedPagesKey);
# endif
numPreallocatedPages--;
# if !defined(OF_HAVE_COMPILER_TLS) && defined(OF_HAVE_THREADS)
OF_ENSURE(of_tlskey_set(numPreallocatedPagesKey,
(void *)numPreallocatedPages) == 0);
# endif
page = preallocatedPages[numPreallocatedPages];
if (numPreallocatedPages == 0) {
free(preallocatedPages);
preallocatedPages = NULL;
# if !defined(OF_HAVE_COMPILER_TLS) && defined(OF_HAVE_THREADS)
OF_ENSURE(of_tlskey_set(preallocatedPagesKey,
preallocatedPages) == 0);
# endif
}
return page;
}
}
|
|
|
|
|
|
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
|
# if !defined(OF_HAVE_COMPILER_TLS) && defined(OF_HAVE_THREADS)
struct page *lastPage;
# endif
if (allowPreallocated) {
# if !defined(OF_HAVE_COMPILER_TLS) && defined(OF_HAVE_THREADS)
uintptr_t numPreallocatedPages =
(uintptr_t)OFTLSKeyGet(numPreallocatedPagesKey);
# endif
if (numPreallocatedPages > 0) {
# if !defined(OF_HAVE_COMPILER_TLS) && defined(OF_HAVE_THREADS)
struct page **preallocatedPages =
OFTLSKeyGet(preallocatedPagesKey);
# endif
numPreallocatedPages--;
# if !defined(OF_HAVE_COMPILER_TLS) && defined(OF_HAVE_THREADS)
OF_ENSURE(OFTLSKeySet(numPreallocatedPagesKey,
(void *)numPreallocatedPages) == 0);
# endif
page = preallocatedPages[numPreallocatedPages];
if (numPreallocatedPages == 0) {
free(preallocatedPages);
preallocatedPages = NULL;
# if !defined(OF_HAVE_COMPILER_TLS) && defined(OF_HAVE_THREADS)
OF_ENSURE(OFTLSKeySet(preallocatedPagesKey,
preallocatedPages) == 0);
# endif
}
return page;
}
}
|
︙ | | | ︙ | |
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
|
free(page->map);
free(page);
@throw e;
}
of_explicit_memset(page->page, 0, pageSize);
# if !defined(OF_HAVE_COMPILER_TLS) && defined(OF_HAVE_THREADS)
lastPage = of_tlskey_get(lastPageKey);
# endif
page->previous = lastPage;
page->next = NULL;
if (lastPage != NULL)
lastPage->next = page;
# if defined(OF_HAVE_COMPILER_TLS) || !defined(OF_HAVE_THREADS)
lastPage = page;
if (firstPage == NULL)
firstPage = page;
# else
OF_ENSURE(of_tlskey_set(lastPageKey, page) == 0);
if (of_tlskey_get(firstPageKey) == NULL)
OF_ENSURE(of_tlskey_set(firstPageKey, page) == 0);
# endif
return page;
}
static void
removePageIfEmpty(struct page *page)
|
|
|
|
|
|
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
|
free(page->map);
free(page);
@throw e;
}
of_explicit_memset(page->page, 0, pageSize);
# if !defined(OF_HAVE_COMPILER_TLS) && defined(OF_HAVE_THREADS)
lastPage = OFTLSKeyGet(lastPageKey);
# endif
page->previous = lastPage;
page->next = NULL;
if (lastPage != NULL)
lastPage->next = page;
# if defined(OF_HAVE_COMPILER_TLS) || !defined(OF_HAVE_THREADS)
lastPage = page;
if (firstPage == NULL)
firstPage = page;
# else
OF_ENSURE(OFTLSKeySet(lastPageKey, page) == 0);
if (OFTLSKeyGet(firstPageKey) == NULL)
OF_ENSURE(OFTLSKeySet(firstPageKey, page) == 0);
# endif
return page;
}
static void
removePageIfEmpty(struct page *page)
|
︙ | | | ︙ | |
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
|
# if defined(OF_HAVE_COMPILER_TLS) || !defined(OF_HAVE_THREADS)
if (firstPage == page)
firstPage = page->next;
if (lastPage == page)
lastPage = page->previous;
# else
if (of_tlskey_get(firstPageKey) == page)
OF_ENSURE(of_tlskey_set(firstPageKey, page->next) == 0);
if (of_tlskey_get(lastPageKey) == page)
OF_ENSURE(of_tlskey_set(lastPageKey, page->previous) == 0);
# endif
free(page);
}
static void *
allocateMemory(struct page *page, size_t bytes)
|
|
|
|
|
|
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
|
# if defined(OF_HAVE_COMPILER_TLS) || !defined(OF_HAVE_THREADS)
if (firstPage == page)
firstPage = page->next;
if (lastPage == page)
lastPage = page->previous;
# else
if (OFTLSKeyGet(firstPageKey) == page)
OF_ENSURE(OFTLSKeySet(firstPageKey, page->next) == 0);
if (OFTLSKeyGet(lastPageKey) == page)
OF_ENSURE(OFTLSKeySet(lastPageKey, page->previous) == 0);
# endif
free(page);
}
static void *
allocateMemory(struct page *page, size_t bytes)
|
︙ | | | ︙ | |
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
|
#if defined(HAVE_MMAP) && defined(HAVE_MLOCK) && defined(MAP_ANON) && \
!defined(OF_HAVE_COMPILER_TLS) && defined(OF_HAVE_THREADS)
+ (void)initialize
{
if (self != [OFSecureData class])
return;
if (of_tlskey_new(&firstPageKey) != 0 ||
of_tlskey_new(&lastPageKey) != 0 ||
of_tlskey_new(&preallocatedPagesKey) != 0 ||
of_tlskey_new(&numPreallocatedPagesKey) != 0)
@throw [OFInitializationFailedException
exceptionWithClass: self];
}
#endif
+ (void)preallocateUnswappableMemoryWithSize: (size_t)size
{
#if defined(HAVE_MMAP) && defined(HAVE_MLOCK) && defined(MAP_ANON)
size_t pageSize = [OFSystemInfo pageSize];
size_t numPages = OF_ROUND_UP_POW2(pageSize, size) / pageSize;
# if !defined(OF_HAVE_COMPILER_TLS) && defined(OF_HAVE_THREADS)
struct page **preallocatedPages = of_tlskey_get(preallocatedPagesKey);
size_t numPreallocatedPages;
# endif
size_t i;
if (preallocatedPages != NULL)
@throw [OFInvalidArgumentException exception];
preallocatedPages = of_alloc_zeroed(numPages, sizeof(struct page));
# if !defined(OF_HAVE_COMPILER_TLS) && defined(OF_HAVE_THREADS)
OF_ENSURE(of_tlskey_set(preallocatedPagesKey, preallocatedPages) == 0);
# endif
@try {
for (i = 0; i < numPages; i++)
preallocatedPages[i] = addPage(false);
} @catch (id e) {
for (size_t j = 0; j < i; j++)
removePageIfEmpty(preallocatedPages[j]);
free(preallocatedPages);
preallocatedPages = NULL;
@throw e;
}
numPreallocatedPages = numPages;
# if !defined(OF_HAVE_COMPILER_TLS) && defined(OF_HAVE_THREADS)
OF_ENSURE(of_tlskey_set(numPreallocatedPagesKey,
(void *)(uintptr_t)numPreallocatedPages) == 0);
# endif
#else
@throw [OFNotImplementedException exceptionWithSelector: _cmd
object: self];
#endif
}
|
<
|
|
|
|
|
|
|
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
|
#if defined(HAVE_MMAP) && defined(HAVE_MLOCK) && defined(MAP_ANON) && \
!defined(OF_HAVE_COMPILER_TLS) && defined(OF_HAVE_THREADS)
+ (void)initialize
{
if (self != [OFSecureData class])
return;
if (OFTLSKeyNew(&firstPageKey) != 0 || OFTLSKeyNew(&lastPageKey) != 0 ||
OFTLSKeyNew(&preallocatedPagesKey) != 0 ||
OFTLSKeyNew(&numPreallocatedPagesKey) != 0)
@throw [OFInitializationFailedException
exceptionWithClass: self];
}
#endif
+ (void)preallocateUnswappableMemoryWithSize: (size_t)size
{
#if defined(HAVE_MMAP) && defined(HAVE_MLOCK) && defined(MAP_ANON)
size_t pageSize = [OFSystemInfo pageSize];
size_t numPages = OF_ROUND_UP_POW2(pageSize, size) / pageSize;
# if !defined(OF_HAVE_COMPILER_TLS) && defined(OF_HAVE_THREADS)
struct page **preallocatedPages = OFTLSKeyGet(preallocatedPagesKey);
size_t numPreallocatedPages;
# endif
size_t i;
if (preallocatedPages != NULL)
@throw [OFInvalidArgumentException exception];
preallocatedPages = of_alloc_zeroed(numPages, sizeof(struct page));
# if !defined(OF_HAVE_COMPILER_TLS) && defined(OF_HAVE_THREADS)
OF_ENSURE(OFTLSKeySet(preallocatedPagesKey, preallocatedPages) == 0);
# endif
@try {
for (i = 0; i < numPages; i++)
preallocatedPages[i] = addPage(false);
} @catch (id e) {
for (size_t j = 0; j < i; j++)
removePageIfEmpty(preallocatedPages[j]);
free(preallocatedPages);
preallocatedPages = NULL;
@throw e;
}
numPreallocatedPages = numPages;
# if !defined(OF_HAVE_COMPILER_TLS) && defined(OF_HAVE_THREADS)
OF_ENSURE(OFTLSKeySet(numPreallocatedPagesKey,
(void *)(uintptr_t)numPreallocatedPages) == 0);
# endif
#else
@throw [OFNotImplementedException exceptionWithSelector: _cmd
object: self];
#endif
}
|
︙ | | | ︙ | |
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
|
memset(_items, 0, count * itemSize);
#if defined(HAVE_MMAP) && defined(HAVE_MLOCK) && defined(MAP_ANON)
} else if (count * itemSize >= pageSize)
_items = mapPages(OF_ROUND_UP_POW2(pageSize,
count * itemSize) / pageSize);
else {
# if !defined(OF_HAVE_COMPILER_TLS) && defined(OF_HAVE_THREADS)
struct page *lastPage = of_tlskey_get(lastPageKey);
# endif
for (struct page *page = lastPage; page != NULL;
page = page->previous) {
_items = allocateMemory(page, count * itemSize);
if (_items != NULL) {
|
|
|
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
|
memset(_items, 0, count * itemSize);
#if defined(HAVE_MMAP) && defined(HAVE_MLOCK) && defined(MAP_ANON)
} else if (count * itemSize >= pageSize)
_items = mapPages(OF_ROUND_UP_POW2(pageSize,
count * itemSize) / pageSize);
else {
# if !defined(OF_HAVE_COMPILER_TLS) && defined(OF_HAVE_THREADS)
struct page *lastPage = OFTLSKeyGet(lastPageKey);
# endif
for (struct page *page = lastPage; page != NULL;
page = page->previous) {
_items = allocateMemory(page, count * itemSize);
if (_items != NULL) {
|
︙ | | | ︙ | |
︙ | | | ︙ | |
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
|
#if defined(OF_HAVE_THREADS)
# import "tlskey.h"
# if defined(OF_AMIGAOS) && defined(OF_HAVE_SOCKETS)
# import "socket.h"
# endif
static of_tlskey_t threadSelfKey;
static OFThread *mainThread;
#elif defined(OF_HAVE_SOCKETS)
static OFDNSResolver *DNSResolver;
#endif
@implementation OFThread
#ifdef OF_HAVE_THREADS
static void
callMain(id object)
{
OFThread *thread = (OFThread *)object;
OFString *name;
if (of_tlskey_set(threadSelfKey, thread) != 0)
@throw [OFInitializationFailedException
exceptionWithClass: thread.class];
#ifndef OF_OBJFW_RUNTIME
thread->_pool = objc_autoreleasePoolPush();
#endif
|
|
|
|
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
|
#if defined(OF_HAVE_THREADS)
# import "tlskey.h"
# if defined(OF_AMIGAOS) && defined(OF_HAVE_SOCKETS)
# import "socket.h"
# endif
static OFTLSKey threadSelfKey;
static OFThread *mainThread;
#elif defined(OF_HAVE_SOCKETS)
static OFDNSResolver *DNSResolver;
#endif
@implementation OFThread
#ifdef OF_HAVE_THREADS
static void
callMain(id object)
{
OFThread *thread = (OFThread *)object;
OFString *name;
if (OFTLSKeySet(threadSelfKey, thread) != 0)
@throw [OFInitializationFailedException
exceptionWithClass: thread.class];
#ifndef OF_OBJFW_RUNTIME
thread->_pool = objc_autoreleasePoolPush();
#endif
|
︙ | | | ︙ | |
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
|
# endif
+ (void)initialize
{
if (self != [OFThread class])
return;
if (of_tlskey_new(&threadSelfKey) != 0)
@throw [OFInitializationFailedException
exceptionWithClass: self];
}
+ (instancetype)thread
{
return [[[self alloc] init] autorelease];
}
# ifdef OF_HAVE_BLOCKS
+ (instancetype)threadWithThreadBlock: (OFThreadBlock)threadBlock
{
return [[[self alloc] initWithThreadBlock: threadBlock] autorelease];
}
# endif
+ (OFThread *)currentThread
{
return of_tlskey_get(threadSelfKey);
}
+ (OFThread *)mainThread
{
return mainThread;
}
+ (bool)isMainThread
{
if (mainThread == nil)
return false;
return (of_tlskey_get(threadSelfKey) == mainThread);
}
+ (OFMutableDictionary *)threadDictionary
{
OFThread *thread = of_tlskey_get(threadSelfKey);
if (thread == nil)
return nil;
if (thread->_threadDictionary == nil)
thread->_threadDictionary = [[OFMutableDictionary alloc] init];
return thread->_threadDictionary;
}
#endif
#ifdef OF_HAVE_SOCKETS
+ (OFDNSResolver *)DNSResolver
{
# ifdef OF_HAVE_THREADS
OFThread *thread = of_tlskey_get(threadSelfKey);
if (thread == nil)
return nil;
if (thread->_DNSResolver == nil)
thread->_DNSResolver = [[OFDNSResolver alloc] init];
|
|
|
|
|
|
|
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
|
# endif
+ (void)initialize
{
if (self != [OFThread class])
return;
if (OFTLSKeyNew(&threadSelfKey) != 0)
@throw [OFInitializationFailedException
exceptionWithClass: self];
}
+ (instancetype)thread
{
return [[[self alloc] init] autorelease];
}
# ifdef OF_HAVE_BLOCKS
+ (instancetype)threadWithThreadBlock: (OFThreadBlock)threadBlock
{
return [[[self alloc] initWithThreadBlock: threadBlock] autorelease];
}
# endif
+ (OFThread *)currentThread
{
return OFTLSKeyGet(threadSelfKey);
}
+ (OFThread *)mainThread
{
return mainThread;
}
+ (bool)isMainThread
{
if (mainThread == nil)
return false;
return (OFTLSKeyGet(threadSelfKey) == mainThread);
}
+ (OFMutableDictionary *)threadDictionary
{
OFThread *thread = OFTLSKeyGet(threadSelfKey);
if (thread == nil)
return nil;
if (thread->_threadDictionary == nil)
thread->_threadDictionary = [[OFMutableDictionary alloc] init];
return thread->_threadDictionary;
}
#endif
#ifdef OF_HAVE_SOCKETS
+ (OFDNSResolver *)DNSResolver
{
# ifdef OF_HAVE_THREADS
OFThread *thread = OFTLSKeyGet(threadSelfKey);
if (thread == nil)
return nil;
if (thread->_DNSResolver == nil)
thread->_DNSResolver = [[OFDNSResolver alloc] init];
|
︙ | | | ︙ | |
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
|
* returns while being declared OF_NO_RETURN.
*/
OF_UNREACHABLE
}
+ (void)terminateWithObject: (id)object
{
OFThread *thread = of_tlskey_get(threadSelfKey);
if (thread == mainThread)
@throw [OFInvalidArgumentException exception];
OF_ENSURE(thread != nil);
thread->_returnValue = [object retain];
|
|
|
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
|
* returns while being declared OF_NO_RETURN.
*/
OF_UNREACHABLE
}
+ (void)terminateWithObject: (id)object
{
OFThread *thread = OFTLSKeyGet(threadSelfKey);
if (thread == mainThread)
@throw [OFInvalidArgumentException exception];
OF_ENSURE(thread != nil);
thread->_returnValue = [object retain];
|
︙ | | | ︙ | |
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
|
+ (void)of_createMainThread
{
mainThread = [[OFThread alloc] init];
mainThread->_thread = of_thread_current();
mainThread->_running = OF_THREAD_RUNNING;
if (of_tlskey_set(threadSelfKey, mainThread) != 0)
@throw [OFInitializationFailedException
exceptionWithClass: self];
}
- (instancetype)init
{
self = [super init];
|
|
|
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
|
+ (void)of_createMainThread
{
mainThread = [[OFThread alloc] init];
mainThread->_thread = of_thread_current();
mainThread->_running = OF_THREAD_RUNNING;
if (OFTLSKeySet(threadSelfKey, mainThread) != 0)
@throw [OFInitializationFailedException
exceptionWithClass: self];
}
- (instancetype)init
{
self = [super init];
|
︙ | | | ︙ | |
︙ | | | ︙ | |
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
|
#import "tlskey.h"
#include <dos/dostags.h>
#include <proto/dos.h>
#include <proto/exec.h>
#ifndef OF_MORPHOS
extern void of_tlskey_thread_exited(void);
#endif
static of_tlskey_t threadKey;
OF_CONSTRUCTOR()
{
OF_ENSURE(of_tlskey_new(&threadKey) == 0);
}
static void
functionWrapper(void)
{
bool detached = false;
of_thread_t thread =
(of_thread_t)((struct Process *)FindTask(NULL))->pr_ExitData;
OF_ENSURE(of_tlskey_set(threadKey, thread) == 0);
thread->function(thread->object);
ObtainSemaphore(&thread->semaphore);
@try {
thread->done = true;
#ifndef OF_MORPHOS
of_tlskey_thread_exited();
#endif
if (thread->detached)
detached = true;
else if (thread->joinTask != NULL)
Signal(thread->joinTask, (1ul << thread->joinSigBit));
} @finally {
|
|
|
|
|
|
|
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
|
#import "tlskey.h"
#include <dos/dostags.h>
#include <proto/dos.h>
#include <proto/exec.h>
#ifndef OF_MORPHOS
extern void OFTLSKeyThreadExited(void);
#endif
static OFTLSKey threadKey;
OF_CONSTRUCTOR()
{
OF_ENSURE(OFTLSKeyNew(&threadKey) == 0);
}
static void
functionWrapper(void)
{
bool detached = false;
of_thread_t thread =
(of_thread_t)((struct Process *)FindTask(NULL))->pr_ExitData;
OF_ENSURE(OFTLSKeySet(threadKey, thread) == 0);
thread->function(thread->object);
ObtainSemaphore(&thread->semaphore);
@try {
thread->done = true;
#ifndef OF_MORPHOS
OFTLSKeyThreadExited();
#endif
if (thread->detached)
detached = true;
else if (thread->joinTask != NULL)
Signal(thread->joinTask, (1ul << thread->joinSigBit));
} @finally {
|
︙ | | | ︙ | |
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
|
return 0;
}
of_thread_t
of_thread_current(void)
{
return of_tlskey_get(threadKey);
}
int
of_thread_join(of_thread_t thread)
{
ObtainSemaphore(&thread->semaphore);
|
|
|
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
|
return 0;
}
of_thread_t
of_thread_current(void)
{
return OFTLSKeyGet(threadKey);
}
int
of_thread_join(of_thread_t thread)
{
ObtainSemaphore(&thread->semaphore);
|
︙ | | | ︙ | |
︙ | | | ︙ | |
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
|
/*
* As we use this file in both the runtime and ObjFW, and since AmigaOS always
* has the runtime, use the hashtable from the runtime.
*/
#import "runtime/private.h"
static of_tlskey_t firstKey = NULL, lastKey = NULL;
static struct SignalSemaphore semaphore;
static bool semaphoreInitialized = false;
static uint32_t
hashFunc(const void *ptr)
{
return (uint32_t)(uintptr_t)ptr;
|
|
|
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
|
/*
* As we use this file in both the runtime and ObjFW, and since AmigaOS always
* has the runtime, use the hashtable from the runtime.
*/
#import "runtime/private.h"
static OFTLSKey firstKey = NULL, lastKey = NULL;
static struct SignalSemaphore semaphore;
static bool semaphoreInitialized = false;
static uint32_t
hashFunc(const void *ptr)
{
return (uint32_t)(uintptr_t)ptr;
|
︙ | | | ︙ | |
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
|
if (!semaphoreInitialized) {
InitSemaphore(&semaphore);
semaphoreInitialized = true;
}
}
int
of_tlskey_new(of_tlskey_t *key)
{
if (!semaphoreInitialized) {
/*
* We might be called from another constructor, while ours has
* not run yet. This is safe, as the constructor is definitely
* run before a thread is spawned.
*/
|
|
|
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
|
if (!semaphoreInitialized) {
InitSemaphore(&semaphore);
semaphoreInitialized = true;
}
}
int
OFTLSKeyNew(OFTLSKey *key)
{
if (!semaphoreInitialized) {
/*
* We might be called from another constructor, while ours has
* not run yet. This is safe, as the constructor is definitely
* run before a thread is spawned.
*/
|
︙ | | | ︙ | |
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
|
}
/* We create the hash table lazily. */
return 0;
}
int
of_tlskey_free(of_tlskey_t key)
{
ObtainSemaphore(&semaphore);
@try {
if (key->previous != NULL)
key->previous->next = key->next;
if (key->next != NULL)
key->next->previous = key->previous;
|
|
|
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
|
}
/* We create the hash table lazily. */
return 0;
}
int
OFTLSKeyFree(OFTLSKey key)
{
ObtainSemaphore(&semaphore);
@try {
if (key->previous != NULL)
key->previous->next = key->next;
if (key->next != NULL)
key->next->previous = key->previous;
|
︙ | | | ︙ | |
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
|
ReleaseSemaphore(&semaphore);
}
return 0;
}
void *
of_tlskey_get(of_tlskey_t key)
{
void *ret;
ObtainSemaphore(&semaphore);
@try {
if (key->table == NULL)
return NULL;
ret = objc_hashtable_get(key->table, FindTask(NULL));
} @finally {
ReleaseSemaphore(&semaphore);
}
return ret;
}
int
of_tlskey_set(of_tlskey_t key, void *ptr)
{
ObtainSemaphore(&semaphore);
@try {
struct Task *task = FindTask(NULL);
if (key->table == NULL)
key->table = objc_hashtable_new(hashFunc, equalFunc, 2);
if (ptr == NULL)
objc_hashtable_delete(key->table, task);
else
objc_hashtable_set(key->table, task, ptr);
} @finally {
ReleaseSemaphore(&semaphore);
}
return 0;
}
void
of_tlskey_thread_exited(void)
{
ObtainSemaphore(&semaphore);
@try {
struct Task *task = FindTask(NULL);
for (of_tlskey_t iter = firstKey; iter != NULL;
iter = iter->next)
if (iter->table != NULL)
objc_hashtable_delete(iter->table, task);
} @finally {
ReleaseSemaphore(&semaphore);
}
}
|
|
|
|
|
<
|
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
|
ReleaseSemaphore(&semaphore);
}
return 0;
}
void *
OFTLSKeyGet(OFTLSKey key)
{
void *ret;
ObtainSemaphore(&semaphore);
@try {
if (key->table == NULL)
return NULL;
ret = objc_hashtable_get(key->table, FindTask(NULL));
} @finally {
ReleaseSemaphore(&semaphore);
}
return ret;
}
int
OFTLSKeySet(OFTLSKey key, void *ptr)
{
ObtainSemaphore(&semaphore);
@try {
struct Task *task = FindTask(NULL);
if (key->table == NULL)
key->table = objc_hashtable_new(hashFunc, equalFunc, 2);
if (ptr == NULL)
objc_hashtable_delete(key->table, task);
else
objc_hashtable_set(key->table, task, ptr);
} @finally {
ReleaseSemaphore(&semaphore);
}
return 0;
}
void
OFTLSKeyThreadExited(void)
{
ObtainSemaphore(&semaphore);
@try {
struct Task *task = FindTask(NULL);
for (OFTLSKey iter = firstKey; iter != NULL; iter = iter->next)
if (iter->table != NULL)
objc_hashtable_delete(iter->table, task);
} @finally {
ReleaseSemaphore(&semaphore);
}
}
|
︙ | | | ︙ | |
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
|
of_rmutex_new(of_rmutex_t *rmutex)
{
int error;
if ((error = of_mutex_new(&rmutex->mutex)) != 0)
return error;
if ((error = of_tlskey_new(&rmutex->count)) != 0)
return error;
return 0;
}
int
of_rmutex_lock(of_rmutex_t *rmutex)
{
uintptr_t count = (uintptr_t)of_tlskey_get(rmutex->count);
int error;
if (count > 0) {
if ((error = of_tlskey_set(rmutex->count,
(void *)(count + 1))) != 0)
return error;
return 0;
}
if ((error = of_mutex_lock(&rmutex->mutex)) != 0)
return error;
if ((error = of_tlskey_set(rmutex->count, (void *)1)) != 0) {
of_mutex_unlock(&rmutex->mutex);
return error;
}
return 0;
}
int
of_rmutex_trylock(of_rmutex_t *rmutex)
{
uintptr_t count = (uintptr_t)of_tlskey_get(rmutex->count);
int error;
if (count > 0) {
if ((error = of_tlskey_set(rmutex->count,
(void *)(count + 1))) != 0)
return error;
return 0;
}
if ((error = of_mutex_trylock(&rmutex->mutex)) != 0)
return error;
if ((error = of_tlskey_set(rmutex->count, (void *)1)) != 0) {
of_mutex_unlock(&rmutex->mutex);
return error;
}
return 0;
}
int
of_rmutex_unlock(of_rmutex_t *rmutex)
{
uintptr_t count = (uintptr_t)of_tlskey_get(rmutex->count);
int error;
if (count > 1) {
if ((error = of_tlskey_set(rmutex->count,
(void *)(count - 1))) != 0)
return error;
return 0;
}
if ((error = of_tlskey_set(rmutex->count, (void *)0)) != 0)
return error;
if ((error = of_mutex_unlock(&rmutex->mutex)) != 0)
return error;
return 0;
}
int
of_rmutex_free(of_rmutex_t *rmutex)
{
int error;
if ((error = of_mutex_free(&rmutex->mutex)) != 0)
return error;
if ((error = of_tlskey_free(rmutex->count)) != 0)
return error;
return 0;
}
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
|
of_rmutex_new(of_rmutex_t *rmutex)
{
int error;
if ((error = of_mutex_new(&rmutex->mutex)) != 0)
return error;
if ((error = OFTLSKeyNew(&rmutex->count)) != 0)
return error;
return 0;
}
int
of_rmutex_lock(of_rmutex_t *rmutex)
{
uintptr_t count = (uintptr_t)OFTLSKeyGet(rmutex->count);
int error;
if (count > 0) {
if ((error = OFTLSKeySet(rmutex->count,
(void *)(count + 1))) != 0)
return error;
return 0;
}
if ((error = of_mutex_lock(&rmutex->mutex)) != 0)
return error;
if ((error = OFTLSKeySet(rmutex->count, (void *)1)) != 0) {
of_mutex_unlock(&rmutex->mutex);
return error;
}
return 0;
}
int
of_rmutex_trylock(of_rmutex_t *rmutex)
{
uintptr_t count = (uintptr_t)OFTLSKeyGet(rmutex->count);
int error;
if (count > 0) {
if ((error = OFTLSKeySet(rmutex->count,
(void *)(count + 1))) != 0)
return error;
return 0;
}
if ((error = of_mutex_trylock(&rmutex->mutex)) != 0)
return error;
if ((error = OFTLSKeySet(rmutex->count, (void *)1)) != 0) {
of_mutex_unlock(&rmutex->mutex);
return error;
}
return 0;
}
int
of_rmutex_unlock(of_rmutex_t *rmutex)
{
uintptr_t count = (uintptr_t)OFTLSKeyGet(rmutex->count);
int error;
if (count > 1) {
if ((error = OFTLSKeySet(rmutex->count,
(void *)(count - 1))) != 0)
return error;
return 0;
}
if ((error = OFTLSKeySet(rmutex->count, (void *)0)) != 0)
return error;
if ((error = of_mutex_unlock(&rmutex->mutex)) != 0)
return error;
return 0;
}
int
of_rmutex_free(of_rmutex_t *rmutex)
{
int error;
if ((error = of_mutex_free(&rmutex->mutex)) != 0)
return error;
if ((error = OFTLSKeyFree(rmutex->count)) != 0)
return error;
return 0;
}
#endif
|
︙ | | | ︙ | |
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
|
#endif
#if defined(OF_HAVE_COMPILER_TLS)
static thread_local id *objects = NULL;
static thread_local uintptr_t count = 0;
static thread_local uintptr_t size = 0;
#elif defined(OF_HAVE_THREADS)
static of_tlskey_t objectsKey, countKey, sizeKey;
#else
static id *objects = NULL;
static uintptr_t count = 0;
static uintptr_t size = 0;
#endif
#if !defined(OF_HAVE_COMPILER_TLS) && defined(OF_HAVE_THREADS)
OF_CONSTRUCTOR()
{
OF_ENSURE(of_tlskey_new(&objectsKey) == 0);
OF_ENSURE(of_tlskey_new(&countKey) == 0);
OF_ENSURE(of_tlskey_new(&sizeKey) == 0);
}
#endif
void *
objc_autoreleasePoolPush()
{
#if !defined(OF_HAVE_COMPILER_TLS) && defined(OF_HAVE_THREADS)
uintptr_t count = (uintptr_t)of_tlskey_get(countKey);
#endif
return (void *)count;
}
void
objc_autoreleasePoolPop(void *pool)
{
#if !defined(OF_HAVE_COMPILER_TLS) && defined(OF_HAVE_THREADS)
id *objects = of_tlskey_get(objectsKey);
uintptr_t count = (uintptr_t)of_tlskey_get(countKey);
#endif
uintptr_t idx = (uintptr_t)pool;
bool freeMem = false;
if (idx == (uintptr_t)-1) {
idx++;
freeMem = true;
}
for (uintptr_t i = idx; i < count; i++) {
[objects[i] release];
#if !defined(OF_HAVE_COMPILER_TLS) && defined(OF_HAVE_THREADS)
objects = of_tlskey_get(objectsKey);
count = (uintptr_t)of_tlskey_get(countKey);
#endif
}
count = idx;
if (freeMem) {
free(objects);
objects = NULL;
#if defined(OF_HAVE_COMPILER_TLS) || !defined(OF_HAVE_THREADS)
size = 0;
#else
OF_ENSURE(of_tlskey_set(objectsKey, objects) == 0);
OF_ENSURE(of_tlskey_set(sizeKey, (void *)0) == 0);
#endif
}
#if !defined(OF_HAVE_COMPILER_TLS) && defined(OF_HAVE_THREADS)
OF_ENSURE(of_tlskey_set(countKey, (void *)count) == 0);
#endif
}
id
_objc_rootAutorelease(id object)
{
#if !defined(OF_HAVE_COMPILER_TLS) && defined(OF_HAVE_THREADS)
id *objects = of_tlskey_get(objectsKey);
uintptr_t count = (uintptr_t)of_tlskey_get(countKey);
uintptr_t size = (uintptr_t)of_tlskey_get(sizeKey);
#endif
if (count >= size) {
if (size == 0)
size = 16;
else
size *= 2;
OF_ENSURE((objects =
realloc(objects, size * sizeof(id))) != NULL);
#if !defined(OF_HAVE_COMPILER_TLS) && defined(OF_HAVE_THREADS)
OF_ENSURE(of_tlskey_set(objectsKey, objects) == 0);
OF_ENSURE(of_tlskey_set(sizeKey, (void *)size) == 0);
#endif
}
objects[count++] = object;
#if !defined(OF_HAVE_COMPILER_TLS) && defined(OF_HAVE_THREADS)
OF_ENSURE(of_tlskey_set(countKey, (void *)count) == 0);
#endif
return object;
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
|
#endif
#if defined(OF_HAVE_COMPILER_TLS)
static thread_local id *objects = NULL;
static thread_local uintptr_t count = 0;
static thread_local uintptr_t size = 0;
#elif defined(OF_HAVE_THREADS)
static OFTLSKey objectsKey, countKey, sizeKey;
#else
static id *objects = NULL;
static uintptr_t count = 0;
static uintptr_t size = 0;
#endif
#if !defined(OF_HAVE_COMPILER_TLS) && defined(OF_HAVE_THREADS)
OF_CONSTRUCTOR()
{
OF_ENSURE(OFTLSKeyNew(&objectsKey) == 0);
OF_ENSURE(OFTLSKeyNew(&countKey) == 0);
OF_ENSURE(OFTLSKeyNew(&sizeKey) == 0);
}
#endif
void *
objc_autoreleasePoolPush()
{
#if !defined(OF_HAVE_COMPILER_TLS) && defined(OF_HAVE_THREADS)
uintptr_t count = (uintptr_t)OFTLSKeyGet(countKey);
#endif
return (void *)count;
}
void
objc_autoreleasePoolPop(void *pool)
{
#if !defined(OF_HAVE_COMPILER_TLS) && defined(OF_HAVE_THREADS)
id *objects = OFTLSKeyGet(objectsKey);
uintptr_t count = (uintptr_t)OFTLSKeyGet(countKey);
#endif
uintptr_t idx = (uintptr_t)pool;
bool freeMem = false;
if (idx == (uintptr_t)-1) {
idx++;
freeMem = true;
}
for (uintptr_t i = idx; i < count; i++) {
[objects[i] release];
#if !defined(OF_HAVE_COMPILER_TLS) && defined(OF_HAVE_THREADS)
objects = OFTLSKeyGet(objectsKey);
count = (uintptr_t)OFTLSKeyGet(countKey);
#endif
}
count = idx;
if (freeMem) {
free(objects);
objects = NULL;
#if defined(OF_HAVE_COMPILER_TLS) || !defined(OF_HAVE_THREADS)
size = 0;
#else
OF_ENSURE(OFTLSKeySet(objectsKey, objects) == 0);
OF_ENSURE(OFTLSKeySet(sizeKey, (void *)0) == 0);
#endif
}
#if !defined(OF_HAVE_COMPILER_TLS) && defined(OF_HAVE_THREADS)
OF_ENSURE(OFTLSKeySet(countKey, (void *)count) == 0);
#endif
}
id
_objc_rootAutorelease(id object)
{
#if !defined(OF_HAVE_COMPILER_TLS) && defined(OF_HAVE_THREADS)
id *objects = OFTLSKeyGet(objectsKey);
uintptr_t count = (uintptr_t)OFTLSKeyGet(countKey);
uintptr_t size = (uintptr_t)OFTLSKeyGet(sizeKey);
#endif
if (count >= size) {
if (size == 0)
size = 16;
else
size *= 2;
OF_ENSURE((objects =
realloc(objects, size * sizeof(id))) != NULL);
#if !defined(OF_HAVE_COMPILER_TLS) && defined(OF_HAVE_THREADS)
OF_ENSURE(OFTLSKeySet(objectsKey, objects) == 0);
OF_ENSURE(OFTLSKeySet(sizeKey, (void *)size) == 0);
#endif
}
objects[count++] = object;
#if !defined(OF_HAVE_COMPILER_TLS) && defined(OF_HAVE_THREADS)
OF_ENSURE(OFTLSKeySet(countKey, (void *)count) == 0);
#endif
return object;
}
|
︙ | | | ︙ | |
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
|
#endif
#if !defined(OF_AMIGAOS) || defined(OF_MORPHOS) || !defined(OF_HAVE_THREADS)
static bool initSuccessful = false;
#endif
#ifdef OF_AMIGAOS
# if defined(OF_HAVE_THREADS) && !defined(OF_MORPHOS)
of_tlskey_t of_socket_base_key;
# ifdef OF_AMIGAOS4
of_tlskey_t of_socket_interface_key;
# endif
# else
struct Library *SocketBase;
# ifdef OF_AMIGAOS4
struct SocketIFace *ISocket = NULL;
# endif
# endif
#endif
#if defined(OF_HAVE_THREADS) && defined(OF_AMIGAOS) && !defined(OF_MORPHOS)
OF_CONSTRUCTOR()
{
if (of_tlskey_new(&of_socket_base_key) != 0)
@throw [OFInitializationFailedException exception];
# ifdef OF_AMIGAOS4
if (of_tlskey_new(&of_socket_interface_key) != 0)
@throw [OFInitializationFailedException exception];
# endif
}
#endif
#if !defined(OF_AMIGAOS) || defined(OF_MORPHOS) || !defined(OF_HAVE_THREADS)
static void
|
|
|
|
|
|
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
|
#endif
#if !defined(OF_AMIGAOS) || defined(OF_MORPHOS) || !defined(OF_HAVE_THREADS)
static bool initSuccessful = false;
#endif
#ifdef OF_AMIGAOS
# if defined(OF_HAVE_THREADS) && !defined(OF_MORPHOS)
OFTLSKey of_socket_base_key;
# ifdef OF_AMIGAOS4
OFTLSKey of_socket_interface_key;
# endif
# else
struct Library *SocketBase;
# ifdef OF_AMIGAOS4
struct SocketIFace *ISocket = NULL;
# endif
# endif
#endif
#if defined(OF_HAVE_THREADS) && defined(OF_AMIGAOS) && !defined(OF_MORPHOS)
OF_CONSTRUCTOR()
{
if (OFTLSKeyNew(&of_socket_base_key) != 0)
@throw [OFInitializationFailedException exception];
# ifdef OF_AMIGAOS4
if (OFTLSKeyNew(&of_socket_interface_key) != 0)
@throw [OFInitializationFailedException exception];
# endif
}
#endif
#if !defined(OF_AMIGAOS) || defined(OF_MORPHOS) || !defined(OF_HAVE_THREADS)
static void
|
︙ | | | ︙ | |
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
|
#else
struct Library *socketBase;
# ifdef OF_AMIGAOS4
struct SocketIFace *socketInterface;
# endif
# ifdef OF_AMIGAOS4
if ((socketInterface = of_tlskey_get(of_socket_interface_key)) != NULL)
# else
if ((socketBase = of_tlskey_get(of_socket_base_key)) != NULL)
# endif
return true;
if ((socketBase = OpenLibrary("bsdsocket.library", 4)) == NULL)
return false;
# ifdef OF_AMIGAOS4
if ((socketInterface = (struct SocketIFace *)
GetInterface(socketBase, "main", 1, NULL)) == NULL) {
CloseLibrary(socketBase);
return false;
}
# endif
if (of_tlskey_set(of_socket_base_key, socketBase) != 0) {
CloseLibrary(socketBase);
# ifdef OF_AMIGAOS4
DropInterface((struct Interface *)socketInterface);
# endif
return false;
}
# ifdef OF_AMIGAOS4
if (of_tlskey_set(of_socket_interface_key, socketInterface) != 0) {
CloseLibrary(socketBase);
DropInterface((struct Interface *)socketInterface);
return false;
}
# endif
return true;
#endif
}
#if defined(OF_HAVE_THREADS) && defined(OF_AMIGAOS) && !defined(OF_MORPHOS)
void
of_socket_deinit(void)
{
struct Library *socketBase = of_tlskey_get(of_socket_base_key);
# ifdef OF_AMIGAOS4
struct SocketIFace *socketInterface =
of_tlskey_get(of_socket_interface_key);
if (socketInterface != NULL)
DropInterface((struct Interface *)socketInterface);
# endif
if (socketBase != NULL)
CloseLibrary(socketBase);
}
|
|
|
|
|
|
|
|
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
|
#else
struct Library *socketBase;
# ifdef OF_AMIGAOS4
struct SocketIFace *socketInterface;
# endif
# ifdef OF_AMIGAOS4
if ((socketInterface = OFTLSKeyGet(of_socket_interface_key)) != NULL)
# else
if ((socketBase = OFTLSKeyGet(of_socket_base_key)) != NULL)
# endif
return true;
if ((socketBase = OpenLibrary("bsdsocket.library", 4)) == NULL)
return false;
# ifdef OF_AMIGAOS4
if ((socketInterface = (struct SocketIFace *)
GetInterface(socketBase, "main", 1, NULL)) == NULL) {
CloseLibrary(socketBase);
return false;
}
# endif
if (OFTLSKeySet(of_socket_base_key, socketBase) != 0) {
CloseLibrary(socketBase);
# ifdef OF_AMIGAOS4
DropInterface((struct Interface *)socketInterface);
# endif
return false;
}
# ifdef OF_AMIGAOS4
if (OFTLSKeySet(of_socket_interface_key, socketInterface) != 0) {
CloseLibrary(socketBase);
DropInterface((struct Interface *)socketInterface);
return false;
}
# endif
return true;
#endif
}
#if defined(OF_HAVE_THREADS) && defined(OF_AMIGAOS) && !defined(OF_MORPHOS)
void
of_socket_deinit(void)
{
struct Library *socketBase = OFTLSKeyGet(of_socket_base_key);
# ifdef OF_AMIGAOS4
struct SocketIFace *socketInterface =
OFTLSKeyGet(of_socket_interface_key);
if (socketInterface != NULL)
DropInterface((struct Interface *)socketInterface);
# endif
if (socketBase != NULL)
CloseLibrary(socketBase);
}
|
︙ | | | ︙ | |
︙ | | | ︙ | |
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
|
# error No thread-local storage available!
#endif
#import "macros.h"
#if defined(OF_HAVE_PTHREADS)
# include <pthread.h>
typedef pthread_key_t of_tlskey_t;
#elif defined(OF_WINDOWS)
# include <windows.h>
typedef DWORD of_tlskey_t;
#elif defined(OF_MORPHOS)
# include <proto/exec.h>
typedef ULONG of_tlskey_t;
#elif defined(OF_AMIGAOS)
typedef struct of_tlskey {
struct objc_hashtable *table;
struct of_tlskey *next, *previous;
} *of_tlskey_t;
#endif
#ifdef __cplusplus
extern "C" {
#endif
extern int of_tlskey_new(of_tlskey_t *key);
extern int of_tlskey_free(of_tlskey_t key);
#ifdef __cplusplus
}
#endif
/* TLS keys are inlined for performance. */
#if defined(OF_HAVE_PTHREADS)
static OF_INLINE void *
of_tlskey_get(of_tlskey_t key)
{
return pthread_getspecific(key);
}
static OF_INLINE int
of_tlskey_set(of_tlskey_t key, void *ptr)
{
return pthread_setspecific(key, ptr);
}
#elif defined(OF_WINDOWS)
static OF_INLINE void *
of_tlskey_get(of_tlskey_t key)
{
return TlsGetValue(key);
}
static OF_INLINE int
of_tlskey_set(of_tlskey_t key, void *ptr)
{
return (TlsSetValue(key, ptr) ? 0 : EINVAL);
}
#elif defined(OF_MORPHOS)
static OF_INLINE void *
of_tlskey_get(of_tlskey_t key)
{
return (void *)TLSGetValue(key);
}
static OF_INLINE int
of_tlskey_set(of_tlskey_t key, void *ptr)
{
return (TLSSetValue(key, (APTR)ptr) ? 0 : EINVAL);
}
#elif defined(OF_AMIGAOS)
/* Those are too big too inline. */
# ifdef __cplusplus
extern "C" {
# endif
extern void *of_tlskey_get(of_tlskey_t key);
extern int of_tlskey_set(of_tlskey_t key, void *ptr);
# ifdef __cplusplus
}
# endif
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
|
# error No thread-local storage available!
#endif
#import "macros.h"
#if defined(OF_HAVE_PTHREADS)
# include <pthread.h>
typedef pthread_key_t OFTLSKey;
#elif defined(OF_WINDOWS)
# include <windows.h>
typedef DWORD OFTLSKey;
#elif defined(OF_MORPHOS)
# include <proto/exec.h>
typedef ULONG OFTLSKey;
#elif defined(OF_AMIGAOS)
typedef struct OFTLSKey {
struct objc_hashtable *table;
struct OFTLSKey *next, *previous;
} *OFTLSKey;
#endif
#ifdef __cplusplus
extern "C" {
#endif
extern int OFTLSKeyNew(OFTLSKey *key);
extern int OFTLSKeyFree(OFTLSKey key);
#ifdef __cplusplus
}
#endif
/* TLS keys are inlined for performance. */
#if defined(OF_HAVE_PTHREADS)
static OF_INLINE void *
OFTLSKeyGet(OFTLSKey key)
{
return pthread_getspecific(key);
}
static OF_INLINE int
OFTLSKeySet(OFTLSKey key, void *ptr)
{
return pthread_setspecific(key, ptr);
}
#elif defined(OF_WINDOWS)
static OF_INLINE void *
OFTLSKeyGet(OFTLSKey key)
{
return TlsGetValue(key);
}
static OF_INLINE int
OFTLSKeySet(OFTLSKey key, void *ptr)
{
return (TlsSetValue(key, ptr) ? 0 : EINVAL);
}
#elif defined(OF_MORPHOS)
static OF_INLINE void *
OFTLSKeyGet(OFTLSKey key)
{
return (void *)TLSGetValue(key);
}
static OF_INLINE int
OFTLSKeySet(OFTLSKey key, void *ptr)
{
return (TLSSetValue(key, (APTR)ptr) ? 0 : EINVAL);
}
#elif defined(OF_AMIGAOS)
/* Those are too big too inline. */
# ifdef __cplusplus
extern "C" {
# endif
extern void *OFTLSKeyGet(OFTLSKey key);
extern int OFTLSKeySet(OFTLSKey key, void *ptr);
# ifdef __cplusplus
}
# endif
#endif
|