diff options
author | ian <ian@138bc75d-0d04-0410-961f-82ee72b054a4> | 2013-11-19 01:09:47 +0000 |
---|---|---|
committer | ian <ian@138bc75d-0d04-0410-961f-82ee72b054a4> | 2013-11-19 01:09:47 +0000 |
commit | bcafb4a81d1fc8deefed6e6fa567d66417857c9a (patch) | |
tree | a715cbe6fb809ff31f1487b709ea67a6f616cec5 /libbacktrace/fileline.c | |
parent | 5dbddbd9cba08722841cff67404dd01e2654c099 (diff) | |
download | gcc-bcafb4a81d1fc8deefed6e6fa567d66417857c9a.tar.gz |
* configure.ac: Check for support of __atomic extensions.
* internal.h: Declare or #define atomic functions for use in
backtrace code.
* atomic.c: New file.
* dwarf.c (dwarf_lookup_pc): Use atomic functions.
(dwarf_fileline, backtrace_dwarf_add): Likewise.
* elf.c (elf_add_syminfo_data, elf_syminfo): Likewise.
(backtrace_initialize): Likewise.
* fileline.c (fileline_initialize): Likewise.
* Makefile.am (libbacktrace_la_SOURCES): Add atomic.c.
* configure, config.h.in, Makefile.in: Rebuild.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@204994 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libbacktrace/fileline.c')
-rw-r--r-- | libbacktrace/fileline.c | 40 |
1 files changed, 13 insertions, 27 deletions
diff --git a/libbacktrace/fileline.c b/libbacktrace/fileline.c index e5c39be8e0e..cc063f52c0d 100644 --- a/libbacktrace/fileline.c +++ b/libbacktrace/fileline.c @@ -58,15 +58,10 @@ fileline_initialize (struct backtrace_state *state, int called_error_callback; int descriptor; - failed = state->fileline_initialization_failed; - - if (state->threaded) - { - /* Use __sync_bool_compare_and_swap to do an atomic load. */ - while (!__sync_bool_compare_and_swap - (&state->fileline_initialization_failed, failed, failed)) - failed = state->fileline_initialization_failed; - } + if (!state->threaded) + failed = state->fileline_initialization_failed; + else + failed = backtrace_atomic_load_int (&state->fileline_initialization_failed); if (failed) { @@ -74,13 +69,10 @@ fileline_initialize (struct backtrace_state *state, return 0; } - fileline_fn = state->fileline_fn; - if (state->threaded) - { - while (!__sync_bool_compare_and_swap (&state->fileline_fn, fileline_fn, - fileline_fn)) - fileline_fn = state->fileline_fn; - } + if (!state->threaded) + fileline_fn = state->fileline_fn; + else + fileline_fn = backtrace_atomic_load_pointer (&state->fileline_fn); if (fileline_fn != NULL) return 1; @@ -151,8 +143,7 @@ fileline_initialize (struct backtrace_state *state, if (!state->threaded) state->fileline_initialization_failed = 1; else - __sync_bool_compare_and_swap (&state->fileline_initialization_failed, - 0, failed); + backtrace_atomic_store_int (&state->fileline_initialization_failed, 1); return 0; } @@ -160,15 +151,10 @@ fileline_initialize (struct backtrace_state *state, state->fileline_fn = fileline_fn; else { - __sync_bool_compare_and_swap (&state->fileline_fn, NULL, fileline_fn); - - /* At this point we know that state->fileline_fn is not NULL. - Either we stored our value, or some other thread stored its - value. If some other thread stored its value, we leak the - one we just initialized. Either way, state->fileline_fn is - initialized. The compare_and_swap is a full memory barrier, - so we should have full access to that value even if it was - created by another thread. */ + backtrace_atomic_store_pointer (&state->fileline_fn, fileline_fn); + + /* Note that if two threads initialize at once, one of the data + sets may be leaked. */ } return 1; |