added epicsAtomicGetUIntT for completeness

This commit is contained in:
Jeff Hill
2011-08-12 10:06:09 -06:00
parent 049e070b3a
commit a50482a0c9
9 changed files with 90 additions and 28 deletions

View File

@@ -83,6 +83,12 @@ OSD_ATOMIC_INLINE size_t epicsAtomicGetSizeT ( const size_t * pTarget )
return *pTarget;
}
OSD_ATOMIC_INLINE unsigned epicsAtomicGetUIntT ( const unsigned * pTarget )
{
__sync_synchronize ();
return *pTarget;
}
OSD_ATOMIC_INLINE unsigned epicsAtomicTestAndSetUIntT ( unsigned * pTarget )
{
const size_t prev = __sync_lock_test_and_set ( pTarget, 1u );

View File

@@ -66,7 +66,7 @@
extern "C" {
#endif /* __cplusplus */
/* necessary for next two functions */
/* necessary for next three functions */
STATIC_ASSERT ( sizeof ( long ) == sizeof ( unsigned ) );
OSD_ATOMIC_INLINE void epicsAtomicSetUIntT ( unsigned * pTarget, unsigned newVal )
@@ -75,6 +75,12 @@ OSD_ATOMIC_INLINE void epicsAtomicSetUIntT ( unsigned * pTarget, unsigned newVal
_InterlockedExchange ( pTarg, ( long ) newVal );
}
OSD_ATOMIC_INLINE unsigned epicsAtomicGetUIntT ( const unsigned * pTarget )
{
long * const pTarg = ( long * ) ( pTarget );
return _InterlockedExchangeAdd ( pTarg, 0 );
}
OSD_ATOMIC_INLINE unsigned epicsAtomicTestAndSetUIntT ( unsigned * pTarget )
{
long * const pTarg = ( long * ) ( pTarget );

View File

@@ -58,6 +58,7 @@ epicsShareFunc void epicsAtomicSetUIntT ( unsigned * pTarget, unsigned newValue
* fetch target in cache, return new value of target
*/
epicsShareFunc size_t epicsAtomicGetSizeT ( const size_t * pTarget );
epicsShareFunc unsigned epicsAtomicGetUIntT ( const unsigned * pTarget );
/*
* lock out other smp processors from accessing the target,
@@ -84,6 +85,7 @@ epicsShareFunc size_t epicsLockedDecrSizeT ( size_t * pTarget );
epicsShareFunc void epicsLockedSetSizeT ( size_t * pTarget, size_t newVal );
epicsShareFunc void epicsLockedSetUIntT ( unsigned * pTarget, unsigned newVal );
epicsShareFunc size_t epicsLockedGetSizeT ( const size_t * pTarget );
epicsShareFunc unsigned epicsLockedGetUIntT ( const unsigned * pTarget );
epicsShareFunc unsigned epicsLockedTestAndSetUIntT ( unsigned * pTarget );
#ifdef __cplusplus

View File

@@ -86,6 +86,12 @@ size_t epicsLockedGetSizeT ( const size_t * pTarget )
return *pTarget;
}
unsigned epicsLockedGetUIntT ( const unsigned * pTarget )
{
AtomicGuard atomicGuard;
return *pTarget;
}
unsigned epicsLockedTestAndSetUIntT ( unsigned * pTarget )
{
AtomicGuard atomicGuard;

View File

@@ -52,6 +52,11 @@ OSD_ATOMIC_INLINE size_t epicsAtomicGetSizeT ( const size_t * pTarget )
return epicsLockedGetSizeT ( pTarget );
}
OSD_ATOMIC_INLINE unsigned epicsAtomicGetUIntT ( const unsigned * pTarget )
{
return epicsLockedGetUIntT ( pTarget );
}
#ifdef __cplusplus
} /* end of extern "C" */
#endif /* __cplusplus */
@@ -63,6 +68,7 @@ OSD_ATOMIC_INLINE size_t epicsAtomicGetSizeT ( const size_t * pTarget )
# define epicsAtomicSetSizeT epicsLockedSetSizeT
# define epicsAtomicSetUIntT epicsLockedSetUIntT
# define epicsAtomicGetSizeT epicsLockedGetSizeT
# define epicsAtomicGetUIntT epicsLockedGetUIntT
# define epicsAtomicTestAndSetUIntT epicsLockedTestAndSetUIntT
#endif /* if defined ( OSD_ATOMIC_INLINE ) */

View File

@@ -33,7 +33,7 @@
extern "C" {
#endif /* __cplusplus */
/* necessary for next two functions */
/* necessary for next three functions */
STATIC_ASSERT ( sizeof ( LONG ) == sizeof ( unsigned ) );
OSD_ATOMIC_INLINE void epicsAtomicSetUIntT ( unsigned * pTarget, unsigned newVal )
@@ -42,6 +42,12 @@ OSD_ATOMIC_INLINE void epicsAtomicSetUIntT ( unsigned * pTarget, unsigned newVal
InterlockedExchange ( pTarg, ( LONG ) newVal );
}
OSD_ATOMIC_INLINE unsigned epicsAtomicGetUIntT ( const unsigned * pTarget )
{
LONG * const pTarg = ( LONG * ) ( pTarget );
return InterlockedExchangeAdd ( pTarg, 0 );
}
OSD_ATOMIC_INLINE unsigned epicsAtomicTestAndSetUIntT ( unsigned * pTarget )
{
long * const pTarg = ( LONG * ) ( pTarget );

View File

@@ -44,6 +44,16 @@ OSD_ATOMIC_INLINE void epicsAtomicSetUIntT ( unsigned * pTarget, unsigned newVal
atomic_swap_uint ( pTarget, newVal );
}
OSD_ATOMIC_INLINE unsigned epicsAtomicGetUIntT ( const unsigned * pTarget )
{
/*
* we cast away const, but are careful not to modify
* the target
*/
unsigned * const pTarg = ( unsigned * ) ( pTarget );
return atomic_or_uint_nv ( pTarg, 0U );
}
#if SIZE_MAX == UINT_MAX
OSD_ATOMIC_INLINE size_t epicsAtomicIncrSizeT ( size_t * pTarget )

View File

@@ -126,6 +126,13 @@ OSD_ATOMIC_INLINE unsigned epicsAtomicTestAndSetUIntT ( unsigned * pTarget )
return vxCas ( pTarg, 0, 1 ) != 0;
}
OSD_ATOMIC_INLINE unsigned epicsAtomicGetUIntT ( const unsigned * pTarget )
{
STATIC_ASSERT ( sizeof ( atomic_t ) == sizeof ( unsigned ) );
atomic_t * const pTarg = ( atomic_t * ) ( pTarget );
return ( unsigned ) vxAtomicGet ( pTarg );
}
#ifdef __cplusplus
} /* end of extern "C" */
#endif /* __cplusplus */
@@ -198,6 +205,15 @@ OSD_ATOMIC_INLINE size_t epicsAtomicGetSizeT ( const size_t * pTarget )
return *pTarget;
}
OSD_ATOMIC_INLINE unsigned epicsAtomicGetUIntT ( const unsigned * pTarget )
{
/*
* no need for memory barrior since this
* is a single cpu system
*/
return *pTarget;
}
OSD_ATOMIC_INLINE unsigned epicsAtomicTestAndSetUIntT ( unsigned * pTarget )
{
STATIC_ASSERT ( sizeof ( int ) == sizeof ( unsigned ) );

View File

@@ -48,6 +48,8 @@ static void tns ( void *arg )
epicsAtomicIncrSizeT ( & pTestData->m_testIterationsNotSet );
while ( ! epicsAtomicTestAndSetUIntT ( & pTestData->m_testValue ) ) {
}
testOk ( epicsAtomicGetUIntT ( & pTestData->m_testValue ),
"test and set must leave operand in true state" );
epicsAtomicDecrSizeT ( & pTestData->m_testIterationsNotSet );
epicsAtomicSetUIntT ( & pTestData->m_testValue, 0u );
epicsAtomicIncrSizeT ( & pTestData->m_testIterationsSet );
@@ -58,59 +60,61 @@ MAIN(epicsAtomicTest)
const unsigned int stackSize =
epicsThreadGetStackSize ( epicsThreadStackSmall );
testPlan(8);
static const size_t N_incrDecr = 100;
static const size_t N_testAndSet = 10;
testPlan( 9 + N_testAndSet );
{
static const size_t N = 100;
size_t i;
TestDataIncrDecr testData = { 0, N };;
epicsAtomicSetSizeT ( & testData.m_testValue, N );
testOk ( epicsAtomicGetSizeT ( & testData.m_testValue ) == N,
TestDataIncrDecr testData = { 0, N_incrDecr };
epicsAtomicSetSizeT ( & testData.m_testValue, N_incrDecr );
testOk ( epicsAtomicGetSizeT ( & testData.m_testValue ) == N_incrDecr,
"set/get %u", testData.m_testValue );
epicsAtomicSetSizeT ( & testData.m_testIterations, 0u );
testOk ( epicsAtomicGetSizeT ( & testData.m_testIterations ) == 0u,
"set/get %u", testData.m_testIterations );
for ( i = 0u; i < N; i++ ) {
epicsThreadCreate ( "incr",
50, stackSize, incr, & testData );
epicsThreadCreate ( "decr",
50, stackSize, decr, & testData );
for ( i = 0u; i < N_incrDecr; i++ ) {
epicsThreadCreate ( "incr", 50, stackSize, incr, & testData );
epicsThreadCreate ( "decr", 50, stackSize, decr, & testData );
}
while ( testData.m_testIterations < 2 * N ) {
while ( testData.m_testIterations < 2 * N_incrDecr ) {
epicsThreadSleep ( 0.01 );
}
testOk ( epicsAtomicGetSizeT ( & testData.m_testIterations ) == 2 * N,
"incr/decr iterations %u",
testData.m_testIterations );
testOk ( epicsAtomicGetSizeT ( & testData.m_testValue ) == N,
"incr/decr final value %u",
testData.m_testValue );
testOk ( epicsAtomicGetSizeT ( & testData.m_testIterations ) == 2 * N_incrDecr,
"incr/decr iterations %u", testData.m_testIterations );
testOk ( epicsAtomicGetSizeT ( & testData.m_testValue ) == N_incrDecr,
"incr/decr final value %u", testData.m_testValue );
}
{
static const size_t N = 10;
size_t i;
TestDataTNS testData = { 1, N, N };
TestDataTNS testData = { 1, N_testAndSet, N_testAndSet };
epicsAtomicSetSizeT ( & testData.m_testIterationsSet, 0u );
testOk ( epicsAtomicGetSizeT ( & testData.m_testIterationsSet ) == 0u,
"set/get %u", testData.m_testIterationsSet );
epicsAtomicSetSizeT ( & testData.m_testIterationsNotSet, 0u );
testOk ( epicsAtomicGetSizeT ( & testData.m_testIterationsNotSet ) == 0u,
"set/get %u", testData.m_testIterationsNotSet );
for ( i = 0u; i < N; i++ ) {
for ( i = 0u; i < N_testAndSet; i++ ) {
epicsThreadCreate ( "tns",
50, stackSize, tns, & testData );
}
epicsAtomicSetUIntT ( & testData.m_testValue, 0u );
while ( testData.m_testIterationsSet < N ) {
while ( testData.m_testIterationsSet < N_testAndSet ) {
epicsThreadSleep ( 0.01 );
}
testOk ( epicsAtomicGetSizeT ( & testData.m_testIterationsSet ) == N,
"test and set iterations %u",
testData.m_testIterationsSet );
testOk ( epicsAtomicGetSizeT ( & testData.m_testIterationsSet ) == N_testAndSet,
"test and set iterations %u", testData.m_testIterationsSet );
testOk ( epicsAtomicGetSizeT ( & testData.m_testIterationsNotSet ) == 0u,
"test and set not-set tracking = %u",
testData.m_testIterationsNotSet );
"test and set not-set tracking = %u", testData.m_testIterationsNotSet );
{
static unsigned setVal = 5;
epicsAtomicSetUIntT ( & testData.m_testValue, setVal );
testOk ( epicsAtomicGetUIntT ( & testData.m_testValue ) == setVal,
"unsigned version of set and get must concur" );
}
}
return testDone();