1ff80b92a58ef802e2721d1b51da6157be696c932José Fonseca/**************************************************************************
2ff80b92a58ef802e2721d1b51da6157be696c932José Fonseca *
3ff80b92a58ef802e2721d1b51da6157be696c932José Fonseca * Copyright 2014 VMware, Inc.
4ff80b92a58ef802e2721d1b51da6157be696c932José Fonseca * All Rights Reserved.
5ff80b92a58ef802e2721d1b51da6157be696c932José Fonseca *
6ff80b92a58ef802e2721d1b51da6157be696c932José Fonseca * Permission is hereby granted, free of charge, to any person obtaining a
7ff80b92a58ef802e2721d1b51da6157be696c932José Fonseca * copy of this software and associated documentation files (the
8ff80b92a58ef802e2721d1b51da6157be696c932José Fonseca * "Software"), to deal in the Software without restriction, including
9ff80b92a58ef802e2721d1b51da6157be696c932José Fonseca * without limitation the rights to use, copy, modify, merge, publish,
10ff80b92a58ef802e2721d1b51da6157be696c932José Fonseca * distribute, sub license, and/or sell copies of the Software, and to
11ff80b92a58ef802e2721d1b51da6157be696c932José Fonseca * permit persons to whom the Software is furnished to do so, subject to
12ff80b92a58ef802e2721d1b51da6157be696c932José Fonseca * the following conditions:
13ff80b92a58ef802e2721d1b51da6157be696c932José Fonseca *
14ff80b92a58ef802e2721d1b51da6157be696c932José Fonseca * The above copyright notice and this permission notice (including the
15ff80b92a58ef802e2721d1b51da6157be696c932José Fonseca * next paragraph) shall be included in all copies or substantial portions
16ff80b92a58ef802e2721d1b51da6157be696c932José Fonseca * of the Software.
17ff80b92a58ef802e2721d1b51da6157be696c932José Fonseca *
18ff80b92a58ef802e2721d1b51da6157be696c932José Fonseca * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19ff80b92a58ef802e2721d1b51da6157be696c932José Fonseca * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20ff80b92a58ef802e2721d1b51da6157be696c932José Fonseca * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21ff80b92a58ef802e2721d1b51da6157be696c932José Fonseca * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
22ff80b92a58ef802e2721d1b51da6157be696c932José Fonseca * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23ff80b92a58ef802e2721d1b51da6157be696c932José Fonseca * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24ff80b92a58ef802e2721d1b51da6157be696c932José Fonseca * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25ff80b92a58ef802e2721d1b51da6157be696c932José Fonseca *
26ff80b92a58ef802e2721d1b51da6157be696c932José Fonseca **************************************************************************/
27ff80b92a58ef802e2721d1b51da6157be696c932José Fonseca
28ff80b92a58ef802e2721d1b51da6157be696c932José Fonseca
29d566382a98bc1f6cbc8b93ca7eb9136d2363e5b0Giuseppe Bilotta/* Force assertions, even on release builds. */
30ff80b92a58ef802e2721d1b51da6157be696c932José Fonseca#undef NDEBUG
31ff80b92a58ef802e2721d1b51da6157be696c932José Fonseca
32ff80b92a58ef802e2721d1b51da6157be696c932José Fonseca
33ff80b92a58ef802e2721d1b51da6157be696c932José Fonseca#include <stdint.h>
34ff80b92a58ef802e2721d1b51da6157be696c932José Fonseca#include <inttypes.h>
35ff80b92a58ef802e2721d1b51da6157be696c932José Fonseca#include <assert.h>
36ff80b92a58ef802e2721d1b51da6157be696c932José Fonseca
37ff80b92a58ef802e2721d1b51da6157be696c932José Fonseca#include "u_atomic.h"
38ff80b92a58ef802e2721d1b51da6157be696c932José Fonseca
3925d6cdd2ff1f00e0eab532956c0ae17d4ffa42daJosé Fonseca#ifdef _MSC_VER
4025d6cdd2ff1f00e0eab532956c0ae17d4ffa42daJosé Fonseca#pragma warning( disable : 28112 ) /* Accessing a local variable via an Interlocked function */
4125d6cdd2ff1f00e0eab532956c0ae17d4ffa42daJosé Fonseca#pragma warning( disable : 28113 ) /* A variable which is accessed via an Interlocked function must always be accessed via an Interlocked function */
4225d6cdd2ff1f00e0eab532956c0ae17d4ffa42daJosé Fonseca#endif
4325d6cdd2ff1f00e0eab532956c0ae17d4ffa42daJosé Fonseca
44ff80b92a58ef802e2721d1b51da6157be696c932José Fonseca
45b09f25428ff5e908aefc03b8f9931599c3afd6d2José Fonseca/* Test only assignment-like operations, which are supported on all types */
46b09f25428ff5e908aefc03b8f9931599c3afd6d2José Fonseca#define test_atomic_assign(type, ones) \
47b09f25428ff5e908aefc03b8f9931599c3afd6d2José Fonseca   static void test_atomic_assign_##type (void) { \
48ff80b92a58ef802e2721d1b51da6157be696c932José Fonseca      type v, r; \
49ff80b92a58ef802e2721d1b51da6157be696c932José Fonseca      \
50ff80b92a58ef802e2721d1b51da6157be696c932José Fonseca      p_atomic_set(&v, ones); \
51ff80b92a58ef802e2721d1b51da6157be696c932José Fonseca      assert(v == ones && "p_atomic_set"); \
52ff80b92a58ef802e2721d1b51da6157be696c932José Fonseca      \
53ff80b92a58ef802e2721d1b51da6157be696c932José Fonseca      r = p_atomic_read(&v); \
54ff80b92a58ef802e2721d1b51da6157be696c932José Fonseca      assert(r == ones && "p_atomic_read"); \
55ff80b92a58ef802e2721d1b51da6157be696c932José Fonseca      \
56ff80b92a58ef802e2721d1b51da6157be696c932José Fonseca      v = ones; \
57ff80b92a58ef802e2721d1b51da6157be696c932José Fonseca      r = p_atomic_cmpxchg(&v, 0, 1); \
58ff80b92a58ef802e2721d1b51da6157be696c932José Fonseca      assert(v == ones && "p_atomic_cmpxchg"); \
59ff80b92a58ef802e2721d1b51da6157be696c932José Fonseca      assert(r == ones && "p_atomic_cmpxchg"); \
60ff80b92a58ef802e2721d1b51da6157be696c932José Fonseca      r = p_atomic_cmpxchg(&v, ones, 0); \
61ff80b92a58ef802e2721d1b51da6157be696c932José Fonseca      assert(v == 0 && "p_atomic_cmpxchg"); \
62ff80b92a58ef802e2721d1b51da6157be696c932José Fonseca      assert(r == ones && "p_atomic_cmpxchg"); \
63ff80b92a58ef802e2721d1b51da6157be696c932José Fonseca      \
64b09f25428ff5e908aefc03b8f9931599c3afd6d2José Fonseca      (void) r; \
65b09f25428ff5e908aefc03b8f9931599c3afd6d2José Fonseca   }
66b09f25428ff5e908aefc03b8f9931599c3afd6d2José Fonseca
67b09f25428ff5e908aefc03b8f9931599c3afd6d2José Fonseca
68b09f25428ff5e908aefc03b8f9931599c3afd6d2José Fonseca/* Test arithmetic operations that are supported on 8 bits integer types */
69b09f25428ff5e908aefc03b8f9931599c3afd6d2José Fonseca#define test_atomic_8bits(type, ones) \
70b09f25428ff5e908aefc03b8f9931599c3afd6d2José Fonseca   test_atomic_assign(type, ones) \
71b09f25428ff5e908aefc03b8f9931599c3afd6d2José Fonseca   \
72b09f25428ff5e908aefc03b8f9931599c3afd6d2José Fonseca   static void test_atomic_8bits_##type (void) { \
73b09f25428ff5e908aefc03b8f9931599c3afd6d2José Fonseca      type v, r; \
74b09f25428ff5e908aefc03b8f9931599c3afd6d2José Fonseca      \
75b09f25428ff5e908aefc03b8f9931599c3afd6d2José Fonseca      test_atomic_assign_##type(); \
76b09f25428ff5e908aefc03b8f9931599c3afd6d2José Fonseca      \
77d2438f5920b95a880e9146882a58bf37ec57bad5José Fonseca      v = 23; \
78d2438f5920b95a880e9146882a58bf37ec57bad5José Fonseca      p_atomic_add(&v, 42); \
79d2438f5920b95a880e9146882a58bf37ec57bad5José Fonseca      r = p_atomic_read(&v); \
80d2438f5920b95a880e9146882a58bf37ec57bad5José Fonseca      assert(r == 65 && "p_atomic_add"); \
81d2438f5920b95a880e9146882a58bf37ec57bad5José Fonseca      \
82ff80b92a58ef802e2721d1b51da6157be696c932José Fonseca      (void) r; \
83ff80b92a58ef802e2721d1b51da6157be696c932José Fonseca   }
84ff80b92a58ef802e2721d1b51da6157be696c932José Fonseca
85ff80b92a58ef802e2721d1b51da6157be696c932José Fonseca
86b09f25428ff5e908aefc03b8f9931599c3afd6d2José Fonseca/* Test all operations */
87ff80b92a58ef802e2721d1b51da6157be696c932José Fonseca#define test_atomic(type, ones) \
88d2438f5920b95a880e9146882a58bf37ec57bad5José Fonseca   test_atomic_8bits(type, ones) \
89ff80b92a58ef802e2721d1b51da6157be696c932José Fonseca   \
90ff80b92a58ef802e2721d1b51da6157be696c932José Fonseca   static void test_atomic_##type (void) { \
91ff80b92a58ef802e2721d1b51da6157be696c932José Fonseca      type v, r; \
92ff80b92a58ef802e2721d1b51da6157be696c932José Fonseca      bool b; \
93ff80b92a58ef802e2721d1b51da6157be696c932José Fonseca      \
94d2438f5920b95a880e9146882a58bf37ec57bad5José Fonseca      test_atomic_8bits_##type(); \
95ff80b92a58ef802e2721d1b51da6157be696c932José Fonseca      \
96ff80b92a58ef802e2721d1b51da6157be696c932José Fonseca      v = 2; \
97ff80b92a58ef802e2721d1b51da6157be696c932José Fonseca      b = p_atomic_dec_zero(&v); \
98ff80b92a58ef802e2721d1b51da6157be696c932José Fonseca      assert(v == 1 && "p_atomic_dec_zero"); \
99ff80b92a58ef802e2721d1b51da6157be696c932José Fonseca      assert(b == false && "p_atomic_dec_zero"); \
100ff80b92a58ef802e2721d1b51da6157be696c932José Fonseca      b = p_atomic_dec_zero(&v); \
101ff80b92a58ef802e2721d1b51da6157be696c932José Fonseca      assert(v == 0 && "p_atomic_dec_zero"); \
102ff80b92a58ef802e2721d1b51da6157be696c932José Fonseca      assert(b == true && "p_atomic_dec_zero"); \
103ff80b92a58ef802e2721d1b51da6157be696c932José Fonseca      b = p_atomic_dec_zero(&v); \
104ff80b92a58ef802e2721d1b51da6157be696c932José Fonseca      assert(v == ones && "p_atomic_dec_zero"); \
105ff80b92a58ef802e2721d1b51da6157be696c932José Fonseca      assert(b == false && "p_atomic_dec_zero"); \
106ff80b92a58ef802e2721d1b51da6157be696c932José Fonseca      \
107ff80b92a58ef802e2721d1b51da6157be696c932José Fonseca      v = ones; \
108ff80b92a58ef802e2721d1b51da6157be696c932José Fonseca      p_atomic_inc(&v); \
109ff80b92a58ef802e2721d1b51da6157be696c932José Fonseca      assert(v == 0 && "p_atomic_inc"); \
110ff80b92a58ef802e2721d1b51da6157be696c932José Fonseca      \
111ff80b92a58ef802e2721d1b51da6157be696c932José Fonseca      v = ones; \
112ff80b92a58ef802e2721d1b51da6157be696c932José Fonseca      r = p_atomic_inc_return(&v); \
113ff80b92a58ef802e2721d1b51da6157be696c932José Fonseca      assert(v == 0 && "p_atomic_inc_return"); \
114ff80b92a58ef802e2721d1b51da6157be696c932José Fonseca      assert(r == v && "p_atomic_inc_return"); \
115ff80b92a58ef802e2721d1b51da6157be696c932José Fonseca      \
116ff80b92a58ef802e2721d1b51da6157be696c932José Fonseca      v = 0; \
117ff80b92a58ef802e2721d1b51da6157be696c932José Fonseca      p_atomic_dec(&v); \
118ff80b92a58ef802e2721d1b51da6157be696c932José Fonseca      assert(v == ones && "p_atomic_dec"); \
119ff80b92a58ef802e2721d1b51da6157be696c932José Fonseca      \
120ff80b92a58ef802e2721d1b51da6157be696c932José Fonseca      v = 0; \
121ff80b92a58ef802e2721d1b51da6157be696c932José Fonseca      r = p_atomic_dec_return(&v); \
122ff80b92a58ef802e2721d1b51da6157be696c932José Fonseca      assert(v == ones && "p_atomic_dec_return"); \
123ff80b92a58ef802e2721d1b51da6157be696c932José Fonseca      assert(r == v && "p_atomic_dec_return"); \
124ff80b92a58ef802e2721d1b51da6157be696c932José Fonseca      \
125ff80b92a58ef802e2721d1b51da6157be696c932José Fonseca      (void) r; \
126ff80b92a58ef802e2721d1b51da6157be696c932José Fonseca      (void) b; \
127ff80b92a58ef802e2721d1b51da6157be696c932José Fonseca   }
128ff80b92a58ef802e2721d1b51da6157be696c932José Fonseca
129ff80b92a58ef802e2721d1b51da6157be696c932José Fonseca
130ff80b92a58ef802e2721d1b51da6157be696c932José Fonsecatest_atomic(int, -1)
131ff80b92a58ef802e2721d1b51da6157be696c932José Fonsecatest_atomic(unsigned, ~0U)
132ff80b92a58ef802e2721d1b51da6157be696c932José Fonseca
133ff80b92a58ef802e2721d1b51da6157be696c932José Fonsecatest_atomic(int16_t, INT16_C(-1))
134ff80b92a58ef802e2721d1b51da6157be696c932José Fonsecatest_atomic(uint16_t, UINT16_C(0xffff))
135ff80b92a58ef802e2721d1b51da6157be696c932José Fonsecatest_atomic(int32_t, INT32_C(-1))
136ff80b92a58ef802e2721d1b51da6157be696c932José Fonsecatest_atomic(uint32_t, UINT32_C(0xffffffff))
137ff80b92a58ef802e2721d1b51da6157be696c932José Fonsecatest_atomic(int64_t, INT64_C(-1))
138ff80b92a58ef802e2721d1b51da6157be696c932José Fonsecatest_atomic(uint64_t, UINT64_C(0xffffffffffffffff))
139ff80b92a58ef802e2721d1b51da6157be696c932José Fonseca
140d2438f5920b95a880e9146882a58bf37ec57bad5José Fonsecatest_atomic_8bits(int8_t, INT8_C(-1))
141d2438f5920b95a880e9146882a58bf37ec57bad5José Fonsecatest_atomic_8bits(uint8_t, UINT8_C(0xff))
142b09f25428ff5e908aefc03b8f9931599c3afd6d2José Fonsecatest_atomic_assign(bool, true)
143ff80b92a58ef802e2721d1b51da6157be696c932José Fonseca
144ff80b92a58ef802e2721d1b51da6157be696c932José Fonsecaint
145ff80b92a58ef802e2721d1b51da6157be696c932José Fonsecamain()
146ff80b92a58ef802e2721d1b51da6157be696c932José Fonseca{
147ff80b92a58ef802e2721d1b51da6157be696c932José Fonseca   test_atomic_int();
148ff80b92a58ef802e2721d1b51da6157be696c932José Fonseca   test_atomic_unsigned();
149ff80b92a58ef802e2721d1b51da6157be696c932José Fonseca
150ff80b92a58ef802e2721d1b51da6157be696c932José Fonseca   test_atomic_int16_t();
151ff80b92a58ef802e2721d1b51da6157be696c932José Fonseca   test_atomic_uint16_t();
152ff80b92a58ef802e2721d1b51da6157be696c932José Fonseca   test_atomic_int32_t();
153ff80b92a58ef802e2721d1b51da6157be696c932José Fonseca   test_atomic_uint32_t();
154ff80b92a58ef802e2721d1b51da6157be696c932José Fonseca   test_atomic_int64_t();
155ff80b92a58ef802e2721d1b51da6157be696c932José Fonseca   test_atomic_uint64_t();
156ff80b92a58ef802e2721d1b51da6157be696c932José Fonseca
157d2438f5920b95a880e9146882a58bf37ec57bad5José Fonseca   test_atomic_8bits_int8_t();
158d2438f5920b95a880e9146882a58bf37ec57bad5José Fonseca   test_atomic_8bits_uint8_t();
159b09f25428ff5e908aefc03b8f9931599c3afd6d2José Fonseca   test_atomic_assign_bool();
160ff80b92a58ef802e2721d1b51da6157be696c932José Fonseca
161ff80b92a58ef802e2721d1b51da6157be696c932José Fonseca   return 0;
162ff80b92a58ef802e2721d1b51da6157be696c932José Fonseca}
163