1 /* 2 * Testsuite for atomic64_t functions 3 * 4 * Copyright © 2010 Luca Barbieri 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or 9 * (at your option) any later version. 10 */ 11 12 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 13 14 #include <linux/init.h> 15 #include <linux/bug.h> 16 #include <linux/kernel.h> 17 #include <linux/atomic.h> 18 19 #define INIT(c) do { atomic64_set(&v, c); r = c; } while (0) 20 static __init int test_atomic64(void) 21 { 22 long long v0 = 0xaaa31337c001d00dLL; 23 long long v1 = 0xdeadbeefdeafcafeLL; 24 long long v2 = 0xfaceabadf00df001LL; 25 long long onestwos = 0x1111111122222222LL; 26 long long one = 1LL; 27 28 atomic64_t v = ATOMIC64_INIT(v0); 29 long long r = v0; 30 BUG_ON(v.counter != r); 31 32 atomic64_set(&v, v1); 33 r = v1; 34 BUG_ON(v.counter != r); 35 BUG_ON(atomic64_read(&v) != r); 36 37 INIT(v0); 38 atomic64_add(onestwos, &v); 39 r += onestwos; 40 BUG_ON(v.counter != r); 41 42 INIT(v0); 43 atomic64_add(-one, &v); 44 r += -one; 45 BUG_ON(v.counter != r); 46 47 INIT(v0); 48 r += onestwos; 49 BUG_ON(atomic64_add_return(onestwos, &v) != r); 50 BUG_ON(v.counter != r); 51 52 INIT(v0); 53 r += -one; 54 BUG_ON(atomic64_add_return(-one, &v) != r); 55 BUG_ON(v.counter != r); 56 57 INIT(v0); 58 atomic64_sub(onestwos, &v); 59 r -= onestwos; 60 BUG_ON(v.counter != r); 61 62 INIT(v0); 63 atomic64_sub(-one, &v); 64 r -= -one; 65 BUG_ON(v.counter != r); 66 67 INIT(v0); 68 r -= onestwos; 69 BUG_ON(atomic64_sub_return(onestwos, &v) != r); 70 BUG_ON(v.counter != r); 71 72 INIT(v0); 73 r -= -one; 74 BUG_ON(atomic64_sub_return(-one, &v) != r); 75 BUG_ON(v.counter != r); 76 77 INIT(v0); 78 atomic64_inc(&v); 79 r += one; 80 BUG_ON(v.counter != r); 81 82 INIT(v0); 83 r += one; 84 BUG_ON(atomic64_inc_return(&v) != r); 85 BUG_ON(v.counter != r); 86 87 INIT(v0); 88 atomic64_dec(&v); 89 r -= one; 90 BUG_ON(v.counter != r); 91 92 INIT(v0); 93 r -= one; 94 BUG_ON(atomic64_dec_return(&v) != r); 95 BUG_ON(v.counter != r); 96 97 INIT(v0); 98 BUG_ON(atomic64_xchg(&v, v1) != v0); 99 r = v1; 100 BUG_ON(v.counter != r); 101 102 INIT(v0); 103 BUG_ON(atomic64_cmpxchg(&v, v0, v1) != v0); 104 r = v1; 105 BUG_ON(v.counter != r); 106 107 INIT(v0); 108 BUG_ON(atomic64_cmpxchg(&v, v2, v1) != v0); 109 BUG_ON(v.counter != r); 110 111 INIT(v0); 112 BUG_ON(atomic64_add_unless(&v, one, v0)); 113 BUG_ON(v.counter != r); 114 115 INIT(v0); 116 BUG_ON(!atomic64_add_unless(&v, one, v1)); 117 r += one; 118 BUG_ON(v.counter != r); 119 120 #ifdef CONFIG_ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE 121 INIT(onestwos); 122 BUG_ON(atomic64_dec_if_positive(&v) != (onestwos - 1)); 123 r -= one; 124 BUG_ON(v.counter != r); 125 126 INIT(0); 127 BUG_ON(atomic64_dec_if_positive(&v) != -one); 128 BUG_ON(v.counter != r); 129 130 INIT(-one); 131 BUG_ON(atomic64_dec_if_positive(&v) != (-one - one)); 132 BUG_ON(v.counter != r); 133 #else 134 #warning Please implement atomic64_dec_if_positive for your architecture and select the above Kconfig symbol 135 #endif 136 137 INIT(onestwos); 138 BUG_ON(!atomic64_inc_not_zero(&v)); 139 r += one; 140 BUG_ON(v.counter != r); 141 142 INIT(0); 143 BUG_ON(atomic64_inc_not_zero(&v)); 144 BUG_ON(v.counter != r); 145 146 INIT(-one); 147 BUG_ON(!atomic64_inc_not_zero(&v)); 148 r += one; 149 BUG_ON(v.counter != r); 150 151 #ifdef CONFIG_X86 152 pr_info("passed for %s platform %s CX8 and %s SSE\n", 153 #ifdef CONFIG_X86_64 154 "x86-64", 155 #elif defined(CONFIG_X86_CMPXCHG64) 156 "i586+", 157 #else 158 "i386+", 159 #endif 160 boot_cpu_has(X86_FEATURE_CX8) ? "with" : "without", 161 boot_cpu_has(X86_FEATURE_XMM) ? "with" : "without"); 162 #else 163 pr_info("passed\n"); 164 #endif 165 166 return 0; 167 } 168 169 core_initcall(test_atomic64); 170