atomicops.c raw
1 /*
2 * Copyright (c) 2017 Ivan Maidanski
3 *
4 * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
5 * OR IMPLIED. ANY USE IS AT YOUR OWN RISK.
6 *
7 * Permission is hereby granted to use or copy this program
8 * for any purpose, provided the above notices are retained on all copies.
9 * Permission to modify the code and to distribute modified code is granted,
10 * provided the above notices are retained, and a notice that the code was
11 * modified is included with the above copyright notice.
12 */
13
14 /*
15 * Minimal testing of atomic operations used by the collector.
16 * Primary use is to determine whether the compiler atomic intrinsics
17 * can be relied on.
18 */
19
20 #ifdef HAVE_CONFIG_H
21 # include "config.h"
22 #endif
23
24 #include <stdio.h>
25
26 #if defined(GC_BUILTIN_ATOMIC) || defined(GC_THREADS)
27
28 # include <stdlib.h>
29
30 # ifdef PARALLEL_MARK
31 # define AO_REQUIRE_CAS
32 # if !defined(__GNUC__) && !defined(AO_ASSUME_WINDOWS98)
33 # define AO_ASSUME_WINDOWS98
34 # endif
35 # endif
36
37 # include "private/gc_atomic_ops.h"
38
39 # define TA_assert(e) \
40 if (!(e)) { \
41 fprintf(stderr, "Assertion failure, line %d: " #e "\n", __LINE__); \
42 exit(-1); \
43 }
44
45 int
46 main(void)
47 {
48 AO_t x = 13;
49 # if defined(AO_HAVE_char_load) || defined(AO_HAVE_char_store)
50 unsigned char c = 117;
51 # endif
52 # ifdef AO_HAVE_test_and_set_acquire
53 AO_TS_t z = AO_TS_INITIALIZER;
54
55 TA_assert(AO_test_and_set_acquire(&z) == AO_TS_CLEAR);
56 TA_assert(AO_test_and_set_acquire(&z) == AO_TS_SET);
57 AO_CLEAR(&z);
58 # endif
59 AO_compiler_barrier();
60 # ifdef AO_HAVE_nop_full
61 AO_nop_full();
62 # endif
63 # ifdef AO_HAVE_char_load
64 TA_assert(AO_char_load(&c) == 117);
65 # endif
66 # ifdef AO_HAVE_char_store
67 AO_char_store(&c, 119);
68 TA_assert(c == 119);
69 # endif
70 # ifdef AO_HAVE_load_acquire
71 TA_assert(AO_load_acquire(&x) == 13);
72 # endif
73 # if defined(AO_HAVE_fetch_and_add) && defined(AO_HAVE_fetch_and_add1) \
74 && defined(AO_HAVE_fetch_and_sub1)
75 TA_assert(AO_fetch_and_add(&x, 42) == 13);
76 TA_assert(AO_fetch_and_add(&x, (AO_t)(-43)) == 55);
77 TA_assert(AO_fetch_and_add1(&x) == 12);
78 TA_assert(AO_fetch_and_sub1(&x) == 13);
79 TA_assert(AO_fetch_and_add1(&x) == 12); /*< the 2nd call */
80 # endif
81 # ifdef AO_HAVE_compare_and_swap_release
82 TA_assert(!AO_compare_and_swap_release(&x, 14, 42));
83 TA_assert(x == 13);
84 TA_assert(AO_compare_and_swap_release(&x, 13, 42));
85 TA_assert(x == 42);
86 # ifdef AO_REQUIRE_CAS
87 {
88 char *cptr = (char *)NULL;
89
90 TA_assert(GC_cptr_compare_and_swap(&cptr, (char *)NULL, (char *)&x));
91 TA_assert(cptr == (char *)&x);
92 }
93 # endif
94 # else
95 if (*(volatile AO_t *)&x == 13)
96 *(volatile AO_t *)&x = 42;
97 # endif
98 # ifdef AO_HAVE_or
99 AO_or(&x, 66);
100 TA_assert(x == 106);
101 # endif
102 # ifdef AO_HAVE_store_release
103 AO_store_release(&x, 113);
104 TA_assert(x == 113);
105 # endif
106 return 0;
107 }
108
109 #else
110
111 int
112 main(void)
113 {
114 printf("test skipped\n");
115 return 0;
116 }
117
118 #endif
119