1 //===- subzero/crosstest/test_sync_atomic.cpp - Implementation for tests --===// 2 // 3 // The Subzero Code Generator 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This aims to test that all the atomic RMW instructions and compare and swap 11 // work across the allowed atomic types. This uses the __sync_* builtins 12 // to test the atomic operations. 13 // 14 //===----------------------------------------------------------------------===// 15 16 #include <stdint.h> 17 18 #include <cstdlib> 19 20 #include "test_sync_atomic.h" 21 22 #define X(inst, type) \ 23 type test_##inst(bool fetch_first, volatile type *ptr, type a) { \ 24 if (fetch_first) { \ 25 return __sync_fetch_and_##inst(ptr, a); \ 26 } else { \ 27 return __sync_##inst##_and_fetch(ptr, a); \ 28 } \ 29 } \ 30 type test_alloca_##inst(bool fetch, volatile type *ptr, type a) { \ 31 const size_t buf_size = 8; \ 32 type buf[buf_size]; \ 33 for (size_t i = 0; i < buf_size; ++i) { \ 34 if (fetch) { \ 35 buf[i] = __sync_fetch_and_##inst(ptr, a); \ 36 } else { \ 37 buf[i] = __sync_##inst##_and_fetch(ptr, a); \ 38 } \ 39 } \ 40 type sum = 0; \ 41 for (size_t i = 0; i < buf_size; ++i) { \ 42 sum += buf[i]; \ 43 } \ 44 return sum; \ 45 } \ 46 type test_const_##inst(bool fetch, volatile type *ptr, type ign) { \ 47 if (fetch) { \ 48 return __sync_fetch_and_##inst(ptr, 42); \ 49 } else { \ 50 const type value = static_cast<type>(0xaaaaaaaaaaaaaaaaull); \ 51 return __sync_##inst##_and_fetch(ptr, value); \ 52 } \ 53 } 54 55 FOR_ALL_RMWOP_TYPES(X) 56 #undef X 57 58 #define X(type) \ 59 type test_val_cmp_swap(volatile type *ptr, type oldval, type newval) { \ 60 return __sync_val_compare_and_swap(ptr, oldval, newval); \ 61 } \ 62 type test_val_cmp_swap_loop(volatile type *ptr, type oldval, type newval) { \ 63 type prev; \ 64 type succeeded_first_try = 1; \ 65 while (1) { \ 66 prev = __sync_val_compare_and_swap(ptr, oldval, newval); \ 67 if (prev == oldval) \ 68 break; \ 69 succeeded_first_try = 0; \ 70 oldval = prev; \ 71 } \ 72 return succeeded_first_try; \ 73 } 74 75 ATOMIC_TYPE_TABLE 76 #undef X 77