Modified configure.ac
from [713816fa59]
to [574361ab39].
︙ | | | ︙ | |
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
|
AC_C_BIGENDIAN([
AC_DEFINE(OF_BIG_ENDIAN, 1, [Whether we are big endian])
])
AS_IF([test x"$ac_cv_c_bigendian" = x"universal"], [
AC_DEFINE(OF_UNIVERSAL, 1, [Whether we are building a universal binary])
])
AC_MSG_CHECKING(for SIZE_MAX)
AC_EGREP_CPP(egrep_cpp_yes, [
#include <stdint.h>
#include <limits.h>
#ifdef SIZE_MAX
egrep_cpp_yes
#endif
], [
AC_MSG_RESULT(yes)
], [
AC_MSG_RESULT(no)
AC_MSG_CHECKING(for SIZE_T_MAX)
AC_EGREP_CPP(egrep_cpp_yes, [
#include <stdint.h>
#include <limits.h>
#ifdef SIZE_T_MAX
egrep_cpp_yes
#endif
], [
AC_MSG_RESULT(yes)
size_max="SIZE_T_MAX"
], [
AC_MSG_RESULT(no)
size_max="(~(size_t)0)"
])
AC_DEFINE_UNQUOTED(SIZE_MAX, $size_max, [Maximum value for size_t])
])
AC_MSG_CHECKING(for SSIZE_MAX)
AC_EGREP_CPP(egrep_cpp_yes, [
#include <stdint.h>
#include <limits.h>
#ifdef SSIZE_MAX
egrep_cpp_yes
#endif
], [
AC_MSG_RESULT(yes)
], [
AC_MSG_RESULT(no)
AC_DEFINE(SSIZE_MAX, [((ssize_t)(SIZE_MAX / 2))],
[Maximum value for ssize_t])
])
AC_MSG_CHECKING(for UINTPTR_MAX)
AC_EGREP_CPP(egrep_cpp_yes, [
#include <stdint.h>
#include <limits.h>
#ifdef UINTPTR_MAX
egrep_cpp_yes
#endif
], [
AC_MSG_RESULT(yes)
], [
AC_MSG_RESULT(no)
AC_DEFINE(UINTPTR_MAX, [(~(uintptr_t)0)], [Maximum value for uintptr_t])
])
AC_CHECK_HEADER(inttypes.h,
[AC_DEFINE(OF_HAVE_INTTYPES_H, 1, [Whether we have inttypes.h])])
AC_CHECK_HEADER(sys/types.h,
[AC_DEFINE(OF_HAVE_SYS_TYPES_H, 1, [Whether we have sys/types.h])])
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
>
|
>
|
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
|
AC_C_BIGENDIAN([
AC_DEFINE(OF_BIG_ENDIAN, 1, [Whether we are big endian])
])
AS_IF([test x"$ac_cv_c_bigendian" = x"universal"], [
AC_DEFINE(OF_UNIVERSAL, 1, [Whether we are building a universal binary])
])
AC_MSG_CHECKING(for SSIZE_MAX)
AC_EGREP_CPP(egrep_cpp_yes, [
#include <stdint.h>
#include <limits.h>
#ifdef SSIZE_MAX
egrep_cpp_yes
#endif
], [
AC_MSG_RESULT(yes)
], [
AC_MSG_RESULT(no)
AC_DEFINE(SSIZE_MAX, [(SIZE_MAX / 2)], [Maximum value for ssize_t])
])
AC_MSG_CHECKING(for UINTPTR_MAX)
AC_EGREP_CPP(egrep_cpp_yes, [
#include <stdint.h>
#include <limits.h>
#ifdef UINTPTR_MAX
egrep_cpp_yes
#endif
], [
AC_MSG_RESULT(yes)
], [
AC_MSG_RESULT(no)
AC_CHECK_SIZEOF(uintptr_t)
AC_DEFINE(UINTPTR_MAX,
[(SIZEOF_UINTPTR_T * CHAR_BIT)], [Maximum value for uintptr_t])
])
AC_CHECK_HEADER(inttypes.h,
[AC_DEFINE(OF_HAVE_INTTYPES_H, 1, [Whether we have inttypes.h])])
AC_CHECK_HEADER(sys/types.h,
[AC_DEFINE(OF_HAVE_SYS_TYPES_H, 1, [Whether we have sys/types.h])])
|
︙ | | | ︙ | |
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
|
fp_endianess="universal"
])
AC_MSG_RESULT($fp_endianess)
AS_IF([test x"$fp_endianess" = x"unknown"], [
AC_MSG_ERROR(
[Floating point implementation does not conform to IEEE 754!])])
AC_MSG_CHECKING(for INFINITY)
AC_COMPILE_IFELSE([
AC_LANG_PROGRAM([
#include <stdio.h>
#include <math.h>
], [
printf("%f", INFINITY);
])
], [
AC_MSG_RESULT(yes)
], [
AC_MSG_RESULT(no)
AC_MSG_CHECKING(for __builtin_inf)
AC_COMPILE_IFELSE([
AC_LANG_PROGRAM([
#include <stdio.h>
], [
printf("%f", __builtin_inf());
])
], [
AC_MSG_RESULT(yes)
AC_DEFINE(INFINITY, [(__builtin_inf())],
[Workaround for missing INFINITY])
], [
AC_MSG_RESULT(no)
AC_MSG_ERROR([Neither INFINITY or __builtin_inf was found!])
])
])
case "$host_cpu" in
arm* | earm*)
AC_MSG_CHECKING(for VFP2 or above)
AC_COMPILE_IFELSE([
AC_LANG_PROGRAM([], [
#if !defined(__arm64__) && \
!defined(__aarch64__) && \
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
847
848
849
850
851
852
853
854
855
856
857
858
859
860
|
fp_endianess="universal"
])
AC_MSG_RESULT($fp_endianess)
AS_IF([test x"$fp_endianess" = x"unknown"], [
AC_MSG_ERROR(
[Floating point implementation does not conform to IEEE 754!])])
case "$host_cpu" in
arm* | earm*)
AC_MSG_CHECKING(for VFP2 or above)
AC_COMPILE_IFELSE([
AC_LANG_PROGRAM([], [
#if !defined(__arm64__) && \
!defined(__aarch64__) && \
|
︙ | | | ︙ | |
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
|
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]));
block->flags++;
OF_ENSURE(of_spinlock_unlock(&blockSpinlocks[hash]));
#endif
}
return block;
}
void
|
|
|
|
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]) == 0);
block->flags++;
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
|
block->descriptor->dispose_helper(block);
free(block);
}
#else
unsigned hash = SPINLOCK_HASH(block);
OF_ENSURE(of_spinlock_lock(&blockSpinlocks[hash]));
if ((--block->flags & OF_BLOCK_REFCOUNT_MASK) == 0) {
OF_ENSURE(of_spinlock_unlock(&blockSpinlocks[hash]));
if (block->flags & OF_BLOCK_HAS_COPY_DISPOSE)
block->descriptor->dispose_helper(block);
free(block);
return;
}
OF_ENSURE(of_spinlock_unlock(&blockSpinlocks[hash]));
#endif
}
void
_Block_object_assign(void *dst_, const void *src_, const int flags_)
{
int flags = flags_ & (OF_BLOCK_FIELD_IS_BLOCK |
|
|
|
|
|
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]) == 0);
if ((--block->flags & OF_BLOCK_REFCOUNT_MASK) == 0) {
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]) == 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
|
free(*dst);
*dst = src->forwarding;
}
#else
unsigned hash = SPINLOCK_HASH(src);
OF_ENSURE(of_spinlock_lock(&byrefSpinlocks[hash]));
if (src->forwarding == src)
src->forwarding = *dst;
else {
src->byref_dispose(*dst);
free(*dst);
*dst = src->forwarding;
}
OF_ENSURE(of_spinlock_unlock(&byrefSpinlocks[hash]));
#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]));
(*dst)->flags++;
OF_ENSURE(of_spinlock_unlock(&byrefSpinlocks[hash]));
#endif
break;
}
}
void
_Block_object_dispose(const void *object_, const int flags_)
|
|
>
|
|
|
|
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]) == 0);
if (src->forwarding == src)
src->forwarding = *dst;
else {
src->byref_dispose(*dst);
free(*dst);
*dst = src->forwarding;
}
OF_ENSURE(
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]) == 0);
(*dst)->flags++;
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
|
object->byref_dispose(object);
free(object);
}
#else
unsigned hash = SPINLOCK_HASH(object);
OF_ENSURE(of_spinlock_lock(&byrefSpinlocks[hash]));
if ((--object->flags & OF_BLOCK_REFCOUNT_MASK) == 0) {
OF_ENSURE(of_spinlock_unlock(&byrefSpinlocks[hash]));
if (object->flags & OF_BLOCK_HAS_COPY_DISPOSE)
object->byref_dispose(object);
free(object);
}
OF_ENSURE(of_spinlock_unlock(&byrefSpinlocks[hash]));
#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]))
@throw [OFInitializationFailedException
exceptionWithClass: self];
#endif
#ifdef OF_APPLE_RUNTIME
Class tmp;
|
|
>
|
|
|
|
|
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]) == 0);
if ((--object->flags & OF_BLOCK_REFCOUNT_MASK) == 0) {
OF_ENSURE(
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]) == 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]) != 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
|
return [[[self alloc] init] autorelease];
}
- (instancetype)init
{
self = [super init];
if (!of_condition_new(&_condition)) {
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);
@throw [OFConditionStillWaitingException
exceptionWithCondition: self];
}
}
[super dealloc];
}
- (void)wait
{
if (!of_condition_wait(&_condition, &_mutex))
@throw [OFConditionWaitFailedException
exceptionWithCondition: self
errNo: errno];
}
#ifdef OF_AMIGAOS
- (void)waitForConditionOrExecSignal: (ULONG *)signalMask
{
if (!of_condition_wait_or_signal(&_condition, &_mutex, signalMask))
@throw [OFConditionWaitFailedException
exceptionWithCondition: self
errNo: errno];
}
#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];
}
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];
}
return true;
}
#endif
- (bool)waitUntilDate: (OFDate *)date
{
|
|
|
>
>
|
|
>
>
|
|
>
>
>
|
|
>
|
|
|
>
|
|
|
<
|
|
>
|
|
|
>
|
|
|
<
|
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) != 0) {
Class c = self.class;
[self release];
@throw [OFInitializationFailedException exceptionWithClass: c];
}
_conditionInitialized = true;
return self;
}
- (void)dealloc
{
if (_conditionInitialized) {
int error = of_condition_free(&_condition);
if (error != 0) {
OF_ENSURE(error == EBUSY);
@throw [OFConditionStillWaitingException
exceptionWithCondition: self];
}
}
[super dealloc];
}
- (void)wait
{
int error = of_condition_wait(&_condition, &_mutex);
if (error != 0)
@throw [OFConditionWaitFailedException
exceptionWithCondition: self
errNo: error];
}
#ifdef OF_AMIGAOS
- (void)waitForConditionOrExecSignal: (ULONG *)signalMask
{
int error = of_condition_wait_or_signal(&_condition, &_mutex,
signalMask);
if (error != 0)
@throw [OFConditionWaitFailedException
exceptionWithCondition: self
errNo: error];
}
#endif
- (bool)waitForTimeInterval: (of_time_interval_t)timeInterval
{
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
{
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
|
return [self waitForTimeInterval: date.timeIntervalSinceNow
orExecSignal: signalMask];
}
#endif
- (void)signal
{
if (!of_condition_signal(&_condition))
@throw [OFConditionSignalFailedException
exceptionWithCondition: self
errNo: errno];
}
- (void)broadcast
{
if (!of_condition_broadcast(&_condition))
@throw [OFConditionBroadcastFailedException
exceptionWithCondition: self
errNo: errno];
}
@end
|
|
>
>
|
|
>
>
|
|
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
{
int error = of_condition_signal(&_condition);
if (error != 0)
@throw [OFConditionSignalFailedException
exceptionWithCondition: self
errNo: error];
}
- (void)broadcast
{
int error = of_condition_broadcast(&_condition);
if (error != 0)
@throw [OFConditionBroadcastFailedException
exceptionWithCondition: self
errNo: error];
}
@end
|
Modified src/OFFileURLHandler.m
from [9e0a7e3741]
to [529682cb40].
︙ | | | ︙ | |
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
|
modificationTime -= locale->loc_GMTOffset * 60.0;
CloseLocale(locale);
date.ds_Days = modificationTime / 86400;
date.ds_Minute = ((LONG)modificationTime % 86400) / 60;
date.ds_Tick = fmod(modificationTime, 60) * TICKS_PER_SECOND;
if (!SetFileDate([path cStringWithEncoding: [OFLocale encoding]],
&date) != 0) {
setErrno();
@throw [OFSetItemAttributesFailedException
exceptionWithURL: URL
attributes: attributes
failedAttribute: attributeKey
errNo: errno];
|
>
>
>
>
>
|
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
|
modificationTime -= locale->loc_GMTOffset * 60.0;
CloseLocale(locale);
date.ds_Days = modificationTime / 86400;
date.ds_Minute = ((LONG)modificationTime % 86400) / 60;
date.ds_Tick = fmod(modificationTime, 60) * TICKS_PER_SECOND;
# ifdef OF_AMIGAOS4
if (!SetDate([path cStringWithEncoding: [OFLocale encoding]],
&date) != 0) {
# else
if (!SetFileDate([path cStringWithEncoding: [OFLocale encoding]],
&date) != 0) {
# endif
setErrno();
@throw [OFSetItemAttributesFailedException
exceptionWithURL: URL
attributes: attributes
failedAttribute: attributeKey
errNo: errno];
|
︙ | | | ︙ | |
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
|
return [[[self alloc] init] autorelease];
}
- (instancetype)init
{
self = [super init];
if (!of_mutex_new(&_mutex)) {
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);
@throw [OFStillLockedException exceptionWithLock: self];
}
}
[_name release];
[super dealloc];
}
- (void)lock
{
if (!of_mutex_lock(&_mutex))
@throw [OFLockFailedException exceptionWithLock: self
errNo: errno];
}
- (bool)tryLock
{
if (!of_mutex_trylock(&_mutex)) {
if (errno == EBUSY)
return false;
else
@throw [OFLockFailedException exceptionWithLock: self
errNo: errno];
}
return true;
}
- (void)unlock
{
if (!of_mutex_unlock(&_mutex))
@throw [OFUnlockFailedException exceptionWithLock: self
errNo: errno];
}
- (OFString *)description
{
if (_name == nil)
return super.description;
return [OFString stringWithFormat: @"<%@: %@>", self.className, _name];
}
@end
|
|
|
>
>
|
|
>
>
|
|
>
>
|
|
|
>
>
|
|
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) != 0) {
Class c = self.class;
[self release];
@throw [OFInitializationFailedException exceptionWithClass: c];
}
_initialized = true;
return self;
}
- (void)dealloc
{
if (_initialized) {
int error = of_mutex_free(&_mutex);
if (error != 0) {
OF_ENSURE(error == EBUSY);
@throw [OFStillLockedException exceptionWithLock: self];
}
}
[_name release];
[super dealloc];
}
- (void)lock
{
int error = of_mutex_lock(&_mutex);
if (error != 0)
@throw [OFLockFailedException exceptionWithLock: self
errNo: error];
}
- (bool)tryLock
{
int error = of_mutex_trylock(&_mutex);
if (error != 0) {
if (error == EBUSY)
return false;
else
@throw [OFLockFailedException exceptionWithLock: self
errNo: error];
}
return true;
}
- (void)unlock
{
int error = of_mutex_unlock(&_mutex);
if (error != 0)
@throw [OFUnlockFailedException exceptionWithLock: self
errNo: error];
}
- (OFString *)description
{
if (_name == nil)
return super.description;
return [OFString stringWithFormat: @"<%@: %@>", self.className, _name];
}
@end
|
Modified src/OFObject.m
from [7354b5ddd4]
to [779114b0ef].
︙ | | | ︙ | |
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
|
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)) {
free(instance);
@throw [OFInitializationFailedException
exceptionWithClass: class];
}
#endif
instance = (OFObject *)(void *)((char *)instance + PRE_IVARS_ALIGN);
|
|
|
|
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
|
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) != 0) {
free(instance);
@throw [OFInitializationFailedException
exceptionWithClass: class];
}
#endif
instance = (OFObject *)(void *)((char *)instance + PRE_IVARS_ALIGN);
|
︙ | | | ︙ | |
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
|
Forbid();
# endif
PRE_IVARS->retainCount++;
# ifndef OF_AMIGAOS_M68K
Permit();
# endif
#else
OF_ENSURE(of_spinlock_lock(&PRE_IVARS->retainCountSpinlock));
PRE_IVARS->retainCount++;
OF_ENSURE(of_spinlock_unlock(&PRE_IVARS->retainCountSpinlock));
#endif
return self;
}
- (unsigned int)retainCount
{
|
|
|
|
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
|
Forbid();
# endif
PRE_IVARS->retainCount++;
# ifndef OF_AMIGAOS_M68K
Permit();
# endif
#else
OF_ENSURE(of_spinlock_lock(&PRE_IVARS->retainCountSpinlock) == 0);
PRE_IVARS->retainCount++;
OF_ENSURE(of_spinlock_unlock(&PRE_IVARS->retainCountSpinlock) == 0);
#endif
return self;
}
- (unsigned int)retainCount
{
|
︙ | | | ︙ | |
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
|
Permit();
if (retainCount == 0)
[self dealloc];
#else
int retainCount;
OF_ENSURE(of_spinlock_lock(&PRE_IVARS->retainCountSpinlock));
retainCount = --PRE_IVARS->retainCount;
OF_ENSURE(of_spinlock_unlock(&PRE_IVARS->retainCountSpinlock));
if (retainCount == 0)
[self dealloc];
#endif
}
- (instancetype)autorelease
|
|
|
|
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
|
Permit();
if (retainCount == 0)
[self dealloc];
#else
int retainCount;
OF_ENSURE(of_spinlock_lock(&PRE_IVARS->retainCountSpinlock) == 0);
retainCount = --PRE_IVARS->retainCount;
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
|
return [[[self alloc] init] autorelease];
}
- (instancetype)init
{
self = [super init];
if (!of_rmutex_new(&_rmutex)) {
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);
@throw [OFStillLockedException exceptionWithLock: self];
}
}
[_name release];
[super dealloc];
}
- (void)lock
{
if (!of_rmutex_lock(&_rmutex))
@throw [OFLockFailedException exceptionWithLock: self
errNo: errno];
}
- (bool)tryLock
{
if (!of_rmutex_trylock(&_rmutex)) {
if (errno == EBUSY)
return false;
else
@throw [OFLockFailedException exceptionWithLock: self
errNo: errno];
}
return true;
}
- (void)unlock
{
if (!of_rmutex_unlock(&_rmutex))
@throw [OFUnlockFailedException exceptionWithLock: self
errNo: errno];
}
- (OFString *)description
{
if (_name == nil)
return super.description;
return [OFString stringWithFormat: @"<%@: %@>", self.className, _name];
}
@end
|
|
|
>
>
|
|
>
>
|
|
>
>
|
|
|
>
>
|
|
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) != 0) {
Class c = self.class;
[self release];
@throw [OFInitializationFailedException exceptionWithClass: c];
}
_initialized = true;
return self;
}
- (void)dealloc
{
if (_initialized) {
int error = of_rmutex_free(&_rmutex);
if (error != 0) {
OF_ENSURE(error == EBUSY);
@throw [OFStillLockedException exceptionWithLock: self];
}
}
[_name release];
[super dealloc];
}
- (void)lock
{
int error = of_rmutex_lock(&_rmutex);
if (error != 0)
@throw [OFLockFailedException exceptionWithLock: self
errNo: error];
}
- (bool)tryLock
{
int error = of_rmutex_trylock(&_rmutex);
if (error != 0) {
if (error == EBUSY)
return false;
else
@throw [OFLockFailedException exceptionWithLock: self
errNo: error];
}
return true;
}
- (void)unlock
{
int error = of_rmutex_unlock(&_rmutex);
if (error != 0)
@throw [OFUnlockFailedException exceptionWithLock: self
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
|
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));
# 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));
# endif
}
return page;
}
}
|
|
|
|
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) == 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;
}
}
|
︙ | | | ︙ | |
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));
if (of_tlskey_get(firstPageKey) == NULL)
OF_ENSURE(of_tlskey_set(firstPageKey, page));
# endif
return page;
}
static void
removePageIfEmpty(struct page *page)
|
|
|
|
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) == 0);
if (of_tlskey_get(firstPageKey) == NULL)
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
|
# 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));
if (of_tlskey_get(lastPageKey) == page)
OF_ENSURE(of_tlskey_set(lastPageKey, page->previous));
# endif
free(page);
}
static void *
allocateMemory(struct page *page, size_t bytes)
|
|
|
|
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) == 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)
|
︙ | | | ︙ | |
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
|
#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) || !of_tlskey_new(&lastPageKey) ||
!of_tlskey_new(&preallocatedPagesKey) ||
!of_tlskey_new(&numPreallocatedPagesKey))
@throw [OFInitializationFailedException
exceptionWithClass: self];
}
#endif
+ (void)preallocateUnswappableMemoryWithSize: (size_t)size
{
|
>
|
|
|
|
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 ||
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
|
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);
# 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);
# endif
#else
@throw [OFNotImplementedException exceptionWithSelector: _cmd
object: self];
#endif
}
|
|
|
|
|
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_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
}
|
︙ | | | ︙ | |
Modified src/OFString+JSONParsing.m
from [57caefd874]
to [87dbebe87e].
︙ | | | ︙ | |
27
28
29
30
31
32
33
34
35
36
37
38
39
40
|
#import "OFString+JSONParsing.h"
#import "OFArray.h"
#import "OFDictionary.h"
#import "OFNumber.h"
#import "OFNull.h"
#import "OFInvalidJSONException.h"
int _OFString_JSONParsing_reference;
static id nextObject(const char **pointer, const char *stop, size_t *line,
size_t depthLimit);
static void
|
>
>
>
>
|
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
|
#import "OFString+JSONParsing.h"
#import "OFArray.h"
#import "OFDictionary.h"
#import "OFNumber.h"
#import "OFNull.h"
#import "OFInvalidJSONException.h"
#ifndef INFINITY
# define INFINITY __builtin_inf()
#endif
int _OFString_JSONParsing_reference;
static id nextObject(const char **pointer, const char *stop, size_t *line,
size_t depthLimit);
static void
|
︙ | | | ︙ | |
Modified src/OFString.m
from [8c96d0cf6e]
to [77195aa3b1].
︙ | | | ︙ | |
72
73
74
75
76
77
78
79
80
81
82
83
84
85
|
# define strtod __strtod
#endif
#ifdef OF_AMIGAOS_M68K
/* libnix has strtod, but not strtof */
# define strtof strtod
#endif
static struct {
Class isa;
} placeholder;
#if defined(HAVE_STRTOF_L) || defined(HAVE_STRTOD_L)
static locale_t cLocale;
|
>
>
>
>
|
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
|
# define strtod __strtod
#endif
#ifdef OF_AMIGAOS_M68K
/* libnix has strtod, but not strtof */
# define strtof strtod
#endif
#ifndef INFINITY
# define INFINITY __builtin_inf()
#endif
static struct {
Class isa;
} placeholder;
#if defined(HAVE_STRTOF_L) || defined(HAVE_STRTOD_L)
static locale_t cLocale;
|
︙ | | | ︙ | |
Modified src/OFThread.m
from [fe4bfba4ee]
to [7d209d5958].
︙ | | | ︙ | |
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))
@throw [OFInitializationFailedException
exceptionWithClass: thread.class];
#ifndef OF_OBJFW_RUNTIME
thread->_pool = objc_autoreleasePoolPush();
#endif
|
|
|
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) != 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
|
# endif
+ (void)initialize
{
if (self != [OFThread class])
return;
if (!of_tlskey_new(&threadSelfKey))
@throw [OFInitializationFailedException
exceptionWithClass: self];
}
+ (instancetype)thread
{
return [[[self alloc] init] autorelease];
|
|
|
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) != 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
|
+ (void)of_createMainThread
{
mainThread = [[OFThread alloc] init];
mainThread->_thread = of_thread_current();
mainThread->_running = OF_THREAD_RUNNING;
if (!of_tlskey_set(threadSelfKey, mainThread))
@throw [OFInitializationFailedException
exceptionWithClass: self];
}
- (instancetype)init
{
self = [super init];
@try {
if (!of_thread_attr_init(&_attr))
@throw [OFInitializationFailedException
exceptionWithClass: self.class];
} @catch (id e) {
[self release];
@throw e;
}
|
|
|
|
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) != 0)
@throw [OFInitializationFailedException
exceptionWithClass: self];
}
- (instancetype)init
{
self = [super init];
@try {
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
|
[_DNSResolver release];
_DNSResolver = nil;
# endif
}
- (void)start
{
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,
&_attr)) {
[self release];
@throw [OFThreadStartFailedException
exceptionWithThread: self
errNo: errno];
}
}
- (id)join
{
if (_running == OF_THREAD_NOT_RUNNING)
@throw [OFThreadJoinFailedException
exceptionWithThread: self
errNo: EINVAL];
if (!of_thread_join(_thread))
@throw [OFThreadJoinFailedException exceptionWithThread: self
errNo: errno];
_running = OF_THREAD_NOT_RUNNING;
return _returnValue;
}
- (id)copy
|
>
>
|
|
<
|
>
>
|
|
|
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 ((error = of_thread_new(&_thread, [_name cStringWithEncoding:
[OFLocale encoding]], callMain, self, &_attr)) != 0) {
[self release];
@throw [OFThreadStartFailedException
exceptionWithThread: self
errNo: error];
}
}
- (id)join
{
int error;
if (_running == OF_THREAD_NOT_RUNNING)
@throw [OFThreadJoinFailedException
exceptionWithThread: self
errNo: EINVAL];
if ((error = of_thread_join(_thread)) != 0)
@throw [OFThreadJoinFailedException exceptionWithThread: self
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
|
} *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,
of_mutex_t *mutex, of_time_interval_t timeout);
#ifdef OF_AMIGAOS
extern bool 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,
of_mutex_t *mutex, of_time_interval_t timeout, ULONG *signalMask);
#endif
extern bool of_condition_free(of_condition_t *condition);
#ifdef __cplusplus
}
#endif
|
|
|
|
|
|
|
|
|
|
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 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 int of_condition_wait_or_signal(of_condition_t *condition,
of_mutex_t *mutex, ULONG *signalMask);
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 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
|
#endif
#if !defined(HAVE_STRERROR_R) && defined(OF_HAVE_THREADS)
static of_mutex_t mutex;
OF_CONSTRUCTOR()
{
if (!of_mutex_new(&mutex))
@throw [OFInitializationFailedException exception];
}
#endif
OFString *
of_strerror(int errNo)
{
|
|
|
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) != 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
|
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))
@throw [OFLockFailedException exception];
@try {
# endif
ret = [OFString
stringWithCString: strerror(errNo)
encoding: [OFLocale encoding]];
# ifdef OF_HAVE_THREADS
} @finally {
if (!of_mutex_unlock(&mutex))
@throw [OFUnlockFailedException exception];
}
# endif
#endif
return ret;
}
|
|
|
|
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) != 0)
@throw [OFLockFailedException exception];
@try {
# endif
ret = [OFString
stringWithCString: strerror(errNo)
encoding: [OFLocale encoding]];
# ifdef OF_HAVE_THREADS
} @finally {
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
|
* 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 "platform.h"
#if !defined(OF_HAVE_THREADS) || \
(!defined(OF_HAVE_PTHREADS) && !defined(OF_WINDOWS) && !defined(OF_AMIGAOS))
# error No mutexes available!
#endif
|
>
>
|
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
|
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);
#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
of_spinlock_new(of_spinlock_t *spinlock)
{
#if defined(OF_HAVE_ATOMIC_OPS)
*spinlock = 0;
return true;
#elif defined(OF_HAVE_PTHREAD_SPINLOCKS)
return (pthread_spin_init(spinlock, 0) == 0);
#else
return of_mutex_new(spinlock);
#endif
}
static OF_INLINE bool
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 false;
#elif defined(OF_HAVE_PTHREAD_SPINLOCKS)
return (pthread_spin_trylock(spinlock) == 0);
#else
return of_mutex_trylock(spinlock);
#endif
}
static OF_INLINE bool
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;
while (!of_spinlock_trylock(spinlock))
of_thread_yield();
return true;
#elif defined(OF_HAVE_PTHREAD_SPINLOCKS)
return (pthread_spin_lock(spinlock) == 0);
#else
return of_mutex_lock(spinlock);
#endif
}
static OF_INLINE bool
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;
#elif defined(OF_HAVE_PTHREAD_SPINLOCKS)
return (pthread_spin_unlock(spinlock) == 0);
#else
return of_mutex_unlock(spinlock);
#endif
}
static OF_INLINE bool
of_spinlock_free(of_spinlock_t *spinlock)
{
#if defined(OF_HAVE_ATOMIC_OPS)
return true;
#elif defined(OF_HAVE_PTHREAD_SPINLOCKS)
return (pthread_spin_destroy(spinlock) == 0);
#else
return of_mutex_free(spinlock);
#endif
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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 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 int
of_spinlock_new(of_spinlock_t *spinlock)
{
#if defined(OF_HAVE_ATOMIC_OPS)
*spinlock = 0;
return 0;
#elif defined(OF_HAVE_PTHREAD_SPINLOCKS)
return pthread_spin_init(spinlock, 0);
#else
return of_mutex_new(spinlock);
#endif
}
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 0;
}
return EBUSY;
#elif defined(OF_HAVE_PTHREAD_SPINLOCKS)
return pthread_spin_trylock(spinlock);
#else
return of_mutex_trylock(spinlock);
#endif
}
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) == 0)
return 0;
while (of_spinlock_trylock(spinlock) == EBUSY)
of_thread_yield();
return 0;
#elif defined(OF_HAVE_PTHREAD_SPINLOCKS)
return pthread_spin_lock(spinlock);
#else
return of_mutex_lock(spinlock);
#endif
}
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 ? 0 : EINVAL);
#elif defined(OF_HAVE_PTHREAD_SPINLOCKS)
return pthread_spin_unlock(spinlock);
#else
return of_mutex_unlock(spinlock);
#endif
}
static OF_INLINE int
of_spinlock_free(of_spinlock_t *spinlock)
{
#if defined(OF_HAVE_ATOMIC_OPS)
return 0;
#elif defined(OF_HAVE_PTHREAD_SPINLOCKS)
return pthread_spin_destroy(spinlock);
#else
return of_mutex_free(spinlock);
#endif
}
|
Modified src/objfw-defs.h.in
from [4530c4317b]
to [cb58f5fac1].
1
2
3
4
5
6
7
8
9
10
|
#undef INFINITY
#undef LLONG_MAX
#undef LLONG_MIN
#undef OF_APPLE_RUNTIME
#undef OF_BIG_ENDIAN
#undef OF_FLOAT_BIG_ENDIAN
#undef OF_HAVE_ATOMIC_BUILTINS
#undef OF_HAVE_ATOMIC_OPS
#undef OF_HAVE_BUILTIN_BSWAP16
#undef OF_HAVE_BUILTIN_BSWAP32
|
<
<
<
|
1
2
3
4
5
6
7
|
#undef OF_APPLE_RUNTIME
#undef OF_BIG_ENDIAN
#undef OF_FLOAT_BIG_ENDIAN
#undef OF_HAVE_ATOMIC_BUILTINS
#undef OF_HAVE_ATOMIC_OPS
#undef OF_HAVE_BUILTIN_BSWAP16
#undef OF_HAVE_BUILTIN_BSWAP32
|
︙ | | | ︙ | |
44
45
46
47
48
49
50
51
52
53
54
|
#undef OF_HAVE___THREAD
#undef OF_NINTENDO_3DS
#undef OF_NINTENDO_DS
#undef OF_NO_SHARED
#undef OF_OBJFW_RUNTIME
#undef OF_UNIVERSAL
#undef OF_WII
#undef SIZE_MAX
#undef UINTPTR_MAX
#undef ULLONG_MAX
#undef __have_longlong64
|
<
<
<
<
|
41
42
43
44
45
46
47
|
#undef OF_HAVE___THREAD
#undef OF_NINTENDO_3DS
#undef OF_NINTENDO_DS
#undef OF_NO_SHARED
#undef OF_OBJFW_RUNTIME
#undef OF_UNIVERSAL
#undef OF_WII
|
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
|
#include <proto/exec.h>
#include <devices/timer.h>
#ifndef OF_AMIGAOS4
# include <clib/alib_protos.h>
#endif
bool
of_condition_new(of_condition_t *condition)
{
condition->waitingTasks = NULL;
return true;
}
bool
of_condition_signal(of_condition_t *condition)
{
Forbid();
@try {
if (condition->waitingTasks == NULL)
return true;
Signal(condition->waitingTasks->task,
(1ul << condition->waitingTasks->sigBit));
condition->waitingTasks = condition->waitingTasks->next;
} @finally {
Permit();
}
return true;
}
bool
of_condition_broadcast(of_condition_t *condition)
{
Forbid();
@try {
if (condition->waitingTasks == NULL)
return true;
while (condition->waitingTasks != NULL) {
Signal(condition->waitingTasks->task,
(1ul << condition->waitingTasks->sigBit));
condition->waitingTasks = condition->waitingTasks->next;
}
} @finally {
Permit();
}
return true;
}
bool
of_condition_wait(of_condition_t *condition, of_mutex_t *mutex)
{
ULONG signalMask = 0;
return of_condition_wait_or_signal(condition, mutex, &signalMask);
}
bool
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;
ULONG mask;
if (waitingTask.sigBit == -1) {
errno = EAGAIN;
return false;
}
Forbid();
if (!of_mutex_unlock(mutex)) {
FreeSignal(waitingTask.sigBit);
return false;
}
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 {
/*
* This should not happen - it means something interrupted the
* Wait(), so the best we can do is return EINTR.
*/
ret = false;
errno = EINTR;
}
FreeSignal(waitingTask.sigBit);
Permit();
return ret;
}
bool
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
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)
};
|
<
>
|
<
>
|
|
<
>
|
|
<
>
<
>
|
|
<
|
<
|
|
|
|
<
|
<
|
<
>
<
>
|
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
int
of_condition_new(of_condition_t *condition)
{
condition->waitingTasks = NULL;
return 0;
}
int
of_condition_signal(of_condition_t *condition)
{
Forbid();
@try {
if (condition->waitingTasks == NULL)
return 0;
Signal(condition->waitingTasks->task,
(1ul << condition->waitingTasks->sigBit));
condition->waitingTasks = condition->waitingTasks->next;
} @finally {
Permit();
}
return 0;
}
int
of_condition_broadcast(of_condition_t *condition)
{
Forbid();
@try {
if (condition->waitingTasks == NULL)
return 0;
while (condition->waitingTasks != NULL) {
Signal(condition->waitingTasks->task,
(1ul << condition->waitingTasks->sigBit));
condition->waitingTasks = condition->waitingTasks->next;
}
} @finally {
Permit();
}
return 0;
}
int
of_condition_wait(of_condition_t *condition, of_mutex_t *mutex)
{
ULONG signalMask = 0;
return of_condition_wait_or_signal(condition, mutex, &signalMask);
}
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)
};
int error = 0;
ULONG mask;
if (waitingTask.sigBit == -1)
return EAGAIN;
Forbid();
if ((error = of_mutex_unlock(mutex)) != 0) {
FreeSignal(waitingTask.sigBit);
return error;
}
waitingTask.next = condition->waitingTasks;
condition->waitingTasks = &waitingTask;
mask = Wait((1ul << waitingTask.sigBit) | *signalMask);
if (mask & (1ul << waitingTask.sigBit) || (*signalMask &= mask))
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.
*/
error = EINTR;
FreeSignal(waitingTask.sigBit);
Permit();
return error;
}
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);
}
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
|
#else
.tr_time = {
.tv_sec = (ULONG)timeout,
.tv_micro = (timeout - request.tr_time.tv_sec) * 1000000
#endif
}
};
ULONG mask;
bool ret;
NewList(&port.mp_MsgList);
if (waitingTask.sigBit == -1 || port.mp_SigBit == -1) {
errno = EAGAIN;
goto fail;
}
if (OpenDevice("timer.device", UNIT_MICROHZ,
(struct IORequest *)&request, 0) != 0) {
errno = EAGAIN;
goto fail;
}
Forbid();
if (!of_mutex_unlock(mutex)) {
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)) {
ret = false;
errno = 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;
}
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;
}
bool
of_condition_free(of_condition_t *condition)
{
Forbid();
@try {
if (condition->waitingTasks != NULL) {
errno = EBUSY;
return false;
}
} @finally {
Permit();
}
return true;
}
|
>
<
|
|
|
|
|
<
|
|
<
|
<
<
<
<
<
<
|
<
>
|
<
|
<
|
|
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;
NewList(&port.mp_MsgList);
if (waitingTask.sigBit == -1 || port.mp_SigBit == -1) {
error = EAGAIN;
goto fail;
}
if (OpenDevice("timer.device", UNIT_MICROHZ,
(struct IORequest *)&request, 0) != 0) {
error = EAGAIN;
goto fail;
}
Forbid();
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))
error = of_mutex_lock(mutex);
else if (mask & (1ul << port.mp_SigBit))
error = ETIMEDOUT;
else
/*
* This should not happen - it means something interrupted the
* Wait(), so the best we can do is return 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();
fail:
if (waitingTask.sigBit != -1)
FreeSignal(waitingTask.sigBit);
if (port.mp_SigBit != -1)
FreeSignal(port.mp_SigBit);
return error;
}
int
of_condition_free(of_condition_t *condition)
{
Forbid();
@try {
if (condition->waitingTasks != NULL)
return EBUSY;
} @finally {
Permit();
}
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
|
#include <errno.h>
#import "mutex.h"
#include <proto/exec.h>
bool
of_mutex_new(of_mutex_t *mutex)
{
InitSemaphore(mutex);
return true;
}
bool
of_mutex_lock(of_mutex_t *mutex)
{
ObtainSemaphore(mutex);
return true;
}
bool
of_mutex_trylock(of_mutex_t *mutex)
{
if (!AttemptSemaphore(mutex)) {
errno = EBUSY;
return false;
}
return true;
}
bool
of_mutex_unlock(of_mutex_t *mutex)
{
ReleaseSemaphore(mutex);
return true;
}
bool
of_mutex_free(of_mutex_t *mutex)
{
return true;
}
bool
of_rmutex_new(of_rmutex_t *rmutex)
{
return of_mutex_new(rmutex);
}
bool
of_rmutex_lock(of_rmutex_t *rmutex)
{
return of_mutex_lock(rmutex);
}
bool
of_rmutex_trylock(of_rmutex_t *rmutex)
{
return of_mutex_trylock(rmutex);
}
bool
of_rmutex_unlock(of_rmutex_t *rmutex)
{
return of_mutex_unlock(rmutex);
}
bool
of_rmutex_free(of_rmutex_t *rmutex)
{
return of_mutex_free(rmutex);
}
|
<
>
|
<
>
|
<
>
|
<
|
|
<
|
<
>
|
<
>
|
<
>
<
>
<
>
<
>
<
>
|
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>
int
of_mutex_new(of_mutex_t *mutex)
{
InitSemaphore(mutex);
return 0;
}
int
of_mutex_lock(of_mutex_t *mutex)
{
ObtainSemaphore(mutex);
return 0;
}
int
of_mutex_trylock(of_mutex_t *mutex)
{
if (!AttemptSemaphore(mutex))
return EBUSY;
return 0;
}
int
of_mutex_unlock(of_mutex_t *mutex)
{
ReleaseSemaphore(mutex);
return 0;
}
int
of_mutex_free(of_mutex_t *mutex)
{
return 0;
}
int
of_rmutex_new(of_rmutex_t *rmutex)
{
return of_mutex_new(rmutex);
}
int
of_rmutex_lock(of_rmutex_t *rmutex)
{
return of_mutex_lock(rmutex);
}
int
of_rmutex_trylock(of_rmutex_t *rmutex)
{
return of_mutex_trylock(rmutex);
}
int
of_rmutex_unlock(of_rmutex_t *rmutex)
{
return of_mutex_unlock(rmutex);
}
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
|
#ifndef OF_MORPHOS
extern void of_tlskey_thread_exited(void);
#endif
static of_tlskey_t threadKey;
OF_CONSTRUCTOR()
{
OF_ENSURE(of_tlskey_new(&threadKey));
}
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));
thread->function(thread->object);
ObtainSemaphore(&thread->semaphore);
@try {
thread->done = true;
|
|
|
|
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) == 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;
|
︙ | | | ︙ | |
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
|
ReleaseSemaphore(&thread->semaphore);
}
if (detached)
free(thread);
}
bool
of_thread_attr_init(of_thread_attr_t *attr)
{
attr->priority = 0;
attr->stackSize = 0;
return true;
}
bool
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) {
errno = ENOMEM;
return false;
}
@try {
(*thread)->function = function;
(*thread)->object = object;
InitSemaphore(&(*thread)->semaphore);
tags = [[OFMutableData alloc]
|
<
>
|
<
>
|
<
|
<
|
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);
}
int
of_thread_attr_init(of_thread_attr_t *attr)
{
attr->priority = 0;
attr->stackSize = 0;
return 0;
}
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)
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
|
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) {
errno = EINVAL;
return false;
}
/*
* -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))
|
|
<
|
<
|
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)
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
|
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;
}
} @catch (id e) {
free(*thread);
@throw e;
} @finally {
[tags release];
}
return true;
}
of_thread_t
of_thread_current(void)
{
return of_tlskey_get(threadKey);
}
bool
of_thread_join(of_thread_t thread)
{
ObtainSemaphore(&thread->semaphore);
if (thread->done) {
ReleaseSemaphore(&thread->semaphore);
free(thread);
return true;
}
@try {
if (thread->detached || thread->joinTask != NULL) {
errno = EINVAL;
return false;
}
if ((thread->joinSigBit = AllocSignal(-1)) == -1) {
errno = EAGAIN;
return false;
}
thread->joinTask = FindTask(NULL);
} @finally {
ReleaseSemaphore(&thread->semaphore);
}
Wait(1ul << thread->joinSigBit);
FreeSignal(thread->joinSigBit);
assert(thread->done);
free(thread);
return true;
}
bool
of_thread_detach(of_thread_t thread)
{
ObtainSemaphore(&thread->semaphore);
if (thread->done)
free(thread);
else
thread->detached = true;
ReleaseSemaphore(&thread->semaphore);
return true;
}
void
of_thread_set_name(const char *name)
{
}
|
<
|
|
<
>
|
|
<
|
|
<
|
<
|
<
|
<
>
|
|
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);
return EAGAIN;
}
} @catch (id e) {
free(*thread);
@throw e;
} @finally {
[tags release];
}
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);
if (thread->done) {
ReleaseSemaphore(&thread->semaphore);
free(thread);
return 0;
}
@try {
if (thread->detached || thread->joinTask != NULL)
return EINVAL;
if ((thread->joinSigBit = AllocSignal(-1)) == -1)
return EAGAIN;
thread->joinTask = FindTask(NULL);
} @finally {
ReleaseSemaphore(&thread->semaphore);
}
Wait(1ul << thread->joinSigBit);
FreeSignal(thread->joinSigBit);
assert(thread->done);
free(thread);
return 0;
}
int
of_thread_detach(of_thread_t thread)
{
ObtainSemaphore(&thread->semaphore);
if (thread->done)
free(thread);
else
thread->detached = true;
ReleaseSemaphore(&thread->semaphore);
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
|
{
if (!semaphoreInitialized) {
InitSemaphore(&semaphore);
semaphoreInitialized = true;
}
}
bool
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;
(*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;
}
bool
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;
}
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
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;
}
void
of_tlskey_thread_exited(void)
{
ObtainSemaphore(&semaphore);
@try {
|
<
>
|
|
<
>
|
<
>
<
<
|
|
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;
}
}
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 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 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;
if (firstKey == key)
firstKey = key->next;
if (lastKey == key)
lastKey = key->previous;
objc_hashtable_free(key->table);
free(key);
} @finally {
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 {
|
︙ | | | ︙ | |
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
|
* file.
*/
#include "config.h"
#import "tlskey.h"
bool
of_tlskey_new(of_tlskey_t *key)
{
return ((*key = TLSAllocA(NULL)) != TLS_INVALID_INDEX);
}
bool
of_tlskey_free(of_tlskey_t key)
{
return TLSFree(key);
}
|
<
>
|
|
>
>
>
>
|
>
|
|
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"
int
of_tlskey_new(of_tlskey_t *key)
{
*key = TLSAllocA(NULL);
if (*key == TLS_INVALID_INDEX)
return EAGAIN;
return 0;
}
int
of_tlskey_free(of_tlskey_t 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
|
* file.
*/
#include "config.h"
#import "condition.h"
bool
of_condition_new(of_condition_t *condition)
{
return (pthread_cond_init(condition, NULL) == 0);
}
bool
of_condition_signal(of_condition_t *condition)
{
return (pthread_cond_signal(condition) == 0);
}
bool
of_condition_broadcast(of_condition_t *condition)
{
return (pthread_cond_broadcast(condition) == 0);
}
bool
of_condition_wait(of_condition_t *condition, of_mutex_t *mutex)
{
return (pthread_cond_wait(condition, mutex) == 0);
}
bool
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);
}
bool
of_condition_free(of_condition_t *condition)
{
return (pthread_cond_destroy(condition) == 0);
}
|
<
>
|
<
>
|
<
>
|
<
>
|
<
>
|
<
>
|
|
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"
int
of_condition_new(of_condition_t *condition)
{
return pthread_cond_init(condition, NULL);
}
int
of_condition_signal(of_condition_t *condition)
{
return pthread_cond_signal(condition);
}
int
of_condition_broadcast(of_condition_t *condition)
{
return pthread_cond_broadcast(condition);
}
int
of_condition_wait(of_condition_t *condition, of_mutex_t *mutex)
{
return pthread_cond_wait(condition, mutex);
}
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);
}
int
of_condition_free(of_condition_t *condition)
{
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
|
* file.
*/
#include "config.h"
#import "mutex.h"
bool
of_mutex_new(of_mutex_t *mutex)
{
return (pthread_mutex_init(mutex, NULL) == 0);
}
bool
of_mutex_lock(of_mutex_t *mutex)
{
return (pthread_mutex_lock(mutex) == 0);
}
bool
of_mutex_trylock(of_mutex_t *mutex)
{
return (pthread_mutex_trylock(mutex) == 0);
}
bool
of_mutex_unlock(of_mutex_t *mutex)
{
return (pthread_mutex_unlock(mutex) == 0);
}
bool
of_mutex_free(of_mutex_t *mutex)
{
return (pthread_mutex_destroy(mutex) == 0);
}
#ifdef OF_HAVE_RECURSIVE_PTHREAD_MUTEXES
bool
of_rmutex_new(of_rmutex_t *rmutex)
{
pthread_mutexattr_t attr;
if (pthread_mutexattr_init(&attr) != 0)
return false;
if (pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE) != 0)
return false;
if (pthread_mutex_init(rmutex, &attr) != 0)
return false;
if (pthread_mutexattr_destroy(&attr) != 0)
return false;
return true;
}
bool
of_rmutex_lock(of_rmutex_t *rmutex)
{
return of_mutex_lock(rmutex);
}
bool
of_rmutex_trylock(of_rmutex_t *rmutex)
{
return of_mutex_trylock(rmutex);
}
bool
of_rmutex_unlock(of_rmutex_t *rmutex)
{
return of_mutex_unlock(rmutex);
}
bool
of_rmutex_free(of_rmutex_t *rmutex)
{
return of_mutex_free(rmutex);
}
#else
bool
of_rmutex_new(of_rmutex_t *rmutex)
{
if (!of_mutex_new(&rmutex->mutex))
return false;
if (!of_tlskey_new(&rmutex->count))
return false;
return true;
}
bool
of_rmutex_lock(of_rmutex_t *rmutex)
{
uintptr_t count = (uintptr_t)of_tlskey_get(rmutex->count);
if (count > 0) {
if (!of_tlskey_set(rmutex->count, (void *)(count + 1)))
return false;
return true;
}
if (!of_mutex_lock(&rmutex->mutex))
return false;
if (!of_tlskey_set(rmutex->count, (void *)1)) {
of_mutex_unlock(&rmutex->mutex);
return false;
}
return true;
}
bool
of_rmutex_trylock(of_rmutex_t *rmutex)
{
uintptr_t count = (uintptr_t)of_tlskey_get(rmutex->count);
if (count > 0) {
if (!of_tlskey_set(rmutex->count, (void *)(count + 1)))
return false;
return true;
}
if (!of_mutex_trylock(&rmutex->mutex))
return false;
if (!of_tlskey_set(rmutex->count, (void *)1)) {
of_mutex_unlock(&rmutex->mutex);
return false;
}
return true;
}
bool
of_rmutex_unlock(of_rmutex_t *rmutex)
{
uintptr_t count = (uintptr_t)of_tlskey_get(rmutex->count);
if (count > 1) {
if (!of_tlskey_set(rmutex->count, (void *)(count - 1)))
return false;
return true;
}
if (!of_tlskey_set(rmutex->count, (void *)0))
return false;
if (!of_mutex_unlock(&rmutex->mutex))
return false;
return true;
}
bool
of_rmutex_free(of_rmutex_t *rmutex)
{
if (!of_mutex_free(&rmutex->mutex))
return false;
if (!of_tlskey_free(rmutex->count))
return false;
return true;
}
#endif
|
<
>
|
<
>
|
<
>
|
<
>
|
<
>
|
<
>
>
|
|
|
>
|
|
|
|
|
|
<
>
<
>
<
>
<
>
<
>
>
>
|
|
|
|
|
<
>
>
|
>
|
|
|
|
|
|
|
<
>
>
|
>
|
|
|
|
|
|
|
<
>
>
|
>
|
|
|
|
|
|
|
<
>
>
>
|
|
|
|
|
|
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"
int
of_mutex_new(of_mutex_t *mutex)
{
return pthread_mutex_init(mutex, NULL);
}
int
of_mutex_lock(of_mutex_t *mutex)
{
return pthread_mutex_lock(mutex);
}
int
of_mutex_trylock(of_mutex_t *mutex)
{
return pthread_mutex_trylock(mutex);
}
int
of_mutex_unlock(of_mutex_t *mutex)
{
return pthread_mutex_unlock(mutex);
}
int
of_mutex_free(of_mutex_t *mutex)
{
return pthread_mutex_destroy(mutex);
}
#ifdef OF_HAVE_RECURSIVE_PTHREAD_MUTEXES
int
of_rmutex_new(of_rmutex_t *rmutex)
{
int error;
pthread_mutexattr_t attr;
if ((error = pthread_mutexattr_init(&attr)) != 0)
return error;
if ((error = pthread_mutexattr_settype(&attr,
PTHREAD_MUTEX_RECURSIVE)) != 0)
return error;
if ((error = pthread_mutex_init(rmutex, &attr)) != 0)
return error;
if ((error = pthread_mutexattr_destroy(&attr)) != 0)
return error;
return 0;
}
int
of_rmutex_lock(of_rmutex_t *rmutex)
{
return of_mutex_lock(rmutex);
}
int
of_rmutex_trylock(of_rmutex_t *rmutex)
{
return of_mutex_trylock(rmutex);
}
int
of_rmutex_unlock(of_rmutex_t *rmutex)
{
return of_mutex_unlock(rmutex);
}
int
of_rmutex_free(of_rmutex_t *rmutex)
{
return of_mutex_free(rmutex);
}
#else
int
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
|
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
|
ctx->function(ctx->object);
pthread_cleanup_pop(1);
return NULL;
}
bool
of_thread_attr_init(of_thread_attr_t *attr)
{
pthread_attr_t pattr;
if (pthread_attr_init(&pattr) != 0)
return false;
@try {
attr->priority = 0;
if (pthread_attr_getstacksize(&pattr, &attr->stackSize) != 0)
return false;
} @finally {
pthread_attr_destroy(&pattr);
}
return true;
}
bool
of_thread_new(of_thread_t *thread, const char *name, void (*function)(id),
id object, const of_thread_attr_t *attr)
{
bool ret;
pthread_attr_t pattr;
if (pthread_attr_init(&pattr) != 0)
return false;
@try {
struct thread_ctx *ctx;
if (attr != NULL) {
struct sched_param param;
if (attr->priority < -1 || attr->priority > 1) {
errno = EINVAL;
return false;
}
#ifdef HAVE_PTHREAD_ATTR_SETINHERITSCHED
if (pthread_attr_setinheritsched(&pattr,
PTHREAD_EXPLICIT_SCHED) != 0)
return false;
#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 (attr->stackSize > 0) {
if (pthread_attr_setstacksize(&pattr,
attr->stackSize) != 0)
return false;
}
}
if ((ctx = malloc(sizeof(*ctx))) == NULL) {
errno = ENOMEM;
return false;
}
ctx->function = function;
ctx->object = object;
ctx->name = name;
ret = (pthread_create(thread, &pattr,
functionWrapper, ctx) == 0);
} @finally {
pthread_attr_destroy(&pattr);
}
return ret;
}
bool
of_thread_join(of_thread_t thread)
{
void *ret;
return (pthread_join(thread, &ret) == 0);
}
bool
of_thread_detach(of_thread_t thread)
{
return (pthread_detach(thread) == 0);
}
void
of_thread_set_name(const char *name)
{
#if defined(OF_HAIKU)
rename_thread(find_thread(NULL), name);
|
<
>
>
|
|
<
|
<
|
|
<
|
|
<
|
<
>
<
>
|
|
|
<
|
|
<
|
|
|
|
>
|
|
|
|
|
<
|
<
|
<
|
<
>
|
<
>
|
|
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;
}
int
of_thread_attr_init(of_thread_attr_t *attr)
{
int error;
pthread_attr_t pattr;
if ((error = pthread_attr_init(&pattr)) != 0)
return error;
attr->priority = 0;
error = pthread_attr_getstacksize(&pattr, &attr->stackSize);
pthread_attr_destroy(&pattr);
return error;
}
int
of_thread_new(of_thread_t *thread, const char *name, void (*function)(id),
id object, const of_thread_attr_t *attr)
{
int error = 0;
pthread_attr_t pattr;
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)
return EINVAL;
#ifdef HAVE_PTHREAD_ATTR_SETINHERITSCHED
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 ((error = pthread_attr_setschedparam(&pattr,
¶m)) != 0)
return error;
if (attr->stackSize > 0) {
if ((error = pthread_attr_setstacksize(&pattr,
attr->stackSize)) != 0)
return error;
}
}
if ((ctx = malloc(sizeof(*ctx))) == NULL)
return ENOMEM;
ctx->function = function;
ctx->object = object;
ctx->name = name;
error = pthread_create(thread, &pattr, functionWrapper, ctx);
} @finally {
pthread_attr_destroy(&pattr);
}
return error;
}
int
of_thread_join(of_thread_t thread)
{
void *ret;
return pthread_join(thread, &ret);
}
int
of_thread_detach(of_thread_t thread)
{
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
|
* file.
*/
#include "config.h"
#import "tlskey.h"
bool
of_tlskey_new(of_tlskey_t *key)
{
return (pthread_key_create(key, NULL) == 0);
}
bool
of_tlskey_free(of_tlskey_t key)
{
return (pthread_key_delete(key) == 0);
}
|
<
>
|
<
>
|
|
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"
int
of_tlskey_new(of_tlskey_t *key)
{
return pthread_key_create(key, NULL);
}
int
of_tlskey_free(of_tlskey_t key)
{
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
|
#include <errno.h>
#import "condition.h"
#include <windows.h>
bool
of_condition_new(of_condition_t *condition)
{
condition->count = 0;
if ((condition->event = CreateEvent(NULL, FALSE, 0, NULL)) == NULL) {
errno = EAGAIN;
return false;
}
return true;
}
bool
of_condition_signal(of_condition_t *condition)
{
if (!SetEvent(condition->event)) {
switch (GetLastError()) {
case ERROR_INVALID_HANDLE:
errno = EINVAL;
return false;
default:
OF_ENSURE(0);
}
}
return true;
}
bool
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;
default:
OF_ENSURE(0);
}
}
}
return true;
}
bool
of_condition_wait(of_condition_t *condition, of_mutex_t *mutex)
{
DWORD status;
if (!of_mutex_unlock(mutex))
return false;
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;
default:
OF_ENSURE(0);
}
default:
OF_ENSURE(0);
}
}
bool
of_condition_timed_wait(of_condition_t *condition, of_mutex_t *mutex,
of_time_interval_t timeout)
{
DWORD status;
if (!of_mutex_unlock(mutex))
return false;
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;
case WAIT_FAILED:
switch (GetLastError()) {
case ERROR_INVALID_HANDLE:
errno = EINVAL;
return false;
default:
OF_ENSURE(0);
}
default:
OF_ENSURE(0);
}
}
bool
of_condition_free(of_condition_t *condition)
{
if (condition->count != 0) {
errno = EBUSY;
return false;
}
return CloseHandle(condition->event);
}
|
<
>
|
<
|
|
<
|
<
>
<
|
|
<
>
<
|
|
<
>
>
|
|
<
|
<
>
>
|
|
<
|
<
|
<
>
|
<
|
|
<
|
|
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>
int
of_condition_new(of_condition_t *condition)
{
condition->count = 0;
if ((condition->event = CreateEvent(NULL, FALSE, 0, NULL)) == NULL)
return EAGAIN;
return 0;
}
int
of_condition_signal(of_condition_t *condition)
{
if (!SetEvent(condition->event)) {
switch (GetLastError()) {
case ERROR_INVALID_HANDLE:
return EINVAL;
default:
OF_ENSURE(0);
}
}
return 0;
}
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:
return EINVAL;
default:
OF_ENSURE(0);
}
}
}
return 0;
}
int
of_condition_wait(of_condition_t *condition, of_mutex_t *mutex)
{
int error;
DWORD status;
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:
return EINVAL;
default:
OF_ENSURE(0);
}
default:
OF_ENSURE(0);
}
}
int
of_condition_timed_wait(of_condition_t *condition, of_mutex_t *mutex,
of_time_interval_t timeout)
{
int error;
DWORD status;
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:
return ETIMEDOUT;
case WAIT_FAILED:
switch (GetLastError()) {
case ERROR_INVALID_HANDLE:
return EINVAL;
default:
OF_ENSURE(0);
}
default:
OF_ENSURE(0);
}
}
int
of_condition_free(of_condition_t *condition)
{
if (condition->count != 0)
return EBUSY;
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
|
#include <errno.h>
#import "mutex.h"
#include <windows.h>
bool
of_mutex_new(of_mutex_t *mutex)
{
InitializeCriticalSection(mutex);
return true;
}
bool
of_mutex_lock(of_mutex_t *mutex)
{
EnterCriticalSection(mutex);
return true;
}
bool
of_mutex_trylock(of_mutex_t *mutex)
{
if (!TryEnterCriticalSection(mutex)) {
errno = EBUSY;
return false;
}
return true;
}
bool
of_mutex_unlock(of_mutex_t *mutex)
{
LeaveCriticalSection(mutex);
return true;
}
bool
of_mutex_free(of_mutex_t *mutex)
{
DeleteCriticalSection(mutex);
return true;
}
bool
of_rmutex_new(of_rmutex_t *rmutex)
{
return of_mutex_new(rmutex);
}
bool
of_rmutex_lock(of_rmutex_t *rmutex)
{
return of_mutex_lock(rmutex);
}
bool
of_rmutex_trylock(of_rmutex_t *rmutex)
{
return of_mutex_trylock(rmutex);
}
bool
of_rmutex_unlock(of_rmutex_t *rmutex)
{
return of_mutex_unlock(rmutex);
}
bool
of_rmutex_free(of_rmutex_t *rmutex)
{
return of_mutex_free(rmutex);
}
|
<
>
|
<
>
|
<
>
|
<
|
|
<
|
<
>
|
<
>
|
<
>
<
>
<
>
<
>
<
>
|
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>
int
of_mutex_new(of_mutex_t *mutex)
{
InitializeCriticalSection(mutex);
return 0;
}
int
of_mutex_lock(of_mutex_t *mutex)
{
EnterCriticalSection(mutex);
return 0;
}
int
of_mutex_trylock(of_mutex_t *mutex)
{
if (!TryEnterCriticalSection(mutex))
return EBUSY;
return 0;
}
int
of_mutex_unlock(of_mutex_t *mutex)
{
LeaveCriticalSection(mutex);
return 0;
}
int
of_mutex_free(of_mutex_t *mutex)
{
DeleteCriticalSection(mutex);
return 0;
}
int
of_rmutex_new(of_rmutex_t *rmutex)
{
return of_mutex_new(rmutex);
}
int
of_rmutex_lock(of_rmutex_t *rmutex)
{
return of_mutex_lock(rmutex);
}
int
of_rmutex_trylock(of_rmutex_t *rmutex)
{
return of_mutex_trylock(rmutex);
}
int
of_rmutex_unlock(of_rmutex_t *rmutex)
{
return of_mutex_unlock(rmutex);
}
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
|
functionWrapper(struct thread_context *context)
{
context->function(context->object);
free(context);
}
bool
of_thread_attr_init(of_thread_attr_t *attr)
{
attr->priority = 0;
attr->stackSize = 0;
return true;
}
bool
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) {
errno = EINVAL;
return false;
}
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) {
errno = ENOMEM;
return false;
}
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;
switch (GetLastError()) {
case ERROR_NOT_ENOUGH_MEMORY:
errNo = ENOMEM;
break;
case ERROR_ACCESS_DENIED:
errNo = EACCES;
break;
default:
OF_ENSURE(0);
}
free(context);
errno = errNo;
return false;
}
if (attr != NULL && attr->priority != 0)
OF_ENSURE(!SetThreadPriority(*thread, priority));
return true;
}
bool
of_thread_join(of_thread_t thread)
{
switch (WaitForSingleObject(thread, INFINITE)) {
case WAIT_OBJECT_0:
CloseHandle(thread);
return true;
case WAIT_FAILED:
switch (GetLastError()) {
case ERROR_INVALID_HANDLE:
errno = EINVAL;
return false;
default:
OF_ENSURE(0);
}
default:
OF_ENSURE(0);
}
}
bool
of_thread_detach(of_thread_t thread)
{
CloseHandle(thread);
return true;
}
void
of_thread_set_name(const char *name)
{
}
|
<
>
|
<
>
|
<
|
<
|
<
|
<
|
|
|
<
|
|
<
>
|
<
|
<
>
|
|
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);
}
int
of_thread_attr_init(of_thread_attr_t *attr)
{
attr->priority = 0;
attr->stackSize = 0;
return 0;
}
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)
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)
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 error;
switch (GetLastError()) {
case ERROR_NOT_ENOUGH_MEMORY:
error = ENOMEM;
break;
case ERROR_ACCESS_DENIED:
error = EACCES;
break;
default:
OF_ENSURE(0);
}
free(context);
return error;
}
if (attr != NULL && attr->priority != 0)
OF_ENSURE(!SetThreadPriority(*thread, priority));
return 0;
}
int
of_thread_join(of_thread_t thread)
{
switch (WaitForSingleObject(thread, INFINITE)) {
case WAIT_OBJECT_0:
CloseHandle(thread);
return 0;
case WAIT_FAILED:
switch (GetLastError()) {
case ERROR_INVALID_HANDLE:
return EINVAL;
default:
OF_ENSURE(0);
}
default:
OF_ENSURE(0);
}
}
int
of_thread_detach(of_thread_t thread)
{
CloseHandle(thread);
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
|
* file.
*/
#include "config.h"
#import "tlskey.h"
bool
of_tlskey_new(of_tlskey_t *key)
{
return ((*key = TlsAlloc()) != TLS_OUT_OF_INDEXES);
}
bool
of_tlskey_free(of_tlskey_t key)
{
return TlsFree(key);
}
|
<
>
|
|
>
>
>
>
|
>
|
|
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"
int
of_tlskey_new(of_tlskey_t *key)
{
*key = TlsAlloc();
if (*key == TLS_OUT_OF_INDEXES)
return EAGAIN;
return 0;
}
int
of_tlskey_free(of_tlskey_t key)
{
return (TlsFree(key) ? 0 : EINVAL);
}
|
Modified src/runtime/amiga-library.h
from [1e7c65ebe4]
to [65524391cb].
︙ | | | ︙ | |
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
|
void *_Nonnull);
void *(*_Nonnull __deregister_frame_info)(const void *_Nonnull);
# endif
# ifdef OF_MORPHOS
void (*_Nonnull __register_frame)(void *_Nonnull);
void (*_Nonnull __deregister_frame)(void *_Nonnull);
# endif
int *_Nonnull (*_Nonnull get_errno)(void);
# ifdef OF_AMIGAOS_M68K
int (*_Nonnull vsnprintf)(char *restrict _Nonnull str, size_t size,
const char *_Nonnull restrict fmt, va_list args);
# endif
int (*_Nonnull atexit)(void (*_Nonnull)(void));
void (*_Nonnull exit)(int);
};
extern bool objc_init(unsigned int, struct objc_libc *_Nonnull,
FILE *_Nonnull *_Nonnull);
|
<
|
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
|
void *_Nonnull);
void *(*_Nonnull __deregister_frame_info)(const void *_Nonnull);
# endif
# ifdef OF_MORPHOS
void (*_Nonnull __register_frame)(void *_Nonnull);
void (*_Nonnull __deregister_frame)(void *_Nonnull);
# endif
# ifdef OF_AMIGAOS_M68K
int (*_Nonnull vsnprintf)(char *restrict _Nonnull str, size_t size,
const char *_Nonnull restrict fmt, va_list args);
# endif
int (*_Nonnull atexit)(void (*_Nonnull)(void));
void (*_Nonnull exit)(int);
};
extern bool objc_init(unsigned int, struct objc_libc *_Nonnull,
FILE *_Nonnull *_Nonnull);
|
Modified src/runtime/amiga-library.m
from [4cd36fe799]
to [174921abc5].
︙ | | | ︙ | |
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
|
void
_Unwind_Resume(void *ex)
{
libc._Unwind_Resume(ex);
}
#endif
int *
objc_get_errno(void)
{
return libc.get_errno();
}
#ifdef OF_AMIGAOS_M68K
int
snprintf(char *restrict str, size_t size, const char *restrict fmt, ...)
{
va_list args;
int ret;
|
<
<
<
<
<
<
|
573
574
575
576
577
578
579
580
581
582
583
584
585
586
|
void
_Unwind_Resume(void *ex)
{
libc._Unwind_Resume(ex);
}
#endif
#ifdef OF_AMIGAOS_M68K
int
snprintf(char *restrict str, size_t size, const char *restrict fmt, ...)
{
va_list args;
int ret;
|
︙ | | | ︙ | |
Modified src/runtime/arc.m
from [4544515edf]
to [0378415cdf].
︙ | | | ︙ | |
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))
OBJC_ERROR("Failed to create spinlock!");
#endif
}
id
objc_retain(id object)
{
|
|
|
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) != 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
|
id
objc_storeWeak(id *object, id value)
{
struct weak_ref *old;
#ifdef OF_HAVE_THREADS
if (!of_spinlock_lock(&spinlock))
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) {
|
|
|
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) != 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
|
ref->locations[ref->count++] = object;
} else
value = nil;
*object = value;
#ifdef OF_HAVE_THREADS
if (!of_spinlock_unlock(&spinlock))
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))
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))
OBJC_ERROR("Failed to unlock spinlock!");
#endif
if (class_respondsToSelector(object_getClass(value),
@selector(retainWeakReference)) && [value retainWeakReference])
return value;
|
|
|
|
|
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) != 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) != 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) != 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
|
void
objc_moveWeak(id *dest, id *src)
{
struct weak_ref *ref;
#ifdef OF_HAVE_THREADS
if (!of_spinlock_lock(&spinlock))
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))
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))
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))
OBJC_ERROR("Failed to unlock spinlock!");
#endif
}
|
|
|
|
|
|
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) != 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) != 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) != 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) != 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
|
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));
}
#endif
void *
objc_autoreleasePoolPush()
{
#if !defined(OF_HAVE_COMPILER_TLS) && defined(OF_HAVE_THREADS)
|
|
|
|
|
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) == 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
|
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));
#endif
}
#if !defined(OF_HAVE_COMPILER_TLS) && defined(OF_HAVE_THREADS)
OF_ENSURE(of_tlskey_set(countKey, (void *)count));
#endif
}
id
_objc_rootAutorelease(id object)
{
#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
|
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)
|
︙ | | | ︙ | |
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));
#endif
}
objects[count++] = object;
#if !defined(OF_HAVE_COMPILER_TLS) && defined(OF_HAVE_THREADS)
OF_ENSURE(of_tlskey_set(countKey, (void *)count));
#endif
return object;
}
|
|
|
|
|
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) == 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;
}
|
Modified src/runtime/exception.m
from [3255d28641]
to [50eac6751c].
︙ | | | ︙ | |
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))
OBJC_ERROR("Cannot create spinlock!");
}
#endif
static uint64_t
readULEB128(const uint8_t **ptr)
{
|
|
|
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) != 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
|
}
static void
emergencyExceptionCleanup(_Unwind_Reason_Code reason,
struct _Unwind_Exception *ex)
{
#ifdef OF_HAVE_THREADS
if (!of_spinlock_lock(&emergencyExceptionsSpinlock))
OBJC_ERROR("Cannot lock spinlock!");
#endif
ex->class = 0;
#ifdef OF_HAVE_THREADS
if (!of_spinlock_unlock(&emergencyExceptionsSpinlock))
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))
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))
OBJC_ERROR("Cannot lock spinlock!");
#endif
}
if (e == NULL)
OBJC_ERROR("Not enough memory to allocate exception!");
|
|
|
|
|
|
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) != 0)
OBJC_ERROR("Cannot lock spinlock!");
#endif
ex->class = 0;
#ifdef OF_HAVE_THREADS
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) != 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) != 0)
OBJC_ERROR("Cannot lock spinlock!");
#endif
}
if (e == NULL)
OBJC_ERROR("Not enough memory to allocate exception!");
|
︙ | | | ︙ | |
Modified src/runtime/linklib/linklib.m
from [05384cb064]
to [8918300072].
︙ | | | ︙ | |
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
|
#include <proto/exec.h>
#include <proto/intuition.h>
struct ObjFWRTBase;
#import "inline.h"
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#if defined(OF_AMIGAOS_M68K)
# include <stabs.h>
# define SYM(name) __asm__("_" name)
#elif defined(OF_MORPHOS)
|
<
|
25
26
27
28
29
30
31
32
33
34
35
36
37
38
|
#include <proto/exec.h>
#include <proto/intuition.h>
struct ObjFWRTBase;
#import "inline.h"
#include <stdio.h>
#include <stdlib.h>
#if defined(OF_AMIGAOS_M68K)
# include <stabs.h>
# define SYM(name) __asm__("_" name)
#elif defined(OF_MORPHOS)
|
︙ | | | ︙ | |
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
|
{
struct Library *IntuitionBase = OpenLibrary("intuition.library", 0);
if (IntuitionBase != NULL) {
struct EasyStruct easy = {
.es_StructSize = sizeof(easy),
.es_Flags = 0,
.es_Title = (UBYTE *)NULL,
.es_TextFormat = (UBYTE *)string,
(UBYTE *)"OK"
};
EasyRequest(NULL, &easy, NULL, arg);
CloseLibrary(IntuitionBase);
}
exit(EXIT_FAILURE);
}
static int *
get_errno(void)
{
return &errno;
}
static void __attribute__((__used__))
ctor(void)
{
static bool initialized = false;
struct objc_libc libc = {
.malloc = malloc,
.calloc = calloc,
|
|
|
|
<
<
<
<
<
<
|
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
|
{
struct Library *IntuitionBase = OpenLibrary("intuition.library", 0);
if (IntuitionBase != NULL) {
struct EasyStruct easy = {
.es_StructSize = sizeof(easy),
.es_Flags = 0,
.es_Title = (void *)NULL,
.es_TextFormat = (void *)string,
(void *)"OK"
};
EasyRequest(NULL, &easy, NULL, arg);
CloseLibrary(IntuitionBase);
}
exit(EXIT_FAILURE);
}
static void __attribute__((__used__))
ctor(void)
{
static bool initialized = false;
struct objc_libc libc = {
.malloc = malloc,
.calloc = calloc,
|
︙ | | | ︙ | |
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
|
.__register_frame_info = __register_frame_info,
.__deregister_frame_info = __deregister_frame_info,
#endif
#ifdef OF_MORPHOS
.__register_frame = __register_frame,
.__deregister_frame = __deregister_frame,
#endif
.get_errno = get_errno,
#ifdef OF_AMIGAOS_M68K
.vsnprintf = vsnprintf,
#endif
.atexit = atexit,
.exit = exit,
};
|
<
|
126
127
128
129
130
131
132
133
134
135
136
137
138
139
|
.__register_frame_info = __register_frame_info,
.__deregister_frame_info = __deregister_frame_info,
#endif
#ifdef OF_MORPHOS
.__register_frame = __register_frame,
.__deregister_frame = __deregister_frame,
#endif
#ifdef OF_AMIGAOS_M68K
.vsnprintf = vsnprintf,
#endif
.atexit = atexit,
.exit = exit,
};
|
︙ | | | ︙ | |
Modified src/runtime/misc.m
from [aa8c7fb972]
to [2faf8bad32].
︙ | | | ︙ | |
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
|
* 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 "config.h"
#include <stdio.h>
#include <stdlib.h>
#include "ObjFWRT.h"
#include "private.h"
#ifdef OF_AMIGAOS
# define USE_INLINE_STDARG
# include <proto/exec.h>
# include <clib/debug_protos.h>
# define __NOLIBBASE__
# include <proto/intuition.h>
# undef __NOLIBBASE__
#endif
static objc_enumeration_mutation_handler_t enumerationMutationHandler = NULL;
void
objc_enumerationMutation(id object)
|
>
>
>
|
13
14
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
|
* 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 "config.h"
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include "ObjFWRT.h"
#include "private.h"
#ifdef OF_AMIGAOS
# define USE_INLINE_STDARG
# include <proto/exec.h>
# include <clib/debug_protos.h>
# define __NOLIBBASE__
# define Class IntuitionClass
# include <proto/intuition.h>
# undef Class
# undef __NOLIBBASE__
#endif
static objc_enumeration_mutation_handler_t enumerationMutationHandler = NULL;
void
objc_enumerationMutation(id object)
|
︙ | | | ︙ | |
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
|
#ifdef OF_AMIGAOS
# define BUF_LEN 256
char title[BUF_LEN];
char message[BUF_LEN];
int status;
va_list args;
struct Library *IntuitionBase;
status = snprintf(title, BUF_LEN, "ObjFWRT @ %s:%u", file, line);
if (status <= 0 || status >= BUF_LEN)
title[0] = '\0';
va_start(args, format);
status = vsnprintf(message, BUF_LEN, format, args);
if (status <= 0 || status >= BUF_LEN)
message[0] = '\0';
va_end(args);
kprintf("[%s] %s\n", title, message);
IntuitionBase = OpenLibrary("intuition.library", 0);
if (IntuitionBase != NULL) {
struct EasyStruct easy = {
.es_StructSize = sizeof(easy),
.es_Flags = 0,
.es_Title = (UBYTE *)title,
.es_TextFormat = (UBYTE *)"%s",
(UBYTE *)"OK"
};
EasyRequest(NULL, &easy, NULL, (ULONG)message);
CloseLibrary(IntuitionBase);
}
exit(EXIT_FAILURE);
# undef BUF_LEN
#else
va_list args;
va_start(args, format);
vfprintf(stderr, "[ObjFWRT @ %s:%u] ", file, line);
vfprintf(stderr, format, args);
vfprintf(stderr, "\n");
fflush(stderr);
va_end(args);
abort();
#endif
OF_UNREACHABLE
}
|
>
>
>
>
>
>
|
>
|
>
>
>
>
>
|
|
|
|
|
|
<
|
>
|
>
|
>
|
|
|
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
|
#ifdef OF_AMIGAOS
# define BUF_LEN 256
char title[BUF_LEN];
char message[BUF_LEN];
int status;
va_list args;
struct Library *IntuitionBase;
# ifdef OF_AMIGAOS4
struct IntuitionIFace *IIntuition;
# endif
struct EasyStruct easy;
status = snprintf(title, BUF_LEN, "ObjFWRT @ %s:%u", file, line);
if (status <= 0 || status >= BUF_LEN)
title[0] = '\0';
va_start(args, format);
status = vsnprintf(message, BUF_LEN, format, args);
if (status <= 0 || status >= BUF_LEN)
message[0] = '\0';
va_end(args);
# ifndef OF_AMIGAOS4
kprintf("[%s] %s\n", title, message);
# endif
if ((IntuitionBase = OpenLibrary("intuition.library", 0)) == NULL)
exit(EXIT_FAILURE);
# ifdef OF_AMIGAOS4
if ((IIntuition = (struct IntuitionIFace *)GetInterface(IntuitionBase,
"main", 1, NULL)) == NULL)
exit(EXIT_FAILURE);
# endif
easy.es_StructSize = sizeof(easy);
easy.es_Flags = 0;
easy.es_Title = (void *)title;
easy.es_TextFormat = (void *)"%s";
easy.es_GadgetFormat = (void *)"OK";
EasyRequest(NULL, &easy, NULL, (ULONG)message);
# ifdef OF_AMIGAOS4
DropInterface((struct Interface *)IIntuition);
# endif
CloseLibrary(IntuitionBase);
exit(EXIT_FAILURE);
# undef BUF_LEN
#else
va_list args;
va_start(args, format);
fprintf(stderr, "[ObjFWRT @ %s:%u] ", file, line);
vfprintf(stderr, format, args);
fprintf(stderr, "\n");
fflush(stderr);
va_end(args);
abort();
#endif
OF_UNREACHABLE
}
|
Modified src/runtime/private.h
from [91ae810d9d]
to [cd3ba36b2b].
︙ | | | ︙ | |
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
|
} *_Nonnull buckets[256];
#else
IMP _Nullable buckets[256];
#endif
} *_Nonnull buckets[256];
};
#ifdef OBJC_COMPILING_AMIGA_LIBRARY
# undef errno
extern int *_Nonnull objc_get_errno(void);
# define errno (*objc_get_errno())
#endif
extern void objc_register_all_categories(struct objc_symtab *_Nonnull);
extern struct objc_category *_Nullable *_Nullable
objc_categories_for_class(Class _Nonnull);
extern void objc_unregister_all_categories(void);
extern void objc_initialize_class(Class _Nonnull);
extern void objc_update_dtable(Class _Nonnull);
extern void objc_register_all_classes(struct objc_symtab *_Nonnull);
|
<
<
<
<
<
<
|
212
213
214
215
216
217
218
219
220
221
222
223
224
225
|
} *_Nonnull buckets[256];
#else
IMP _Nullable buckets[256];
#endif
} *_Nonnull buckets[256];
};
extern void objc_register_all_categories(struct objc_symtab *_Nonnull);
extern struct objc_category *_Nullable *_Nullable
objc_categories_for_class(Class _Nonnull);
extern void objc_unregister_all_categories(void);
extern void objc_initialize_class(Class _Nonnull);
extern void objc_update_dtable(Class _Nonnull);
extern void objc_register_all_classes(struct objc_symtab *_Nonnull);
|
︙ | | | ︙ | |
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
|
uint8_t i = idx >> 8;
uint8_t j = idx;
return dtable->buckets[i]->buckets[j];
#endif
}
extern void OF_NO_RETURN_FUNC objc_error(const char *file, unsigned int line,
const char *format, ...);
#define OBJC_ERROR(...) objc_error(__FILE__, __LINE__, __VA_ARGS__)
#if defined(OF_ELF)
# if defined(OF_X86_64) || defined(OF_X86) || defined(OF_POWERPC) || \
defined(OF_ARM64) || defined(OF_ARM) || \
defined(OF_MIPS64_N64) || defined(OF_MIPS) || \
defined(OF_SPARC64) || defined(OF_SPARC)
|
|
|
|
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
|
uint8_t i = idx >> 8;
uint8_t j = idx;
return dtable->buckets[i]->buckets[j];
#endif
}
extern void OF_NO_RETURN_FUNC objc_error(const char *_Nonnull file,
unsigned int line, const char *_Nonnull format, ...);
#define OBJC_ERROR(...) objc_error(__FILE__, __LINE__, __VA_ARGS__)
#if defined(OF_ELF)
# if defined(OF_X86_64) || defined(OF_X86) || defined(OF_POWERPC) || \
defined(OF_ARM64) || defined(OF_ARM) || \
defined(OF_MIPS64_N64) || defined(OF_MIPS) || \
defined(OF_SPARC64) || defined(OF_SPARC)
|
︙ | | | ︙ | |
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
|
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]))
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]));
@try {
return [[*ptr retain] autorelease];
} @finally {
OF_ENSURE(of_spinlock_unlock(&spinlocks[hash]));
}
#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]));
@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]));
}
#endif
return;
}
id *ptr = (id *)(void *)((char *)self + offset);
|
|
|
|
|
|
|
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]) != 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]) == 0);
@try {
return [[*ptr retain] autorelease];
} @finally {
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]) == 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]) == 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
|
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]));
#endif
memcpy(dest, src, size);
#ifdef OF_HAVE_THREADS
OF_ENSURE(of_spinlock_unlock(&spinlocks[hash]));
#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]));
#endif
memcpy(dest, src, size);
#ifdef OF_HAVE_THREADS
OF_ENSURE(of_spinlock_unlock(&spinlocks[hash]));
#endif
return;
}
memcpy(dest, src, size);
}
|
|
|
|
|
|
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]) == 0);
#endif
memcpy(dest, src, size);
#ifdef OF_HAVE_THREADS
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]) == 0);
#endif
memcpy(dest, src, size);
#ifdef OF_HAVE_THREADS
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
|
struct lock_s *next;
} *locks = NULL;
static of_mutex_t mutex;
OF_CONSTRUCTOR()
{
if (!of_mutex_new(&mutex))
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))
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))
OBJC_ERROR("Failed to unlock mutex!");
if (!of_rmutex_lock(&lock->rmutex))
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))
OBJC_ERROR("Failed to create mutex!");
lock->object = object;
lock->count = 1;
lock->next = locks;
locks = lock;
if (!of_mutex_unlock(&mutex))
OBJC_ERROR("Failed to unlock mutex!");
if (!of_rmutex_lock(&lock->rmutex))
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))
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))
OBJC_ERROR("Failed to unlock mutex!");
if (--lock->count == 0) {
if (!of_rmutex_free(&lock->rmutex))
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))
OBJC_ERROR("Failed to unlock mutex!");
return 0;
}
OBJC_ERROR("objc_sync_exit() was called for an object not locked!");
#else
return 0;
#endif
}
|
|
|
|
|
|
|
|
|
|
|
|
|
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) != 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) != 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) != 0)
OBJC_ERROR("Failed to unlock mutex!");
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) != 0)
OBJC_ERROR("Failed to create mutex!");
lock->object = object;
lock->count = 1;
lock->next = locks;
locks = lock;
if (of_mutex_unlock(&mutex) != 0)
OBJC_ERROR("Failed to unlock mutex!");
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) != 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) != 0)
OBJC_ERROR("Failed to unlock mutex!");
if (--lock->count == 0) {
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) != 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
|
#import "once.h"
static of_rmutex_t globalMutex;
static void
init(void)
{
if (!of_rmutex_new(&globalMutex))
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))
OBJC_ERROR("Failed to lock global mutex!");
}
void
objc_global_mutex_unlock(void)
{
if (!of_rmutex_unlock(&globalMutex))
OBJC_ERROR("Failed to unlock global mutex!");
}
|
|
|
|
|
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) != 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) != 0)
OBJC_ERROR("Failed to lock global mutex!");
}
void
objc_global_mutex_unlock(void)
{
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
|
# endif
# endif
#endif
#if defined(OF_HAVE_THREADS) && defined(OF_AMIGAOS) && !defined(OF_MORPHOS)
OF_CONSTRUCTOR()
{
if (!of_tlskey_new(&of_socket_base_key))
@throw [OFInitializationFailedException exception];
# ifdef OF_AMIGAOS4
if (!of_tlskey_new(&of_socket_interface_key))
@throw [OFInitializationFailedException exception];
# endif
}
#endif
#if !defined(OF_AMIGAOS) || defined(OF_MORPHOS) || !defined(OF_HAVE_THREADS)
static void
|
|
|
|
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) != 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
|
︙ | | | ︙ | |
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))
return;
# ifdef OF_WII
if (!of_spinlock_new(&spinlock))
return;
# endif
# endif
initSuccessful = true;
}
|
|
|
|
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) != 0)
return;
# ifdef OF_WII
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
|
if ((socketInterface = (struct SocketIFace *)
GetInterface(socketBase, "main", 1, NULL)) == NULL) {
CloseLibrary(socketBase);
return false;
}
# endif
if (!of_tlskey_set(of_socket_base_key, socketBase)) {
CloseLibrary(socketBase);
# ifdef OF_AMIGAOS4
DropInterface((struct Interface *)socketInterface);
# endif
return false;
}
# ifdef OF_AMIGAOS4
if (!of_tlskey_set(of_socket_interface_key, socketInterface)) {
CloseLibrary(socketBase);
DropInterface((struct Interface *)socketInterface);
return false;
}
# endif
return 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
|
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;
|
︙ | | | ︙ | |
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))
@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))
@throw [OFUnlockFailedException exception];
# endif
return ret;
}
#endif
|
|
|
|
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) != 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) != 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
|
# 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,
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);
#ifdef __cplusplus
}
#endif
|
|
|
|
|
|
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 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 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
|
* 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 "platform.h"
#if !defined(OF_HAVE_THREADS) || \
(!defined(OF_HAVE_PTHREADS) && !defined(OF_WINDOWS) && !defined(OF_AMIGAOS))
# error No thread-local storage available!
#endif
|
>
>
|
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
|
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);
#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
of_tlskey_set(of_tlskey_t key, void *ptr)
{
return (pthread_setspecific(key, ptr) == 0);
}
#elif defined(OF_WINDOWS)
static OF_INLINE void *
of_tlskey_get(of_tlskey_t key)
{
return TlsGetValue(key);
}
static OF_INLINE bool
of_tlskey_set(of_tlskey_t key, void *ptr)
{
return TlsSetValue(key, ptr);
}
#elif defined(OF_MORPHOS)
static OF_INLINE void *
of_tlskey_get(of_tlskey_t key)
{
return (void *)TLSGetValue(key);
}
static OF_INLINE bool
of_tlskey_set(of_tlskey_t key, void *ptr)
{
return TLSSetValue(key, (APTR)ptr);
}
#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);
# ifdef __cplusplus
}
# endif
#endif
|
|
|
|
|
|
|
|
|
|
|
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 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
|
Modified tests/OFStringTests.m
from [1ca0b0e0e8]
to [bb912e724d].
︙ | | | ︙ | |
22
23
24
25
26
27
28
29
30
31
32
33
34
35
|
#include <math.h>
#import "TestsAppDelegate.h"
#import "OFString.h"
#import "OFMutableUTF8String.h"
#import "OFUTF8String.h"
static OFString *module = nil;
static OFString *whitespace[] = {
@" \r \t\n\t \tasd \t \t\t\r\n",
@" \t\t \t\t \t \t"
};
static of_unichar_t ucstr[] = {
|
>
>
>
>
|
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
|
#include <math.h>
#import "TestsAppDelegate.h"
#import "OFString.h"
#import "OFMutableUTF8String.h"
#import "OFUTF8String.h"
#ifndef INFINITY
# define INFINITY __builtin_inf()
#endif
static OFString *module = nil;
static OFString *whitespace[] = {
@" \r \t\n\t \tasd \t \t\t\r\n",
@" \t\t \t\t \t \t"
};
static of_unichar_t ucstr[] = {
|
︙ | | | ︙ | |