summaryrefslogtreecommitdiff
path: root/m4/simpleops_atomic.m4
blob: 8278f5ef740cce429c72595cbd4ce93f942c6c05 (plain)
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
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
AC_DEFUN([SIMPLEOPS_CHECK_ATOMIC_OP_NEEDS_MEMORY_BARRIER],
[dnl
	AC_CANONICAL_HOST
	AC_CACHE_CHECK([whether atomic ops require a memory barrier],
                       [simpleops_cv_atomic_op_needs_memory_barrier],
	[dnl
		case $host_cpu in
		    i?86)	simpleops_cv_atomic_op_needs_memory_barrier="no"  ;;
		    x86_64)	simpleops_cv_atomic_op_needs_memory_barrier="no"  ;;
		    arm*)	simpleops_cv_atomic_op_needs_memory_barrier="no"  ;;
		    *)		simpleops_cv_atomic_op_needs_memory_barrier="yes" ;;
		esac
	])
	if test "x$simpleops_cv_atomic_op_needs_memory_barrier" = "xyes"; then
		AC_DEFINE(ATOMIC_OP_NEEDS_MEMORY_BARRIER, 1,
		          [Define to 1 if memory barriers are needed around atomic operations.])
	fi
])

AC_DEFUN([SIMPLEOPS_CHECK_NATIVE_ATOMIC_PRIMITIVES],
[dnl
	SIMPLEOPS_CHECK_ATOMIC_OP_NEEDS_MEMORY_BARRIER
	AC_CACHE_CHECK([for native atomic primitives], simpleops_cv_native_atomic_primitives,
	[dnl
		AC_TRY_LINK([
static int test_atomic (void)
{
    int r, x;
#if SIMPLEOPS_ATOMIC_NEEDS_MEMORY_BARRIER
    __sync_synchronize ();
#endif
    x = 0;
    r = __sync_fetch_and_add (&x, 1);
    r |= __sync_bool_compare_and_swap (&x, 0, 1);
}
],
		[test_atomic ()],
		[simpleops_cv_native_atomic_primitives="yes"],
		[simpleops_cv_native_atomic_primitives="no"]
		)
	])
	if test "x$simpleops_cv_native_atomic_primitives" = "xyes"; then
		AC_DEFINE(HAVE_NATIVE_ATOMIC_PRIMITIVES, 1,
			[Define to 1 if your compiler supports the __sync_* atomic primitives])
	fi
])

AC_DEFUN([SIMPLEOPS_CHECK_NATIVE_ATOMIC_SWAP],
[dnl
	AC_CACHE_CHECK([for native atomic swap], simpleops_cv_native_atomic_swap,
	[dnl
		AC_TRY_LINK([
static int test_atomic_swap (void)
{
    int r, x;
    x = 0;
    r = __sync_swap (&x, 1);
}
],
		[test_atomic_swap ()],
		[simpleops_cv_native_atomic_swap="yes"],
		[simpleops_cv_native_atomic_swap="no"]
		)
	])
	if test "x$simpleops_cv_native_atomic_swap" = "xyes"; then
		AC_DEFINE(HAVE_NATIVE_ATOMIC_SWAP, 1,
			[Define to 1 if your compiler supports __sync_swap()])
	fi
])

AC_DEFUN([SIMPLEOPS_CHECK_ATOMIC],
[dnl
	AC_ARG_ENABLE([atomic],
	              [AS_HELP_STRING([--disable-atomic], [disable atomic operations])],
		      [AC_DEFINE(DISABLE_ATOMIC, 1, [Define to 1 to disable atomic operations.])]
		     )

	SIMPLEOPS_CHECK_NATIVE_ATOMIC_PRIMITIVES
	SIMPLEOPS_CHECK_NATIVE_ATOMIC_SWAP
	AC_CHECK_HEADERS([libkern/OSAtomic.h atomic_ops.h])
])