Skip to content

Commit c553291

Browse files
committed
Use atomics in __cxa_guard functions
Similar to SingletonPtr, use atomic accesses when loading the guard word outside the lock, and when storing, to ensure no races for threads that don't take the lock. Lack of atomics unlikely to be a problem in current builds, but code could conceivably be subject to reordering if link-time optimisation was enabled.
1 parent 6e41d6c commit c553291

File tree

1 file changed

+11
-8
lines changed

1 file changed

+11
-8
lines changed

platform/mbed_retarget.cpp

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1426,32 +1426,35 @@ extern "C" void __env_unlock(struct _reent *_r)
14261426
extern "C" int __cxa_guard_acquire(int *guard_object_p)
14271427
{
14281428
uint8_t *guard_object = (uint8_t *)guard_object_p;
1429-
if (CXA_GUARD_INIT_DONE == (*guard_object & CXA_GUARD_MASK)) {
1429+
if ((core_util_atomic_load_u8(guard_object) & CXA_GUARD_MASK) == CXA_GUARD_INIT_DONE) {
14301430
return 0;
14311431
}
14321432
singleton_lock();
1433-
if (CXA_GUARD_INIT_DONE == (*guard_object & CXA_GUARD_MASK)) {
1433+
uint8_t guard = *guard_object;
1434+
if ((guard & CXA_GUARD_MASK) == CXA_GUARD_INIT_DONE) {
14341435
singleton_unlock();
14351436
return 0;
14361437
}
1437-
MBED_ASSERT(0 == (*guard_object & CXA_GUARD_MASK));
1438-
*guard_object = *guard_object | CXA_GUARD_INIT_IN_PROGRESS;
1438+
MBED_ASSERT((guard & CXA_GUARD_MASK) == 0);
1439+
core_util_atomic_store_u8(guard_object, guard | CXA_GUARD_INIT_IN_PROGRESS);
14391440
return 1;
14401441
}
14411442

14421443
extern "C" void __cxa_guard_release(int *guard_object_p)
14431444
{
14441445
uint8_t *guard_object = (uint8_t *)guard_object_p;
1445-
MBED_ASSERT(CXA_GUARD_INIT_IN_PROGRESS == (*guard_object & CXA_GUARD_MASK));
1446-
*guard_object = (*guard_object & ~CXA_GUARD_MASK) | CXA_GUARD_INIT_DONE;
1446+
uint8_t guard = *guard_object;
1447+
MBED_ASSERT((guard & CXA_GUARD_MASK) == CXA_GUARD_INIT_IN_PROGRESS);
1448+
core_util_atomic_store_u8(guard_object, (guard & ~CXA_GUARD_MASK) | CXA_GUARD_INIT_DONE);
14471449
singleton_unlock();
14481450
}
14491451

14501452
extern "C" void __cxa_guard_abort(int *guard_object_p)
14511453
{
14521454
uint8_t *guard_object = (uint8_t *)guard_object_p;
1453-
MBED_ASSERT(CXA_GUARD_INIT_IN_PROGRESS == (*guard_object & CXA_GUARD_MASK));
1454-
*guard_object = *guard_object & ~CXA_GUARD_INIT_IN_PROGRESS;
1455+
uint8_t guard = *guard_object;
1456+
MBED_ASSERT((guard & CXA_GUARD_MASK) == CXA_GUARD_INIT_IN_PROGRESS);
1457+
core_util_atomic_store_u8(guard_object, guard & ~CXA_GUARD_INIT_IN_PROGRESS);
14551458
singleton_unlock();
14561459
}
14571460

0 commit comments

Comments
 (0)