ObjFW  Check-in [9626d917a6]

Overview
Comment:Check if 64 bit version of OSAtomic* functions is available.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 9626d917a6fb70287b182e6726205160b4229f599ab83df43b3cfe80049c00de
User & Date: js on 2010-10-31 22:18:49
Other Links: manifest | tags
Context
2010-11-01
03:46
Fix a bug with recent Clang revisions and Blocks. check-in: eb3e09c153 user: js tags: trunk
2010-10-31
22:18
Check if 64 bit version of OSAtomic* functions is available. check-in: 9626d917a6 user: js tags: trunk
22:01
Make reference counting of blocks atomic. check-in: 758559fd9f user: js tags: trunk
Changes

Modified configure.ac from [4739d63ce4] to [5a82833b3a].

272
273
274
275
276
277
278
279
280





281
282
283
284
285
286
287
272
273
274
275
276
277
278


279
280
281
282
283
284
285
286
287
288
289
290







-
-
+
+
+
+
+







		test x"$atomic_ops" = x"none" && atomic_ops="gcc builtins"
		AC_DEFINE(OF_HAVE_GCC_ATOMIC_OPS, 1,
			[Whether gcc atomic operations are available])
		], [AC_MSG_RESULT(no)])

	AC_CHECK_HEADER(libkern/OSAtomic.h, [
		test x"$atomic_ops" = x"none" && atomic_ops="libkern/OSAtomic.h"
		AC_DEFINE(OF_HAVE_LIBKERN_OSATOMIC_H, 1,
			[Whether we have libkern/OSAtomic.h])])
		AC_DEFINE(OF_HAVE_OSATOMIC, 1,
			[Whether we have libkern/OSAtomic.h])
		AC_CHECK_FUNC(OSAtomicAdd64Barrier, [
			AC_DEFINE(OF_HAVE_OSATOMIC_64, 1,
				[Whether we have OSAtomic*64])])])
else
	dnl We can only have one thread - therefore everything is atomic
	atomic_ops="not needed"
fi

AC_MSG_CHECKING(for atomic operations)
if test x"$atomic_ops" != x"none"; then

Modified src/OFBlock.m from [239ba34c9f] to [d2c4fcd6af].

13
14
15
16
17
18
19

20
21
22
23
24
25
26
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27







+








#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#import "OFBlock.h"
#import "atomic.h"

/// \cond internal
@protocol RetainRelease
- retain;
- (void)release;
@end
/// \endcond

Modified src/atomic.h from [ccf7d7d55b] to [0a81676089].

1
2
3
4
5
6
7
8
9
10
11


12
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
42

43
44

45
46
47
48
49
50
51
1
2
3
4
5
6
7
8
9
10
11
12
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

42
43
44
45
46
47
48
49
50
51
52
53
54
55











+
+



-
+



-
+




















-
+


+


+







/*
 * Copyright (c) 2008 - 2010
 *   Jonathan Schleifer <js@webkeks.org>
 *
 * All rights reserved.
 *
 * This file is part of ObjFW. It may be distributed under the terms of the
 * Q Public License 1.0, which can be found in the file LICENSE included in
 * the packaging of this file.
 */

#include <stdlib.h>

#import "macros.h"

#if defined(OF_THREADS) && !defined(OF_X86_ASM) && !defined(OF_AMD64_ASM) && \
    !defined(OF_HAVE_GCC_ATOMIC_OPS) && !defined(OF_HAVE_LIBKERN_OSATOMIC_H)
    !defined(OF_HAVE_GCC_ATOMIC_OPS) && !defined(OF_HAVE_OSATOMIC)
# error No atomic operations available!
#endif

#ifdef OF_HAVE_LIBKERN_OSATOMIC_H
#ifdef OF_HAVE_OSATOMIC
# include <libkern/OSAtomic.h>
#endif

static OF_INLINE int
of_atomic_add_int(volatile int *p, int i)
{
#if !defined(OF_THREADS)
	return (*p += i);
#elif defined(OF_X86_ASM) || defined(OF_AMD64_ASM)
	__asm__ (
	    "lock\n\t"
	    "xaddl	%0, %2\n\t"
	    "addl	%1, %0"
	    : "+&r"(i)
	    : "r"(i), "m"(*p)
	);

	return i;
#elif defined(OF_HAVE_GCC_ATOMIC_OPS)
	return __sync_add_and_fetch(p, i);
#elif defined(OF_HAVE_LIBKERN_OSATOMIC_H)
#elif defined(OF_HAVE_OSATOMIC)
	if (sizeof(int) == 4)
		return OSAtomicAdd32Barrier(i, p);
# ifdef OF_HAVE_OSATOMIC_64
	else if (sizeof(int) == 8)
		return OSAtomicAdd64Barrier(i, p);
# endif
	else
		abort();
#endif
}

static OF_INLINE int32_t
of_atomic_add_32(volatile int32_t *p, int32_t i)
60
61
62
63
64
65
66
67

68
69
70
71
72
73
74
64
65
66
67
68
69
70

71
72
73
74
75
76
77
78







-
+







	    : "+&r"(i)
	    : "r"(i), "m"(*p)
	);

	return i;
#elif defined(OF_HAVE_GCC_ATOMIC_OPS)
	return __sync_add_and_fetch(p, i);
#elif defined(OF_HAVE_LIBKERN_OSATOMIC_H)
#elif defined(OF_HAVE_OSATOMIC)
	return OSAtomicAdd32Barrier(i, p);
#endif
}

static OF_INLINE void*
of_atomic_add_ptr(volatile void **p, intptr_t i)
{
82
83
84
85
86
87
88
89

90
91


92
93


94
95
96
97
98
99
100
86
87
88
89
90
91
92

93
94

95
96
97

98
99
100
101
102
103
104
105
106







-
+

-
+
+

-
+
+







	    : "+&r"(i)
	    : "r"(i), "m"(*p)
	);

	return (void*)i;
#elif defined(OF_HAVE_GCC_ATOMIC_OPS)
	return __sync_add_and_fetch(p, i);
#elif defined(OF_HAVE_LIBKERN_OSATOMIC_H)
#elif defined(OF_HAVE_OSATOMIC)
	if (sizeof(void*) == 4)
		return OSAtomicAdd32Barrier(i, p);
		return (void*)OSAtomicAdd32Barrier(i, (int32_t*)p);
# ifdef OF_HAVE_OSATOMIC_64
	else if (sizeof(void*) == 8)
		return OSAtomicAdd64Barrier(i, p);
		return (void*)OSAtomicAdd64Barrier(i, (int64_t*)p);
# endif
	else
		abort();
#endif
}

static OF_INLINE int
of_atomic_sub_int(volatile int *p, int i)
110
111
112
113
114
115
116
117

118
119

120
121

122
123
124
125
126
127
128
116
117
118
119
120
121
122

123
124
125
126
127
128
129
130
131
132
133
134
135
136







-
+


+


+







	    : "+&r"(i)
	    : "r"(i), "m"(*p)
	);

	return i;
#elif defined(OF_HAVE_GCC_ATOMIC_OPS)
	return __sync_sub_and_fetch(p, i);
#elif defined(OF_HAVE_LIBKERN_OSATOMIC_H)
#elif defined(OF_HAVE_OSATOMIC)
	if (sizeof(int) == 4)
		return OSAtomicAdd32Barrier(-i, p);
# ifdef OF_HAVE_OSATOMIC_64
	else if (sizeof(int) == 8)
		return OSAtomicAdd64Barrier(-i, p);
# endif
	else
		abort();
#endif
}

static OF_INLINE int32_t
of_atomic_sub_32(volatile int32_t *p, int32_t i)
138
139
140
141
142
143
144
145

146
147
148
149
150
151
152
146
147
148
149
150
151
152

153
154
155
156
157
158
159
160







-
+







	    : "+&r"(i)
	    : "r"(i), "m"(*p)
	);

	return i;
#elif defined(OF_HAVE_GCC_ATOMIC_OPS)
	return __sync_sub_and_fetch(p, i);
#elif defined(OF_HAVE_LIBKERN_OSATOMIC_H)
#elif defined(OF_HAVE_OSATOMIC)
	return OSAtomicAdd32Barrier(-i, p);
#endif
}

static OF_INLINE void*
of_atomic_sub_ptr(volatile void **p, intptr_t i)
{
161
162
163
164
165
166
167
168

169
170


171
172


173
174
175
176
177
178
179
169
170
171
172
173
174
175

176
177

178
179
180

181
182
183
184
185
186
187
188
189







-
+

-
+
+

-
+
+







	    : "+&r"(i)
	    : "r"(i), "m"(*p)
	);

	return (void*)i;
#elif defined(OF_HAVE_GCC_ATOMIC_OPS)
	return __sync_sub_and_fetch(p, i);
#elif defined(OF_HAVE_LIBKERN_OSATOMIC_H)
#elif defined(OF_HAVE_OSATOMIC)
	if (sizeof(void*) == 4)
		return OSAtomicAdd32Barrier(-i, p);
		return (void*)OSAtomicAdd32Barrier(-i, (int32_t*)p);
# ifdef OF_HAVE_OSATOMIC_64
	else if (sizeof(void*) == 8)
		return OSAtomicAdd64Barrier(-i, p);
		return (void*)OSAtomicAdd64Barrier(-i, (int64_t*)p);
# endif
	else
		abort();
#endif
}

static OF_INLINE int
of_atomic_inc_int(volatile int *p)
192
193
194
195
196
197
198
199

200
201

202
203

204
205
206
207
208
209
210
202
203
204
205
206
207
208

209
210
211
212
213
214
215
216
217
218
219
220
221
222







-
+


+


+







	    : "=&r"(i)
	    : "m"(*p)
	);

	return i;
#elif defined(OF_HAVE_GCC_ATOMIC_OPS)
	return __sync_add_and_fetch(p, 1);
#elif defined(OF_HAVE_LIBKERN_OSATOMIC_H)
#elif defined(OF_HAVE_OSATOMIC)
	if (sizeof(int) == 4)
		return OSAtomicIncrement32Barrier(p);
# ifdef OF_HAVE_OSATOMIC_64
	else if (sizeof(int) == 8)
		return OSAtomicDecrement64Barrier(p);
# endif
	else
		abort();
#endif
}
static OF_INLINE int32_t
of_atomic_inc_32(volatile int32_t *p)
{
222
223
224
225
226
227
228
229

230
231
232
233
234
235
236
234
235
236
237
238
239
240

241
242
243
244
245
246
247
248







-
+







	    : "=&r"(i)
	    : "m"(*p)
	);

	return i;
#elif defined(OF_HAVE_GCC_ATOMIC_OPS)
	return __sync_add_and_fetch(p, 1);
#elif defined(OF_HAVE_LIBKERN_OSATOMIC_H)
#elif defined(OF_HAVE_OSATOMIC)
	return OSAtomicIncrement32Barrier(p);
#endif
}

static OF_INLINE int
of_atomic_dec_int(volatile int *p)
{
248
249
250
251
252
253
254
255

256
257

258
259

260
261
262
263
264
265
266
260
261
262
263
264
265
266

267
268
269
270
271
272
273
274
275
276
277
278
279
280







-
+


+


+







	    : "=&r"(i)
	    : "m"(*p)
	);

	return i;
#elif defined(OF_HAVE_GCC_ATOMIC_OPS)
	return __sync_sub_and_fetch(p, 1);
#elif defined(OF_HAVE_LIBKERN_OSATOMIC_H)
#elif defined(OF_HAVE_OSATOMIC)
	if (sizeof(int) == 4)
		return OSAtomicDecrement32Barrier(p);
# ifdef OF_HAVE_OSATOMIC_64
	else if (sizeof(int) == 8)
		return OSAtomicDecrement64Barrier(p);
# endif
	else
		abort();
#endif
}

static OF_INLINE int32_t
of_atomic_dec_32(volatile int32_t *p)
279
280
281
282
283
284
285
286

287
288
289
290
291
292
293
293
294
295
296
297
298
299

300
301
302
303
304
305
306
307







-
+







	    : "=&r"(i)
	    : "m"(*p)
	);

	return i;
#elif defined(OF_HAVE_GCC_ATOMIC_OPS)
	return __sync_sub_and_fetch(p, 1);
#elif defined(OF_HAVE_LIBKERN_OSATOMIC_H)
#elif defined(OF_HAVE_OSATOMIC)
	return OSAtomicDecrement32Barrier(p);
#endif
}

static OF_INLINE unsigned int
of_atomic_or_int(volatile unsigned int *p, unsigned int i)
{
306
307
308
309
310
311
312
313

314
315

316
317

318
319
320
321
322
323
324
320
321
322
323
324
325
326

327
328
329
330
331
332
333
334
335
336
337
338
339
340







-
+


+


+







	    : "r"(i), "m"(*p)
	    : "eax"
	);

	return i;
#elif defined(OF_HAVE_GCC_ATOMIC_OPS)
	return __sync_or_and_fetch(p, i);
#elif defined(OF_HAVE_LIBKERN_OSATOMIC_H)
#elif defined(OF_HAVE_OSATOMIC)
	if (sizeof(int) == 4)
		return OSAtomicOr32Barrier(i, p);
# ifdef OF_HAVE_OSATOMIC_64
	else if (sizeof(int) == 8)
		return OSAtomicOr64Barrier(i, p);
# endif
	else
		abort();
#endif
}

static OF_INLINE uint32_t
of_atomic_or_32(volatile uint32_t *p, uint32_t i)
338
339
340
341
342
343
344
345

346
347
348
349
350
351
352
354
355
356
357
358
359
360

361
362
363
364
365
366
367
368







-
+







	    : "r"(i), "m"(*p)
	    : "eax"
	);

	return i;
#elif defined(OF_HAVE_GCC_ATOMIC_OPS)
	return __sync_or_and_fetch(p, i);
#elif defined(OF_HAVE_LIBKERN_OSATOMIC_H)
#elif defined(OF_HAVE_OSATOMIC)
	return OSAtomicOr32Barrier(i, p);
#endif
}

static OF_INLINE unsigned int
of_atomic_and_int(volatile unsigned int *p, unsigned int i)
{
365
366
367
368
369
370
371
372

373
374

375
376

377
378
379
380
381
382
383
381
382
383
384
385
386
387

388
389
390
391
392
393
394
395
396
397
398
399
400
401







-
+


+


+







	    : "r"(i), "m"(*p)
	    : "eax"
	);

	return i;
#elif defined(OF_HAVE_GCC_ATOMIC_OPS)
	return __sync_and_and_fetch(p, i);
#elif defined(OF_HAVE_LIBKERN_OSATOMIC_H)
#elif defined(OF_HAVE_OSATOMIC)
	if (sizeof(int) == 4)
		return OSAtomicAnd32Barrier(i, p);
# ifdef OF_HAVE_OSATOMIC_64
	else if (sizeof(int) == 8)
		return OSAtomicAnd64Barrier(i, p);
# endif
	else
		abort();
#endif
}

static OF_INLINE uint32_t
of_atomic_and_32(volatile uint32_t *p, uint32_t i)
397
398
399
400
401
402
403
404

405
406
407
408
409
410
411
415
416
417
418
419
420
421

422
423
424
425
426
427
428
429







-
+







	    : "r"(i), "m"(*p)
	    : "eax"
	);

	return i;
#elif defined(OF_HAVE_GCC_ATOMIC_OPS)
	return __sync_and_and_fetch(p, i);
#elif defined(OF_HAVE_LIBKERN_OSATOMIC_H)
#elif defined(OF_HAVE_OSATOMIC)
	return OSAtomicAnd32Barrier(i, p);
#endif
}

static OF_INLINE unsigned int
of_atomic_xor_int(volatile unsigned int *p, unsigned int i)
{
424
425
426
427
428
429
430
431

432
433

434
435

436
437
438
439
440
441
442
442
443
444
445
446
447
448

449
450
451
452
453
454
455
456
457
458
459
460
461
462







-
+


+


+







	    : "r"(i), "m"(*p)
	    : "eax"
	);

	return i;
#elif defined(OF_HAVE_GCC_ATOMIC_OPS)
	return __sync_xor_and_fetch(p, i);
#elif defined(OF_HAVE_LIBKERN_OSATOMIC_H)
#elif defined(OF_HAVE_OSATOMIC)
	if (sizeof(int) == 4)
		return OSAtomicXor32Barrier(i, p);
# ifdef OF_HAVE_OSATOMIC_64
	else (sizeof(int) == 8)
		return OSAtomicXor64Barrier(i, p);
# endif
	else
		abort();
#endif
}

static OF_INLINE uint32_t
of_atomic_xor_32(volatile uint32_t *p, uint32_t i)
456
457
458
459
460
461
462
463

464
465
466
467
468
469
470
476
477
478
479
480
481
482

483
484
485
486
487
488
489
490







-
+







	    : "r"(i), "m"(*p)
	    : "eax"
	);

	return i;
#elif defined(OF_HAVE_GCC_ATOMIC_OPS)
	return __sync_xor_and_fetch(p, i);
#elif defined(OF_HAVE_LIBKERN_OSATOMIC_H)
#elif defined(OF_HAVE_OSATOMIC)
	return OSAtomicXor32Barrier(i, p);
#endif
}

static OF_INLINE BOOL
of_atomic_cmpswap_int(volatile int *p, int o, int n)
{
488
489
490
491
492
493
494
495

496
497
498
499
500
501
502
508
509
510
511
512
513
514

515
516
517
518
519
520
521
522







-
+







	    : "=a"(r)
	    : "a"(o), "r"(n), "m"(*p)
	);

	return r;
#elif defined(OF_HAVE_GCC_ATOMIC_OPS)
	return __sync_bool_compare_and_swap(p, o, n);
#elif defined(OF_HAVE_LIBKERN_OSATOMIC_H)
#elif defined(OF_HAVE_OSATOMIC)
	return OSAtomicCompareAndSwapIntBarrier(o, n, p);
#endif
}

static OF_INLINE BOOL
of_atomic_cmpswap_32(volatile int32_t *p, int32_t o, int32_t n)
{
520
521
522
523
524
525
526
527

528
529
530
531
532
533
534
540
541
542
543
544
545
546

547
548
549
550
551
552
553
554







-
+







	    : "=a"(r)
	    : "a"(o), "r"(n), "m"(*p)
	);

	return r;
#elif defined(OF_HAVE_GCC_ATOMIC_OPS)
	return __sync_bool_compare_and_swap(p, o, n);
#elif defined(OF_HAVE_LIBKERN_OSATOMIC_H)
#elif defined(OF_HAVE_OSATOMIC)
	return OSAtomicCompareAndSwap32Barrier(o, n, p);
#endif
}

static OF_INLINE BOOL
of_atomic_cmpswap_ptr(void* volatile *p, void *o, void *n)
{
552
553
554
555
556
557
558
559

560
561
562
572
573
574
575
576
577
578

579
580
581
582







-
+



	    : "=a"(r)
	    : "a"(o), "q"(n), "m"(*p)
	);

	return r;
#elif defined(OF_HAVE_GCC_ATOMIC_OPS)
	return __sync_bool_compare_and_swap(p, o, n);
#elif defined(OF_HAVE_LIBKERN_OSATOMIC_H)
#elif defined(OF_HAVE_OSATOMIC)
	return OSAtomicCompareAndSwapPtrBarrier(o, n, p);
#endif
}

Modified src/objfw-defs.h.in from [40a7e9074f] to [24da91ee6d].

1
2
3
4
5
6
7
8
9
10


11
12
13
14
15
16
17
18
19
20
1
2
3
4
5
6
7
8
9

10
11
12
13
14
15
16
17
18
19
20
21









-
+
+










#undef OF_APPLE_RUNTIME
#undef OF_HAVE_ASPRINTF
#undef OF_ATOMIC_OPS
#undef OF_BIG_ENDIAN
#undef OF_GNU_RUNTIME
#undef OF_HAVE_ASPRINTF
#undef OF_HAVE_BLOCKS
#undef OF_HAVE_FAST_ENUMERATION
#undef OF_HAVE_GCC_ATOMIC_OPS
#undef OF_HAVE_LIBKERN_OSATOMIC_H
#undef OF_HAVE_OSATOMIC
#undef OF_HAVE_OSATOMIC_64
#undef OF_HAVE_POLL
#undef OF_HAVE_PROPERTIES
#undef OF_HAVE_PTHREADS
#undef OF_HAVE_PTHREAD_SPINLOCKS
#undef OF_HAVE_SCHED_YIELD
#undef OF_HAVE_SYS_SELECT_H
#undef OF_OBJFW_RUNTIME
#undef OF_PLUGINS
#undef OF_THREADS
#undef SIZE_MAX