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