186a89380SLuca Barbieri /* 286a89380SLuca Barbieri * Testsuite for atomic64_t functions 386a89380SLuca Barbieri * 486a89380SLuca Barbieri * Copyright © 2010 Luca Barbieri 586a89380SLuca Barbieri * 686a89380SLuca Barbieri * This program is free software; you can redistribute it and/or modify 786a89380SLuca Barbieri * it under the terms of the GNU General Public License as published by 886a89380SLuca Barbieri * the Free Software Foundation; either version 2 of the License, or 986a89380SLuca Barbieri * (at your option) any later version. 1086a89380SLuca Barbieri */ 1186a89380SLuca Barbieri #include <linux/init.h> 12*0dbdd1bfSPeter Huewe #include <linux/kernel.h> 1386a89380SLuca Barbieri #include <asm/atomic.h> 1486a89380SLuca Barbieri 1586a89380SLuca Barbieri #define INIT(c) do { atomic64_set(&v, c); r = c; } while (0) 1686a89380SLuca Barbieri static __init int test_atomic64(void) 1786a89380SLuca Barbieri { 1886a89380SLuca Barbieri long long v0 = 0xaaa31337c001d00dLL; 1986a89380SLuca Barbieri long long v1 = 0xdeadbeefdeafcafeLL; 2086a89380SLuca Barbieri long long v2 = 0xfaceabadf00df001LL; 2186a89380SLuca Barbieri long long onestwos = 0x1111111122222222LL; 2286a89380SLuca Barbieri long long one = 1LL; 2386a89380SLuca Barbieri 2486a89380SLuca Barbieri atomic64_t v = ATOMIC64_INIT(v0); 2586a89380SLuca Barbieri long long r = v0; 2686a89380SLuca Barbieri BUG_ON(v.counter != r); 2786a89380SLuca Barbieri 2886a89380SLuca Barbieri atomic64_set(&v, v1); 2986a89380SLuca Barbieri r = v1; 3086a89380SLuca Barbieri BUG_ON(v.counter != r); 3186a89380SLuca Barbieri BUG_ON(atomic64_read(&v) != r); 3286a89380SLuca Barbieri 3386a89380SLuca Barbieri INIT(v0); 3486a89380SLuca Barbieri atomic64_add(onestwos, &v); 3586a89380SLuca Barbieri r += onestwos; 3686a89380SLuca Barbieri BUG_ON(v.counter != r); 3786a89380SLuca Barbieri 3886a89380SLuca Barbieri INIT(v0); 3986a89380SLuca Barbieri atomic64_add(-one, &v); 4086a89380SLuca Barbieri r += -one; 4186a89380SLuca Barbieri BUG_ON(v.counter != r); 4286a89380SLuca Barbieri 4386a89380SLuca Barbieri INIT(v0); 4486a89380SLuca Barbieri r += onestwos; 4586a89380SLuca Barbieri BUG_ON(atomic64_add_return(onestwos, &v) != r); 4686a89380SLuca Barbieri BUG_ON(v.counter != r); 4786a89380SLuca Barbieri 4886a89380SLuca Barbieri INIT(v0); 4986a89380SLuca Barbieri r += -one; 5086a89380SLuca Barbieri BUG_ON(atomic64_add_return(-one, &v) != r); 5186a89380SLuca Barbieri BUG_ON(v.counter != r); 5286a89380SLuca Barbieri 5386a89380SLuca Barbieri INIT(v0); 5486a89380SLuca Barbieri atomic64_sub(onestwos, &v); 5586a89380SLuca Barbieri r -= onestwos; 5686a89380SLuca Barbieri BUG_ON(v.counter != r); 5786a89380SLuca Barbieri 5886a89380SLuca Barbieri INIT(v0); 5986a89380SLuca Barbieri atomic64_sub(-one, &v); 6086a89380SLuca Barbieri r -= -one; 6186a89380SLuca Barbieri BUG_ON(v.counter != r); 6286a89380SLuca Barbieri 6386a89380SLuca Barbieri INIT(v0); 6486a89380SLuca Barbieri r -= onestwos; 6586a89380SLuca Barbieri BUG_ON(atomic64_sub_return(onestwos, &v) != r); 6686a89380SLuca Barbieri BUG_ON(v.counter != r); 6786a89380SLuca Barbieri 6886a89380SLuca Barbieri INIT(v0); 6986a89380SLuca Barbieri r -= -one; 7086a89380SLuca Barbieri BUG_ON(atomic64_sub_return(-one, &v) != r); 7186a89380SLuca Barbieri BUG_ON(v.counter != r); 7286a89380SLuca Barbieri 7386a89380SLuca Barbieri INIT(v0); 7486a89380SLuca Barbieri atomic64_inc(&v); 7586a89380SLuca Barbieri r += one; 7686a89380SLuca Barbieri BUG_ON(v.counter != r); 7786a89380SLuca Barbieri 7886a89380SLuca Barbieri INIT(v0); 7986a89380SLuca Barbieri r += one; 8086a89380SLuca Barbieri BUG_ON(atomic64_inc_return(&v) != r); 8186a89380SLuca Barbieri BUG_ON(v.counter != r); 8286a89380SLuca Barbieri 8386a89380SLuca Barbieri INIT(v0); 8486a89380SLuca Barbieri atomic64_dec(&v); 8586a89380SLuca Barbieri r -= one; 8686a89380SLuca Barbieri BUG_ON(v.counter != r); 8786a89380SLuca Barbieri 8886a89380SLuca Barbieri INIT(v0); 8986a89380SLuca Barbieri r -= one; 9086a89380SLuca Barbieri BUG_ON(atomic64_dec_return(&v) != r); 9186a89380SLuca Barbieri BUG_ON(v.counter != r); 9286a89380SLuca Barbieri 9386a89380SLuca Barbieri INIT(v0); 9486a89380SLuca Barbieri BUG_ON(atomic64_xchg(&v, v1) != v0); 9586a89380SLuca Barbieri r = v1; 9686a89380SLuca Barbieri BUG_ON(v.counter != r); 9786a89380SLuca Barbieri 9886a89380SLuca Barbieri INIT(v0); 9986a89380SLuca Barbieri BUG_ON(atomic64_cmpxchg(&v, v0, v1) != v0); 10086a89380SLuca Barbieri r = v1; 10186a89380SLuca Barbieri BUG_ON(v.counter != r); 10286a89380SLuca Barbieri 10386a89380SLuca Barbieri INIT(v0); 10486a89380SLuca Barbieri BUG_ON(atomic64_cmpxchg(&v, v2, v1) != v0); 10586a89380SLuca Barbieri BUG_ON(v.counter != r); 10686a89380SLuca Barbieri 10786a89380SLuca Barbieri INIT(v0); 1089efbcd59SLuca Barbieri BUG_ON(atomic64_add_unless(&v, one, v0)); 10986a89380SLuca Barbieri BUG_ON(v.counter != r); 11086a89380SLuca Barbieri 11186a89380SLuca Barbieri INIT(v0); 1129efbcd59SLuca Barbieri BUG_ON(!atomic64_add_unless(&v, one, v1)); 11386a89380SLuca Barbieri r += one; 11486a89380SLuca Barbieri BUG_ON(v.counter != r); 11586a89380SLuca Barbieri 116d7f6de1eSLuca Barbieri #if defined(CONFIG_X86) || defined(CONFIG_MIPS) || defined(CONFIG_PPC) || defined(_ASM_GENERIC_ATOMIC64_H) 11786a89380SLuca Barbieri INIT(onestwos); 11886a89380SLuca Barbieri BUG_ON(atomic64_dec_if_positive(&v) != (onestwos - 1)); 11986a89380SLuca Barbieri r -= one; 12086a89380SLuca Barbieri BUG_ON(v.counter != r); 12186a89380SLuca Barbieri 12286a89380SLuca Barbieri INIT(0); 12386a89380SLuca Barbieri BUG_ON(atomic64_dec_if_positive(&v) != -one); 12486a89380SLuca Barbieri BUG_ON(v.counter != r); 12586a89380SLuca Barbieri 12686a89380SLuca Barbieri INIT(-one); 12786a89380SLuca Barbieri BUG_ON(atomic64_dec_if_positive(&v) != (-one - one)); 12886a89380SLuca Barbieri BUG_ON(v.counter != r); 1298f4f202bSLuca Barbieri #else 1308f4f202bSLuca Barbieri #warning Please implement atomic64_dec_if_positive for your architecture, and add it to the IF above 1318f4f202bSLuca Barbieri #endif 13286a89380SLuca Barbieri 13386a89380SLuca Barbieri INIT(onestwos); 13425a304f2SLuca Barbieri BUG_ON(!atomic64_inc_not_zero(&v)); 13586a89380SLuca Barbieri r += one; 13686a89380SLuca Barbieri BUG_ON(v.counter != r); 13786a89380SLuca Barbieri 13886a89380SLuca Barbieri INIT(0); 13925a304f2SLuca Barbieri BUG_ON(atomic64_inc_not_zero(&v)); 14086a89380SLuca Barbieri BUG_ON(v.counter != r); 14186a89380SLuca Barbieri 14286a89380SLuca Barbieri INIT(-one); 14325a304f2SLuca Barbieri BUG_ON(!atomic64_inc_not_zero(&v)); 14486a89380SLuca Barbieri r += one; 14586a89380SLuca Barbieri BUG_ON(v.counter != r); 14686a89380SLuca Barbieri 14786a89380SLuca Barbieri #ifdef CONFIG_X86 148a5c9161fSH. Peter Anvin printk(KERN_INFO "atomic64 test passed for %s platform %s CX8 and %s SSE\n", 149a5c9161fSH. Peter Anvin #ifdef CONFIG_X86_64 150a5c9161fSH. Peter Anvin "x86-64", 151a5c9161fSH. Peter Anvin #elif defined(CONFIG_X86_CMPXCHG64) 152a5c9161fSH. Peter Anvin "i586+", 15386a89380SLuca Barbieri #else 154a5c9161fSH. Peter Anvin "i386+", 15586a89380SLuca Barbieri #endif 15686a89380SLuca Barbieri boot_cpu_has(X86_FEATURE_CX8) ? "with" : "without", 15786a89380SLuca Barbieri boot_cpu_has(X86_FEATURE_XMM) ? "with" : "without"); 15886a89380SLuca Barbieri #else 15986a89380SLuca Barbieri printk(KERN_INFO "atomic64 test passed\n"); 16086a89380SLuca Barbieri #endif 16186a89380SLuca Barbieri 16286a89380SLuca Barbieri return 0; 16386a89380SLuca Barbieri } 16486a89380SLuca Barbieri 16586a89380SLuca Barbieri core_initcall(test_atomic64); 166