2012-07-11 17:35:43 +04:00
/*
2013-11-20 02:50:56 +04:00
* Copyright ( C ) 2011 - 2013 Red Hat , Inc .
2012-07-11 17:35:43 +04:00
*
* This library is free software ; you can redistribute it and / or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation ; either
* version 2.1 of the License , or ( at your option ) any later version .
*
* This library is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the GNU
* Lesser General Public License for more details .
*
* You should have received a copy of the GNU Lesser General Public
2012-09-21 02:30:55 +04:00
* License along with this library . If not , see
2012-07-11 17:35:43 +04:00
* < http : //www.gnu.org/licenses/>.
*
*/
# include <config.h>
# include <time.h>
# include <sched.h>
# include "testutils.h"
# include "viratomic.h"
# include "virrandom.h"
2012-12-13 19:49:48 +04:00
# include "virthread.h"
2012-07-11 17:35:43 +04:00
static int
testTypes ( const void * data ATTRIBUTE_UNUSED )
{
unsigned int u , u2 ;
int s , s2 ;
bool res ;
# define virAssertCmpInt(a, op, b) \
2012-10-17 13:23:12 +04:00
if ( ! ( a op b ) ) \
2012-07-11 17:35:43 +04:00
return - 1 ;
virAtomicIntSet ( & u , 5 ) ;
u2 = virAtomicIntGet ( & u ) ;
virAssertCmpInt ( u2 , = = , 5 ) ;
res = virAtomicIntCompareExchange ( & u , 6 , 7 ) ;
if ( res )
return - 1 ;
virAssertCmpInt ( u , = = , 5 ) ;
virAssertCmpInt ( virAtomicIntAdd ( & u , 1 ) , = = , 5 ) ;
virAssertCmpInt ( u , = = , 6 ) ;
virAssertCmpInt ( virAtomicIntInc ( & u ) , = = , 7 ) ;
virAssertCmpInt ( u , = = , 7 ) ;
res = virAtomicIntDecAndTest ( & u ) ;
if ( res )
return - 1 ;
virAssertCmpInt ( u , = = , 6 ) ;
u2 = virAtomicIntAnd ( & u , 5 ) ;
virAssertCmpInt ( u2 , = = , 6 ) ;
virAssertCmpInt ( u , = = , 4 ) ;
u2 = virAtomicIntOr ( & u , 8 ) ;
virAssertCmpInt ( u2 , = = , 4 ) ;
virAssertCmpInt ( u , = = , 12 ) ;
u2 = virAtomicIntXor ( & u , 4 ) ;
virAssertCmpInt ( u2 , = = , 12 ) ;
virAssertCmpInt ( u , = = , 8 ) ;
virAtomicIntSet ( & s , 5 ) ;
s2 = virAtomicIntGet ( & s ) ;
virAssertCmpInt ( s2 , = = , 5 ) ;
res = virAtomicIntCompareExchange ( & s , 6 , 7 ) ;
if ( res )
return - 1 ;
virAssertCmpInt ( s , = = , 5 ) ;
virAtomicIntAdd ( & s , 1 ) ;
virAssertCmpInt ( s , = = , 6 ) ;
virAtomicIntInc ( & s ) ;
virAssertCmpInt ( s , = = , 7 ) ;
res = virAtomicIntDecAndTest ( & s ) ;
if ( res )
return - 1 ;
virAssertCmpInt ( s , = = , 6 ) ;
s2 = virAtomicIntAnd ( & s , 5 ) ;
virAssertCmpInt ( s2 , = = , 6 ) ;
virAssertCmpInt ( s , = = , 4 ) ;
s2 = virAtomicIntOr ( & s , 8 ) ;
virAssertCmpInt ( s2 , = = , 4 ) ;
virAssertCmpInt ( s , = = , 12 ) ;
s2 = virAtomicIntXor ( & s , 4 ) ;
virAssertCmpInt ( s2 , = = , 12 ) ;
virAssertCmpInt ( s , = = , 8 ) ;
return 0 ;
}
# define THREADS 10
# define ROUNDS 10000
volatile int bucket [ THREADS ] ;
volatile int atomic ;
static void
thread_func ( void * data )
{
2012-09-04 14:16:55 +04:00
int idx = ( intptr_t ) data ;
Convert 'int i' to 'size_t i' in tests/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 18:09:33 +04:00
size_t i ;
2012-07-11 17:35:43 +04:00
int d ;
for ( i = 0 ; i < ROUNDS ; i + + ) {
d = virRandomBits ( 7 ) ;
bucket [ idx ] + = d ;
virAtomicIntAdd ( & atomic , d ) ;
# ifdef WIN32
2013-11-20 02:50:56 +04:00
SleepEx ( 0 , 0 ) ;
2012-07-11 17:35:43 +04:00
# else
sched_yield ( ) ;
# endif
}
}
static int
testThreads ( const void * data ATTRIBUTE_UNUSED )
{
int sum ;
Convert 'int i' to 'size_t i' in tests/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 18:09:33 +04:00
size_t i ;
2012-07-11 17:35:43 +04:00
virThread threads [ THREADS ] ;
atomic = 0 ;
for ( i = 0 ; i < THREADS ; i + + )
bucket [ i ] = 0 ;
for ( i = 0 ; i < THREADS ; i + + ) {
2012-09-04 14:16:55 +04:00
if ( virThreadCreate ( & ( threads [ i ] ) , true , thread_func , ( void * ) ( intptr_t ) i ) < 0 )
2012-07-11 17:35:43 +04:00
return - 1 ;
}
for ( i = 0 ; i < THREADS ; i + + )
virThreadJoin ( & threads [ i ] ) ;
sum = 0 ;
for ( i = 0 ; i < THREADS ; i + + )
sum + = bucket [ i ] ;
if ( sum ! = atomic )
return - 1 ;
return 0 ;
}
static int
mymain ( void )
{
int ret = 0 ;
if ( virThreadInitialize ( ) < 0 )
return - 1 ;
2013-09-20 22:13:35 +04:00
if ( virtTestRun ( " types " , testTypes , NULL ) < 0 )
2012-07-11 17:35:43 +04:00
ret = - 1 ;
2013-09-20 22:13:35 +04:00
if ( virtTestRun ( " threads " , testThreads , NULL ) < 0 )
2012-07-11 17:35:43 +04:00
ret = - 1 ;
return ret ;
}
VIRT_TEST_MAIN ( mymain )