This is an archive of the discontinued LLVM Phabricator instance.

[libcxxabi] On single threaded systems, turn mutexes into nops
ClosedPublic

Authored by jroelofs on Apr 15 2014, 2:17 PM.

Details

Summary

This is one of several pieces needed for bare-metal ARM support.

Diff Detail

Event Timeline

joerg added a comment.Apr 15 2014, 2:46 PM

Please introduce a switch in __config instead. There are valid reasons for wanting single threaded code independent of whether pthread is supported or not.

kledzik added inline comments.Apr 15 2014, 5:02 PM
src/cxa_exception_storage.cpp
35

Should this be:

#include <unistd.h>
#ifdef _POSIX_THREADS
#include <pthread.h>
#endif

so that this will also compile on a system without pthread.h?

Joerg, you may be thinking of the __config in libc++. libc++abi doesn't have one, but I'd be happy to create it. Should it go in src/, or in include/ ?

src/cxa_exception_storage.cpp
35

ok, sounds good.

jroelofs updated this revision to Unknown Object (????).Apr 16 2014, 1:57 PM

Added a config.h to src/, and put all of the pthread things under LIBCXXABI_SINGLE_THREADED. Also gave test/test_exception_storage.cpp the same treatment (which I forgot to attach to the previous diff).

kledzik added inline comments.May 5 2014, 4:12 PM
src/cxa_exception_storage.cpp
48

Why is eh_globals_ being allocated with calloc() in the single threaded case?

This would be much simpler to have a block (like the #if HAS_THREAD_LOCAL) that just has:

#elif LIBCXXABI_SINGLE_THREADED
   static __cxa_eh_globals eh_globals;
   __cxa_eh_globals *_cxa_get_globals() { return &eh_globals; }
   __cxa_eh_globals *_cxa_get_globals_fast() { return &eh_globals; }
 #else

and the rest of the file stays the same.

jroelofs added inline comments.May 5 2014, 4:55 PM
src/cxa_exception_storage.cpp
48

There's a comment above cxa_get_globals_fast() saying that it has to return 0 if cxa_get_globals() wasn't called first (which might be a bug in the HAS_THREAD_LOCAL side?).

Good point though, structuring it like that will make it cleaner.

That comment is in the context when _cxa_get_globals() and _cxa_get_globals_fast() are different. In the single threaded and thread local case, they are the same.

Background: there was originally just _cxa_get_globals(). But it had to always check if the global had been allocated for the current thread. Someone realized extra check was a waste of performance, given the way it was used in the unwinder. The only way to get into the bowels of the unwinder was to pass through some code that already called _cxa_get_globals(). Therefore, there were uses that did not need the allocation check. So, _cxa_get_globals_fast() was created which was exactly the same, except did not check for allocation. Then someone said, what if someone refactors the unwinder and forgets to make sure _cxa_get_globals() was called before _cxa_get_globals()? Adding an assert in _cxa_get_globals_fast would slow down the unwinder in the case that is supposed to be fast. So, instead they decided to return NULL which should immediately cause a bus error on use.

None of that applies to the single threaded and thread local cases.

jroelofs updated this revision to Diff 9126.May 6 2014, 1:42 PM
jroelofs edited edge metadata.

Restructure cxa_exception_storage.cpp changes per kledzik's review comments.
Restructure cxa_guard.cpp similarly to make things tidier there too.

Nick, thanks for the helpful explanation on __cxa_get_globals_fast() behavior & history!

LGTM. Thanks for simplifying the guard stuff too.

jroelofs accepted this revision.May 6 2014, 2:38 PM
jroelofs added a reviewer: jroelofs.

Committed r208135.

This revision is now accepted and ready to land.May 6 2014, 2:38 PM
jroelofs closed this revision.May 6 2014, 3:08 PM