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> 1286a89380SLuca Barbieri #include <asm/atomic.h> 1386a89380SLuca Barbieri 1486a89380SLuca Barbieri #define INIT(c) do { atomic64_set(&v, c); r = c; } while (0) 1586a89380SLuca Barbieri static __init int test_atomic64(void) 1686a89380SLuca Barbieri { 1786a89380SLuca Barbieri long long v0 = 0xaaa31337c001d00dLL; 1886a89380SLuca Barbieri long long v1 = 0xdeadbeefdeafcafeLL; 1986a89380SLuca Barbieri long long v2 = 0xfaceabadf00df001LL; 2086a89380SLuca Barbieri long long onestwos = 0x1111111122222222LL; 2186a89380SLuca Barbieri long long one = 1LL; 2286a89380SLuca Barbieri 2386a89380SLuca Barbieri atomic64_t v = ATOMIC64_INIT(v0); 2486a89380SLuca Barbieri long long r = v0; 2586a89380SLuca Barbieri BUG_ON(v.counter != r); 2686a89380SLuca Barbieri 2786a89380SLuca Barbieri atomic64_set(&v, v1); 2886a89380SLuca Barbieri r = v1; 2986a89380SLuca Barbieri BUG_ON(v.counter != r); 3086a89380SLuca Barbieri BUG_ON(atomic64_read(&v) != r); 3186a89380SLuca Barbieri 3286a89380SLuca Barbieri INIT(v0); 3386a89380SLuca Barbieri atomic64_add(onestwos, &v); 3486a89380SLuca Barbieri r += onestwos; 3586a89380SLuca Barbieri BUG_ON(v.counter != r); 3686a89380SLuca Barbieri 3786a89380SLuca Barbieri INIT(v0); 3886a89380SLuca Barbieri atomic64_add(-one, &v); 3986a89380SLuca Barbieri r += -one; 4086a89380SLuca Barbieri BUG_ON(v.counter != r); 4186a89380SLuca Barbieri 4286a89380SLuca Barbieri INIT(v0); 4386a89380SLuca Barbieri r += onestwos; 4486a89380SLuca Barbieri BUG_ON(atomic64_add_return(onestwos, &v) != r); 4586a89380SLuca Barbieri BUG_ON(v.counter != r); 4686a89380SLuca Barbieri 4786a89380SLuca Barbieri INIT(v0); 4886a89380SLuca Barbieri r += -one; 4986a89380SLuca Barbieri BUG_ON(atomic64_add_return(-one, &v) != r); 5086a89380SLuca Barbieri BUG_ON(v.counter != r); 5186a89380SLuca Barbieri 5286a89380SLuca Barbieri INIT(v0); 5386a89380SLuca Barbieri atomic64_sub(onestwos, &v); 5486a89380SLuca Barbieri r -= onestwos; 5586a89380SLuca Barbieri BUG_ON(v.counter != r); 5686a89380SLuca Barbieri 5786a89380SLuca Barbieri INIT(v0); 5886a89380SLuca Barbieri atomic64_sub(-one, &v); 5986a89380SLuca Barbieri r -= -one; 6086a89380SLuca Barbieri BUG_ON(v.counter != r); 6186a89380SLuca Barbieri 6286a89380SLuca Barbieri INIT(v0); 6386a89380SLuca Barbieri r -= onestwos; 6486a89380SLuca Barbieri BUG_ON(atomic64_sub_return(onestwos, &v) != r); 6586a89380SLuca Barbieri BUG_ON(v.counter != r); 6686a89380SLuca Barbieri 6786a89380SLuca Barbieri INIT(v0); 6886a89380SLuca Barbieri r -= -one; 6986a89380SLuca Barbieri BUG_ON(atomic64_sub_return(-one, &v) != r); 7086a89380SLuca Barbieri BUG_ON(v.counter != r); 7186a89380SLuca Barbieri 7286a89380SLuca Barbieri INIT(v0); 7386a89380SLuca Barbieri atomic64_inc(&v); 7486a89380SLuca Barbieri r += one; 7586a89380SLuca Barbieri BUG_ON(v.counter != r); 7686a89380SLuca Barbieri 7786a89380SLuca Barbieri INIT(v0); 7886a89380SLuca Barbieri r += one; 7986a89380SLuca Barbieri BUG_ON(atomic64_inc_return(&v) != r); 8086a89380SLuca Barbieri BUG_ON(v.counter != r); 8186a89380SLuca Barbieri 8286a89380SLuca Barbieri INIT(v0); 8386a89380SLuca Barbieri atomic64_dec(&v); 8486a89380SLuca Barbieri r -= one; 8586a89380SLuca Barbieri BUG_ON(v.counter != r); 8686a89380SLuca Barbieri 8786a89380SLuca Barbieri INIT(v0); 8886a89380SLuca Barbieri r -= one; 8986a89380SLuca Barbieri BUG_ON(atomic64_dec_return(&v) != r); 9086a89380SLuca Barbieri BUG_ON(v.counter != r); 9186a89380SLuca Barbieri 9286a89380SLuca Barbieri INIT(v0); 9386a89380SLuca Barbieri BUG_ON(atomic64_xchg(&v, v1) != v0); 9486a89380SLuca Barbieri r = v1; 9586a89380SLuca Barbieri BUG_ON(v.counter != r); 9686a89380SLuca Barbieri 9786a89380SLuca Barbieri INIT(v0); 9886a89380SLuca Barbieri BUG_ON(atomic64_cmpxchg(&v, v0, v1) != v0); 9986a89380SLuca Barbieri r = v1; 10086a89380SLuca Barbieri BUG_ON(v.counter != r); 10186a89380SLuca Barbieri 10286a89380SLuca Barbieri INIT(v0); 10386a89380SLuca Barbieri BUG_ON(atomic64_cmpxchg(&v, v2, v1) != v0); 10486a89380SLuca Barbieri BUG_ON(v.counter != r); 10586a89380SLuca Barbieri 10686a89380SLuca Barbieri INIT(v0); 10786a89380SLuca Barbieri BUG_ON(!atomic64_add_unless(&v, one, v0)); 10886a89380SLuca Barbieri BUG_ON(v.counter != r); 10986a89380SLuca Barbieri 11086a89380SLuca Barbieri INIT(v0); 11186a89380SLuca Barbieri BUG_ON(atomic64_add_unless(&v, one, v1)); 11286a89380SLuca Barbieri r += one; 11386a89380SLuca Barbieri BUG_ON(v.counter != r); 11486a89380SLuca Barbieri 115*d7f6de1eSLuca Barbieri #if defined(CONFIG_X86) || defined(CONFIG_MIPS) || defined(CONFIG_PPC) || defined(_ASM_GENERIC_ATOMIC64_H) 11686a89380SLuca Barbieri INIT(onestwos); 11786a89380SLuca Barbieri BUG_ON(atomic64_dec_if_positive(&v) != (onestwos - 1)); 11886a89380SLuca Barbieri r -= one; 11986a89380SLuca Barbieri BUG_ON(v.counter != r); 12086a89380SLuca Barbieri 12186a89380SLuca Barbieri INIT(0); 12286a89380SLuca Barbieri BUG_ON(atomic64_dec_if_positive(&v) != -one); 12386a89380SLuca Barbieri BUG_ON(v.counter != r); 12486a89380SLuca Barbieri 12586a89380SLuca Barbieri INIT(-one); 12686a89380SLuca Barbieri BUG_ON(atomic64_dec_if_positive(&v) != (-one - one)); 12786a89380SLuca Barbieri BUG_ON(v.counter != r); 1288f4f202bSLuca Barbieri #else 1298f4f202bSLuca Barbieri #warning Please implement atomic64_dec_if_positive for your architecture, and add it to the IF above 1308f4f202bSLuca Barbieri #endif 13186a89380SLuca Barbieri 13286a89380SLuca Barbieri INIT(onestwos); 13386a89380SLuca Barbieri BUG_ON(atomic64_inc_not_zero(&v)); 13486a89380SLuca Barbieri r += one; 13586a89380SLuca Barbieri BUG_ON(v.counter != r); 13686a89380SLuca Barbieri 13786a89380SLuca Barbieri INIT(0); 13886a89380SLuca Barbieri BUG_ON(!atomic64_inc_not_zero(&v)); 13986a89380SLuca Barbieri BUG_ON(v.counter != r); 14086a89380SLuca Barbieri 14186a89380SLuca Barbieri INIT(-one); 14286a89380SLuca Barbieri BUG_ON(atomic64_inc_not_zero(&v)); 14386a89380SLuca Barbieri r += one; 14486a89380SLuca Barbieri BUG_ON(v.counter != r); 14586a89380SLuca Barbieri 14686a89380SLuca Barbieri #ifdef CONFIG_X86 14786a89380SLuca Barbieri printk(KERN_INFO "atomic64 test passed for %s+ platform %s CX8 and %s SSE\n", 14886a89380SLuca Barbieri #ifdef CONFIG_X86_CMPXCHG64 14986a89380SLuca Barbieri "586", 15086a89380SLuca Barbieri #else 15186a89380SLuca Barbieri "386", 15286a89380SLuca Barbieri #endif 15386a89380SLuca Barbieri boot_cpu_has(X86_FEATURE_CX8) ? "with" : "without", 15486a89380SLuca Barbieri boot_cpu_has(X86_FEATURE_XMM) ? "with" : "without"); 15586a89380SLuca Barbieri #else 15686a89380SLuca Barbieri printk(KERN_INFO "atomic64 test passed\n"); 15786a89380SLuca Barbieri #endif 15886a89380SLuca Barbieri 15986a89380SLuca Barbieri return 0; 16086a89380SLuca Barbieri } 16186a89380SLuca Barbieri 16286a89380SLuca Barbieri core_initcall(test_atomic64); 163