gold patch committed: More thread safety patches
Ian Lance Taylor
iant@google.com
Fri Feb 12 03:31:00 GMT 2010
I committed this set of patches to make gold --threads clean with
respect to Thread Sanitizer
(http://code.google.com/p/data-race-test/wiki/ThreadSanitizer).
* The code to set the target_ field in the Parameters structure was
invoked by multiple threads. This was not a race on typical
machines since the field was always set to the same value, but I
generalized the lock initializer support to avoid the race.
* The code to instantiate the selected target used double checked
locking, and was probably fine, but I used the extended initializer
support for that as well.
* At the start of a group the symbol reading thread fetched the number
of undefined symbols. This was a race because that number could be
updated simulataneously by the current symbol adding thread. It was
not very serious since the count was only used to decide whether to
go around the group again. However, the count fetched at that time
was reliably wrong, which caused the linker to process groups twice
in cases where that was unnecessary. I introduced a Start_group
task to fetch the number of undefined symbols just before entering
the group, which should reliably permit the linker to only scan the
group once if scanning the group did not add any undefined symbols.
I also changed the undefined symbol count from int to size_t.
* The byte counts for file I/O maintained for --stats output were
simply incremented by each thread, so they could race each other and
lose increments. I added a lock, and changed the code to only keep
the counts when --stats is used.
* Clearing the empty string actually writes a zero in the empty string
representation, which looks like a race condition. This is not a
real problem, of course, but it's easy to avoid.
Ian
2010-02-11 Ian Lance Taylor <iant@google.com>
* gold-threads.h (class Once): Define.
(class Initialize_lock): Rewrite as child of Once.
* gold-threads.cc (class Once_initialize): Define.
(once_pointer_control): New static variable.
(once_pointer, once_arg): New static variables.
(c_run_once): New static function.
(Once::Once, Once::run_once, Once::internal_run): New functions.
(class Initialize_lock_once): Remove.
(initialize_lock_control): Remove.
(initialize_lock_pointer): Remove.
(initialize_lock_once): Remove.
(Initialize_lock::Initialize_lock): Move to gold-threads.h.
(Initialize_lock::initialize): Rewrite.
(Initialize_lock::do_run_once): New function.
* archive.cc (Archive::interpret_header): Only clear name if it is
not already empty.
* fileread.cc: Include "gold-threads.h"
(file_counts_lock): New static variable.
(file_counts_initialize_lock): Likewise.
(File_read::release): Only increment counts when using --stats.
Use a lock around the increment.
* parameters.cc (class Set_parameters_target_once): Define.
(set_parameters_target_once): New static variable.
(Parameters::Parameters): Move here from parameters.h.
(Parameters::set_target): Rewrite.
(Parameters::set_target_once): New function.
(Parameters::clear_target): Move here and rewrite.
* parameters.h (class Parameters): Update declarations. Add
set_parameters_target_once_ field.
(Parameters::Parameters): Move to parameters.cc.
(Parameters::clear_target): Likewise.
* readsyms.cc (Read_symbols::do_group): Create a Start_group
task.
(Start_group::~Start_group): New function.
(Start_group::is_runnable): New function.
(Start_group::locks, Start_group::run): New functions.
(Finish_group::run): Change saw_undefined to size_t.
* readsyms.h (class Start_group): Define.
(class Finish_group): Change saw_undefined_ field to size_t.
(Finish_group::Finish_group): Remove saw_undefined and
this_blocker parameters. Change all callers.
(Finish_group::set_saw_undefined): New function.
(Finish_group::set_blocker): New function.
* symtab.h (class Symbol_table): Change saw_undefined to return
size_t. Change saw_undefined_ field to size_t.
* target-select.cc (Set_target_once::do_run_once): New function.
(Target_selector::Target_selector): Initialize set_target_once_
field. Don't initialize lock_ and initialize_lock_ fields.
(Target_selector::instantiate_target): Rewrite.
(Target_selector::set_target): New function.
* target-select.h (class Set_target_once): Define.
(class Target_selector): Update declarations. Make
Set_target_once a friend. Remove lock_ and initialize_lock_
fields. Add set_target_once_ field.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: foo.patch
Type: text/x-diff
Size: 30026 bytes
Desc: threads
URL: <https://sourceware.org/pipermail/binutils/attachments/20100212/0a85336b/attachment.bin>
More information about the Binutils
mailing list