Skip to content
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

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

Merged
merged 3 commits into from Jan 31, 2019

Conversation

Projects
None yet
5 participants
@kjbracey-arm
Copy link
Contributor

commented Jan 29, 2019

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

@pan-

pan- approved these changes Jan 29, 2019

Copy link
Member

left a comment

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-arm

This comment has been minimized.

Copy link
Contributor Author

commented Jan 29, 2019

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-arm kjbracey-arm force-pushed the kjbracey-arm:atomic_singletonptr branch Jan 29, 2019

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.

@kjbracey-arm kjbracey-arm force-pushed the kjbracey-arm:atomic_singletonptr branch Jan 29, 2019

kjbracey-arm added some commits Jan 29, 2019

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.
mbed_retarget.cpp: Combine ARMC5 and ARMC6 tests
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.

@kjbracey-arm kjbracey-arm force-pushed the kjbracey-arm:atomic_singletonptr branch to 6e3c492 Jan 29, 2019

@cmonr

cmonr approved these changes Jan 29, 2019

@cmonr

This comment has been minimized.

Copy link
Contributor

commented Jan 29, 2019

CI started

@mbed-ci

This comment has been minimized.

Copy link

commented Jan 30, 2019

Test run: SUCCESS

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

@cmonr cmonr added ready for merge and removed needs: CI labels Jan 30, 2019

@cmonr cmonr merged commit 0fb2870 into ARMmbed:master Jan 31, 2019

24 checks passed

continuous-integration/jenkins/pr-head This commit looks good
Details
continuous-integration/travis-ci/pr The Travis CI build passed
Details
jenkins-ci/build-ARM Success
Details
jenkins-ci/build-ARMC6 Success
Details
jenkins-ci/build-GCC_ARM Success
Details
jenkins-ci/build-IAR Success
Details
jenkins-ci/cloud-client-test Success
Details
jenkins-ci/dynamic-memory-usage RTOS ROM(+0 bytes) RAM(+0 bytes)
Details
jenkins-ci/exporter Success
Details
jenkins-ci/greentea-test Success
Details
jenkins-ci/mbed2-build-ARM Success
Details
jenkins-ci/mbed2-build-GCC_ARM Success
Details
jenkins-ci/mbed2-build-IAR Success
Details
jenkins-ci/unittests Success
Details
travis-ci/astyle Local astyle testing has passed
Details
travis-ci/docs Local docs testing has passed
Details
travis-ci/doxy-spellcheck Local doxy-spellcheck testing has passed
Details
travis-ci/events Passed, runtime is 9832 cycles (+99 cycles)
Details
travis-ci/gitattributestest Local gitattributestest testing has passed
Details
travis-ci/include_check Local include_check testing has passed
Details
travis-ci/licence_check Local licence_check testing has passed
Details
travis-ci/littlefs Passed, code size is 8408B (+0.00%)
Details
travis-ci/psa-autogen Local psa-autogen testing has passed
Details
travis-ci/tools-py2.7 Local tools-py2.7 testing has passed
Details

@cmonr cmonr removed the ready for merge label Jan 31, 2019

@kjbracey-arm kjbracey-arm deleted the kjbracey-arm:atomic_singletonptr branch Feb 22, 2019

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.