ae2f_docs
c89atomic_basic.c
1/*
2Tests basic logic of all atomic functions. Does not test atomicity.
3*/
4#include <stdio.h>
5#include <string.h>
6
7//#define C89ATOMIC_MODERN_GCC
8//#define C89ATOMIC_LEGACY_GCC
9//#define C89ATOMIC_LEGACY_GCC_ASM
10//#define C89ATOMIC_MODERN_MSVC
11//#define C89ATOMIC_LEGACY_MSVC
12//#define C89ATOMIC_LEGACY_MSVC_ASM
13#include "../c89atomic.c"
14
15#include "../extras/c89atomic_deque.c"
16#include "../extras/c89atomic_bitmap_allocator.c"
17
18#if defined(__clang__) || (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)))
19 #pragma GCC diagnostic push
20 #pragma GCC diagnostic ignored "-Wlong-long"
21 #if defined(__clang__)
22 #pragma GCC diagnostic ignored "-Wc++11-long-long"
23 #endif
24#endif
25
26#if defined(_MSC_VER) || defined(__BORLANDC__)
27 #define C89ATOMIC_ULL(x) (c89atomic_uint64)(x##i64)
28#else
29 #define C89ATOMIC_ULL(x) (c89atomic_uint64)(x##ULL)
30#endif
31
32#if defined(_WIN32)
33#include <windows.h>
34
35#ifndef ENABLE_VIRTUAL_TERMINAL_PROCESSING
36#define ENABLE_VIRTUAL_TERMINAL_PROCESSING 0x0004
37#endif
38
39static void enable_colored_output(void)
40{
41 HANDLE hOut;
42 DWORD mode;
43
44 hOut = GetStdHandle(STD_OUTPUT_HANDLE);
45 if (hOut == INVALID_HANDLE_VALUE) {
46 return;
47 }
48
49 if (!GetConsoleMode(hOut, &mode)) {
50 return;
51 }
52
53 SetConsoleMode(hOut, mode | ENABLE_VIRTUAL_TERMINAL_PROCESSING);
54}
55#else
56static void enable_colored_output(void)
57{
58 /* Do nothing. */
59}
60#endif
61
62
63#define PRINT_WIDTH 40
64
65/* Need to use a non-0 value for the old value to test byte ordering stuff properly. */
66#define OLD_VAL 42
67
68static int g_ErrorCount = 0;
69
70const char* c89atomic_memory_order_to_string(c89atomic_memory_order order)
71{
72 switch (order)
73 {
74 case c89atomic_memory_order_relaxed: return "c89atomic_memory_order_relaxed";
75 case c89atomic_memory_order_consume: return "c89atomic_memory_order_consume";
76 case c89atomic_memory_order_acquire: return "c89atomic_memory_order_acquire";
77 case c89atomic_memory_order_release: return "c89atomic_memory_order_release";
78 case c89atomic_memory_order_acq_rel: return "c89atomic_memory_order_acq_rel";
79 case c89atomic_memory_order_seq_cst: return "c89atomic_memory_order_seq_cst";
80 }
81
82 return "[unknown memory order]";
83}
84
85
86void c89atomic_test_passed(void)
87{
88 printf("\033[32mPASSED\033[0m\n");
89}
90
91void c89atomic_test_failed(void)
92{
93 printf("\033[31mFAILED\033[0m\n");
94 g_ErrorCount += 1;
95}
96
97
98#define c89atomic_test__basic__flag_test_and_set_explicit(order) \
99{
100 printf(" %-*s", PRINT_WIDTH, c89atomic_memory_order_to_string(order));
101 {
102 c89atomic_flag a = 0;
103 c89atomic_flag b = 0;
104 c89atomic_flag r = c89atomic_flag_test_and_set_explicit(&b, order);
105 if (a == r && b == 1) {
106 c89atomic_test_passed();
107 } else {
108 c89atomic_test_failed();
109 }
110 } \
111}
112
113void c89atomic_test__basic__flag_test_and_set(void)
114{
115 printf("c89atomic_flag_test_and_set():\n");
116
118 /*c89atomic_test__basic__flag_test_and_set_explicit(c89atomic_memory_order_consume);*/
123
124 printf("\n");
125}
126
127#define c89atomic_test__basic__flag_clear_explicit(order) \
128{
129 printf(" %-*s", PRINT_WIDTH, c89atomic_memory_order_to_string(order));
130 {
131 c89atomic_flag a = 1;
132 c89atomic_flag_clear_explicit(&a, order);
133 if (a == 0) {
134 c89atomic_test_passed();
135 } else {
136 c89atomic_test_failed();
137 }
138 } \
139}
140
141void c89atomic_test__basic__flag_clear(void)
142{
143 printf("c89atomic_flag_clear():\n");
144
148
149 printf("\n");
150}
151
152#define c89atomic_test__basic__flag_load_explicit(order) \
153{
154 printf(" %-*s", PRINT_WIDTH, c89atomic_memory_order_to_string(order));
155 {
156 c89atomic_flag a = 42;
157 c89atomic_flag b = c89atomic_flag_load_explicit(&a, order);
158 if (a == b) {
159 c89atomic_test_passed();
160 } else {
161 c89atomic_test_failed();
162 }
163 } \
164}
165
166void c89atomic_test__basic__flag_load(void)
167{
168 printf("c89atomic_flag_load():\n");
169
173 /*c89atomic_test__basic__flag_load_explicit(c89atomic_memory_order_release);*/
174 /*c89atomic_test__basic__flag_load_explicit(c89atomic_memory_order_acq_rel);*/
176
177 printf("\n");
178}
179
180
181#define c89atomic_test__basic_load_explicit(sizeInBits, src, order) \
182{
183 printf(" %-*s", PRINT_WIDTH, c89atomic_memory_order_to_string(order));
184 {
185 c89atomic_uint##sizeInBits a = src;
186 c89atomic_uint##sizeInBits b = c89atomic_load_explicit_##sizeInBits(&a, order);
187 if (a == b) {
188 c89atomic_test_passed();
189 } else {
190 c89atomic_test_failed();
191 }
192 } \
193}
194
195#define c89atomic_test__basic_load_n(sizeInBits, src) \
196{
197 printf("c89atomic_load_%d():\n", sizeInBits);
201 /*c89atomic_test__basic_load_explicit(sizeInBits, src, c89atomic_memory_order_release);*/
202 /*c89atomic_test__basic_load_explicit(sizeInBits, src, c89atomic_memory_order_acq_rel);*/
204}
205
206void c89atomic_test__basic__load(void)
207{
212 printf("\n");
213}
214
215
216#define c89atomic_test__basic_store_explicit(sizeInBits, src, order) \
217{
218 printf(" %-*s", PRINT_WIDTH, c89atomic_memory_order_to_string(order));
219 {
220 c89atomic_uint##sizeInBits a = OLD_VAL;
221 c89atomic_uint##sizeInBits b = src;
222 c89atomic_store_explicit_##sizeInBits(&a, b, order);
223 if (b == a) {
224 c89atomic_test_passed();
225 } else {
226 c89atomic_test_failed();
227 }
228 } \
229}
230
231#define c89atomic_test__basic_store_n(sizeInBits, src) \
232{
233 printf("c89atomic_store_%d():\n", sizeInBits);
235 /*c89atomic_test__basic_store_explicit(sizeInBits, src, c89atomic_memory_order_consume);*/
236 /*c89atomic_test__basic_store_explicit(sizeInBits, src, c89atomic_memory_order_acquire);*/
238 /*c89atomic_test__basic_store_explicit(sizeInBits, src, c89atomic_memory_order_acq_rel);*/
240}
241
242void c89atomic_test__basic__store(void)
243{
248 printf("\n");
249}
250
251
252#define c89atomic_test__basic_exchange_explicit(sizeInBits, src, order) \
253{
254 printf(" %-*s", PRINT_WIDTH, c89atomic_memory_order_to_string(order));
255 {
256 c89atomic_uint##sizeInBits a = OLD_VAL;
257 c89atomic_uint##sizeInBits b = OLD_VAL;
258 c89atomic_uint##sizeInBits c = src;
259 c89atomic_uint##sizeInBits r = c89atomic_exchange_explicit_##sizeInBits(&b, c, order);
260 if (r == a && b == c) {
261 c89atomic_test_passed();
262 } else {
263 c89atomic_test_failed();
264 }
265 } \
266}
267
268#define c89atomic_test__basic_exchange_n(sizeInBits, src) \
269{
270 printf("c89atomic_exchange_%d():\n", sizeInBits);
272 /*c89atomic_test__basic_exchange_explicit(sizeInBits, src, c89atomic_memory_order_consume);*/
277}
278
279void c89atomic_test__basic__exchange(void)
280{
285 printf("\n");
286}
287
288
289#define c89atomic_test__basic_compare_exchange_strong_explicit(sizeInBits, src, orderSuccess, orderFailure) \
290{
291 printf(" %s, %s ", c89atomic_memory_order_to_string(orderSuccess), c89atomic_memory_order_to_string(orderFailure));
292 {
293 c89atomic_uint##sizeInBits a = OLD_VAL;
294 c89atomic_uint##sizeInBits b = OLD_VAL;
295 c89atomic_uint##sizeInBits c = src;
296 c89atomic_bool r = c89atomic_compare_exchange_strong_explicit_##sizeInBits(&a, &b, c, orderSuccess, orderFailure);
297 if (a == c && b == OLD_VAL && r == 1) {
298 /* Negative case. Expecting a to remain unchanged, b to be set to OLD_VAL (previous value of a) and the result to be false. */
299 a = OLD_VAL;
300 b = (c89atomic_uint##sizeInBits)(a + 1);
301 r = c89atomic_compare_exchange_strong_explicit_##sizeInBits(&a, &b, c, orderSuccess, orderFailure);
302 if (a == OLD_VAL && b == OLD_VAL && r == 0) {
303 c89atomic_test_passed();
304 } else {
305 c89atomic_test_failed();
306 }
307 } else {
308 c89atomic_test_failed();
309 }
310 } \
311}
312
313#define c89atomic_test__basic_compare_exchange_strong_n(sizeInBits, src) \
314{
315 printf("c89atomic_compare_exchange_%d():\n", sizeInBits);
322}
323
324void c89atomic_test__basic__compare_exchange_strong(void)
325{
330 printf("\n");
331}
332
333
334#define c89atomic_test__basic_compare_exchange_weak_explicit(sizeInBits, src, orderSuccess, orderFailure) \
335{
336 printf(" %s, %s ", c89atomic_memory_order_to_string(orderSuccess), c89atomic_memory_order_to_string(orderFailure));
337 {
338 c89atomic_uint##sizeInBits a = OLD_VAL;
339 c89atomic_uint##sizeInBits b = OLD_VAL;
340 c89atomic_uint##sizeInBits c = src;
341 c89atomic_bool r = c89atomic_compare_exchange_weak_explicit_##sizeInBits(&a, &b, c, orderSuccess, orderFailure);
342 if (a == c && b == OLD_VAL && r == 1) {
343 /* Negative case. Expecting a to remain unchanged, b to be set to OLD_VAL (previous value of a) and the result to be false. */
344 a = OLD_VAL;
345 b = (c89atomic_uint##sizeInBits)(a + 1);
346 r = c89atomic_compare_exchange_weak_explicit_##sizeInBits(&a, &b, c, orderSuccess, orderFailure);
347 if (a == OLD_VAL && b == OLD_VAL && r == 0) {
348 c89atomic_test_passed();
349 } else {
350 c89atomic_test_failed();
351 }
352 } else {
353 c89atomic_test_failed();
354 }
355 } \
356}
357
358#define c89atomic_test__basic_compare_exchange_weak_n(sizeInBits, src) \
359{
360 printf("c89atomic_compare_exchange_weak_%d():\n", sizeInBits);
367}
368
369void c89atomic_test__basic__compare_exchange_weak(void)
370{
375 printf("\n");
376}
377
378
379#define c89atomic_test__basic_fetch_add_explicit(sizeInBits, src, order) \
380{
381 printf(" %-*s", PRINT_WIDTH, c89atomic_memory_order_to_string(order));
382 {
383 c89atomic_uint##sizeInBits a = OLD_VAL;
384 c89atomic_uint##sizeInBits b = a;
385 c89atomic_uint##sizeInBits c = src;
386 c89atomic_uint##sizeInBits r = c89atomic_fetch_add_explicit_##sizeInBits(&a, c, order);
387 if (r == b && a == (b + c)) {
388 c89atomic_test_passed();
389 } else {
390 c89atomic_test_failed();
391 }
392 } \
393}
394
395#define c89atomic_test__basic_fetch_add_n(sizeInBits, src) \
396{
397 printf("c89atomic_fetch_add_%d():\n", sizeInBits);
404}
405
406void c89atomic_test__basic__fetch_add(void)
407{
412 printf("\n");
413}
414
415
416#define c89atomic_test__basic_fetch_sub_explicit(sizeInBits, src, order) \
417{
418 printf(" %-*s", PRINT_WIDTH, c89atomic_memory_order_to_string(order));
419 {
420 c89atomic_uint##sizeInBits a = OLD_VAL;
421 c89atomic_uint##sizeInBits b = a;
422 c89atomic_uint##sizeInBits c = src;
423 c89atomic_uint##sizeInBits r = c89atomic_fetch_sub_explicit_##sizeInBits(&a, c, order);
424 if (r == b && a == (c89atomic_uint##sizeInBits)(b - c)) {
425 c89atomic_test_passed();
426 } else {
427 c89atomic_test_failed();
428 }
429 } \
430}
431
432#define c89atomic_test__basic_fetch_sub_n(sizeInBits, src) \
433{
434 printf("c89atomic_fetch_sub_%d():\n", sizeInBits);
441}
442
443void c89atomic_test__basic__fetch_sub(void)
444{
449 printf("\n");
450}
451
452
453#define c89atomic_test__basic_fetch_or_explicit(sizeInBits, src, order) \
454{
455 printf(" %-*s", PRINT_WIDTH, c89atomic_memory_order_to_string(order));
456 {
457 c89atomic_uint##sizeInBits a = OLD_VAL;
458 c89atomic_uint##sizeInBits b = a;
459 c89atomic_uint##sizeInBits c = src;
460 c89atomic_uint##sizeInBits r = c89atomic_fetch_or_explicit_##sizeInBits(&a, c, order);
461 if (r == b && a == (c89atomic_uint##sizeInBits)(b | c)) {
462 c89atomic_test_passed();
463 } else {
464 c89atomic_test_failed();
465 }
466 } \
467}
468
469#define c89atomic_test__basic_fetch_or_n(sizeInBits, src) \
470{
471 printf("c89atomic_fetch_or_%d():\n", sizeInBits);
478}
479
480void c89atomic_test__basic__fetch_or(void)
481{
486 printf("\n");
487}
488
489
490#define c89atomic_test__basic_fetch_xor_explicit(sizeInBits, src, order) \
491{
492 printf(" %-*s", PRINT_WIDTH, c89atomic_memory_order_to_string(order));
493 {
494 c89atomic_uint##sizeInBits a = OLD_VAL;
495 c89atomic_uint##sizeInBits b = a;
496 c89atomic_uint##sizeInBits c = src;
497 c89atomic_uint##sizeInBits r = c89atomic_fetch_xor_explicit_##sizeInBits(&a, c, order);
498 if (r == b && a == (c89atomic_uint##sizeInBits)(b ^ c)) {
499 c89atomic_test_passed();
500 } else {
501 c89atomic_test_failed();
502 }
503 } \
504}
505
506#define c89atomic_test__basic_fetch_xor_n(sizeInBits, src) \
507{
508 printf("c89atomic_fetch_xor_%d():\n", sizeInBits);
515}
516
517void c89atomic_test__basic__fetch_xor(void)
518{
523 printf("\n");
524}
525
526
527#define c89atomic_test__basic_fetch_and_explicit(sizeInBits, src, order) \
528{
529 printf(" %-*s", PRINT_WIDTH, c89atomic_memory_order_to_string(order));
530 {
531 c89atomic_uint##sizeInBits a = OLD_VAL;
532 c89atomic_uint##sizeInBits b = a;
533 c89atomic_uint##sizeInBits c = src;
534 c89atomic_uint##sizeInBits r = c89atomic_fetch_and_explicit_##sizeInBits(&a, c, order);
535 if (r == b && a == (c89atomic_uint##sizeInBits)(b & c)) {
536 c89atomic_test_passed();
537 } else {
538 c89atomic_test_failed();
539 }
540 } \
541}
542
543#define c89atomic_test__basic_fetch_and_n(sizeInBits, src) \
544{
545 printf("c89atomic_fetch_and_%d():\n", sizeInBits);
552}
553
554void c89atomic_test__basic__fetch_and(void)
555{
560 printf("\n");
561}
562
563
564#define c89atomic_test__basic_compare_and_swap_explicit(sizeInBits, src) \
565{
566 printf("c89atomic_compare_and_swap_%d() ", sizeInBits); printf("%*s", (int)(sizeInBits == 8), "");
567 {
568 c89atomic_uint##sizeInBits a = OLD_VAL;
569 c89atomic_uint##sizeInBits b = a;
570 c89atomic_uint##sizeInBits c = src;
571 c89atomic_uint##sizeInBits r = c89atomic_compare_and_swap_##sizeInBits(&a, b, c);
572 if (a == c && r == b) {
573 /* Negative case. Expecting a to remain unchanged and the result to not be equal to the expected value. */
574 a = OLD_VAL;
575 b = (c89atomic_uint##sizeInBits)(a + 1);
576 r = c89atomic_compare_and_swap_##sizeInBits(&a, b, c);
577 if (a == OLD_VAL && r != b) {
578 c89atomic_test_passed();
579 } else {
580 c89atomic_test_failed();
581 }
582 } else {
583 c89atomic_test_failed();
584 }
585 } \
586}
587
588void c89atomic_test__basic__compare_and_swap(void)
589{
594 printf("\n");
595}
596
597
598#define C89ATOMIC_CHECK_SIZEOF(type, size) \
599{
600 printf("sizeof(%s)%*.s== %d ", #type, 17 - (int)strlen(#type), "", size);
601 if (sizeof(type) != size) {
602 c89atomic_test_failed();
603 } else {
604 c89atomic_test_passed();
605 } \
606}
607
608static void c89atomic_test__basic__sizeof(void)
609{
610 C89ATOMIC_CHECK_SIZEOF(c89atomic_int8, 1);
611 C89ATOMIC_CHECK_SIZEOF(c89atomic_uint8, 1);
612 C89ATOMIC_CHECK_SIZEOF(c89atomic_int16, 2);
613 C89ATOMIC_CHECK_SIZEOF(c89atomic_uint16, 2);
614 C89ATOMIC_CHECK_SIZEOF(c89atomic_int32, 4);
615 C89ATOMIC_CHECK_SIZEOF(c89atomic_uint32, 4);
616 C89ATOMIC_CHECK_SIZEOF(c89atomic_int64, 8);
617 C89ATOMIC_CHECK_SIZEOF(c89atomic_uint64, 8);
618 printf("\n");
619}
620
621
622int main(int argc, char** argv)
623{
624 enable_colored_output();
625
626 /* The size of basic types must be valid. If not, the architecture/compiler/platform is not supported. */
627 c89atomic_test__basic__sizeof();
628 if (g_ErrorCount > 0) {
629 printf("Tests cannot continue because the size of one or more basic types are not valid.\n");
630 return 1;
631 }
632
633 c89atomic_test__basic__flag_test_and_set();
634 c89atomic_test__basic__flag_clear();
635 c89atomic_test__basic__flag_load();
636 c89atomic_test__basic__load();
637 c89atomic_test__basic__store();
638 c89atomic_test__basic__exchange();
639 c89atomic_test__basic__compare_exchange_strong();
640 c89atomic_test__basic__compare_exchange_weak();
641 c89atomic_test__basic__fetch_add();
642 c89atomic_test__basic__fetch_sub();
643 c89atomic_test__basic__fetch_or();
644 c89atomic_test__basic__fetch_xor();
645 c89atomic_test__basic__fetch_and();
646 c89atomic_test__basic__compare_and_swap();
647
648 printf("c89atomic_is_lock_free_8 = %s\n", c89atomic_is_lock_free_8(NULL) ? "\033[32mTRUE\033[0m" : "\033[31mFALSE\033[0m");
649 printf("c89atomic_is_lock_free_16 = %s\n", c89atomic_is_lock_free_16(NULL) ? "\033[32mTRUE\033[0m" : "\033[31mFALSE\033[0m");
650 printf("c89atomic_is_lock_free_32 = %s\n", c89atomic_is_lock_free_32(NULL) ? "\033[32mTRUE\033[0m" : "\033[31mFALSE\033[0m");
651 printf("c89atomic_is_lock_free_64 = %s\n", c89atomic_is_lock_free_64(NULL) ? "\033[32mTRUE\033[0m" : "\033[31mFALSE\033[0m");
652
653 /* Putting these functions here for testing that they compile. */
654 c89atomic_thread_fence(c89atomic_memory_order_seq_cst);
656
657 /* Testing cases where the return value is not used. */
658 {
659 void* dst = NULL;
660 void* src = NULL;
661 c89atomic_exchange_ptr(&dst, src);
663 }
664
665 {
666 c89atomic_uint64 dst = 0;
667 c89atomic_uint64 src = 1;
668 c89atomic_exchange_64(&dst, src);
669 }
670
671 /* Testing that some basic integer versions are working without compilation errors. */
672 {
673 int dst = 0;
674 int src = 1;
675 int res = c89atomic_exchange_i32(&dst, src);
676 (void)res;
677 }
678
679 /* Basic floating point tests. */
680 {
681 float dst = 1.0f;
682 float src = 2.0f;
683 float res = c89atomic_exchange_f32(&dst, src);
684 (void)res;
685
686 res = c89atomic_load_f32(&dst);
687 (void)res;
688 }
689
690 {
691 double dst = 1.0f;
692 double src = 2.0f;
693 double res = c89atomic_exchange_f64(&dst, src);
694 (void)res;
695
696 res = c89atomic_load_f64(&dst);
697 (void)res;
698 }
699
700
701 /* Basic deque tests. Not currently testing for multi-threaded correctness. */
702 {
703 c89atomic_deque_result result;
704 c89atomic_deque deque;
705 void* pValue = (void*)123456;
706
707 c89atomic_deque_init(&deque);
708
709 /* First thing to test is to take from the tail while the deque is empty. Want to test for wrap around bugs due to 1 being subtracted from 0. */
710 printf("\n");
711 printf("Deque Take Tail (Empty): ");
712 result = c89atomic_deque_take_tail(&deque, &pValue);
713 if (result == C89ATOMIC_DEQUE_NO_DATA_AVAILABLE) {
714 c89atomic_test_passed();
715 } else {
716 c89atomic_test_failed();
717 }
718
719 printf("Deque Take Head (Empty): ");
720 result = c89atomic_deque_take_head(&deque, &pValue);
721 if (result == C89ATOMIC_DEQUE_NO_DATA_AVAILABLE) {
722 c89atomic_test_passed();
723 } else {
724 c89atomic_test_failed();
725 }
726
727 printf("Deque Push Tail: ");
728 result = c89atomic_deque_push_tail(&deque, (void*)1);
729 if (result == C89ATOMIC_DEQUE_SUCCESS) {
730 result = c89atomic_deque_push_tail(&deque, (void*)2);
731 if (result == C89ATOMIC_DEQUE_SUCCESS) {
732 result = c89atomic_deque_push_tail(&deque, (void*)3);
733 if (result == C89ATOMIC_DEQUE_SUCCESS) {
734 c89atomic_test_passed();
735 } else {
736 c89atomic_test_failed();
737 }
738 } else {
739 c89atomic_test_failed();
740 }
741 } else {
742 c89atomic_test_failed();
743 }
744
745
746 /* Take from the tail. Expecting "3". */
747 printf("Deque Take Tail: ");
748 result = c89atomic_deque_take_tail(&deque, &pValue);
749 if (result == C89ATOMIC_DEQUE_SUCCESS && pValue == (void*)3) {
750 c89atomic_test_passed();
751 } else {
752 c89atomic_test_failed();
753 }
754
755 /* Steal from the head. Expecting "1". */
756 printf("Deque Take Head: ");
757 result = c89atomic_deque_take_head(&deque, &pValue);
758 if (result == C89ATOMIC_DEQUE_SUCCESS && pValue == (void*)1) {
759 c89atomic_test_passed();
760 } else {
761 c89atomic_test_failed();
762 }
763
764 /* Take last item. */
765 printf("Deque Take Tail (Last): ");
766 result = c89atomic_deque_take_tail(&deque, &pValue);
767 if (result == C89ATOMIC_DEQUE_SUCCESS && pValue == (void*)2) {
768 c89atomic_test_passed();
769 } else {
770 c89atomic_test_failed();
771 }
772
773 /* Now the deque should be empty. */
774 printf("Deque Empty: ");
775 if (deque.head == deque.tail) {
776 c89atomic_test_passed();
777 } else {
778 c89atomic_test_failed();
779 }
780
781 /* Now we're going to take the last item from the head. We'll need to push a fresh item. */
782 printf("Deque Take Head (Last): ");
783 result = c89atomic_deque_push_tail(&deque, (void*)4);
784 if (result == C89ATOMIC_DEQUE_SUCCESS) {
785 result = c89atomic_deque_take_head(&deque, &pValue);
786 if (result == C89ATOMIC_DEQUE_SUCCESS && pValue == (void*)4) {
787 c89atomic_test_passed();
788 } else {
789 c89atomic_test_failed();
790 }
791 } else {
792 c89atomic_test_failed();
793 }
794
795 printf("Deque Empty: ");
796 if (deque.head == deque.tail) {
797 c89atomic_test_passed();
798 } else {
799 c89atomic_test_failed();
800 }
801 }
802
803
804 /* Basic bitmap allocator test. */
805 {
806 c89atomic_bitmap_allocator_result result;
807 c89atomic_uint32 bitmap[2];
808 c89atomic_bitmap_allocator allocator;
809 size_t i = 0;
810 size_t allocIndex = 1234;
811 c89atomic_bool success = 1;
812
813 c89atomic_bitmap_allocator_init(bitmap, sizeof(bitmap) * 8, &allocator);
814
815 printf("\n");
816 printf("Bitmap Allocator Alloc: ");
817 for (i = 0; i < sizeof(bitmap) * 8; i += 1) {
818 result = c89atomic_bitmap_allocator_alloc(&allocator, &allocIndex);
819 if (result != C89ATOMIC_BITMAP_ALLOCATOR_SUCCESS) {
820 c89atomic_test_failed();
821 success = 0;
822 break;
823 }
824
825 if (allocIndex != i) {
826 c89atomic_test_failed();
827 success = 0;
828 break;
829 }
830 }
831
832 if (success) {
833 c89atomic_test_passed();
834 }
835
836 printf("Bitmap Allocator No Mem: ");
837 result = c89atomic_bitmap_allocator_alloc(&allocator, &allocIndex);
838 if (result == C89ATOMIC_BITMAP_ALLOCATOR_OUT_OF_MEMORY) {
839 c89atomic_test_passed();
840 } else {
841 c89atomic_test_failed();
842 }
843
844 printf("Bitmap Allocator Free: ");
845 c89atomic_bitmap_allocator_free(&allocator, 34);
846 result = c89atomic_bitmap_allocator_alloc(&allocator, &allocIndex);
847 if (result == C89ATOMIC_BITMAP_ALLOCATOR_SUCCESS && allocIndex == 34) {
848 c89atomic_test_passed();
849 } else {
850 c89atomic_test_failed();
851 }
852 }
853
854
855 (void)argc;
856 (void)argv;
857
858 printf("\n");
859
860 printf("Compiler: ");
861 #if defined(__clang__)
862 printf("Clang %d.%d\n", __clang_major__, __clang_minor__);
863 #elif defined(__GNUC__)
864 printf("GCC %d.%d\n", __GNUC__, __GNUC_MINOR__);
865 #elif defined(_MSC_VER)
866 printf("MSVC %d\n", _MSC_VER);
867 #elif defined(__TINYC__)
868 printf("TinyCC %d\n", __TINYC__);
869 #elif defined(__WATCOMC__)
870 printf("Watcom %d.%d\n", __WATCOMC__ / 100, (__WATCOMC__ - (__WATCOMC__ / 100)) / 10);
871 #elif defined(__DMC__)
872 printf("Digital Mars %d\n", __DMC__);
873 #elif defined(__BORLANDC__)
874 printf("Borland C++ %d\n", __BORLANDC__);
875 #else
876 printf("Unknown\n");
877 #endif
878
879 printf("Architecture: ");
880 #if defined(C89ATOMIC_X64)
881 printf("x64\n");
882 #endif
883 #if defined(C89ATOMIC_X86)
884 printf("x86");
885 #if defined(__GNUC__)
886 #if !defined(__i486__)
887 printf(" (i386)\n");
888 #elif !defined(__i586__)
889 printf(" (i486)\n");
890 #elif !defined(__i686__)
891 printf(" (i586+)\n");
892 #else
893 printf("\n");
894 #endif
895 #elif defined(_M_IX86)
896 #if _M_IX86 == 300
897 printf(" (i386)\n");
898 #elif _M_IX86 == 400
899 printf(" (i486)\n");
900 #elif _M_IX86 >= 500
901 printf(" (i586+)\n");
902 #else
903 printf("\n");
904 #endif
905 #else
906 printf("\n");
907 #endif
908 #endif
909 #if defined(C89ATOMIC_ARM64)
910 printf("ARM64\n");
911 #endif
912 #if defined(C89ATOMIC_ARM32)
913 printf("ARM32\n");
914 #endif
915 #if defined(C89ATOMIC_PPC64)
916 printf("PowerPC64\n");
917 #endif
918 #if defined(C89ATOMIC_PPC32)
919 printf("PowerPC\n");
920 #endif
921
922 printf("Code Path: ");
923 #if defined(C89ATOMIC_MODERN_GCC)
924 printf("GCC __atomic* intrinsics\n");
925 #elif defined(C89ATOMIC_LEGACY_GCC)
926 printf("GCC __sync* intrinsics\n");
927 #elif defined(C89ATOMIC_LEGACY_GCC_ASM)
928 printf("GCC inlined assembly\n");
929 #elif defined(C89ATOMIC_MODERN_MSVC)
930 printf("MSVC _Interlocked* intrinsics\n");
931 #elif defined(C89ATOMIC_LEGACY_MSVC)
932 printf("MSVC _Interlocked* intrinsics (no lock-free 8/16 bit)\n");
933 #elif defined(C89ATOMIC_LEGACY_MSVC_ASM)
934 printf("MSVC inlined assembly\n");
935 #endif
936
937 if (g_ErrorCount > 0) {
938 printf("\033[31m%d test(s) failed.\033[0m\n", g_ErrorCount);
939 return 1;
940 } else {
941 /*printf("\033[32mAll tests passed.\033[0m\n");*/
942 return 0;
943 }
944}
945
946#if defined(__clang__) || (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)))
947 #pragma GCC diagnostic pop /* -Wlong-long */
948#endif
#define c89atomic_memory_order_release
Definition c89atomic.h:583
#define c89atomic_memory_order_seq_cst
Definition c89atomic.h:585
#define c89atomic_memory_order_acquire
Definition c89atomic.h:582
#define c89atomic_exchange_f64(dst, src)
Definition c89atomic.h:4044
#define c89atomic_signal_fence(order)
Definition c89atomic.h:2320
#define c89atomic_memory_order_relaxed
Definition c89atomic.h:580
#define c89atomic_exchange_f32(dst, src)
Definition c89atomic.h:4043
#define c89atomic_memory_order_consume
Definition c89atomic.h:581
#define c89atomic_exchange_64(dst, src)
Definition c89atomic.h:3691
#define c89atomic_exchange_ptr(dst, src)
Definition c89atomic.h:3671
#define c89atomic_load_f32(ptr)
Definition c89atomic.h:4040
#define c89atomic_memory_order_acq_rel
Definition c89atomic.h:584
#define c89atomic_load_f64(ptr)
Definition c89atomic.h:4041
#define c89atomic_exchange_i32(dst, src)
Definition c89atomic.h:3796
#define c89atomic_compare_exchange_strong_ptr(dst, expected, replacement)
Definition c89atomic.h:3672
#define c89atomic_test__basic_compare_exchange_weak_n(sizeInBits, src)
#define c89atomic_test__basic_fetch_or_explicit(sizeInBits, src, order)
#define PRINT_WIDTH
#define c89atomic_test__basic_fetch_or_n(sizeInBits, src)
#define c89atomic_test__basic_compare_exchange_strong_explicit(sizeInBits, src, orderSuccess, orderFailure)
#define c89atomic_test__basic_compare_exchange_strong_n(sizeInBits, src)
#define c89atomic_test__basic_fetch_xor_explicit(sizeInBits, src, order)
#define c89atomic_test__basic_fetch_add_explicit(sizeInBits, src, order)
#define c89atomic_test__basic__flag_load_explicit(order)
#define C89ATOMIC_CHECK_SIZEOF(type, size)
#define c89atomic_test__basic_compare_exchange_weak_explicit(sizeInBits, src, orderSuccess, orderFailure)
#define c89atomic_test__basic_fetch_and_explicit(sizeInBits, src, order)
#define c89atomic_test__basic_store_explicit(sizeInBits, src, order)
#define c89atomic_test__basic__flag_test_and_set_explicit(order)
#define c89atomic_test__basic_fetch_sub_n(sizeInBits, src)
#define c89atomic_test__basic_compare_and_swap_explicit(sizeInBits, src)
#define c89atomic_test__basic_fetch_and_n(sizeInBits, src)
#define c89atomic_test__basic_fetch_xor_n(sizeInBits, src)
#define C89ATOMIC_ULL(x)
#define c89atomic_test__basic__flag_clear_explicit(order)
#define c89atomic_test__basic_load_explicit(sizeInBits, src, order)
#define c89atomic_test__basic_load_n(sizeInBits, src)
#define OLD_VAL
#define c89atomic_test__basic_fetch_sub_explicit(sizeInBits, src, order)
#define c89atomic_test__basic_exchange_n(sizeInBits, src)
#define c89atomic_test__basic_store_n(sizeInBits, src)
#define c89atomic_test__basic_fetch_add_n(sizeInBits, src)
#define c89atomic_test__basic_exchange_explicit(sizeInBits, src, order)