2010-02-24 12:54:24 +03:00
/*
* Testsuite for atomic64_t functions
*
* Copyright © 2010 Luca Barbieri
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation ; either version 2 of the License , or
* ( at your option ) any later version .
*/
2014-06-05 03:12:00 +04:00
# define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
2010-02-24 12:54:24 +03:00
# include <linux/init.h>
2012-01-21 03:35:53 +04:00
# include <linux/bug.h>
2010-05-24 23:13:20 +04:00
# include <linux/kernel.h>
2011-07-27 03:09:06 +04:00
# include <linux/atomic.h>
2010-02-24 12:54:24 +03:00
# define INIT(c) do { atomic64_set(&v, c); r = c; } while (0)
static __init int test_atomic64 ( void )
{
long long v0 = 0xaaa31337c001d00dLL ;
long long v1 = 0xdeadbeefdeafcafeLL ;
long long v2 = 0xfaceabadf00df001LL ;
long long onestwos = 0x1111111122222222LL ;
long long one = 1LL ;
atomic64_t v = ATOMIC64_INIT ( v0 ) ;
long long r = v0 ;
BUG_ON ( v . counter ! = r ) ;
atomic64_set ( & v , v1 ) ;
r = v1 ;
BUG_ON ( v . counter ! = r ) ;
BUG_ON ( atomic64_read ( & v ) ! = r ) ;
INIT ( v0 ) ;
atomic64_add ( onestwos , & v ) ;
r + = onestwos ;
BUG_ON ( v . counter ! = r ) ;
INIT ( v0 ) ;
atomic64_add ( - one , & v ) ;
r + = - one ;
BUG_ON ( v . counter ! = r ) ;
INIT ( v0 ) ;
r + = onestwos ;
BUG_ON ( atomic64_add_return ( onestwos , & v ) ! = r ) ;
BUG_ON ( v . counter ! = r ) ;
INIT ( v0 ) ;
r + = - one ;
BUG_ON ( atomic64_add_return ( - one , & v ) ! = r ) ;
BUG_ON ( v . counter ! = r ) ;
INIT ( v0 ) ;
atomic64_sub ( onestwos , & v ) ;
r - = onestwos ;
BUG_ON ( v . counter ! = r ) ;
INIT ( v0 ) ;
atomic64_sub ( - one , & v ) ;
r - = - one ;
BUG_ON ( v . counter ! = r ) ;
INIT ( v0 ) ;
r - = onestwos ;
BUG_ON ( atomic64_sub_return ( onestwos , & v ) ! = r ) ;
BUG_ON ( v . counter ! = r ) ;
INIT ( v0 ) ;
r - = - one ;
BUG_ON ( atomic64_sub_return ( - one , & v ) ! = r ) ;
BUG_ON ( v . counter ! = r ) ;
INIT ( v0 ) ;
atomic64_inc ( & v ) ;
r + = one ;
BUG_ON ( v . counter ! = r ) ;
INIT ( v0 ) ;
r + = one ;
BUG_ON ( atomic64_inc_return ( & v ) ! = r ) ;
BUG_ON ( v . counter ! = r ) ;
INIT ( v0 ) ;
atomic64_dec ( & v ) ;
r - = one ;
BUG_ON ( v . counter ! = r ) ;
INIT ( v0 ) ;
r - = one ;
BUG_ON ( atomic64_dec_return ( & v ) ! = r ) ;
BUG_ON ( v . counter ! = r ) ;
INIT ( v0 ) ;
BUG_ON ( atomic64_xchg ( & v , v1 ) ! = v0 ) ;
r = v1 ;
BUG_ON ( v . counter ! = r ) ;
INIT ( v0 ) ;
BUG_ON ( atomic64_cmpxchg ( & v , v0 , v1 ) ! = v0 ) ;
r = v1 ;
BUG_ON ( v . counter ! = r ) ;
INIT ( v0 ) ;
BUG_ON ( atomic64_cmpxchg ( & v , v2 , v1 ) ! = v0 ) ;
BUG_ON ( v . counter ! = r ) ;
INIT ( v0 ) ;
2010-03-01 21:55:45 +03:00
BUG_ON ( atomic64_add_unless ( & v , one , v0 ) ) ;
2010-02-24 12:54:24 +03:00
BUG_ON ( v . counter ! = r ) ;
INIT ( v0 ) ;
2010-03-01 21:55:45 +03:00
BUG_ON ( ! atomic64_add_unless ( & v , one , v1 ) ) ;
2010-02-24 12:54:24 +03:00
r + = one ;
BUG_ON ( v . counter ! = r ) ;
2012-07-31 01:41:09 +04:00
# ifdef CONFIG_ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
2010-02-24 12:54:24 +03:00
INIT ( onestwos ) ;
BUG_ON ( atomic64_dec_if_positive ( & v ) ! = ( onestwos - 1 ) ) ;
r - = one ;
BUG_ON ( v . counter ! = r ) ;
INIT ( 0 ) ;
BUG_ON ( atomic64_dec_if_positive ( & v ) ! = - one ) ;
BUG_ON ( v . counter ! = r ) ;
INIT ( - one ) ;
BUG_ON ( atomic64_dec_if_positive ( & v ) ! = ( - one - one ) ) ;
BUG_ON ( v . counter ! = r ) ;
2010-02-26 14:22:40 +03:00
# else
2012-07-31 01:41:09 +04:00
# warning Please implement atomic64_dec_if_positive for your architecture and select the above Kconfig symbol
2010-02-26 14:22:40 +03:00
# endif
2010-02-24 12:54:24 +03:00
INIT ( onestwos ) ;
2010-03-01 21:55:48 +03:00
BUG_ON ( ! atomic64_inc_not_zero ( & v ) ) ;
2010-02-24 12:54:24 +03:00
r + = one ;
BUG_ON ( v . counter ! = r ) ;
INIT ( 0 ) ;
2010-03-01 21:55:48 +03:00
BUG_ON ( atomic64_inc_not_zero ( & v ) ) ;
2010-02-24 12:54:24 +03:00
BUG_ON ( v . counter ! = r ) ;
INIT ( - one ) ;
2010-03-01 21:55:48 +03:00
BUG_ON ( ! atomic64_inc_not_zero ( & v ) ) ;
2010-02-24 12:54:24 +03:00
r + = one ;
BUG_ON ( v . counter ! = r ) ;
# ifdef CONFIG_X86
2014-06-05 03:12:00 +04:00
pr_info ( " passed for %s platform %s CX8 and %s SSE \n " ,
2010-03-01 22:49:23 +03:00
# ifdef CONFIG_X86_64
2014-06-05 03:12:00 +04:00
" x86-64 " ,
2010-03-01 22:49:23 +03:00
# elif defined(CONFIG_X86_CMPXCHG64)
2014-06-05 03:12:00 +04:00
" i586+ " ,
2010-02-24 12:54:24 +03:00
# else
2014-06-05 03:12:00 +04:00
" i386+ " ,
2010-02-24 12:54:24 +03:00
# endif
2010-03-01 22:49:23 +03:00
boot_cpu_has ( X86_FEATURE_CX8 ) ? " with " : " without " ,
boot_cpu_has ( X86_FEATURE_XMM ) ? " with " : " without " ) ;
2010-02-24 12:54:24 +03:00
# else
2014-06-05 03:12:00 +04:00
pr_info ( " passed \n " ) ;
2010-02-24 12:54:24 +03:00
# endif
return 0 ;
}
core_initcall ( test_atomic64 ) ;