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