blob: 2ab5ee932265d1b6e25343da1bf9a727f798c1f5 [file] [log] [blame]
/*
* Copyright (c) 2013 The Native Client Authors. All rights reserved.
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
/*
* This test ensures that the PNaCl backends can deal with volatile
* operations as would be written by regular users, including PNaCl's
* ABI stabilization and target lowering.
*
* See other synchronization_* tests in this directory.
*
* This is a syntactical check as we do not run this multithreaded. Some
* real testing is done here: tests/threads/thread_test.c
*
* PNaCl's atomic support is based on C11/C++11's. PNaCl only supports
* 8, 16, 32 and 64-bit atomics, and should be able to handle any type
* that can map to these (e.g. 32- and 64-bit atomic floating point
* load/store).
*/
#include <inttypes.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#define STR_(A) #A
#define STR(A) STR_(A)
#define CHECK_EQ(LHS, RHS, MSG) do { \
printf("\t" MSG ":\t" STR(LHS) "=%" PRIu64 \
" and " STR(RHS) "=%" PRIu64 "\n", \
(uint64_t)(LHS), (uint64_t)(RHS)); \
if ((LHS) != (RHS)) { \
fprintf(stderr, "ERROR: " MSG ": `" \
STR(LHS) " != " STR(RHS) "` " \
"\n"); \
exit(1); \
} \
} while (0)
void test_volatile_operations(void) {
# define VOLATILE_OPERATION_TEST(OPERATION_NAME, OPERATION, TYPE) do { \
volatile TYPE loc = 5; \
TYPE loc_ = 5; \
TYPE value = 41; \
printf("Testing volatile " STR(OPERATION_NAME) \
" with " STR(TYPE) "\n"); \
loc = loc OPERATION value; \
loc_ = loc_ OPERATION value; \
CHECK_EQ(loc, loc_, "volatile " STR(TYPE) " " STR(OPERATION_NAME)); \
} while (0)
# define VOLATILE_OPERATION_TEST_ALL_TYPES(OPERATION_NAME, OPERATION) \
VOLATILE_OPERATION_TEST(OPERATION_NAME, OPERATION, uint8_t); \
VOLATILE_OPERATION_TEST(OPERATION_NAME, OPERATION, uint16_t); \
VOLATILE_OPERATION_TEST(OPERATION_NAME, OPERATION, uint32_t); \
VOLATILE_OPERATION_TEST(OPERATION_NAME, OPERATION, uint64_t);
VOLATILE_OPERATION_TEST_ALL_TYPES(add, +);
VOLATILE_OPERATION_TEST_ALL_TYPES(sub, -);
VOLATILE_OPERATION_TEST_ALL_TYPES(or, |);
VOLATILE_OPERATION_TEST_ALL_TYPES(and, &);
VOLATILE_OPERATION_TEST_ALL_TYPES(xor, ^);
}
void test_volatile_load_store(void) {
# define VOLATILE_LOAD_STORE_TEST(TYPE) do { \
volatile TYPE loc = 5; \
TYPE res = loc; \
CHECK_EQ(res, 5, "volatile " STR(TYPE) " load"); \
loc = 41; \
CHECK_EQ(loc, 41, "volatile " STR(TYPE) " store"); \
} while (0)
VOLATILE_LOAD_STORE_TEST(uint8_t);
VOLATILE_LOAD_STORE_TEST(uint16_t);
VOLATILE_LOAD_STORE_TEST(uint32_t);
VOLATILE_LOAD_STORE_TEST(uint64_t);
VOLATILE_LOAD_STORE_TEST(float);
VOLATILE_LOAD_STORE_TEST(double);
}
int main(void) {
test_volatile_operations();
test_volatile_load_store();
return 0;
}