summaryrefslogtreecommitdiff
path: root/libbacktrace/fileline.c
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@google.com>2013-11-19 01:09:47 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2013-11-19 01:09:47 +0000
commit49579c7e20da4cf0dc82bf1c8458bf4fc7a38007 (patch)
treea715cbe6fb809ff31f1487b709ea67a6f616cec5 /libbacktrace/fileline.c
parent7f369373da8aa1cfe4aa172d29ae2180a2b31139 (diff)
configure.ac: Check for support of __atomic extensions.
* 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. From-SVN: r204994
Diffstat (limited to 'libbacktrace/fileline.c')
-rw-r--r--libbacktrace/fileline.c40
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;