added epicsAtomicGetUIntT for completeness
This commit is contained in:
@@ -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 );
|
||||
|
||||
@@ -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 );
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 ) */
|
||||
|
||||
@@ -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 );
|
||||
|
||||
@@ -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 )
|
||||
|
||||
@@ -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 ) );
|
||||
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user