Skip to content

Use atomics for double-checked locks (SingletonPtr + __cxa_guard) #9530

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jan 31, 2019

Conversation

kjbracey
Copy link
Contributor

Description

Make SingletonPtr safe using atomics

SingletonPtr's implementation wasn't totally safe - see "C++ and the Perils of Double-Checked Locking" by Meyers and Alexandrescu. No problems observed in practice, but it was potentially susceptible to compiler optimisation (or maybe even SMP issues).

Now that we have atomic loads and stores, the function can be made safe, avoiding any potential races for threads that don't take the lock: ensure that the unlocked load is atomic, and that the pointer store is
atomic.

See https://preshing.com/20130930/double-checked-locking-is-fixed-in-cpp11/ for more discussion.

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.

Pull request type

[ ] Fix
[X] Refactor
[ ] Target update
[ ] Functionality change
[ ] Docs update
[ ] Test update
[ ] Breaking change

Reviewers

@pan-, @c1728p9

Copy link
Member

@pan- pan- left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The changes looks good and now static initialisation follows C++11 requirements.

Is there any argument still in favour of using SingletonPtr over static initialisation ?

Foo& getFoo {
    static Foo foo;
    return foo;
} 

SingletonPtr<Foo> foo;

@kjbracey
Copy link
Contributor Author

Is there any argument still in favour of using SingletonPtr over static initialisation ?

Not much, apart from its syntactic handiness. The get is transparent inside the operator -> or *.

If there was a way to achieve the syntactic handiness using a C++ static thing inside the template, that would be ideal.

Only other distinction is SingletonPtr never invokes destructors, but that's already been nobbled in the C++ library for statics by yourself, as I recall.

@kjbracey kjbracey force-pushed the atomic_singletonptr branch from 679affe to ad68d25 Compare January 29, 2019 11:58
SingletonPtr's implementation wasn't totally safe - see "C++ and the
Perils of Double-Checked Locking"by Meyers and Alexandrescu. No problems
observed in practice, but it was potentially susceptible to compiler
optimisation (or maybe even SMP issues).

Now that we have atomic loads and stores, the function can be made safe,
avoiding any potential races for threads that don't take the lock:
ensure that the unlocked load is atomic, and that the pointer store is
atomic.

See https://preshing.com/20130930/double-checked-locking-is-fixed-in-cpp11/
for more discussion.
@kjbracey kjbracey force-pushed the atomic_singletonptr branch from ad68d25 to 7de71e8 Compare January 29, 2019 14:01
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.
A couple of places in mbed_retarget.cpp were testing for either ARMC5 or
ARMC6 in a long-winded fashion. Testing for __ARMCC_VERSION being
defined is sufficient.
@cmonr
Copy link
Contributor

cmonr commented Jan 29, 2019

CI started

@mbed-ci
Copy link

mbed-ci commented Jan 30, 2019

Test run: SUCCESS

Summary: 12 of 12 test jobs passed
Build number : 1
Build artifacts

@cmonr cmonr merged commit 0fb2870 into ARMmbed:master Jan 31, 2019
@kjbracey kjbracey deleted the atomic_singletonptr branch February 22, 2019 10:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants