Serenity Operating System
at hosted 364 lines 12 kB view raw
1/* 2 * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright notice, this 9 * list of conditions and the following disclaimer. 10 * 11 * 2. Redistributions in binary form must reproduce the above copyright notice, 12 * this list of conditions and the following disclaimer in the documentation 13 * and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 16 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 21 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 22 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 23 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 */ 26 27#include <AK/TestSuite.h> 28 29#include <AK/Atomic.h> 30 31TEST_CASE(construct_empty) 32{ 33 EXPECT(Atomic<bool>().load() == false); 34 EXPECT(Atomic<u32>().load() == 0); 35 EXPECT(Atomic<u16>().load() == 0); 36 EXPECT(Atomic<u8>().load() == 0); 37 38 EXPECT(Atomic<u16*>().load() == nullptr); 39} 40 41TEST_CASE(construct_with_value) 42{ 43 EXPECT(Atomic<bool>(false).load() == false); 44 EXPECT(Atomic<bool>(true).load() == true); 45 EXPECT(Atomic<u32>(2).load() == 2); 46 EXPECT(Atomic<u16>(3).load() == 3); 47 EXPECT(Atomic<u8>(4).load() == 4); 48 49 u16 v_u16 = 0; 50 EXPECT(Atomic<u16*>(&v_u16).load() == &v_u16); 51} 52 53TEST_CASE(do_exchange) 54{ 55 Atomic<bool> a_bool(false); 56 EXPECT(a_bool.exchange(true) == false); 57 EXPECT(a_bool.load() == true && static_cast<bool>(a_bool) == true); 58 59 Atomic<u32> a_u32(2); 60 EXPECT(a_u32.exchange(22) == 2); 61 EXPECT(a_u32.load() == 22 && static_cast<u8>(a_u32) == 22); 62 63 Atomic<u16> a_u16(3); 64 EXPECT(a_u16.exchange(33) == 3); 65 EXPECT(a_u16.load() == 33 && static_cast<u8>(a_u16) == 33); 66 67 Atomic<u8> a_u8(4); 68 EXPECT(a_u8.exchange(44) == 4); 69 EXPECT(a_u8.load() == 44 && static_cast<u8>(a_u8) == 44); 70 71 u16 v_u16[6]; 72 Atomic<u16*> a_pu16(&v_u16[2]); 73 EXPECT(a_pu16.load() == &v_u16[2] && static_cast<u16*>(a_pu16) == &v_u16[2]); 74} 75 76TEST_CASE(do_compare_exchange) 77{ 78 Atomic<bool> a_bool(false); 79 bool e_bool = true; 80 EXPECT(a_bool.compare_exchange_strong(e_bool, true) == false); 81 EXPECT(e_bool == false); 82 EXPECT(a_bool.load() == false && static_cast<bool>(a_bool) == false); 83 e_bool = false; 84 EXPECT(a_bool.compare_exchange_strong(e_bool, true) == true); 85 EXPECT(a_bool.load() == true && static_cast<bool>(a_bool) == true); 86 87 Atomic<u32> a_u32(2); 88 u32 e_u32 = 99; 89 EXPECT(a_u32.compare_exchange_strong(e_u32, 22) == false); 90 EXPECT(e_u32 == 2); 91 EXPECT(a_u32.load() == 2 && static_cast<u32>(a_u32) == 2); 92 e_u32 = 2; 93 EXPECT(a_u32.compare_exchange_strong(e_u32, 22) == true); 94 EXPECT(a_u32.load() == 22 && static_cast<u32>(a_u32) == 22); 95 96 Atomic<u16> a_u16(3); 97 u16 e_u16 = 99; 98 EXPECT(a_u16.compare_exchange_strong(e_u16, 33) == false); 99 EXPECT(e_u16 == 3); 100 EXPECT(a_u16.load() == 3 && static_cast<u16>(a_u16) == 3); 101 e_u16 = 3; 102 EXPECT(a_u16.compare_exchange_strong(e_u16, 33) == true); 103 EXPECT(a_u16.load() == 33 && static_cast<u16>(a_u16) == 33); 104 105 Atomic<u8> a_u8(4); 106 u8 e_u8 = 99; 107 EXPECT(a_u8.compare_exchange_strong(e_u8, 44) == false); 108 EXPECT(e_u8 == 4); 109 EXPECT(a_u8.load() == 4 && static_cast<u16>(a_u8) == 4); 110 e_u8 = 4; 111 EXPECT(a_u8.compare_exchange_strong(e_u8, 44) == true); 112 EXPECT(a_u8.load() == 44 && static_cast<u16>(a_u8) == 44); 113} 114 115TEST_CASE(fetch_add) 116{ 117 Atomic<u32> a_u32(5); 118 EXPECT(a_u32.fetch_add(2) == 5); 119 EXPECT(a_u32.load() == 7 && static_cast<u32>(a_u32) == 7); 120 121 Atomic<u16> a_u16(5); 122 EXPECT(a_u16.fetch_add(2) == 5); 123 EXPECT(a_u16.load() == 7 && static_cast<u16>(a_u16) == 7); 124 125 Atomic<u8> a_u8(5); 126 EXPECT(a_u8.fetch_add(2) == 5); 127 EXPECT(a_u8.load() == 7 && static_cast<u8>(a_u8) == 7); 128 129 u32 v_u32[6]; 130 Atomic<u32*> a_pu32(&v_u32[2]); 131 EXPECT(a_pu32.load() == &v_u32[2] && static_cast<u32*>(a_pu32) == &v_u32[2]); 132 EXPECT(a_pu32.fetch_add(2) == &v_u32[2]); 133 EXPECT(a_pu32.load() == &v_u32[4] && static_cast<u32*>(a_pu32) == &v_u32[4]); 134 EXPECT(a_pu32.fetch_add(-3) == &v_u32[4]); 135 EXPECT(a_pu32.load() == &v_u32[1] && static_cast<u32*>(a_pu32) == &v_u32[1]); 136 137 u16 v_u16[6]; 138 Atomic<u16*> a_pu16(&v_u16[2]); 139 EXPECT(a_pu16.load() == &v_u16[2] && static_cast<u16*>(a_pu16) == &v_u16[2]); 140 EXPECT(a_pu16.fetch_add(2) == &v_u16[2]); 141 EXPECT(a_pu16.load() == &v_u16[4] && static_cast<u16*>(a_pu16) == &v_u16[4]); 142 EXPECT(a_pu16.fetch_add(-3) == &v_u16[4]); 143 EXPECT(a_pu16.load() == &v_u16[1] && static_cast<u16*>(a_pu16) == &v_u16[1]); 144 145 u8 v_u8[6]; 146 Atomic<u8*> a_pu8(&v_u8[2]); 147 EXPECT(a_pu8.load() == &v_u8[2] && static_cast<u8*>(a_pu8) == &v_u8[2]); 148 EXPECT(a_pu8.fetch_add(2) == &v_u8[2]); 149 EXPECT(a_pu8.load() == &v_u8[4] && static_cast<u8*>(a_pu8) == &v_u8[4]); 150 EXPECT(a_pu8.fetch_add(-3) == &v_u8[4]); 151 EXPECT(a_pu8.load() == &v_u8[1] && static_cast<u8*>(a_pu8) == &v_u8[1]); 152} 153 154TEST_CASE(fetch_sub) 155{ 156 Atomic<u32> a_u32(5); 157 EXPECT(a_u32.fetch_sub(2) == 5); 158 EXPECT(a_u32.load() == 3 && static_cast<u32>(a_u32) == 3); 159 160 Atomic<u16> a_u16(5); 161 EXPECT(a_u16.fetch_sub(2) == 5); 162 EXPECT(a_u16.load() == 3 && static_cast<u16>(a_u16) == 3); 163 164 Atomic<u8> a_u8(5); 165 EXPECT(a_u8.fetch_sub(2) == 5); 166 EXPECT(a_u8.load() == 3 && static_cast<u8>(a_u8) == 3); 167 168 u32 v_u32[6]; 169 Atomic<u32*> a_pu32(&v_u32[2]); 170 EXPECT(a_pu32.load() == &v_u32[2] && static_cast<u32*>(a_pu32) == &v_u32[2]); 171 EXPECT(a_pu32.fetch_sub(2) == &v_u32[2]); 172 EXPECT(a_pu32.load() == &v_u32[0] && static_cast<u32*>(a_pu32) == &v_u32[0]); 173 EXPECT(a_pu32.fetch_sub(-3) == &v_u32[0]); 174 EXPECT(a_pu32.load() == &v_u32[3] && static_cast<u32*>(a_pu32) == &v_u32[3]); 175 176 u16 v_u16[6]; 177 Atomic<u16*> a_pu16(&v_u16[2]); 178 EXPECT(a_pu16.load() == &v_u16[2] && static_cast<u16*>(a_pu16) == &v_u16[2]); 179 EXPECT(a_pu16.fetch_sub(2) == &v_u16[2]); 180 EXPECT(a_pu16.load() == &v_u16[0] && static_cast<u16*>(a_pu16) == &v_u16[0]); 181 EXPECT(a_pu16.fetch_sub(-3) == &v_u16[0]); 182 EXPECT(a_pu16.load() == &v_u16[3] && static_cast<u16*>(a_pu16) == &v_u16[3]); 183 184 u8 v_u8[6]; 185 Atomic<u8*> a_pu8(&v_u8[2]); 186 EXPECT(a_pu8.load() == &v_u8[2] && static_cast<u8*>(a_pu8) == &v_u8[2]); 187 EXPECT(a_pu8.fetch_sub(2) == &v_u8[2]); 188 EXPECT(a_pu8.load() == &v_u8[0] && static_cast<u8*>(a_pu8) == &v_u8[0]); 189 EXPECT(a_pu8.fetch_sub(-3) == &v_u8[0]); 190 EXPECT(a_pu8.load() == &v_u8[3] && static_cast<u8*>(a_pu8) == &v_u8[3]); 191} 192 193TEST_CASE(fetch_inc) 194{ 195 Atomic<u32> a_u32(5); 196 EXPECT(a_u32++ == 5); 197 EXPECT(a_u32.load() == 6 && a_u32 == 6); 198 EXPECT(++a_u32 == 7); 199 EXPECT(a_u32.load() == 7 && a_u32 == 7); 200 EXPECT((a_u32 += 2) == 9); 201 EXPECT(a_u32.load() == 9 && a_u32 == 9); 202 203 Atomic<u16> a_u16(5); 204 EXPECT(a_u16++ == 5); 205 EXPECT(a_u16.load() == 6 && a_u16 == 6); 206 EXPECT(++a_u16 == 7); 207 EXPECT(a_u16.load() == 7 && a_u16 == 7); 208 EXPECT((a_u16 += 2) == 9); 209 EXPECT(a_u16.load() == 9 && a_u16 == 9); 210 211 Atomic<u8> a_u8(5); 212 EXPECT(a_u8++ == 5); 213 EXPECT(a_u8.load() == 6 && a_u8 == 6); 214 EXPECT(++a_u8 == 7); 215 EXPECT(a_u8.load() == 7 && a_u8 == 7); 216 EXPECT((a_u8 += 2) == 9); 217 EXPECT(a_u8.load() == 9 && a_u8 == 9); 218 219 u32 v_u32[8]; 220 Atomic<u32*> a_pu32(&v_u32[2]); 221 EXPECT(a_pu32++ == &v_u32[2]); 222 EXPECT(a_pu32.load() == &v_u32[3] && a_pu32 == &v_u32[3]); 223 EXPECT(++a_pu32 == &v_u32[4]); 224 EXPECT(a_pu32.load() == &v_u32[4] && a_pu32 == &v_u32[4]); 225 EXPECT((a_pu32 += 2) == &v_u32[6]); 226 EXPECT(a_pu32.load() == &v_u32[6] && a_pu32 == &v_u32[6]); 227 228 u16 v_u16[8]; 229 Atomic<u16*> a_pu16(&v_u16[2]); 230 EXPECT(a_pu16++ == &v_u16[2]); 231 EXPECT(a_pu16.load() == &v_u16[3] && a_pu16 == &v_u16[3]); 232 EXPECT(++a_pu16 == &v_u16[4]); 233 EXPECT(a_pu16.load() == &v_u16[4] && a_pu16 == &v_u16[4]); 234 EXPECT((a_pu16 += 2) == &v_u16[6]); 235 EXPECT(a_pu16.load() == &v_u16[6] && a_pu16 == &v_u16[6]); 236 237 u8 v_u8[8]; 238 Atomic<u8*> a_pu8(&v_u8[2]); 239 EXPECT(a_pu8++ == &v_u8[2]); 240 EXPECT(a_pu8.load() == &v_u8[3] && a_pu8 == &v_u8[3]); 241 EXPECT(++a_pu8 == &v_u8[4]); 242 EXPECT(a_pu8.load() == &v_u8[4] && a_pu8 == &v_u8[4]); 243 EXPECT((a_pu8 += 2) == &v_u8[6]); 244 EXPECT(a_pu8.load() == &v_u8[6] && a_pu8 == &v_u8[6]); 245} 246 247TEST_CASE(fetch_dec) 248{ 249 Atomic<u32> a_u32(5); 250 EXPECT(a_u32-- == 5); 251 EXPECT(a_u32.load() == 4 && a_u32 == 4); 252 EXPECT(--a_u32 == 3); 253 EXPECT(a_u32.load() == 3 && a_u32 == 3); 254 EXPECT((a_u32 -= 2) == 1); 255 EXPECT(a_u32.load() == 1 && a_u32 == 1); 256 257 Atomic<u16> a_u16(5); 258 EXPECT(a_u16-- == 5); 259 EXPECT(a_u16.load() == 4 && a_u16 == 4); 260 EXPECT(--a_u16 == 3); 261 EXPECT(a_u16.load() == 3 && a_u16 == 3); 262 EXPECT((a_u16 -= 2) == 1); 263 EXPECT(a_u16.load() == 1 && a_u16 == 1); 264 265 Atomic<u8> a_u8(5); 266 EXPECT(a_u8-- == 5); 267 EXPECT(a_u8.load() == 4 && a_u8 == 4); 268 EXPECT(--a_u8 == 3); 269 EXPECT(a_u8.load() == 3 && a_u8 == 3); 270 EXPECT((a_u8 -= 2) == 1); 271 EXPECT(a_u8.load() == 1 && a_u8 == 1); 272 273 u32 v_u32[8]; 274 Atomic<u32*> a_pu32(&v_u32[7]); 275 EXPECT(a_pu32-- == &v_u32[7]); 276 EXPECT(a_pu32.load() == &v_u32[6] && a_pu32 == &v_u32[6]); 277 EXPECT(--a_pu32 == &v_u32[5]); 278 EXPECT(a_pu32.load() == &v_u32[5] && a_pu32 == &v_u32[5]); 279 EXPECT((a_pu32 -= 2) == &v_u32[3]); 280 EXPECT(a_pu32.load() == &v_u32[3] && a_pu32 == &v_u32[3]); 281 282 u16 v_u16[8]; 283 Atomic<u16*> a_pu16(&v_u16[7]); 284 EXPECT(a_pu16-- == &v_u16[7]); 285 EXPECT(a_pu16.load() == &v_u16[6] && a_pu16 == &v_u16[6]); 286 EXPECT(--a_pu16 == &v_u16[5]); 287 EXPECT(a_pu16.load() == &v_u16[5] && a_pu16 == &v_u16[5]); 288 EXPECT((a_pu16 -= 2) == &v_u16[3]); 289 EXPECT(a_pu16.load() == &v_u16[3] && a_pu16 == &v_u16[3]); 290 291 u8 v_u8[8]; 292 Atomic<u8*> a_pu8(&v_u8[7]); 293 EXPECT(a_pu8-- == &v_u8[7]); 294 EXPECT(a_pu8.load() == &v_u8[6] && a_pu8 == &v_u8[6]); 295 EXPECT(--a_pu8 == &v_u8[5]); 296 EXPECT(a_pu8.load() == &v_u8[5] && a_pu8 == &v_u8[5]); 297 EXPECT((a_pu8 -= 2) == &v_u8[3]); 298 EXPECT(a_pu8.load() == &v_u8[3] && a_pu8 == &v_u8[3]); 299} 300 301TEST_CASE(fetch_and) 302{ 303 Atomic<u32> a_u32(0xdeadbeef); 304 EXPECT(a_u32.fetch_and(0x8badf00d) == 0xdeadbeef); 305 EXPECT(a_u32.load() == 0x8aadb00d && static_cast<u32>(a_u32) == 0x8aadb00d); 306 a_u32 = 0xdeadbeef; 307 EXPECT((a_u32 &= 0x8badf00d) == 0x8aadb00d); 308 309 Atomic<u16> a_u16(0xbeef); 310 EXPECT(a_u16.fetch_and(0xf00d) == 0xbeef); 311 EXPECT(a_u16.load() == 0xb00d && static_cast<u16>(a_u16) == 0xb00d); 312 a_u16 = 0xbeef; 313 EXPECT((a_u16 &= 0xf00d) == 0xb00d); 314 315 Atomic<u8> a_u8(0xef); 316 EXPECT(a_u8.fetch_and(0x0d) == 0xef); 317 EXPECT(a_u8.load() == 0x0d && static_cast<u8>(a_u8) == 0x0d); 318 a_u8 = 0xef; 319 EXPECT((a_u8 &= 0x0d) == 0x0d); 320} 321 322TEST_CASE(fetch_or) 323{ 324 Atomic<u32> a_u32(0xaadb00d); 325 EXPECT(a_u32.fetch_or(0xdeadbeef) == 0xaadb00d); 326 EXPECT(a_u32.load() == 0xdeadbeef && static_cast<u32>(a_u32) == 0xdeadbeef); 327 a_u32 = 0xaadb00d; 328 EXPECT((a_u32 |= 0xdeadbeef) == 0xdeadbeef); 329 330 Atomic<u16> a_u16(0xb00d); 331 EXPECT(a_u16.fetch_or(0xbeef) == 0xb00d); 332 EXPECT(a_u16.load() == 0xbeef && static_cast<u16>(a_u16) == 0xbeef); 333 a_u16 = 0xb00d; 334 EXPECT((a_u16 |= 0xbeef) == 0xbeef); 335 336 Atomic<u8> a_u8(0x0d); 337 EXPECT(a_u8.fetch_or(0xef) == 0x0d); 338 EXPECT(a_u8.load() == 0xef && static_cast<u8>(a_u8) == 0xef); 339 a_u8 = 0x0d; 340 EXPECT((a_u8 |= 0xef) == 0xef); 341} 342 343TEST_CASE(fetch_xor) 344{ 345 Atomic<u32> a_u32(0x55004ee2); 346 EXPECT(a_u32.fetch_xor(0xdeadbeef) == 0x55004ee2); 347 EXPECT(a_u32.load() == 0x8badf00d && static_cast<u32>(a_u32) == 0x8badf00d); 348 a_u32 = 0x55004ee2; 349 EXPECT((a_u32 ^= 0xdeadbeef) == 0x8badf00d); 350 351 Atomic<u16> a_u16(0x4ee2); 352 EXPECT(a_u16.fetch_xor(0xbeef) == 0x4ee2); 353 EXPECT(a_u16.load() == 0xf00d && static_cast<u16>(a_u16) == 0xf00d); 354 a_u16 = 0x4ee2; 355 EXPECT((a_u16 ^= 0xbeef) == 0xf00d); 356 357 Atomic<u8> a_u8(0xe2); 358 EXPECT(a_u8.fetch_xor(0xef) == 0xe2); 359 EXPECT(a_u8.load() == 0x0d && static_cast<u8>(a_u8) == 0x0d); 360 a_u8 = 0xe2; 361 EXPECT((a_u8 ^= 0xef) == 0x0d); 362} 363 364TEST_MAIN(Atomic)