1 // SPDX-FileCopyrightText: 2009 Mathieu Desnoyers <mathieu.desnoyers (at) efficios.com> 2 // 3 // SPDX-License-Identifier: GPL-2.0-or-later 4 5 #include <stdio.h> 6 #include <urcu/uatomic.h> 7 8 #include "tap.h" 9 10 #define NR_TESTS 17 11 12 #define BYTE_PER_LONG (sizeof(unsigned long) / sizeof(unsigned char)) 13 #define SHORT_PER_LONG (sizeof(unsigned long) / sizeof(unsigned short)) 14 #define INT_PER_LONG (sizeof(unsigned long) / sizeof(unsigned int)) 15 16 struct testvals { 17 #ifdef UATOMIC_HAS_ATOMIC_BYTE 18 unsigned char c[BYTE_PER_LONG]; 19 #endif 20 #ifdef UATOMIC_HAS_ATOMIC_SHORT 21 unsigned short s[SHORT_PER_LONG]; 22 #endif 23 unsigned int i[INT_PER_LONG]; 24 unsigned long l; 25 }; 26 27 static struct testvals vals; 28 29 #define do_test(ptr) \ 30 do { \ 31 __typeof__(*(ptr)) v; \ 32 \ 33 uatomic_add(ptr, 10); \ 34 ok1(uatomic_read(ptr) == 10); \ 35 \ 36 uatomic_add(ptr, -11UL); \ 37 ok1(uatomic_read(ptr) == (__typeof__(*(ptr)))-1UL); \ 38 \ 39 v = uatomic_cmpxchg(ptr, -1UL, 22); \ 40 ok1(uatomic_read(ptr) == 22); \ 41 ok1(v == (__typeof__(*(ptr)))-1UL); \ 42 \ 43 v = uatomic_cmpxchg(ptr, 33, 44); \ 44 ok1(uatomic_read(ptr) == 22); \ 45 ok1(v == 22); \ 46 \ 47 v = uatomic_xchg(ptr, 55); \ 48 ok1(uatomic_read(ptr) == 55); \ 49 ok1(v == 22); \ 50 \ 51 uatomic_set(ptr, 22); \ 52 uatomic_inc(ptr); \ 53 ok1(uatomic_read(ptr) == 23); \ 54 \ 55 uatomic_dec(ptr); \ 56 ok1(uatomic_read(ptr) == 22); \ 57 \ 58 v = uatomic_add_return(ptr, 74); \ 59 ok1(v == 96); \ 60 ok1(uatomic_read(ptr) == 96); \ 61 \ 62 uatomic_or(ptr, 58); \ 63 ok1(uatomic_read(ptr) == 122); \ 64 \ 65 v = uatomic_sub_return(ptr, 1); \ 66 ok1(v == 121); \ 67 \ 68 uatomic_sub(ptr, (unsigned int) 2); \ 69 ok1(uatomic_read(ptr) == 119); \ 70 \ 71 uatomic_inc(ptr); \ 72 uatomic_inc(ptr); \ 73 ok1(uatomic_read(ptr) == 121); \ 74 \ 75 uatomic_and(ptr, 129); \ 76 ok1(uatomic_read(ptr) == 1); \ 77 \ 78 } while (0) 79 80 int main(void) 81 { 82 int nr_run = INT_PER_LONG + 1; 83 unsigned long i; 84 85 #ifdef UATOMIC_HAS_ATOMIC_BYTE 86 nr_run += BYTE_PER_LONG; 87 #endif 88 #ifdef UATOMIC_HAS_ATOMIC_SHORT 89 nr_run += SHORT_PER_LONG; 90 #endif 91 92 plan_tests(nr_run * NR_TESTS); 93 #ifdef UATOMIC_HAS_ATOMIC_BYTE 94 for (i = 0; i < BYTE_PER_LONG; i++) { 95 diag("Test atomic ops on byte with %lu byte offset from long alignment", 96 i); 97 do_test(&vals.c[i]); 98 } 99 #endif 100 #ifdef UATOMIC_HAS_ATOMIC_SHORT 101 for (i = 0; i < SHORT_PER_LONG; i++) { 102 diag("Test atomic ops on short with %lu byte offset from long alignment", 103 i * sizeof(unsigned short)); 104 do_test(&vals.s[i]); 105 } 106 #endif 107 for (i = 0; i < INT_PER_LONG; i++) { 108 diag("Test atomic ops on int with %lu byte offset from long alignment", 109 i * sizeof(unsigned int)); 110 do_test(&vals.i[i]); 111 } 112 diag("Test atomic ops on long"); 113 do_test(&vals.l); 114 115 return exit_status(); 116 } 117