Modified src/OFBlock.m
from [d3c798f275]
to [ada45ac629].
︙ | | |
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
|
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
|
-
+
-
+
|
if ([(id)block isMemberOfClass: (Class)&_NSConcreteMallocBlock]) {
#ifdef OF_HAVE_ATOMIC_OPS
of_atomic_int_inc(&block->flags);
#else
unsigned hash = SPINLOCK_HASH(block);
OF_ENSURE(of_spinlock_lock(&blockSpinlocks[hash]));
OF_ENSURE(of_spinlock_lock(&blockSpinlocks[hash]) == 0);
block->flags++;
OF_ENSURE(of_spinlock_unlock(&blockSpinlocks[hash]));
OF_ENSURE(of_spinlock_unlock(&blockSpinlocks[hash]) == 0);
#endif
}
return block;
}
void
|
︙ | | |
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
|
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
|
-
+
-
+
-
+
|
block->descriptor->dispose_helper(block);
free(block);
}
#else
unsigned hash = SPINLOCK_HASH(block);
OF_ENSURE(of_spinlock_lock(&blockSpinlocks[hash]));
OF_ENSURE(of_spinlock_lock(&blockSpinlocks[hash]) == 0);
if ((--block->flags & OF_BLOCK_REFCOUNT_MASK) == 0) {
OF_ENSURE(of_spinlock_unlock(&blockSpinlocks[hash]));
OF_ENSURE(of_spinlock_unlock(&blockSpinlocks[hash]) == 0);
if (block->flags & OF_BLOCK_HAS_COPY_DISPOSE)
block->descriptor->dispose_helper(block);
free(block);
return;
}
OF_ENSURE(of_spinlock_unlock(&blockSpinlocks[hash]));
OF_ENSURE(of_spinlock_unlock(&blockSpinlocks[hash]) == 0);
#endif
}
void
_Block_object_assign(void *dst_, const void *src_, const int flags_)
{
int flags = flags_ & (OF_BLOCK_FIELD_IS_BLOCK |
|
︙ | | |
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
|
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
|
-
+
+
-
+
-
+
-
+
|
free(*dst);
*dst = src->forwarding;
}
#else
unsigned hash = SPINLOCK_HASH(src);
OF_ENSURE(of_spinlock_lock(&byrefSpinlocks[hash]));
OF_ENSURE(of_spinlock_lock(&byrefSpinlocks[hash]) == 0);
if (src->forwarding == src)
src->forwarding = *dst;
else {
src->byref_dispose(*dst);
free(*dst);
*dst = src->forwarding;
}
OF_ENSURE(
OF_ENSURE(of_spinlock_unlock(&byrefSpinlocks[hash]));
of_spinlock_unlock(&byrefSpinlocks[hash]) == 0);
#endif
} else
*dst = src;
#ifdef OF_HAVE_ATOMIC_OPS
of_atomic_int_inc(&(*dst)->flags);
#else
unsigned hash = SPINLOCK_HASH(*dst);
OF_ENSURE(of_spinlock_lock(&byrefSpinlocks[hash]));
OF_ENSURE(of_spinlock_lock(&byrefSpinlocks[hash]) == 0);
(*dst)->flags++;
OF_ENSURE(of_spinlock_unlock(&byrefSpinlocks[hash]));
OF_ENSURE(of_spinlock_unlock(&byrefSpinlocks[hash]) == 0);
#endif
break;
}
}
void
_Block_object_dispose(const void *object_, const int flags_)
|
︙ | | |
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
|
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
|
-
+
+
-
+
-
+
-
-
+
+
|
object->byref_dispose(object);
free(object);
}
#else
unsigned hash = SPINLOCK_HASH(object);
OF_ENSURE(of_spinlock_lock(&byrefSpinlocks[hash]));
OF_ENSURE(of_spinlock_lock(&byrefSpinlocks[hash]) == 0);
if ((--object->flags & OF_BLOCK_REFCOUNT_MASK) == 0) {
OF_ENSURE(
OF_ENSURE(of_spinlock_unlock(&byrefSpinlocks[hash]));
of_spinlock_unlock(&byrefSpinlocks[hash]) == 0);
if (object->flags & OF_BLOCK_HAS_COPY_DISPOSE)
object->byref_dispose(object);
free(object);
}
OF_ENSURE(of_spinlock_unlock(&byrefSpinlocks[hash]));
OF_ENSURE(of_spinlock_unlock(&byrefSpinlocks[hash]) == 0);
#endif
break;
}
}
@implementation OFBlock
+ (void)load
{
#ifndef OF_HAVE_ATOMIC_OPS
for (size_t i = 0; i < NUM_SPINLOCKS; i++)
if (!of_spinlock_new(&blockSpinlocks[i]) ||
!of_spinlock_new(&byrefSpinlocks[i]))
if (of_spinlock_new(&blockSpinlocks[i]) != 0 ||
of_spinlock_new(&byrefSpinlocks[i]) != 0)
@throw [OFInitializationFailedException
exceptionWithClass: self];
#endif
#ifdef OF_APPLE_RUNTIME
Class tmp;
|
︙ | | |
Modified src/OFCondition.m
from [24791db544]
to [53f832df7b].
︙ | | |
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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
|
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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
|
-
+
-
-
+
+
+
+
-
+
+
+
-
+
-
+
+
+
+
-
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
|
return [[[self alloc] init] autorelease];
}
- (instancetype)init
{
self = [super init];
if (!of_condition_new(&_condition)) {
if (of_condition_new(&_condition) != 0) {
Class c = self.class;
[self release];
@throw [OFInitializationFailedException exceptionWithClass: c];
}
_conditionInitialized = true;
return self;
}
- (void)dealloc
{
if (_conditionInitialized) {
if (!of_condition_free(&_condition)) {
OF_ENSURE(errno == EBUSY);
int error = of_condition_free(&_condition);
if (error != 0) {
OF_ENSURE(error == EBUSY);
@throw [OFConditionStillWaitingException
exceptionWithCondition: self];
}
}
[super dealloc];
}
- (void)wait
{
if (!of_condition_wait(&_condition, &_mutex))
int error = of_condition_wait(&_condition, &_mutex);
if (error != 0)
@throw [OFConditionWaitFailedException
exceptionWithCondition: self
errNo: errno];
errNo: error];
}
#ifdef OF_AMIGAOS
- (void)waitForConditionOrExecSignal: (ULONG *)signalMask
{
if (!of_condition_wait_or_signal(&_condition, &_mutex, signalMask))
int error = of_condition_wait_or_signal(&_condition, &_mutex,
signalMask);
if (error != 0)
@throw [OFConditionWaitFailedException
exceptionWithCondition: self
errNo: errno];
errNo: error];
}
#endif
- (bool)waitForTimeInterval: (of_time_interval_t)timeInterval
{
if (!of_condition_timed_wait(&_condition, &_mutex, timeInterval)) {
if (errno == ETIMEDOUT)
return false;
else
@throw [OFConditionWaitFailedException
exceptionWithCondition: self
errNo: errno];
int error = of_condition_timed_wait(&_condition, &_mutex, timeInterval);
if (error == ETIMEDOUT)
return false;
if (error != 0)
@throw [OFConditionWaitFailedException
exceptionWithCondition: self
errNo: error];
}
return true;
}
#ifdef OF_AMIGAOS
- (bool)waitForTimeInterval: (of_time_interval_t)timeInterval
orExecSignal: (ULONG *)signalMask
{
if (!of_condition_timed_wait_or_signal(&_condition, &_mutex,
timeInterval, signalMask)) {
if (errno == ETIMEDOUT)
return false;
else
@throw [OFConditionWaitFailedException
exceptionWithCondition: self
errNo: errno];
int error = of_condition_timed_wait_or_signal(&_condition, &_mutex,
timeInterval, signalMask);
if (error == ETIMEDOUT)
return false;
if (error != 0)
@throw [OFConditionWaitFailedException
exceptionWithCondition: self
errNo: error];
}
return true;
}
#endif
- (bool)waitUntilDate: (OFDate *)date
{
|
︙ | | |
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
|
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
|
-
+
+
+
-
+
-
+
+
+
-
+
|
return [self waitForTimeInterval: date.timeIntervalSinceNow
orExecSignal: signalMask];
}
#endif
- (void)signal
{
if (!of_condition_signal(&_condition))
int error = of_condition_signal(&_condition);
if (error != 0)
@throw [OFConditionSignalFailedException
exceptionWithCondition: self
errNo: errno];
errNo: error];
}
- (void)broadcast
{
if (!of_condition_broadcast(&_condition))
int error = of_condition_broadcast(&_condition);
if (error != 0)
@throw [OFConditionBroadcastFailedException
exceptionWithCondition: self
errNo: errno];
errNo: error];
}
@end
|
Modified src/OFMutex.m
from [2c5bdb0793]
to [4c3fd1c33e].
︙ | | |
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
|
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
103
104
105
106
107
108
109
110
|
-
+
-
-
+
+
+
+
-
+
+
+
-
+
-
-
+
+
+
+
-
+
-
+
+
+
-
+
|
return [[[self alloc] init] autorelease];
}
- (instancetype)init
{
self = [super init];
if (!of_mutex_new(&_mutex)) {
if (of_mutex_new(&_mutex) != 0) {
Class c = self.class;
[self release];
@throw [OFInitializationFailedException exceptionWithClass: c];
}
_initialized = true;
return self;
}
- (void)dealloc
{
if (_initialized) {
if (!of_mutex_free(&_mutex)) {
OF_ENSURE(errno == EBUSY);
int error = of_mutex_free(&_mutex);
if (error != 0) {
OF_ENSURE(error == EBUSY);
@throw [OFStillLockedException exceptionWithLock: self];
}
}
[_name release];
[super dealloc];
}
- (void)lock
{
if (!of_mutex_lock(&_mutex))
int error = of_mutex_lock(&_mutex);
if (error != 0)
@throw [OFLockFailedException exceptionWithLock: self
errNo: errno];
errNo: error];
}
- (bool)tryLock
{
if (!of_mutex_trylock(&_mutex)) {
if (errno == EBUSY)
int error = of_mutex_trylock(&_mutex);
if (error != 0) {
if (error == EBUSY)
return false;
else
@throw [OFLockFailedException exceptionWithLock: self
errNo: errno];
errNo: error];
}
return true;
}
- (void)unlock
{
if (!of_mutex_unlock(&_mutex))
int error = of_mutex_unlock(&_mutex);
if (error != 0)
@throw [OFUnlockFailedException exceptionWithLock: self
errNo: errno];
errNo: error];
}
- (OFString *)description
{
if (_name == nil)
return super.description;
return [OFString stringWithFormat: @"<%@: %@>", self.className, _name];
}
@end
|
Modified src/OFObject.m
from [dfafb38c1f]
to [d5d0a02ee8].
︙ | | |
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
|
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
|
-
-
+
+
|
allocFailedException.isa = [OFAllocFailedException class];
@throw (id)&allocFailedException;
}
((struct pre_ivar *)instance)->retainCount = 1;
#if !defined(OF_HAVE_ATOMIC_OPS) && !defined(OF_AMIGAOS)
if OF_UNLIKELY (!of_spinlock_new(
&((struct pre_ivar *)instance)->retainCountSpinlock)) {
if OF_UNLIKELY (of_spinlock_new(
&((struct pre_ivar *)instance)->retainCountSpinlock) != 0) {
free(instance);
@throw [OFInitializationFailedException
exceptionWithClass: class];
}
#endif
instance = (OFObject *)(void *)((char *)instance + PRE_IVARS_ALIGN);
|
︙ | | |
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
|
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
|
-
+
-
+
|
Forbid();
# endif
PRE_IVARS->retainCount++;
# ifndef OF_AMIGAOS_M68K
Permit();
# endif
#else
OF_ENSURE(of_spinlock_lock(&PRE_IVARS->retainCountSpinlock));
OF_ENSURE(of_spinlock_lock(&PRE_IVARS->retainCountSpinlock) == 0);
PRE_IVARS->retainCount++;
OF_ENSURE(of_spinlock_unlock(&PRE_IVARS->retainCountSpinlock));
OF_ENSURE(of_spinlock_unlock(&PRE_IVARS->retainCountSpinlock) == 0);
#endif
return self;
}
- (unsigned int)retainCount
{
|
︙ | | |
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
|
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
|
-
+
-
+
|
Permit();
if (retainCount == 0)
[self dealloc];
#else
int retainCount;
OF_ENSURE(of_spinlock_lock(&PRE_IVARS->retainCountSpinlock));
OF_ENSURE(of_spinlock_lock(&PRE_IVARS->retainCountSpinlock) == 0);
retainCount = --PRE_IVARS->retainCount;
OF_ENSURE(of_spinlock_unlock(&PRE_IVARS->retainCountSpinlock));
OF_ENSURE(of_spinlock_unlock(&PRE_IVARS->retainCountSpinlock) == 0);
if (retainCount == 0)
[self dealloc];
#endif
}
- (instancetype)autorelease
|
︙ | | |
Modified src/OFRecursiveMutex.m
from [3739c89b37]
to [e5da5416e7].
︙ | | |
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
|
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
103
104
105
106
107
108
109
110
|
-
+
-
-
+
+
+
+
-
+
+
+
-
+
-
-
+
+
+
+
-
+
-
+
+
+
-
+
|
return [[[self alloc] init] autorelease];
}
- (instancetype)init
{
self = [super init];
if (!of_rmutex_new(&_rmutex)) {
if (of_rmutex_new(&_rmutex) != 0) {
Class c = self.class;
[self release];
@throw [OFInitializationFailedException exceptionWithClass: c];
}
_initialized = true;
return self;
}
- (void)dealloc
{
if (_initialized) {
if (!of_rmutex_free(&_rmutex)) {
OF_ENSURE(errno == EBUSY);
int error = of_rmutex_free(&_rmutex);
if (error != 0) {
OF_ENSURE(error == EBUSY);
@throw [OFStillLockedException exceptionWithLock: self];
}
}
[_name release];
[super dealloc];
}
- (void)lock
{
if (!of_rmutex_lock(&_rmutex))
int error = of_rmutex_lock(&_rmutex);
if (error != 0)
@throw [OFLockFailedException exceptionWithLock: self
errNo: errno];
errNo: error];
}
- (bool)tryLock
{
if (!of_rmutex_trylock(&_rmutex)) {
if (errno == EBUSY)
int error = of_rmutex_trylock(&_rmutex);
if (error != 0) {
if (error == EBUSY)
return false;
else
@throw [OFLockFailedException exceptionWithLock: self
errNo: errno];
errNo: error];
}
return true;
}
- (void)unlock
{
if (!of_rmutex_unlock(&_rmutex))
int error = of_rmutex_unlock(&_rmutex);
if (error != 0)
@throw [OFUnlockFailedException exceptionWithLock: self
errNo: errno];
errNo: error];
}
- (OFString *)description
{
if (_name == nil)
return super.description;
return [OFString stringWithFormat: @"<%@: %@>", self.className, _name];
}
@end
|
Modified src/OFSecureData.m
from [7de8ab3a25]
to [a977d1a98b].
︙ | | |
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
|
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
|
-
+
-
+
|
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));
(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));
preallocatedPages) == 0);
# endif
}
return page;
}
}
|
︙ | | |
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
|
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
|
-
+
-
+
|
# 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));
OF_ENSURE(of_tlskey_set(lastPageKey, page) == 0);
if (of_tlskey_get(firstPageKey) == NULL)
OF_ENSURE(of_tlskey_set(firstPageKey, page));
OF_ENSURE(of_tlskey_set(firstPageKey, page) == 0);
# endif
return page;
}
static void
removePageIfEmpty(struct page *page)
|
︙ | | |
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
|
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
|
-
+
-
+
|
# 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));
OF_ENSURE(of_tlskey_set(firstPageKey, page->next) == 0);
if (of_tlskey_get(lastPageKey) == page)
OF_ENSURE(of_tlskey_set(lastPageKey, page->previous));
OF_ENSURE(of_tlskey_set(lastPageKey, page->previous) == 0);
# endif
free(page);
}
static void *
allocateMemory(struct page *page, size_t bytes)
|
︙ | | |
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
|
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
|
+
-
-
-
+
+
+
|
#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 ||
if (!of_tlskey_new(&firstPageKey) || !of_tlskey_new(&lastPageKey) ||
!of_tlskey_new(&preallocatedPagesKey) ||
!of_tlskey_new(&numPreallocatedPagesKey))
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
{
|
︙ | | |
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
326
327
|
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
326
327
328
|
-
+
-
-
+
+
|
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_tlskey_set(preallocatedPagesKey, preallocatedPages);
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_tlskey_set(numPreallocatedPagesKey,
(void *)(uintptr_t)numPreallocatedPages);
OF_ENSURE(of_tlskey_set(numPreallocatedPagesKey,
(void *)(uintptr_t)numPreallocatedPages) == 0);
# endif
#else
@throw [OFNotImplementedException exceptionWithSelector: _cmd
object: self];
#endif
}
|
︙ | | |
Modified src/OFThread.m
from [fe4bfba4ee]
to [7d209d5958].
︙ | | |
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
|
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
|
-
+
|
#ifdef OF_HAVE_THREADS
static void
callMain(id object)
{
OFThread *thread = (OFThread *)object;
OFString *name;
if (!of_tlskey_set(threadSelfKey, thread))
if (of_tlskey_set(threadSelfKey, thread) != 0)
@throw [OFInitializationFailedException
exceptionWithClass: thread.class];
#ifndef OF_OBJFW_RUNTIME
thread->_pool = objc_autoreleasePoolPush();
#endif
|
︙ | | |
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
|
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
|
-
+
|
# endif
+ (void)initialize
{
if (self != [OFThread class])
return;
if (!of_tlskey_new(&threadSelfKey))
if (of_tlskey_new(&threadSelfKey) != 0)
@throw [OFInitializationFailedException
exceptionWithClass: self];
}
+ (instancetype)thread
{
return [[[self alloc] init] autorelease];
|
︙ | | |
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
|
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
|
-
+
-
+
|
+ (void)of_createMainThread
{
mainThread = [[OFThread alloc] init];
mainThread->_thread = of_thread_current();
mainThread->_running = OF_THREAD_RUNNING;
if (!of_tlskey_set(threadSelfKey, mainThread))
if (of_tlskey_set(threadSelfKey, mainThread) != 0)
@throw [OFInitializationFailedException
exceptionWithClass: self];
}
- (instancetype)init
{
self = [super init];
@try {
if (!of_thread_attr_init(&_attr))
if (of_thread_attr_init(&_attr) != 0)
@throw [OFInitializationFailedException
exceptionWithClass: self.class];
} @catch (id e) {
[self release];
@throw e;
}
|
︙ | | |
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
|
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
|
+
+
-
-
+
+
-
-
+
+
+
-
+
-
+
|
[_DNSResolver release];
_DNSResolver = nil;
# endif
}
- (void)start
{
int error;
if (_running == OF_THREAD_RUNNING)
@throw [OFThreadStillRunningException
exceptionWithThread: self];
if (_running == OF_THREAD_WAITING_FOR_JOIN) {
of_thread_detach(_thread);
[_returnValue release];
}
[self retain];
_running = OF_THREAD_RUNNING;
if (!of_thread_new(&_thread,
[_name cStringWithEncoding: [OFLocale encoding]], callMain, self,
if ((error = of_thread_new(&_thread, [_name cStringWithEncoding:
[OFLocale encoding]], callMain, self, &_attr)) != 0) {
&_attr)) {
[self release];
@throw [OFThreadStartFailedException
exceptionWithThread: self
errNo: errno];
errNo: error];
}
}
- (id)join
{
int error;
if (_running == OF_THREAD_NOT_RUNNING)
@throw [OFThreadJoinFailedException
exceptionWithThread: self
errNo: EINVAL];
if (!of_thread_join(_thread))
if ((error = of_thread_join(_thread)) != 0)
@throw [OFThreadJoinFailedException exceptionWithThread: self
errNo: errno];
errNo: error];
_running = OF_THREAD_NOT_RUNNING;
return _returnValue;
}
- (id)copy
|
︙ | | |
Modified src/condition.h
from [ed39b78cbd]
to [cbe5713cf5].
︙ | | |
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
|
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
|
-
-
-
-
-
+
+
+
+
+
-
+
-
+
-
+
|
} *waitingTasks;
} of_condition_t;
#endif
#ifdef __cplusplus
extern "C" {
#endif
extern bool of_condition_new(of_condition_t *condition);
extern bool of_condition_signal(of_condition_t *condition);
extern bool of_condition_broadcast(of_condition_t *condition);
extern bool of_condition_wait(of_condition_t *condition, of_mutex_t *mutex);
extern bool of_condition_timed_wait(of_condition_t *condition,
extern int of_condition_new(of_condition_t *condition);
extern int of_condition_signal(of_condition_t *condition);
extern int of_condition_broadcast(of_condition_t *condition);
extern int of_condition_wait(of_condition_t *condition, of_mutex_t *mutex);
extern int of_condition_timed_wait(of_condition_t *condition,
of_mutex_t *mutex, of_time_interval_t timeout);
#ifdef OF_AMIGAOS
extern bool of_condition_wait_or_signal(of_condition_t *condition,
extern int of_condition_wait_or_signal(of_condition_t *condition,
of_mutex_t *mutex, ULONG *signalMask);
extern bool of_condition_timed_wait_or_signal(of_condition_t *condition,
extern int of_condition_timed_wait_or_signal(of_condition_t *condition,
of_mutex_t *mutex, of_time_interval_t timeout, ULONG *signalMask);
#endif
extern bool of_condition_free(of_condition_t *condition);
extern int of_condition_free(of_condition_t *condition);
#ifdef __cplusplus
}
#endif
|
Modified src/exceptions/OFException.m
from [bf7ff24437]
to [aa89efc62e].
︙ | | |
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
|
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
|
-
+
|
#endif
#if !defined(HAVE_STRERROR_R) && defined(OF_HAVE_THREADS)
static of_mutex_t mutex;
OF_CONSTRUCTOR()
{
if (!of_mutex_new(&mutex))
if (of_mutex_new(&mutex) != 0)
@throw [OFInitializationFailedException exception];
}
#endif
OFString *
of_strerror(int errNo)
{
|
︙ | | |
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
|
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
|
-
+
-
+
|
if (strerror_r(errNo, buffer, 256) != 0)
return @"Unknown error (strerror_r failed)";
ret = [OFString stringWithCString: buffer
encoding: [OFLocale encoding]];
#else
# ifdef OF_HAVE_THREADS
if (!of_mutex_lock(&mutex))
if (of_mutex_lock(&mutex) != 0)
@throw [OFLockFailedException exception];
@try {
# endif
ret = [OFString
stringWithCString: strerror(errNo)
encoding: [OFLocale encoding]];
# ifdef OF_HAVE_THREADS
} @finally {
if (!of_mutex_unlock(&mutex))
if (of_mutex_unlock(&mutex) != 0)
@throw [OFUnlockFailedException exception];
}
# endif
#endif
return ret;
}
|
︙ | | |
Modified src/mutex.h
from [cbacd2f77f]
to [5c06ee482b].
︙ | | |
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
+
+
|
* Alternatively, it may be distributed under the terms of the GNU General
* Public License, either version 2 or 3, which can be found in the file
* LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
* file.
*/
#include "objfw-defs.h"
#include <errno.h>
#include "platform.h"
#if !defined(OF_HAVE_THREADS) || \
(!defined(OF_HAVE_PTHREADS) && !defined(OF_WINDOWS) && !defined(OF_AMIGAOS))
# error No mutexes available!
#endif
|
︙ | | |
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
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
|
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
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
|
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
-
+
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
|
of_tlskey_t count;
} of_rmutex_t;
#endif
#ifdef __cplusplus
extern "C" {
#endif
extern bool of_mutex_new(of_mutex_t *mutex);
extern bool of_mutex_lock(of_mutex_t *mutex);
extern bool of_mutex_trylock(of_mutex_t *mutex);
extern bool of_mutex_unlock(of_mutex_t *mutex);
extern bool of_mutex_free(of_mutex_t *mutex);
extern bool of_rmutex_new(of_rmutex_t *rmutex);
extern bool of_rmutex_lock(of_rmutex_t *rmutex);
extern bool of_rmutex_trylock(of_rmutex_t *rmutex);
extern bool of_rmutex_unlock(of_rmutex_t *rmutex);
extern bool of_rmutex_free(of_rmutex_t *rmutex);
extern int of_mutex_new(of_mutex_t *mutex);
extern int of_mutex_lock(of_mutex_t *mutex);
extern int of_mutex_trylock(of_mutex_t *mutex);
extern int of_mutex_unlock(of_mutex_t *mutex);
extern int of_mutex_free(of_mutex_t *mutex);
extern int of_rmutex_new(of_rmutex_t *rmutex);
extern int of_rmutex_lock(of_rmutex_t *rmutex);
extern int of_rmutex_trylock(of_rmutex_t *rmutex);
extern int of_rmutex_unlock(of_rmutex_t *rmutex);
extern int of_rmutex_free(of_rmutex_t *rmutex);
#ifdef __cplusplus
}
#endif
/* Spinlocks are inlined for performance. */
static OF_INLINE void
of_thread_yield(void)
{
#if defined(OF_HAVE_SCHED_YIELD)
sched_yield();
#elif defined(OF_WINDOWS)
Sleep(0);
#endif
}
static OF_INLINE bool
static OF_INLINE int
of_spinlock_new(of_spinlock_t *spinlock)
{
#if defined(OF_HAVE_ATOMIC_OPS)
*spinlock = 0;
return true;
return 0;
#elif defined(OF_HAVE_PTHREAD_SPINLOCKS)
return (pthread_spin_init(spinlock, 0) == 0);
return pthread_spin_init(spinlock, 0);
#else
return of_mutex_new(spinlock);
#endif
}
static OF_INLINE bool
static OF_INLINE int
of_spinlock_trylock(of_spinlock_t *spinlock)
{
#if defined(OF_HAVE_ATOMIC_OPS)
if (of_atomic_int_cmpswap(spinlock, 0, 1)) {
of_memory_barrier_acquire();
return true;
return 0;
}
return false;
return EBUSY;
#elif defined(OF_HAVE_PTHREAD_SPINLOCKS)
return (pthread_spin_trylock(spinlock) == 0);
return pthread_spin_trylock(spinlock);
#else
return of_mutex_trylock(spinlock);
#endif
}
static OF_INLINE bool
static OF_INLINE int
of_spinlock_lock(of_spinlock_t *spinlock)
{
#if defined(OF_HAVE_ATOMIC_OPS)
size_t i;
for (i = 0; i < OF_SPINCOUNT; i++)
if (of_spinlock_trylock(spinlock))
return true;
if (of_spinlock_trylock(spinlock) == 0)
return 0;
while (!of_spinlock_trylock(spinlock))
while (of_spinlock_trylock(spinlock) == EBUSY)
of_thread_yield();
return true;
return 0;
#elif defined(OF_HAVE_PTHREAD_SPINLOCKS)
return (pthread_spin_lock(spinlock) == 0);
return pthread_spin_lock(spinlock);
#else
return of_mutex_lock(spinlock);
#endif
}
static OF_INLINE bool
static OF_INLINE int
of_spinlock_unlock(of_spinlock_t *spinlock)
{
#if defined(OF_HAVE_ATOMIC_OPS)
bool ret = of_atomic_int_cmpswap(spinlock, 1, 0);
of_memory_barrier_release();
return ret;
return (ret ? 0 : EINVAL);
#elif defined(OF_HAVE_PTHREAD_SPINLOCKS)
return (pthread_spin_unlock(spinlock) == 0);
return pthread_spin_unlock(spinlock);
#else
return of_mutex_unlock(spinlock);
#endif
}
static OF_INLINE bool
static OF_INLINE int
of_spinlock_free(of_spinlock_t *spinlock)
{
#if defined(OF_HAVE_ATOMIC_OPS)
return true;
return 0;
#elif defined(OF_HAVE_PTHREAD_SPINLOCKS)
return (pthread_spin_destroy(spinlock) == 0);
return pthread_spin_destroy(spinlock);
#else
return of_mutex_free(spinlock);
#endif
}
|
Modified src/platform/amiga/condition.m
from [022f3487c0]
to [e63442b656].
︙ | | |
23
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
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
|
23
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
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
|
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
-
+
-
-
+
-
+
-
-
+
+
-
-
+
-
-
+
-
+
-
+
|
#include <proto/exec.h>
#include <devices/timer.h>
#ifndef OF_AMIGAOS4
# include <clib/alib_protos.h>
#endif
bool
int
of_condition_new(of_condition_t *condition)
{
condition->waitingTasks = NULL;
return true;
return 0;
}
bool
int
of_condition_signal(of_condition_t *condition)
{
Forbid();
@try {
if (condition->waitingTasks == NULL)
return true;
return 0;
Signal(condition->waitingTasks->task,
(1ul << condition->waitingTasks->sigBit));
condition->waitingTasks = condition->waitingTasks->next;
} @finally {
Permit();
}
return true;
return 0;
}
bool
int
of_condition_broadcast(of_condition_t *condition)
{
Forbid();
@try {
if (condition->waitingTasks == NULL)
return true;
return 0;
while (condition->waitingTasks != NULL) {
Signal(condition->waitingTasks->task,
(1ul << condition->waitingTasks->sigBit));
condition->waitingTasks = condition->waitingTasks->next;
}
} @finally {
Permit();
}
return true;
return 0;
}
bool
int
of_condition_wait(of_condition_t *condition, of_mutex_t *mutex)
{
ULONG signalMask = 0;
return of_condition_wait_or_signal(condition, mutex, &signalMask);
}
bool
int
of_condition_wait_or_signal(of_condition_t *condition, of_mutex_t *mutex,
ULONG *signalMask)
{
struct of_condition_waiting_task waitingTask = {
.task = FindTask(NULL),
.sigBit = AllocSignal(-1)
};
bool ret;
int error = 0;
ULONG mask;
if (waitingTask.sigBit == -1) {
if (waitingTask.sigBit == -1)
errno = EAGAIN;
return false;
return EAGAIN;
}
Forbid();
if (!of_mutex_unlock(mutex)) {
if ((error = of_mutex_unlock(mutex)) != 0) {
FreeSignal(waitingTask.sigBit);
return false;
return error;
}
waitingTask.next = condition->waitingTasks;
condition->waitingTasks = &waitingTask;
mask = Wait((1ul << waitingTask.sigBit) | *signalMask);
if (mask & (1ul << waitingTask.sigBit) || (*signalMask &= mask))
ret = of_mutex_lock(mutex);
else {
error = of_mutex_lock(mutex);
else
/*
* This should not happen - it means something interrupted the
* Wait(), so the best we can do is return EINTR.
*/
ret = false;
errno = EINTR;
error = EINTR;
}
FreeSignal(waitingTask.sigBit);
Permit();
return ret;
return error;
}
bool
int
of_condition_timed_wait(of_condition_t *condition, of_mutex_t *mutex,
of_time_interval_t timeout)
{
ULONG signalMask = 0;
return of_condition_timed_wait_or_signal(condition, mutex, timeout,
&signalMask);
}
bool
int
of_condition_timed_wait_or_signal(of_condition_t *condition, of_mutex_t *mutex,
of_time_interval_t timeout, ULONG *signalMask)
{
struct of_condition_waiting_task waitingTask = {
.task = FindTask(NULL),
.sigBit = AllocSignal(-1)
};
|
︙ | | |
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
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
|
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
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
|
+
-
-
+
-
+
-
+
-
-
+
+
-
-
-
+
+
-
-
+
-
-
-
-
-
-
-
+
-
+
-
+
-
-
+
-
-
+
|
#else
.tr_time = {
.tv_sec = (ULONG)timeout,
.tv_micro = (timeout - request.tr_time.tv_sec) * 1000000
#endif
}
};
int error = 0;
ULONG mask;
bool ret;
NewList(&port.mp_MsgList);
if (waitingTask.sigBit == -1 || port.mp_SigBit == -1) {
errno = EAGAIN;
error = EAGAIN;
goto fail;
}
if (OpenDevice("timer.device", UNIT_MICROHZ,
(struct IORequest *)&request, 0) != 0) {
errno = EAGAIN;
error = EAGAIN;
goto fail;
}
Forbid();
if (!of_mutex_unlock(mutex)) {
if ((error = of_mutex_unlock(mutex)) != 0) {
Permit();
goto fail;
}
waitingTask.next = condition->waitingTasks;
condition->waitingTasks = &waitingTask;
SendIO((struct IORequest *)&request);
mask = Wait((1ul << waitingTask.sigBit) | (1ul << port.mp_SigBit) |
*signalMask);
if (mask & (1ul << waitingTask.sigBit) || (*signalMask &= mask))
ret = of_mutex_lock(mutex);
else if (mask & (1ul << port.mp_SigBit)) {
error = of_mutex_lock(mutex);
else if (mask & (1ul << port.mp_SigBit))
ret = false;
errno = ETIMEDOUT;
} else {
error = ETIMEDOUT;
else
/*
* This should not happen - it means something interrupted the
* Wait(), so the best we can do is return EINTR.
*/
ret = false;
errno = EINTR;
error = EINTR;
}
condition->waitingTasks = waitingTask.next;
if (!CheckIO((struct IORequest *)&request)) {
AbortIO((struct IORequest *)&request);
WaitIO((struct IORequest *)&request);
}
CloseDevice((struct IORequest *)&request);
Permit();
FreeSignal(waitingTask.sigBit);
FreeSignal(port.mp_SigBit);
return ret;
fail:
if (waitingTask.sigBit != -1)
FreeSignal(waitingTask.sigBit);
if (port.mp_SigBit != -1)
FreeSignal(port.mp_SigBit);
return false;
return error;
}
bool
int
of_condition_free(of_condition_t *condition)
{
Forbid();
@try {
if (condition->waitingTasks != NULL) {
if (condition->waitingTasks != NULL)
errno = EBUSY;
return false;
return EBUSY;
}
} @finally {
Permit();
}
return true;
return 0;
}
|
Modified src/platform/amiga/mutex.m
from [c8d24f47bf]
to [53f62a4365].
︙ | | |
19
20
21
22
23
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
|
19
20
21
22
23
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
|
-
+
-
+
-
+
-
+
-
+
-
+
-
-
-
+
+
-
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
|
#include <errno.h>
#import "mutex.h"
#include <proto/exec.h>
bool
int
of_mutex_new(of_mutex_t *mutex)
{
InitSemaphore(mutex);
return true;
return 0;
}
bool
int
of_mutex_lock(of_mutex_t *mutex)
{
ObtainSemaphore(mutex);
return true;
return 0;
}
bool
int
of_mutex_trylock(of_mutex_t *mutex)
{
if (!AttemptSemaphore(mutex)) {
if (!AttemptSemaphore(mutex))
errno = EBUSY;
return false;
}
return EBUSY;
return true;
return 0;
}
bool
int
of_mutex_unlock(of_mutex_t *mutex)
{
ReleaseSemaphore(mutex);
return true;
return 0;
}
bool
int
of_mutex_free(of_mutex_t *mutex)
{
return true;
return 0;
}
bool
int
of_rmutex_new(of_rmutex_t *rmutex)
{
return of_mutex_new(rmutex);
}
bool
int
of_rmutex_lock(of_rmutex_t *rmutex)
{
return of_mutex_lock(rmutex);
}
bool
int
of_rmutex_trylock(of_rmutex_t *rmutex)
{
return of_mutex_trylock(rmutex);
}
bool
int
of_rmutex_unlock(of_rmutex_t *rmutex)
{
return of_mutex_unlock(rmutex);
}
bool
int
of_rmutex_free(of_rmutex_t *rmutex)
{
return of_mutex_free(rmutex);
}
|
Modified src/platform/amiga/thread.m
from [1416763f86]
to [020e13328a].
︙ | | |
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
|
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
|
-
+
-
+
|
#ifndef OF_MORPHOS
extern void of_tlskey_thread_exited(void);
#endif
static of_tlskey_t threadKey;
OF_CONSTRUCTOR()
{
OF_ENSURE(of_tlskey_new(&threadKey));
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));
OF_ENSURE(of_tlskey_set(threadKey, thread) == 0);
thread->function(thread->object);
ObtainSemaphore(&thread->semaphore);
@try {
thread->done = true;
|
︙ | | |
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
|
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
|
-
+
-
+
-
+
-
+
-
-
+
-
|
ReleaseSemaphore(&thread->semaphore);
}
if (detached)
free(thread);
}
bool
int
of_thread_attr_init(of_thread_attr_t *attr)
{
attr->priority = 0;
attr->stackSize = 0;
return true;
return 0;
}
bool
int
of_thread_new(of_thread_t *thread, const char *name, void (*function)(id),
id object, const of_thread_attr_t *attr)
{
OFMutableData *tags = nil;
if ((*thread = calloc(1, sizeof(**thread))) == NULL) {
if ((*thread = calloc(1, sizeof(**thread))) == NULL)
errno = ENOMEM;
return false;
return ENOMEM;
}
@try {
(*thread)->function = function;
(*thread)->object = object;
InitSemaphore(&(*thread)->semaphore);
tags = [[OFMutableData alloc]
|
︙ | | |
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
|
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
|
-
+
-
-
+
-
|
ADD_TAG(NP_Output, ((struct Process *)FindTask(NULL))->pr_COS)
ADD_TAG(NP_Error, ((struct Process *)FindTask(NULL))->pr_CES)
ADD_TAG(NP_CloseInput, FALSE)
ADD_TAG(NP_CloseOutput, FALSE)
ADD_TAG(NP_CloseError, FALSE)
if (attr != NULL && attr->priority != 0) {
if (attr->priority < 1 || attr->priority > 1) {
if (attr->priority < 1 || attr->priority > 1)
errno = EINVAL;
return false;
return EINVAL;
}
/*
* -1 should be -128 (lowest possible priority) while
* +1 should be +127 (highest possible priority).
*/
ADD_TAG(NP_Priority, (attr->priority > 0
? attr->priority * 127 : attr->priority * 128))
|
︙ | | |
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
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
|
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
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
|
-
-
+
-
+
-
+
-
+
-
+
-
-
-
+
+
-
-
+
-
-
+
-
-
+
-
+
-
+
|
ADD_TAG(TAG_DONE, 0)
#undef ADD_TAG
(*thread)->task = (struct Task *)CreateNewProc(tags.items);
if ((*thread)->task == NULL) {
free(*thread);
errno = EAGAIN;
return false;
return EAGAIN;
}
} @catch (id e) {
free(*thread);
@throw e;
} @finally {
[tags release];
}
return true;
return 0;
}
of_thread_t
of_thread_current(void)
{
return of_tlskey_get(threadKey);
}
bool
int
of_thread_join(of_thread_t thread)
{
ObtainSemaphore(&thread->semaphore);
if (thread->done) {
ReleaseSemaphore(&thread->semaphore);
free(thread);
return true;
return 0;
}
@try {
if (thread->detached || thread->joinTask != NULL) {
if (thread->detached || thread->joinTask != NULL)
errno = EINVAL;
return false;
}
return EINVAL;
if ((thread->joinSigBit = AllocSignal(-1)) == -1) {
if ((thread->joinSigBit = AllocSignal(-1)) == -1)
errno = EAGAIN;
return false;
return EAGAIN;
}
thread->joinTask = FindTask(NULL);
} @finally {
ReleaseSemaphore(&thread->semaphore);
}
Wait(1ul << thread->joinSigBit);
FreeSignal(thread->joinSigBit);
assert(thread->done);
free(thread);
return true;
return 0;
}
bool
int
of_thread_detach(of_thread_t thread)
{
ObtainSemaphore(&thread->semaphore);
if (thread->done)
free(thread);
else
thread->detached = true;
ReleaseSemaphore(&thread->semaphore);
return true;
return 0;
}
void
of_thread_set_name(const char *name)
{
}
|
Modified src/platform/amiga/tlskey.m
from [c1bdeb2ced]
to [55fe5cc12c].
︙ | | |
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
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
|
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
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
|
-
+
-
+
-
+
-
+
-
+
-
+
-
-
-
+
|
{
if (!semaphoreInitialized) {
InitSemaphore(&semaphore);
semaphoreInitialized = true;
}
}
bool
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.
*/
InitSemaphore(&semaphore);
semaphoreInitialized = true;
}
if ((*key = malloc(sizeof(**key))) == NULL)
return false;
return ENOMEM;
(*key)->table = NULL;
ObtainSemaphore(&semaphore);
@try {
(*key)->next = NULL;
(*key)->previous = lastKey;
if (lastKey != NULL)
lastKey->next = *key;
lastKey = *key;
if (firstKey == NULL)
firstKey = *key;
} @finally {
ReleaseSemaphore(&semaphore);
}
/* We create the hash table lazily. */
return true;
return 0;
}
bool
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;
if (firstKey == key)
firstKey = key->next;
if (lastKey == key)
lastKey = key->previous;
objc_hashtable_free(key->table);
free(key);
} @finally {
ReleaseSemaphore(&semaphore);
}
return true;
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;
}
bool
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);
} @catch (id e) {
return false;
} @finally {
ReleaseSemaphore(&semaphore);
}
return true;
return 0;
}
void
of_tlskey_thread_exited(void)
{
ObtainSemaphore(&semaphore);
@try {
|
︙ | | |
Modified src/platform/morphos/tlskey.m
from [b6a6f32a2b]
to [ac011a1581].
︙ | | |
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
|
-
+
-
-
+
+
+
+
+
+
-
+
+
-
+
|
* file.
*/
#include "config.h"
#import "tlskey.h"
bool
int
of_tlskey_new(of_tlskey_t *key)
{
return ((*key = TLSAllocA(NULL)) != TLS_INVALID_INDEX);
}
*key = TLSAllocA(NULL);
if (*key == TLS_INVALID_INDEX)
return EAGAIN;
return 0;
}
bool
int
of_tlskey_free(of_tlskey_t key)
{
return TLSFree(key);
return (TLSFree(key) ? 0 : EINVAL);
}
|
Modified src/platform/posix/condition.m
from [59d3a90643]
to [d7af2c3e9e].
︙ | | |
15
16
17
18
19
20
21
22
23
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
|
15
16
17
18
19
20
21
22
23
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
|
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
|
* file.
*/
#include "config.h"
#import "condition.h"
bool
int
of_condition_new(of_condition_t *condition)
{
return (pthread_cond_init(condition, NULL) == 0);
return pthread_cond_init(condition, NULL);
}
bool
int
of_condition_signal(of_condition_t *condition)
{
return (pthread_cond_signal(condition) == 0);
return pthread_cond_signal(condition);
}
bool
int
of_condition_broadcast(of_condition_t *condition)
{
return (pthread_cond_broadcast(condition) == 0);
return pthread_cond_broadcast(condition);
}
bool
int
of_condition_wait(of_condition_t *condition, of_mutex_t *mutex)
{
return (pthread_cond_wait(condition, mutex) == 0);
return pthread_cond_wait(condition, mutex);
}
bool
int
of_condition_timed_wait(of_condition_t *condition, of_mutex_t *mutex,
of_time_interval_t timeout)
{
struct timespec ts;
ts.tv_sec = (time_t)timeout;
ts.tv_nsec = (long)((timeout - ts.tv_sec) * 1000000000);
return (pthread_cond_timedwait(condition, mutex, &ts) == 0);
return pthread_cond_timedwait(condition, mutex, &ts);
}
bool
int
of_condition_free(of_condition_t *condition)
{
return (pthread_cond_destroy(condition) == 0);
return pthread_cond_destroy(condition);
}
|
Modified src/platform/posix/mutex.m
from [608d6df3a8]
to [9dc6dfa8c4].
︙ | | |
15
16
17
18
19
20
21
22
23
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
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
|
15
16
17
18
19
20
21
22
23
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
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
198
199
|
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
+
-
-
+
+
-
-
+
+
+
-
-
+
+
-
-
+
+
-
+
-
+
-
+
-
+
-
+
-
+
+
+
-
-
+
+
-
-
+
+
-
+
-
+
+
-
-
+
+
+
-
+
-
-
+
+
-
+
-
+
-
+
-
+
+
-
-
+
+
+
-
+
-
-
+
+
-
+
-
+
-
+
-
+
+
-
-
+
+
+
-
+
-
-
+
+
-
-
+
+
-
+
-
+
+
+
-
-
+
+
-
-
+
+
-
+
|
* file.
*/
#include "config.h"
#import "mutex.h"
bool
int
of_mutex_new(of_mutex_t *mutex)
{
return (pthread_mutex_init(mutex, NULL) == 0);
return pthread_mutex_init(mutex, NULL);
}
bool
int
of_mutex_lock(of_mutex_t *mutex)
{
return (pthread_mutex_lock(mutex) == 0);
return pthread_mutex_lock(mutex);
}
bool
int
of_mutex_trylock(of_mutex_t *mutex)
{
return (pthread_mutex_trylock(mutex) == 0);
return pthread_mutex_trylock(mutex);
}
bool
int
of_mutex_unlock(of_mutex_t *mutex)
{
return (pthread_mutex_unlock(mutex) == 0);
return pthread_mutex_unlock(mutex);
}
bool
int
of_mutex_free(of_mutex_t *mutex)
{
return (pthread_mutex_destroy(mutex) == 0);
return pthread_mutex_destroy(mutex);
}
#ifdef OF_HAVE_RECURSIVE_PTHREAD_MUTEXES
bool
int
of_rmutex_new(of_rmutex_t *rmutex)
{
int error;
pthread_mutexattr_t attr;
if (pthread_mutexattr_init(&attr) != 0)
return false;
if ((error = pthread_mutexattr_init(&attr)) != 0)
return error;
if (pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE) != 0)
return false;
if ((error = pthread_mutexattr_settype(&attr,
PTHREAD_MUTEX_RECURSIVE)) != 0)
return error;
if (pthread_mutex_init(rmutex, &attr) != 0)
return false;
if ((error = pthread_mutex_init(rmutex, &attr)) != 0)
return error;
if (pthread_mutexattr_destroy(&attr) != 0)
return false;
if ((error = pthread_mutexattr_destroy(&attr)) != 0)
return error;
return true;
return 0;
}
bool
int
of_rmutex_lock(of_rmutex_t *rmutex)
{
return of_mutex_lock(rmutex);
}
bool
int
of_rmutex_trylock(of_rmutex_t *rmutex)
{
return of_mutex_trylock(rmutex);
}
bool
int
of_rmutex_unlock(of_rmutex_t *rmutex)
{
return of_mutex_unlock(rmutex);
}
bool
int
of_rmutex_free(of_rmutex_t *rmutex)
{
return of_mutex_free(rmutex);
}
#else
bool
int
of_rmutex_new(of_rmutex_t *rmutex)
{
int error;
if (!of_mutex_new(&rmutex->mutex))
return false;
if ((error = of_mutex_new(&rmutex->mutex)) != 0)
return error;
if (!of_tlskey_new(&rmutex->count))
return false;
if ((error = of_tlskey_new(&rmutex->count)) != 0)
return error;
return true;
return 0;
}
bool
int
of_rmutex_lock(of_rmutex_t *rmutex)
{
uintptr_t count = (uintptr_t)of_tlskey_get(rmutex->count);
int error;
if (count > 0) {
if (!of_tlskey_set(rmutex->count, (void *)(count + 1)))
return false;
if ((error = of_tlskey_set(rmutex->count,
(void *)(count + 1))) != 0)
return error;
return true;
return 0;
}
if (!of_mutex_lock(&rmutex->mutex))
return false;
if ((error = of_mutex_lock(&rmutex->mutex)) != 0)
return error;
if (!of_tlskey_set(rmutex->count, (void *)1)) {
if ((error = of_tlskey_set(rmutex->count, (void *)1)) != 0) {
of_mutex_unlock(&rmutex->mutex);
return false;
return error;
}
return true;
return 0;
}
bool
int
of_rmutex_trylock(of_rmutex_t *rmutex)
{
uintptr_t count = (uintptr_t)of_tlskey_get(rmutex->count);
int error;
if (count > 0) {
if (!of_tlskey_set(rmutex->count, (void *)(count + 1)))
return false;
if ((error = of_tlskey_set(rmutex->count,
(void *)(count + 1))) != 0)
return error;
return true;
return 0;
}
if (!of_mutex_trylock(&rmutex->mutex))
return false;
if ((error = of_mutex_trylock(&rmutex->mutex)) != 0)
return error;
if (!of_tlskey_set(rmutex->count, (void *)1)) {
if ((error = of_tlskey_set(rmutex->count, (void *)1)) != 0) {
of_mutex_unlock(&rmutex->mutex);
return false;
return error;
}
return true;
return 0;
}
bool
int
of_rmutex_unlock(of_rmutex_t *rmutex)
{
uintptr_t count = (uintptr_t)of_tlskey_get(rmutex->count);
int error;
if (count > 1) {
if (!of_tlskey_set(rmutex->count, (void *)(count - 1)))
return false;
if ((error = of_tlskey_set(rmutex->count,
(void *)(count - 1))) != 0)
return error;
return true;
return 0;
}
if (!of_tlskey_set(rmutex->count, (void *)0))
return false;
if ((error = of_tlskey_set(rmutex->count, (void *)0)) != 0)
return error;
if (!of_mutex_unlock(&rmutex->mutex))
return false;
if ((error = of_mutex_unlock(&rmutex->mutex)) != 0)
return error;
return true;
return 0;
}
bool
int
of_rmutex_free(of_rmutex_t *rmutex)
{
int error;
if (!of_mutex_free(&rmutex->mutex))
return false;
if ((error = of_mutex_free(&rmutex->mutex)) != 0)
return error;
if (!of_tlskey_free(rmutex->count))
return false;
if ((error = of_tlskey_free(rmutex->count)) != 0)
return error;
return true;
return 0;
}
#endif
|
Modified src/platform/posix/thread.m
from [cdd7c510a1]
to [08a22e6008].
︙ | | |
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
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
|
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
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
|
-
+
+
-
-
+
+
-
-
+
-
-
-
+
+
-
-
-
+
+
-
-
+
-
+
-
+
-
-
+
+
-
+
-
-
-
+
+
-
-
-
-
+
+
+
-
-
+
+
+
-
-
-
+
+
+
-
+
-
-
+
-
-
+
-
-
+
-
+
-
+
-
+
-
+
|
ctx->function(ctx->object);
pthread_cleanup_pop(1);
return NULL;
}
bool
int
of_thread_attr_init(of_thread_attr_t *attr)
{
int error;
pthread_attr_t pattr;
if (pthread_attr_init(&pattr) != 0)
return false;
if ((error = pthread_attr_init(&pattr)) != 0)
return error;
@try {
attr->priority = 0;
attr->priority = 0;
if (pthread_attr_getstacksize(&pattr, &attr->stackSize) != 0)
return false;
error = pthread_attr_getstacksize(&pattr, &attr->stackSize);
} @finally {
pthread_attr_destroy(&pattr);
}
pthread_attr_destroy(&pattr);
return true;
return error;
}
bool
int
of_thread_new(of_thread_t *thread, const char *name, void (*function)(id),
id object, const of_thread_attr_t *attr)
{
bool ret;
int error = 0;
pthread_attr_t pattr;
if (pthread_attr_init(&pattr) != 0)
return false;
if ((error = pthread_attr_init(&pattr)) != 0)
return error;
@try {
struct thread_ctx *ctx;
if (attr != NULL) {
struct sched_param param;
if (attr->priority < -1 || attr->priority > 1) {
if (attr->priority < -1 || attr->priority > 1)
errno = EINVAL;
return false;
}
return EINVAL;
#ifdef HAVE_PTHREAD_ATTR_SETINHERITSCHED
if (pthread_attr_setinheritsched(&pattr,
PTHREAD_EXPLICIT_SCHED) != 0)
return false;
if ((error = pthread_attr_setinheritsched(&pattr,
PTHREAD_EXPLICIT_SCHED)) != 0)
return error;
#endif
if (attr->priority < 0) {
param.sched_priority = minPrio +
(1.0f + attr->priority) *
(normalPrio - minPrio);
} else
param.sched_priority = normalPrio +
attr->priority * (maxPrio - normalPrio);
if (pthread_attr_setschedparam(&pattr, ¶m) != 0)
return false;
if ((error = pthread_attr_setschedparam(&pattr,
¶m)) != 0)
return error;
if (attr->stackSize > 0) {
if (pthread_attr_setstacksize(&pattr,
attr->stackSize) != 0)
return false;
if ((error = pthread_attr_setstacksize(&pattr,
attr->stackSize)) != 0)
return error;
}
}
if ((ctx = malloc(sizeof(*ctx))) == NULL) {
if ((ctx = malloc(sizeof(*ctx))) == NULL)
errno = ENOMEM;
return false;
return ENOMEM;
}
ctx->function = function;
ctx->object = object;
ctx->name = name;
ret = (pthread_create(thread, &pattr,
error = pthread_create(thread, &pattr, functionWrapper, ctx);
functionWrapper, ctx) == 0);
} @finally {
pthread_attr_destroy(&pattr);
}
return ret;
return error;
}
bool
int
of_thread_join(of_thread_t thread)
{
void *ret;
return (pthread_join(thread, &ret) == 0);
return pthread_join(thread, &ret);
}
bool
int
of_thread_detach(of_thread_t thread)
{
return (pthread_detach(thread) == 0);
return pthread_detach(thread);
}
void
of_thread_set_name(const char *name)
{
#if defined(OF_HAIKU)
rename_thread(find_thread(NULL), name);
|
︙ | | |
Modified src/platform/posix/tlskey.m
from [01a5f7adde]
to [b21f6b68b0].
︙ | | |
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
-
+
-
+
-
+
-
+
|
* file.
*/
#include "config.h"
#import "tlskey.h"
bool
int
of_tlskey_new(of_tlskey_t *key)
{
return (pthread_key_create(key, NULL) == 0);
return pthread_key_create(key, NULL);
}
bool
int
of_tlskey_free(of_tlskey_t key)
{
return (pthread_key_delete(key) == 0);
return pthread_key_delete(key);
}
|
Modified src/platform/windows/condition.m
from [848a636ef0]
to [bcc658da38].
︙ | | |
19
20
21
22
23
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
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
|
19
20
21
22
23
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
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
|
-
+
-
+
-
-
-
+
+
-
-
+
-
+
-
-
+
-
+
-
+
-
-
+
-
+
-
+
+
-
-
+
+
-
-
+
-
+
+
-
-
+
+
-
-
+
-
-
+
-
+
-
+
-
-
-
+
+
-
-
+
|
#include <errno.h>
#import "condition.h"
#include <windows.h>
bool
int
of_condition_new(of_condition_t *condition)
{
condition->count = 0;
if ((condition->event = CreateEvent(NULL, FALSE, 0, NULL)) == NULL) {
if ((condition->event = CreateEvent(NULL, FALSE, 0, NULL)) == NULL)
errno = EAGAIN;
return false;
}
return EAGAIN;
return true;
return 0;
}
bool
int
of_condition_signal(of_condition_t *condition)
{
if (!SetEvent(condition->event)) {
switch (GetLastError()) {
case ERROR_INVALID_HANDLE:
errno = EINVAL;
return false;
return EINVAL;
default:
OF_ENSURE(0);
}
}
return true;
return 0;
}
bool
int
of_condition_broadcast(of_condition_t *condition)
{
int count = condition->count;
for (int i = 0; i < count; i++) {
if (!SetEvent(condition->event)) {
switch (GetLastError()) {
case ERROR_INVALID_HANDLE:
errno = EINVAL;
return false;
return EINVAL;
default:
OF_ENSURE(0);
}
}
}
return true;
return 0;
}
bool
int
of_condition_wait(of_condition_t *condition, of_mutex_t *mutex)
{
int error;
DWORD status;
if (!of_mutex_unlock(mutex))
return false;
if ((error = of_mutex_unlock(mutex)) != 0)
return error;
of_atomic_int_inc(&condition->count);
status = WaitForSingleObject(condition->event, INFINITE);
of_atomic_int_dec(&condition->count);
switch (status) {
case WAIT_OBJECT_0:
return of_mutex_lock(mutex);
case WAIT_FAILED:
switch (GetLastError()) {
case ERROR_INVALID_HANDLE:
errno = EINVAL;
return false;
return EINVAL;
default:
OF_ENSURE(0);
}
default:
OF_ENSURE(0);
}
}
bool
int
of_condition_timed_wait(of_condition_t *condition, of_mutex_t *mutex,
of_time_interval_t timeout)
{
int error;
DWORD status;
if (!of_mutex_unlock(mutex))
return false;
if ((error = of_mutex_unlock(mutex)) != 0)
return error;
of_atomic_int_inc(&condition->count);
status = WaitForSingleObject(condition->event, timeout * 1000);
of_atomic_int_dec(&condition->count);
switch (status) {
case WAIT_OBJECT_0:
return of_mutex_lock(mutex);
case WAIT_TIMEOUT:
errno = ETIMEDOUT;
return false;
return ETIMEDOUT;
case WAIT_FAILED:
switch (GetLastError()) {
case ERROR_INVALID_HANDLE:
errno = EINVAL;
return false;
return EINVAL;
default:
OF_ENSURE(0);
}
default:
OF_ENSURE(0);
}
}
bool
int
of_condition_free(of_condition_t *condition)
{
if (condition->count != 0) {
if (condition->count != 0)
errno = EBUSY;
return false;
}
return EBUSY;
return CloseHandle(condition->event);
return (CloseHandle(condition->event) ? 0 : EINVAL);
}
|
Modified src/platform/windows/mutex.m
from [c67aeb237e]
to [872d7f229b].
︙ | | |
19
20
21
22
23
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
|
19
20
21
22
23
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
|
-
+
-
+
-
+
-
+
-
+
-
+
-
-
-
+
+
-
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
|
#include <errno.h>
#import "mutex.h"
#include <windows.h>
bool
int
of_mutex_new(of_mutex_t *mutex)
{
InitializeCriticalSection(mutex);
return true;
return 0;
}
bool
int
of_mutex_lock(of_mutex_t *mutex)
{
EnterCriticalSection(mutex);
return true;
return 0;
}
bool
int
of_mutex_trylock(of_mutex_t *mutex)
{
if (!TryEnterCriticalSection(mutex)) {
if (!TryEnterCriticalSection(mutex))
errno = EBUSY;
return false;
}
return EBUSY;
return true;
return 0;
}
bool
int
of_mutex_unlock(of_mutex_t *mutex)
{
LeaveCriticalSection(mutex);
return true;
return 0;
}
bool
int
of_mutex_free(of_mutex_t *mutex)
{
DeleteCriticalSection(mutex);
return true;
return 0;
}
bool
int
of_rmutex_new(of_rmutex_t *rmutex)
{
return of_mutex_new(rmutex);
}
bool
int
of_rmutex_lock(of_rmutex_t *rmutex)
{
return of_mutex_lock(rmutex);
}
bool
int
of_rmutex_trylock(of_rmutex_t *rmutex)
{
return of_mutex_trylock(rmutex);
}
bool
int
of_rmutex_unlock(of_rmutex_t *rmutex)
{
return of_mutex_unlock(rmutex);
}
bool
int
of_rmutex_free(of_rmutex_t *rmutex)
{
return of_mutex_free(rmutex);
}
|
Modified src/platform/windows/thread.m
from [d3d9eb9ec8]
to [ea501b1747].
︙ | | |
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
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
|
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
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
|
-
+
-
+
-
+
-
+
-
-
+
-
-
+
-
-
+
-
-
+
-
+
-
+
-
-
+
-
+
-
+
-
+
-
-
+
-
+
-
+
|
functionWrapper(struct thread_context *context)
{
context->function(context->object);
free(context);
}
bool
int
of_thread_attr_init(of_thread_attr_t *attr)
{
attr->priority = 0;
attr->stackSize = 0;
return true;
return 0;
}
bool
int
of_thread_new(of_thread_t *thread, const char *name, void (*function)(id),
id object, const of_thread_attr_t *attr)
{
DWORD priority = THREAD_PRIORITY_NORMAL;
struct thread_context *context;
DWORD threadID;
if (attr != NULL && attr->priority != 0) {
if (attr->priority < -1 || attr->priority > 1) {
if (attr->priority < -1 || attr->priority > 1)
errno = EINVAL;
return false;
return EINVAL;
}
if (attr->priority < 0)
priority = THREAD_PRIORITY_LOWEST +
(1.0 + attr->priority) *
(THREAD_PRIORITY_NORMAL - THREAD_PRIORITY_LOWEST);
else
priority = THREAD_PRIORITY_NORMAL +
attr->priority *
(THREAD_PRIORITY_HIGHEST - THREAD_PRIORITY_NORMAL);
}
if ((context = malloc(sizeof(*context))) == NULL) {
if ((context = malloc(sizeof(*context))) == NULL)
errno = ENOMEM;
return false;
return ENOMEM;
}
context->function = function;
context->object = object;
*thread = CreateThread(NULL, (attr != NULL ? attr->stackSize : 0),
(LPTHREAD_START_ROUTINE)functionWrapper, context, 0, &threadID);
if (thread == NULL) {
int errNo;
int error;
switch (GetLastError()) {
case ERROR_NOT_ENOUGH_MEMORY:
errNo = ENOMEM;
error = ENOMEM;
break;
case ERROR_ACCESS_DENIED:
errNo = EACCES;
error = EACCES;
break;
default:
OF_ENSURE(0);
}
free(context);
errno = errNo;
return false;
return error;
}
if (attr != NULL && attr->priority != 0)
OF_ENSURE(!SetThreadPriority(*thread, priority));
return true;
return 0;
}
bool
int
of_thread_join(of_thread_t thread)
{
switch (WaitForSingleObject(thread, INFINITE)) {
case WAIT_OBJECT_0:
CloseHandle(thread);
return true;
return 0;
case WAIT_FAILED:
switch (GetLastError()) {
case ERROR_INVALID_HANDLE:
errno = EINVAL;
return false;
return EINVAL;
default:
OF_ENSURE(0);
}
default:
OF_ENSURE(0);
}
}
bool
int
of_thread_detach(of_thread_t thread)
{
CloseHandle(thread);
return true;
return 0;
}
void
of_thread_set_name(const char *name)
{
}
|
Modified src/platform/windows/tlskey.m
from [c8aecc8bc3]
to [a76af40888].
︙ | | |
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
|
-
+
-
-
+
+
+
+
+
+
-
+
+
-
+
|
* file.
*/
#include "config.h"
#import "tlskey.h"
bool
int
of_tlskey_new(of_tlskey_t *key)
{
return ((*key = TlsAlloc()) != TLS_OUT_OF_INDEXES);
}
*key = TlsAlloc();
if (*key == TLS_OUT_OF_INDEXES)
return EAGAIN;
return 0;
}
bool
int
of_tlskey_free(of_tlskey_t key)
{
return TlsFree(key);
return (TlsFree(key) ? 0 : EINVAL);
}
|
Modified src/runtime/arc.m
from [4544515edf]
to [0378415cdf].
︙ | | |
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
|
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
|
-
+
|
}
OF_CONSTRUCTOR()
{
hashtable = objc_hashtable_new(hash, equal, 2);
#ifdef OF_HAVE_THREADS
if (!of_spinlock_new(&spinlock))
if (of_spinlock_new(&spinlock) != 0)
OBJC_ERROR("Failed to create spinlock!");
#endif
}
id
objc_retain(id object)
{
|
︙ | | |
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
|
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
|
-
+
|
id
objc_storeWeak(id *object, id value)
{
struct weak_ref *old;
#ifdef OF_HAVE_THREADS
if (!of_spinlock_lock(&spinlock))
if (of_spinlock_lock(&spinlock) != 0)
OBJC_ERROR("Failed to lock spinlock!");
#endif
if (*object != nil &&
(old = objc_hashtable_get(hashtable, *object)) != NULL) {
for (size_t i = 0; i < old->count; i++) {
if (old->locations[i] == object) {
|
︙ | | |
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
|
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
|
-
+
-
+
-
+
|
ref->locations[ref->count++] = object;
} else
value = nil;
*object = value;
#ifdef OF_HAVE_THREADS
if (!of_spinlock_unlock(&spinlock))
if (of_spinlock_unlock(&spinlock) != 0)
OBJC_ERROR("Failed to unlock spinlock!");
#endif
return value;
}
id
objc_loadWeakRetained(id *object)
{
id value = nil;
struct weak_ref *ref;
#ifdef OF_HAVE_THREADS
if (!of_spinlock_lock(&spinlock))
if (of_spinlock_lock(&spinlock) != 0)
OBJC_ERROR("Failed to lock spinlock!");
#endif
if (*object != nil &&
(ref = objc_hashtable_get(hashtable, *object)) != NULL)
value = *object;
#ifdef OF_HAVE_THREADS
if (!of_spinlock_unlock(&spinlock))
if (of_spinlock_unlock(&spinlock) != 0)
OBJC_ERROR("Failed to unlock spinlock!");
#endif
if (class_respondsToSelector(object_getClass(value),
@selector(retainWeakReference)) && [value retainWeakReference])
return value;
|
︙ | | |
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
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
|
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
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
|
-
+
-
+
-
+
-
+
|
void
objc_moveWeak(id *dest, id *src)
{
struct weak_ref *ref;
#ifdef OF_HAVE_THREADS
if (!of_spinlock_lock(&spinlock))
if (of_spinlock_lock(&spinlock) != 0)
OBJC_ERROR("Failed to lock spinlock!");
#endif
if (*src != nil &&
(ref = objc_hashtable_get(hashtable, *src)) != NULL) {
for (size_t i = 0; i < ref->count; i++) {
if (ref->locations[i] == src) {
ref->locations[i] = dest;
break;
}
}
}
*dest = *src;
*src = nil;
#ifdef OF_HAVE_THREADS
if (!of_spinlock_unlock(&spinlock))
if (of_spinlock_unlock(&spinlock) != 0)
OBJC_ERROR("Failed to unlock spinlock!");
#endif
}
void
objc_zero_weak_references(id value)
{
struct weak_ref *ref;
#ifdef OF_HAVE_THREADS
if (!of_spinlock_lock(&spinlock))
if (of_spinlock_lock(&spinlock) != 0)
OBJC_ERROR("Failed to lock spinlock!");
#endif
if ((ref = objc_hashtable_get(hashtable, value)) != NULL) {
for (size_t i = 0; i < ref->count; i++)
*ref->locations[i] = nil;
objc_hashtable_delete(hashtable, value);
free(ref->locations);
free(ref);
}
#ifdef OF_HAVE_THREADS
if (!of_spinlock_unlock(&spinlock))
if (of_spinlock_unlock(&spinlock) != 0)
OBJC_ERROR("Failed to unlock spinlock!");
#endif
}
|
Modified src/runtime/autorelease.m
from [e5ceb906d0]
to [0e5c7aa48b].
︙ | | |
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
|
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
|
-
-
-
+
+
+
|
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));
OF_ENSURE(of_tlskey_new(&countKey));
OF_ENSURE(of_tlskey_new(&sizeKey));
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)
|
︙ | | |
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
|
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
|
-
-
+
+
-
+
|
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));
OF_ENSURE(of_tlskey_set(sizeKey, (void *)0));
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));
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)
|
︙ | | |
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
|
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
|
-
-
+
+
-
+
|
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));
OF_ENSURE(of_tlskey_set(sizeKey, (void *)size));
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));
OF_ENSURE(of_tlskey_set(countKey, (void *)count) == 0);
#endif
return object;
}
|
Modified src/runtime/exception.m
from [3255d28641]
to [50eac6751c].
︙ | | |
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
|
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
|
-
+
|
static objc_uncaught_exception_handler_t uncaughtExceptionHandler;
static struct objc_exception emergencyExceptions[NUM_EMERGENCY_EXCEPTIONS];
#ifdef OF_HAVE_THREADS
static of_spinlock_t emergencyExceptionsSpinlock;
OF_CONSTRUCTOR()
{
if (!of_spinlock_new(&emergencyExceptionsSpinlock))
if (of_spinlock_new(&emergencyExceptionsSpinlock) != 0)
OBJC_ERROR("Cannot create spinlock!");
}
#endif
static uint64_t
readULEB128(const uint8_t **ptr)
{
|
︙ | | |
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
|
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
|
-
+
-
+
-
+
-
+
|
}
static void
emergencyExceptionCleanup(_Unwind_Reason_Code reason,
struct _Unwind_Exception *ex)
{
#ifdef OF_HAVE_THREADS
if (!of_spinlock_lock(&emergencyExceptionsSpinlock))
if (of_spinlock_lock(&emergencyExceptionsSpinlock) != 0)
OBJC_ERROR("Cannot lock spinlock!");
#endif
ex->class = 0;
#ifdef OF_HAVE_THREADS
if (!of_spinlock_unlock(&emergencyExceptionsSpinlock))
if (of_spinlock_unlock(&emergencyExceptionsSpinlock) != 0)
OBJC_ERROR("Cannot unlock spinlock!");
#endif
}
void
objc_exception_throw(id object)
{
struct objc_exception *e = calloc(1, sizeof(*e));
bool emergency = false;
if (e == NULL) {
#ifdef OF_HAVE_THREADS
if (!of_spinlock_lock(&emergencyExceptionsSpinlock))
if (of_spinlock_lock(&emergencyExceptionsSpinlock) != 0)
OBJC_ERROR("Cannot lock spinlock!");
#endif
for (uint_fast8_t i = 0; i < NUM_EMERGENCY_EXCEPTIONS; i++) {
if (emergencyExceptions[i].exception.class == 0) {
e = &emergencyExceptions[i];
e->exception.class = GNUCOBJC_EXCEPTION_CLASS;
emergency = true;
break;
}
}
#ifdef OF_HAVE_THREADS
if (!of_spinlock_unlock(&emergencyExceptionsSpinlock))
if (of_spinlock_unlock(&emergencyExceptionsSpinlock) != 0)
OBJC_ERROR("Cannot lock spinlock!");
#endif
}
if (e == NULL)
OBJC_ERROR("Not enough memory to allocate exception!");
|
︙ | | |
Modified src/runtime/property.m
from [6195775ed5]
to [ead25184a1].
︙ | | |
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
|
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
|
-
+
-
+
-
+
-
+
-
+
|
static of_spinlock_t spinlocks[NUM_SPINLOCKS];
#endif
#ifdef OF_HAVE_THREADS
OF_CONSTRUCTOR()
{
for (size_t i = 0; i < NUM_SPINLOCKS; i++)
if (!of_spinlock_new(&spinlocks[i]))
if (of_spinlock_new(&spinlocks[i]) != 0)
OBJC_ERROR("Failed to initialize spinlocks!");
}
#endif
id
objc_getProperty(id self, SEL _cmd, ptrdiff_t offset, bool atomic)
{
if (atomic) {
id *ptr = (id *)(void *)((char *)self + offset);
#ifdef OF_HAVE_THREADS
unsigned hash = SPINLOCK_HASH(ptr);
OF_ENSURE(of_spinlock_lock(&spinlocks[hash]));
OF_ENSURE(of_spinlock_lock(&spinlocks[hash]) == 0);
@try {
return [[*ptr retain] autorelease];
} @finally {
OF_ENSURE(of_spinlock_unlock(&spinlocks[hash]));
OF_ENSURE(of_spinlock_unlock(&spinlocks[hash]) == 0);
}
#else
return [[*ptr retain] autorelease];
#endif
}
return *(id *)(void *)((char *)self + offset);
}
void
objc_setProperty(id self, SEL _cmd, ptrdiff_t offset, id value, bool atomic,
signed char copy)
{
if (atomic) {
id *ptr = (id *)(void *)((char *)self + offset);
#ifdef OF_HAVE_THREADS
unsigned hash = SPINLOCK_HASH(ptr);
OF_ENSURE(of_spinlock_lock(&spinlocks[hash]));
OF_ENSURE(of_spinlock_lock(&spinlocks[hash]) == 0);
@try {
#endif
id old = *ptr;
switch (copy) {
case 0:
*ptr = [value retain];
break;
case 2:
*ptr = [value mutableCopy];
break;
default:
*ptr = [value copy];
}
[old release];
#ifdef OF_HAVE_THREADS
} @finally {
OF_ENSURE(of_spinlock_unlock(&spinlocks[hash]));
OF_ENSURE(of_spinlock_unlock(&spinlocks[hash]) == 0);
}
#endif
return;
}
id *ptr = (id *)(void *)((char *)self + offset);
|
︙ | | |
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
|
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
|
-
+
-
+
-
+
-
+
|
objc_getPropertyStruct(void *dest, const void *src, ptrdiff_t size, bool atomic,
bool strong)
{
if (atomic) {
#ifdef OF_HAVE_THREADS
unsigned hash = SPINLOCK_HASH(src);
OF_ENSURE(of_spinlock_lock(&spinlocks[hash]));
OF_ENSURE(of_spinlock_lock(&spinlocks[hash]) == 0);
#endif
memcpy(dest, src, size);
#ifdef OF_HAVE_THREADS
OF_ENSURE(of_spinlock_unlock(&spinlocks[hash]));
OF_ENSURE(of_spinlock_unlock(&spinlocks[hash]) == 0);
#endif
return;
}
memcpy(dest, src, size);
}
void
objc_setPropertyStruct(void *dest, const void *src, ptrdiff_t size, bool atomic,
bool strong)
{
if (atomic) {
#ifdef OF_HAVE_THREADS
unsigned hash = SPINLOCK_HASH(src);
OF_ENSURE(of_spinlock_lock(&spinlocks[hash]));
OF_ENSURE(of_spinlock_lock(&spinlocks[hash]) == 0);
#endif
memcpy(dest, src, size);
#ifdef OF_HAVE_THREADS
OF_ENSURE(of_spinlock_unlock(&spinlocks[hash]));
OF_ENSURE(of_spinlock_unlock(&spinlocks[hash]) == 0);
#endif
return;
}
memcpy(dest, src, size);
}
|
︙ | | |
Modified src/runtime/synchronized.m
from [106c451b62]
to [8b8ee09700].
︙ | | |
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
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
|
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
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
|
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
|
struct lock_s *next;
} *locks = NULL;
static of_mutex_t mutex;
OF_CONSTRUCTOR()
{
if (!of_mutex_new(&mutex))
if (of_mutex_new(&mutex) != 0)
OBJC_ERROR("Failed to create mutex!");
}
#endif
int
objc_sync_enter(id object)
{
if (object == nil)
return 0;
#ifdef OF_HAVE_THREADS
struct lock_s *lock;
if (!of_mutex_lock(&mutex))
if (of_mutex_lock(&mutex) != 0)
OBJC_ERROR("Failed to lock mutex!");
/* Look if we already have a lock */
for (lock = locks; lock != NULL; lock = lock->next) {
if (lock->object != object)
continue;
lock->count++;
if (!of_mutex_unlock(&mutex))
if (of_mutex_unlock(&mutex) != 0)
OBJC_ERROR("Failed to unlock mutex!");
if (!of_rmutex_lock(&lock->rmutex))
if (of_rmutex_lock(&lock->rmutex) != 0)
OBJC_ERROR("Failed to lock mutex!");
return 0;
}
/* Create a new lock */
if ((lock = malloc(sizeof(*lock))) == NULL)
OBJC_ERROR("Failed to allocate memory for mutex!");
if (!of_rmutex_new(&lock->rmutex))
if (of_rmutex_new(&lock->rmutex) != 0)
OBJC_ERROR("Failed to create mutex!");
lock->object = object;
lock->count = 1;
lock->next = locks;
locks = lock;
if (!of_mutex_unlock(&mutex))
if (of_mutex_unlock(&mutex) != 0)
OBJC_ERROR("Failed to unlock mutex!");
if (!of_rmutex_lock(&lock->rmutex))
if (of_rmutex_lock(&lock->rmutex) != 0)
OBJC_ERROR("Failed to lock mutex!");
#endif
return 0;
}
int
objc_sync_exit(id object)
{
if (object == nil)
return 0;
#ifdef OF_HAVE_THREADS
struct lock_s *lock, *last = NULL;
if (!of_mutex_lock(&mutex))
if (of_mutex_lock(&mutex) != 0)
OBJC_ERROR("Failed to lock mutex!");
for (lock = locks; lock != NULL; lock = lock->next) {
if (lock->object != object) {
last = lock;
continue;
}
if (!of_rmutex_unlock(&lock->rmutex))
if (of_rmutex_unlock(&lock->rmutex) != 0)
OBJC_ERROR("Failed to unlock mutex!");
if (--lock->count == 0) {
if (!of_rmutex_free(&lock->rmutex))
if (of_rmutex_free(&lock->rmutex) != 0)
OBJC_ERROR("Failed to destroy mutex!");
if (last != NULL)
last->next = lock->next;
if (locks == lock)
locks = lock->next;
free(lock);
}
if (!of_mutex_unlock(&mutex))
if (of_mutex_unlock(&mutex) != 0)
OBJC_ERROR("Failed to unlock mutex!");
return 0;
}
OBJC_ERROR("objc_sync_exit() was called for an object not locked!");
#else
return 0;
#endif
}
|
Modified src/runtime/threading.m
from [e792c643b3]
to [4a1cc07735].
︙ | | |
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
|
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
|
-
+
-
+
-
+
|
#import "once.h"
static of_rmutex_t globalMutex;
static void
init(void)
{
if (!of_rmutex_new(&globalMutex))
if (of_rmutex_new(&globalMutex) != 0)
OBJC_ERROR("Failed to create global mutex!");
}
void
objc_global_mutex_lock(void)
{
static of_once_t once_control = OF_ONCE_INIT;
of_once(&once_control, init);
if (!of_rmutex_lock(&globalMutex))
if (of_rmutex_lock(&globalMutex) != 0)
OBJC_ERROR("Failed to lock global mutex!");
}
void
objc_global_mutex_unlock(void)
{
if (!of_rmutex_unlock(&globalMutex))
if (of_rmutex_unlock(&globalMutex) != 0)
OBJC_ERROR("Failed to unlock global mutex!");
}
|
Modified src/socket.m
from [d03343d8fd]
to [7f38594dbe].
︙ | | |
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
|
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
|
-
+
-
+
|
# endif
# endif
#endif
#if defined(OF_HAVE_THREADS) && defined(OF_AMIGAOS) && !defined(OF_MORPHOS)
OF_CONSTRUCTOR()
{
if (!of_tlskey_new(&of_socket_base_key))
if (of_tlskey_new(&of_socket_base_key) != 0)
@throw [OFInitializationFailedException exception];
# ifdef OF_AMIGAOS4
if (!of_tlskey_new(&of_socket_interface_key))
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
|
︙ | | |
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
|
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
|
-
+
-
+
|
if (socInit(ctx, 0x100000) != 0)
return;
atexit((void (*)(void))socExit);
# endif
# if defined(OF_HAVE_THREADS) && (!defined(OF_AMIGAOS) || defined(OF_MORPHOS))
if (!of_mutex_new(&mutex))
if (of_mutex_new(&mutex) != 0)
return;
# ifdef OF_WII
if (!of_spinlock_new(&spinlock))
if (of_spinlock_new(&spinlock) != 0)
return;
# endif
# endif
initSuccessful = true;
}
|
︙ | | |
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
|
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
|
-
+
-
+
|
if ((socketInterface = (struct SocketIFace *)
GetInterface(socketBase, "main", 1, NULL)) == NULL) {
CloseLibrary(socketBase);
return false;
}
# endif
if (!of_tlskey_set(of_socket_base_key, socketBase)) {
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)) {
if (of_tlskey_set(of_socket_interface_key, socketInterface) != 0) {
CloseLibrary(socketBase);
DropInterface((struct Interface *)socketInterface);
return false;
}
# endif
return true;
|
︙ | | |
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
|
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
|
-
+
-
+
|
int
of_getsockname(of_socket_t sock, struct sockaddr *restrict addr,
socklen_t *restrict addrLen)
{
int ret;
# if defined(OF_HAVE_THREADS) && (!defined(OF_AMIGAOS) || defined(OF_MORPHOS))
if (!of_mutex_lock(&mutex))
if (of_mutex_lock(&mutex) != 0)
@throw [OFLockFailedException exception];
# endif
ret = getsockname(sock, addr, addrLen);
# if defined(OF_HAVE_THREADS) && (!defined(OF_AMIGAOS) || defined(OF_MORPHOS))
if (!of_mutex_unlock(&mutex))
if (of_mutex_unlock(&mutex) != 0)
@throw [OFUnlockFailedException exception];
# endif
return ret;
}
#endif
|
︙ | | |
Modified src/thread.h
from [bf84b7cea6]
to [821c6c8243].
︙ | | |
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
|
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
|
-
-
+
+
-
-
+
+
|
# define of_thread_is_current(t) (t->thread == FindTask(NULL))
extern of_thread_t of_thread_current(void);
#endif
#ifdef __cplusplus
extern "C" {
#endif
extern bool of_thread_attr_init(of_thread_attr_t *attr);
extern bool of_thread_new(of_thread_t *thread, const char *name,
extern int of_thread_attr_init(of_thread_attr_t *attr);
extern int of_thread_new(of_thread_t *thread, const char *name,
void (*function)(id), id object, const of_thread_attr_t *attr);
extern void of_thread_set_name(const char *name);
extern bool of_thread_join(of_thread_t thread);
extern bool of_thread_detach(of_thread_t thread);
extern int of_thread_join(of_thread_t thread);
extern int of_thread_detach(of_thread_t thread);
#ifdef __cplusplus
}
#endif
|
Modified src/tlskey.h
from [19e6f1fad4]
to [bf467b6736].
︙ | | |
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
+
+
|
* Alternatively, it may be distributed under the terms of the GNU General
* Public License, either version 2 or 3, which can be found in the file
* LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
* file.
*/
#include "objfw-defs.h"
#include <errno.h>
#include "platform.h"
#if !defined(OF_HAVE_THREADS) || \
(!defined(OF_HAVE_PTHREADS) && !defined(OF_WINDOWS) && !defined(OF_AMIGAOS))
# error No thread-local storage available!
#endif
|
︙ | | |
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
|
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
|
-
-
+
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
|
struct of_tlskey *next, *previous;
} *of_tlskey_t;
#endif
#ifdef __cplusplus
extern "C" {
#endif
extern bool of_tlskey_new(of_tlskey_t *key);
extern bool of_tlskey_free(of_tlskey_t key);
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 bool
static OF_INLINE int
of_tlskey_set(of_tlskey_t key, void *ptr)
{
return (pthread_setspecific(key, ptr) == 0);
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 bool
static OF_INLINE int
of_tlskey_set(of_tlskey_t key, void *ptr)
{
return TlsSetValue(key, 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 bool
static OF_INLINE int
of_tlskey_set(of_tlskey_t key, void *ptr)
{
return TLSSetValue(key, (APTR)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 bool of_tlskey_set(of_tlskey_t key, void *ptr);
extern int of_tlskey_set(of_tlskey_t key, void *ptr);
# ifdef __cplusplus
}
# endif
#endif
|