Serenity Operating System
at master 342 lines 12 kB view raw
1/* 2 * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org> 3 * 4 * SPDX-License-Identifier: BSD-2-Clause 5 */ 6 7#include <LibTest/TestCase.h> 8 9#include <AK/Atomic.h> 10 11TEST_CASE(construct_empty) 12{ 13 EXPECT(Atomic<bool>().load() == false); 14 EXPECT(Atomic<u32>().load() == 0); 15 EXPECT(Atomic<u16>().load() == 0); 16 EXPECT(Atomic<u8>().load() == 0); 17 18 EXPECT(Atomic<u16*>().load() == nullptr); 19} 20 21TEST_CASE(construct_with_value) 22{ 23 EXPECT(Atomic<bool>(false).load() == false); 24 EXPECT(Atomic<bool>(true).load() == true); 25 EXPECT(Atomic<u32>(2).load() == 2); 26 EXPECT(Atomic<u16>(3).load() == 3); 27 EXPECT(Atomic<u8>(4).load() == 4); 28 29 u16 v_u16 = 0; 30 EXPECT(Atomic<u16*>(&v_u16).load() == &v_u16); 31} 32 33TEST_CASE(do_exchange) 34{ 35 Atomic<bool> a_bool(false); 36 EXPECT(a_bool.exchange(true) == false); 37 EXPECT(a_bool.load() == true && static_cast<bool>(a_bool) == true); 38 39 Atomic<u32> a_u32(2); 40 EXPECT(a_u32.exchange(22) == 2); 41 EXPECT(a_u32.load() == 22 && static_cast<u8>(a_u32) == 22); 42 43 Atomic<u16> a_u16(3); 44 EXPECT(a_u16.exchange(33) == 3); 45 EXPECT(a_u16.load() == 33 && static_cast<u8>(a_u16) == 33); 46 47 Atomic<u8> a_u8(4); 48 EXPECT(a_u8.exchange(44) == 4); 49 EXPECT(a_u8.load() == 44 && static_cast<u8>(a_u8) == 44); 50 51 u16 v_u16[6]; 52 Atomic<u16*> a_pu16(&v_u16[2]); 53 EXPECT(a_pu16.load() == &v_u16[2] && static_cast<u16*>(a_pu16) == &v_u16[2]); 54} 55 56TEST_CASE(do_compare_exchange) 57{ 58 Atomic<bool> a_bool(false); 59 bool e_bool = true; 60 EXPECT(a_bool.compare_exchange_strong(e_bool, true) == false); 61 EXPECT(e_bool == false); 62 EXPECT(a_bool.load() == false && static_cast<bool>(a_bool) == false); 63 e_bool = false; 64 EXPECT(a_bool.compare_exchange_strong(e_bool, true) == true); 65 EXPECT(a_bool.load() == true && static_cast<bool>(a_bool) == true); 66 67 Atomic<u32> a_u32(2); 68 u32 e_u32 = 99; 69 EXPECT(a_u32.compare_exchange_strong(e_u32, 22) == false); 70 EXPECT(e_u32 == 2); 71 EXPECT(a_u32.load() == 2 && static_cast<u32>(a_u32) == 2); 72 e_u32 = 2; 73 EXPECT(a_u32.compare_exchange_strong(e_u32, 22) == true); 74 EXPECT(a_u32.load() == 22 && static_cast<u32>(a_u32) == 22); 75 76 Atomic<u16> a_u16(3); 77 u16 e_u16 = 99; 78 EXPECT(a_u16.compare_exchange_strong(e_u16, 33) == false); 79 EXPECT(e_u16 == 3); 80 EXPECT(a_u16.load() == 3 && static_cast<u16>(a_u16) == 3); 81 e_u16 = 3; 82 EXPECT(a_u16.compare_exchange_strong(e_u16, 33) == true); 83 EXPECT(a_u16.load() == 33 && static_cast<u16>(a_u16) == 33); 84 85 Atomic<u8> a_u8(4); 86 u8 e_u8 = 99; 87 EXPECT(a_u8.compare_exchange_strong(e_u8, 44) == false); 88 EXPECT(e_u8 == 4); 89 EXPECT(a_u8.load() == 4 && static_cast<u16>(a_u8) == 4); 90 e_u8 = 4; 91 EXPECT(a_u8.compare_exchange_strong(e_u8, 44) == true); 92 EXPECT(a_u8.load() == 44 && static_cast<u16>(a_u8) == 44); 93} 94 95TEST_CASE(fetch_add) 96{ 97 Atomic<u32> a_u32(5); 98 EXPECT(a_u32.fetch_add(2) == 5); 99 EXPECT(a_u32.load() == 7 && static_cast<u32>(a_u32) == 7); 100 101 Atomic<u16> a_u16(5); 102 EXPECT(a_u16.fetch_add(2) == 5); 103 EXPECT(a_u16.load() == 7 && static_cast<u16>(a_u16) == 7); 104 105 Atomic<u8> a_u8(5); 106 EXPECT(a_u8.fetch_add(2) == 5); 107 EXPECT(a_u8.load() == 7 && static_cast<u8>(a_u8) == 7); 108 109 u32 v_u32[6]; 110 Atomic<u32*> a_pu32(&v_u32[2]); 111 EXPECT(a_pu32.load() == &v_u32[2] && static_cast<u32*>(a_pu32) == &v_u32[2]); 112 EXPECT(a_pu32.fetch_add(2) == &v_u32[2]); 113 EXPECT(a_pu32.load() == &v_u32[4] && static_cast<u32*>(a_pu32) == &v_u32[4]); 114 EXPECT(a_pu32.fetch_add(-3) == &v_u32[4]); 115 EXPECT(a_pu32.load() == &v_u32[1] && static_cast<u32*>(a_pu32) == &v_u32[1]); 116 117 u16 v_u16[6]; 118 Atomic<u16*> a_pu16(&v_u16[2]); 119 EXPECT(a_pu16.load() == &v_u16[2] && static_cast<u16*>(a_pu16) == &v_u16[2]); 120 EXPECT(a_pu16.fetch_add(2) == &v_u16[2]); 121 EXPECT(a_pu16.load() == &v_u16[4] && static_cast<u16*>(a_pu16) == &v_u16[4]); 122 EXPECT(a_pu16.fetch_add(-3) == &v_u16[4]); 123 EXPECT(a_pu16.load() == &v_u16[1] && static_cast<u16*>(a_pu16) == &v_u16[1]); 124 125 u8 v_u8[6]; 126 Atomic<u8*> a_pu8(&v_u8[2]); 127 EXPECT(a_pu8.load() == &v_u8[2] && static_cast<u8*>(a_pu8) == &v_u8[2]); 128 EXPECT(a_pu8.fetch_add(2) == &v_u8[2]); 129 EXPECT(a_pu8.load() == &v_u8[4] && static_cast<u8*>(a_pu8) == &v_u8[4]); 130 EXPECT(a_pu8.fetch_add(-3) == &v_u8[4]); 131 EXPECT(a_pu8.load() == &v_u8[1] && static_cast<u8*>(a_pu8) == &v_u8[1]); 132} 133 134TEST_CASE(fetch_sub) 135{ 136 Atomic<u32> a_u32(5); 137 EXPECT(a_u32.fetch_sub(2) == 5); 138 EXPECT(a_u32.load() == 3 && static_cast<u32>(a_u32) == 3); 139 140 Atomic<u16> a_u16(5); 141 EXPECT(a_u16.fetch_sub(2) == 5); 142 EXPECT(a_u16.load() == 3 && static_cast<u16>(a_u16) == 3); 143 144 Atomic<u8> a_u8(5); 145 EXPECT(a_u8.fetch_sub(2) == 5); 146 EXPECT(a_u8.load() == 3 && static_cast<u8>(a_u8) == 3); 147 148 u32 v_u32[6]; 149 Atomic<u32*> a_pu32(&v_u32[2]); 150 EXPECT(a_pu32.load() == &v_u32[2] && static_cast<u32*>(a_pu32) == &v_u32[2]); 151 EXPECT(a_pu32.fetch_sub(2) == &v_u32[2]); 152 EXPECT(a_pu32.load() == &v_u32[0] && static_cast<u32*>(a_pu32) == &v_u32[0]); 153 EXPECT(a_pu32.fetch_sub(-3) == &v_u32[0]); 154 EXPECT(a_pu32.load() == &v_u32[3] && static_cast<u32*>(a_pu32) == &v_u32[3]); 155 156 u16 v_u16[6]; 157 Atomic<u16*> a_pu16(&v_u16[2]); 158 EXPECT(a_pu16.load() == &v_u16[2] && static_cast<u16*>(a_pu16) == &v_u16[2]); 159 EXPECT(a_pu16.fetch_sub(2) == &v_u16[2]); 160 EXPECT(a_pu16.load() == &v_u16[0] && static_cast<u16*>(a_pu16) == &v_u16[0]); 161 EXPECT(a_pu16.fetch_sub(-3) == &v_u16[0]); 162 EXPECT(a_pu16.load() == &v_u16[3] && static_cast<u16*>(a_pu16) == &v_u16[3]); 163 164 u8 v_u8[6]; 165 Atomic<u8*> a_pu8(&v_u8[2]); 166 EXPECT(a_pu8.load() == &v_u8[2] && static_cast<u8*>(a_pu8) == &v_u8[2]); 167 EXPECT(a_pu8.fetch_sub(2) == &v_u8[2]); 168 EXPECT(a_pu8.load() == &v_u8[0] && static_cast<u8*>(a_pu8) == &v_u8[0]); 169 EXPECT(a_pu8.fetch_sub(-3) == &v_u8[0]); 170 EXPECT(a_pu8.load() == &v_u8[3] && static_cast<u8*>(a_pu8) == &v_u8[3]); 171} 172 173TEST_CASE(fetch_inc) 174{ 175 Atomic<u32> a_u32(5); 176 EXPECT(a_u32++ == 5); 177 EXPECT(a_u32.load() == 6 && a_u32 == 6); 178 EXPECT(++a_u32 == 7); 179 EXPECT(a_u32.load() == 7 && a_u32 == 7); 180 EXPECT((a_u32 += 2) == 9); 181 EXPECT(a_u32.load() == 9 && a_u32 == 9); 182 183 Atomic<u16> a_u16(5); 184 EXPECT(a_u16++ == 5); 185 EXPECT(a_u16.load() == 6 && a_u16 == 6); 186 EXPECT(++a_u16 == 7); 187 EXPECT(a_u16.load() == 7 && a_u16 == 7); 188 EXPECT((a_u16 += 2) == 9); 189 EXPECT(a_u16.load() == 9 && a_u16 == 9); 190 191 Atomic<u8> a_u8(5); 192 EXPECT(a_u8++ == 5); 193 EXPECT(a_u8.load() == 6 && a_u8 == 6); 194 EXPECT(++a_u8 == 7); 195 EXPECT(a_u8.load() == 7 && a_u8 == 7); 196 EXPECT((a_u8 += 2) == 9); 197 EXPECT(a_u8.load() == 9 && a_u8 == 9); 198 199 u32 v_u32[8]; 200 Atomic<u32*> a_pu32(&v_u32[2]); 201 EXPECT(a_pu32++ == &v_u32[2]); 202 EXPECT(a_pu32.load() == &v_u32[3] && a_pu32 == &v_u32[3]); 203 EXPECT(++a_pu32 == &v_u32[4]); 204 EXPECT(a_pu32.load() == &v_u32[4] && a_pu32 == &v_u32[4]); 205 EXPECT((a_pu32 += 2) == &v_u32[6]); 206 EXPECT(a_pu32.load() == &v_u32[6] && a_pu32 == &v_u32[6]); 207 208 u16 v_u16[8]; 209 Atomic<u16*> a_pu16(&v_u16[2]); 210 EXPECT(a_pu16++ == &v_u16[2]); 211 EXPECT(a_pu16.load() == &v_u16[3] && a_pu16 == &v_u16[3]); 212 EXPECT(++a_pu16 == &v_u16[4]); 213 EXPECT(a_pu16.load() == &v_u16[4] && a_pu16 == &v_u16[4]); 214 EXPECT((a_pu16 += 2) == &v_u16[6]); 215 EXPECT(a_pu16.load() == &v_u16[6] && a_pu16 == &v_u16[6]); 216 217 u8 v_u8[8]; 218 Atomic<u8*> a_pu8(&v_u8[2]); 219 EXPECT(a_pu8++ == &v_u8[2]); 220 EXPECT(a_pu8.load() == &v_u8[3] && a_pu8 == &v_u8[3]); 221 EXPECT(++a_pu8 == &v_u8[4]); 222 EXPECT(a_pu8.load() == &v_u8[4] && a_pu8 == &v_u8[4]); 223 EXPECT((a_pu8 += 2) == &v_u8[6]); 224 EXPECT(a_pu8.load() == &v_u8[6] && a_pu8 == &v_u8[6]); 225} 226 227TEST_CASE(fetch_dec) 228{ 229 Atomic<u32> a_u32(5); 230 EXPECT(a_u32-- == 5); 231 EXPECT(a_u32.load() == 4 && a_u32 == 4); 232 EXPECT(--a_u32 == 3); 233 EXPECT(a_u32.load() == 3 && a_u32 == 3); 234 EXPECT((a_u32 -= 2) == 1); 235 EXPECT(a_u32.load() == 1 && a_u32 == 1); 236 237 Atomic<u16> a_u16(5); 238 EXPECT(a_u16-- == 5); 239 EXPECT(a_u16.load() == 4 && a_u16 == 4); 240 EXPECT(--a_u16 == 3); 241 EXPECT(a_u16.load() == 3 && a_u16 == 3); 242 EXPECT((a_u16 -= 2) == 1); 243 EXPECT(a_u16.load() == 1 && a_u16 == 1); 244 245 Atomic<u8> a_u8(5); 246 EXPECT(a_u8-- == 5); 247 EXPECT(a_u8.load() == 4 && a_u8 == 4); 248 EXPECT(--a_u8 == 3); 249 EXPECT(a_u8.load() == 3 && a_u8 == 3); 250 EXPECT((a_u8 -= 2) == 1); 251 EXPECT(a_u8.load() == 1 && a_u8 == 1); 252 253 u32 v_u32[8]; 254 Atomic<u32*> a_pu32(&v_u32[7]); 255 EXPECT(a_pu32-- == &v_u32[7]); 256 EXPECT(a_pu32.load() == &v_u32[6] && a_pu32 == &v_u32[6]); 257 EXPECT(--a_pu32 == &v_u32[5]); 258 EXPECT(a_pu32.load() == &v_u32[5] && a_pu32 == &v_u32[5]); 259 EXPECT((a_pu32 -= 2) == &v_u32[3]); 260 EXPECT(a_pu32.load() == &v_u32[3] && a_pu32 == &v_u32[3]); 261 262 u16 v_u16[8]; 263 Atomic<u16*> a_pu16(&v_u16[7]); 264 EXPECT(a_pu16-- == &v_u16[7]); 265 EXPECT(a_pu16.load() == &v_u16[6] && a_pu16 == &v_u16[6]); 266 EXPECT(--a_pu16 == &v_u16[5]); 267 EXPECT(a_pu16.load() == &v_u16[5] && a_pu16 == &v_u16[5]); 268 EXPECT((a_pu16 -= 2) == &v_u16[3]); 269 EXPECT(a_pu16.load() == &v_u16[3] && a_pu16 == &v_u16[3]); 270 271 u8 v_u8[8]; 272 Atomic<u8*> a_pu8(&v_u8[7]); 273 EXPECT(a_pu8-- == &v_u8[7]); 274 EXPECT(a_pu8.load() == &v_u8[6] && a_pu8 == &v_u8[6]); 275 EXPECT(--a_pu8 == &v_u8[5]); 276 EXPECT(a_pu8.load() == &v_u8[5] && a_pu8 == &v_u8[5]); 277 EXPECT((a_pu8 -= 2) == &v_u8[3]); 278 EXPECT(a_pu8.load() == &v_u8[3] && a_pu8 == &v_u8[3]); 279} 280 281TEST_CASE(fetch_and) 282{ 283 Atomic<u32> a_u32(0xdeadbeef); 284 EXPECT(a_u32.fetch_and(0x8badf00d) == 0xdeadbeef); 285 EXPECT(a_u32.load() == 0x8aadb00d && static_cast<u32>(a_u32) == 0x8aadb00d); 286 a_u32 = 0xdeadbeef; 287 EXPECT((a_u32 &= 0x8badf00d) == 0x8aadb00d); 288 289 Atomic<u16> a_u16(0xbeef); 290 EXPECT(a_u16.fetch_and(0xf00d) == 0xbeef); 291 EXPECT(a_u16.load() == 0xb00d && static_cast<u16>(a_u16) == 0xb00d); 292 a_u16 = 0xbeef; 293 EXPECT((a_u16 &= 0xf00d) == 0xb00d); 294 295 Atomic<u8> a_u8(0xef); 296 EXPECT(a_u8.fetch_and(0x0d) == 0xef); 297 EXPECT(a_u8.load() == 0x0d && static_cast<u8>(a_u8) == 0x0d); 298 a_u8 = 0xef; 299 EXPECT((a_u8 &= 0x0d) == 0x0d); 300} 301 302TEST_CASE(fetch_or) 303{ 304 Atomic<u32> a_u32(0xaadb00d); 305 EXPECT(a_u32.fetch_or(0xdeadbeef) == 0xaadb00d); 306 EXPECT(a_u32.load() == 0xdeadbeef && static_cast<u32>(a_u32) == 0xdeadbeef); 307 a_u32 = 0xaadb00d; 308 EXPECT((a_u32 |= 0xdeadbeef) == 0xdeadbeef); 309 310 Atomic<u16> a_u16(0xb00d); 311 EXPECT(a_u16.fetch_or(0xbeef) == 0xb00d); 312 EXPECT(a_u16.load() == 0xbeef && static_cast<u16>(a_u16) == 0xbeef); 313 a_u16 = 0xb00d; 314 EXPECT((a_u16 |= 0xbeef) == 0xbeef); 315 316 Atomic<u8> a_u8(0x0d); 317 EXPECT(a_u8.fetch_or(0xef) == 0x0d); 318 EXPECT(a_u8.load() == 0xef && static_cast<u8>(a_u8) == 0xef); 319 a_u8 = 0x0d; 320 EXPECT((a_u8 |= 0xef) == 0xef); 321} 322 323TEST_CASE(fetch_xor) 324{ 325 Atomic<u32> a_u32(0x55004ee2); 326 EXPECT(a_u32.fetch_xor(0xdeadbeef) == 0x55004ee2); 327 EXPECT(a_u32.load() == 0x8badf00d && static_cast<u32>(a_u32) == 0x8badf00d); 328 a_u32 = 0x55004ee2; 329 EXPECT((a_u32 ^= 0xdeadbeef) == 0x8badf00d); 330 331 Atomic<u16> a_u16(0x4ee2); 332 EXPECT(a_u16.fetch_xor(0xbeef) == 0x4ee2); 333 EXPECT(a_u16.load() == 0xf00d && static_cast<u16>(a_u16) == 0xf00d); 334 a_u16 = 0x4ee2; 335 EXPECT((a_u16 ^= 0xbeef) == 0xf00d); 336 337 Atomic<u8> a_u8(0xe2); 338 EXPECT(a_u8.fetch_xor(0xef) == 0xe2); 339 EXPECT(a_u8.load() == 0x0d && static_cast<u8>(a_u8) == 0x0d); 340 a_u8 = 0xe2; 341 EXPECT((a_u8 ^= 0xef) == 0x0d); 342}