mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2025-03-19 13:51:44 +08:00
* gold.cc (queue_middle_gc_tasks): Use a separate blocker for each
Read_relocs task. (queue_middle_tasks): Likewise, and also for Scan_relocs. Run Allocate_commons_task first. * reloc.cc (Read_relocs::run): Pass next_blocker_ down to next task, rather than symtab_lock_. (Gc_process_relocs::~Gc_process_relocs): New function. (Gc_process_relocs::is_runnable): Check this_blocker_. (Gc_process_relocs::locks): Use next_blocker_ rather than blocker_. (Scan_relocs::~Scan_relocs): New function. (Scan_relocs::is_runnable): Check this_blocker_ rather than symtab_lock_. (Scan_relocs::locks): Drop symtab_lock_ and blocker_. Add next_blocker_. * reloc.h (class Read_relocs): Drop symtab_lock_ and blocker_ fields. Add this_blocker_ and next_blocker_ fields. Adjust constructor accordingly. (class Gc_process_relocs): Likewise. (class Scan_relocs): Likewise. * common.h (class Allocate_commons_task): Remove symtab_lock_ field, and corresponding constructor parameter. * common.cc (Allocate_commons_tasK::is_runnable): Remove use of symtab_lock_. (Allocate_commons_task::locks): Likewise.
This commit is contained in:
parent
37ec92403b
commit
93ceb76464
@ -1,3 +1,31 @@
|
||||
2010-02-11 Ian Lance Taylor <iant@google.com>
|
||||
|
||||
* gold.cc (queue_middle_gc_tasks): Use a separate blocker for each
|
||||
Read_relocs task.
|
||||
(queue_middle_tasks): Likewise, and also for Scan_relocs. Run
|
||||
Allocate_commons_task first.
|
||||
* reloc.cc (Read_relocs::run): Pass next_blocker_ down to next
|
||||
task, rather than symtab_lock_.
|
||||
(Gc_process_relocs::~Gc_process_relocs): New function.
|
||||
(Gc_process_relocs::is_runnable): Check this_blocker_.
|
||||
(Gc_process_relocs::locks): Use next_blocker_ rather than
|
||||
blocker_.
|
||||
(Scan_relocs::~Scan_relocs): New function.
|
||||
(Scan_relocs::is_runnable): Check this_blocker_ rather than
|
||||
symtab_lock_.
|
||||
(Scan_relocs::locks): Drop symtab_lock_ and blocker_. Add
|
||||
next_blocker_.
|
||||
* reloc.h (class Read_relocs): Drop symtab_lock_ and blocker_
|
||||
fields. Add this_blocker_ and next_blocker_ fields. Adjust
|
||||
constructor accordingly.
|
||||
(class Gc_process_relocs): Likewise.
|
||||
(class Scan_relocs): Likewise.
|
||||
* common.h (class Allocate_commons_task): Remove symtab_lock_
|
||||
field, and corresponding constructor parameter.
|
||||
* common.cc (Allocate_commons_tasK::is_runnable): Remove use of
|
||||
symtab_lock_.
|
||||
(Allocate_commons_task::locks): Likewise.
|
||||
|
||||
2010-02-11 Ian Lance Taylor <iant@google.com>
|
||||
|
||||
* gold-threads.h (class Once): Define.
|
||||
|
@ -1,6 +1,6 @@
|
||||
// common.cc -- handle common symbols for gold
|
||||
|
||||
// Copyright 2006, 2007, 2008 Free Software Foundation, Inc.
|
||||
// Copyright 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
|
||||
// Written by Ian Lance Taylor <iant@google.com>.
|
||||
|
||||
// This file is part of gold.
|
||||
@ -36,24 +36,21 @@ namespace gold
|
||||
|
||||
// Allocate_commons_task methods.
|
||||
|
||||
// This task allocates the common symbols. We need a lock on the
|
||||
// symbol table.
|
||||
// This task allocates the common symbols. We arrange to run it
|
||||
// before anything else which needs to access the symbol table.
|
||||
|
||||
Task_token*
|
||||
Allocate_commons_task::is_runnable()
|
||||
{
|
||||
if (!this->symtab_lock_->is_writable())
|
||||
return this->symtab_lock_;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Return the locks we hold: one on the symbol table, and one blocker.
|
||||
// Release a blocker.
|
||||
|
||||
void
|
||||
Allocate_commons_task::locks(Task_locker* tl)
|
||||
{
|
||||
tl->add(this, this->blocker_);
|
||||
tl->add(this, this->symtab_lock_);
|
||||
}
|
||||
|
||||
// Allocate the common symbols.
|
||||
|
@ -1,6 +1,6 @@
|
||||
// common.h -- handle common symbols for gold -*- C++ -*-
|
||||
|
||||
// Copyright 2006, 2007, 2008 Free Software Foundation, Inc.
|
||||
// Copyright 2006, 2007, 2008, 2010 Free Software Foundation, Inc.
|
||||
// Written by Ian Lance Taylor <iant@google.com>.
|
||||
|
||||
// This file is part of gold.
|
||||
@ -36,9 +36,8 @@ class Allocate_commons_task : public Task
|
||||
{
|
||||
public:
|
||||
Allocate_commons_task(Symbol_table* symtab, Layout* layout, Mapfile* mapfile,
|
||||
Task_token* symtab_lock, Task_token* blocker)
|
||||
: symtab_(symtab), layout_(layout), mapfile_(mapfile),
|
||||
symtab_lock_(symtab_lock), blocker_(blocker)
|
||||
Task_token* blocker)
|
||||
: symtab_(symtab), layout_(layout), mapfile_(mapfile), blocker_(blocker)
|
||||
{ }
|
||||
|
||||
// The standard Task methods.
|
||||
@ -60,7 +59,6 @@ class Allocate_commons_task : public Task
|
||||
Symbol_table* symtab_;
|
||||
Layout* layout_;
|
||||
Mapfile* mapfile_;
|
||||
Task_token* symtab_lock_;
|
||||
Task_token* blocker_;
|
||||
};
|
||||
|
||||
|
63
gold/gold.cc
63
gold/gold.cc
@ -265,21 +265,23 @@ queue_middle_gc_tasks(const General_options& options,
|
||||
{
|
||||
// Read_relocs for all the objects must be done and processed to find
|
||||
// unused sections before any scanning of the relocs can take place.
|
||||
Task_token* blocker = new Task_token(true);
|
||||
blocker->add_blockers(input_objects->number_of_relobjs());
|
||||
Task_token* symtab_lock = new Task_token(false);
|
||||
Task_token* this_blocker = NULL;
|
||||
for (Input_objects::Relobj_iterator p = input_objects->relobj_begin();
|
||||
p != input_objects->relobj_end();
|
||||
++p)
|
||||
workqueue->queue(new Read_relocs(symtab, layout, *p, symtab_lock,
|
||||
blocker));
|
||||
|
||||
{
|
||||
Task_token* next_blocker = new Task_token(true);
|
||||
next_blocker->add_blocker();
|
||||
workqueue->queue(new Read_relocs(symtab, layout, *p, this_blocker,
|
||||
next_blocker));
|
||||
this_blocker = next_blocker;
|
||||
}
|
||||
workqueue->queue(new Task_function(new Middle_runner(options,
|
||||
input_objects,
|
||||
symtab,
|
||||
layout,
|
||||
mapfile),
|
||||
blocker,
|
||||
this_blocker,
|
||||
"Task_function Middle_runner"));
|
||||
}
|
||||
|
||||
@ -475,12 +477,18 @@ queue_middle_tasks(const General_options& options,
|
||||
// Make sure we have symbols for any required group signatures.
|
||||
layout->define_group_signatures(symtab);
|
||||
|
||||
Task_token* blocker = new Task_token(true);
|
||||
blocker->add_blockers(input_objects->number_of_relobjs());
|
||||
if (parameters->options().define_common())
|
||||
blocker->add_blocker();
|
||||
Task_token* this_blocker = NULL;
|
||||
|
||||
Task_token* symtab_lock = new Task_token(false);
|
||||
// Allocate common symbols. We use a blocker to run this before the
|
||||
// Scan_relocs tasks, because it writes to the symbol table just as
|
||||
// they do.
|
||||
if (parameters->options().define_common())
|
||||
{
|
||||
this_blocker = new Task_token(true);
|
||||
this_blocker->add_blocker();
|
||||
workqueue->queue(new Allocate_commons_task(symtab, layout, mapfile,
|
||||
this_blocker));
|
||||
}
|
||||
|
||||
// If doing garbage collection, the relocations have already been read.
|
||||
// Otherwise, read and scan the relocations.
|
||||
@ -490,9 +498,14 @@ queue_middle_tasks(const General_options& options,
|
||||
for (Input_objects::Relobj_iterator p = input_objects->relobj_begin();
|
||||
p != input_objects->relobj_end();
|
||||
++p)
|
||||
workqueue->queue(new Scan_relocs(symtab, layout, *p,
|
||||
(*p)->get_relocs_data(),
|
||||
symtab_lock, blocker));
|
||||
{
|
||||
Task_token* next_blocker = new Task_token(true);
|
||||
next_blocker->add_blocker();
|
||||
workqueue->queue(new Scan_relocs(symtab, layout, *p,
|
||||
(*p)->get_relocs_data(),
|
||||
this_blocker, next_blocker));
|
||||
this_blocker = next_blocker;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -511,22 +524,14 @@ queue_middle_tasks(const General_options& options,
|
||||
p != input_objects->relobj_end();
|
||||
++p)
|
||||
{
|
||||
// We can read and process the relocations in any order. But we
|
||||
// only want one task to write to the symbol table at a time.
|
||||
// So we queue up a task for each object to read the
|
||||
// relocations. That task will in turn queue a task to wait
|
||||
// until it can write to the symbol table.
|
||||
workqueue->queue(new Read_relocs(symtab, layout, *p, symtab_lock,
|
||||
blocker));
|
||||
Task_token* next_blocker = new Task_token(true);
|
||||
next_blocker->add_blocker();
|
||||
workqueue->queue(new Read_relocs(symtab, layout, *p, this_blocker,
|
||||
next_blocker));
|
||||
this_blocker = next_blocker;
|
||||
}
|
||||
}
|
||||
|
||||
// Allocate common symbols. This requires write access to the
|
||||
// symbol table, but is independent of the relocation processing.
|
||||
if (parameters->options().define_common())
|
||||
workqueue->queue(new Allocate_commons_task(symtab, layout, mapfile,
|
||||
symtab_lock, blocker));
|
||||
|
||||
// When all those tasks are complete, we can start laying out the
|
||||
// output file.
|
||||
// TODO(csilvers): figure out a more principled way to get the target
|
||||
@ -537,7 +542,7 @@ queue_middle_tasks(const General_options& options,
|
||||
target,
|
||||
layout,
|
||||
mapfile),
|
||||
blocker,
|
||||
this_blocker,
|
||||
"Task_function Layout_task_runner"));
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
// reloc.cc -- relocate input files for gold.
|
||||
|
||||
// Copyright 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
|
||||
// Copyright 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
|
||||
// Written by Ian Lance Taylor <iant@google.com>.
|
||||
|
||||
// This file is part of gold.
|
||||
@ -75,15 +75,15 @@ Read_relocs::run(Workqueue* workqueue)
|
||||
workqueue->queue_next(new Gc_process_relocs(this->symtab_,
|
||||
this->layout_,
|
||||
this->object_, rd,
|
||||
this->symtab_lock_,
|
||||
this->blocker_));
|
||||
this->this_blocker_,
|
||||
this->next_blocker_));
|
||||
}
|
||||
else
|
||||
{
|
||||
workqueue->queue_next(new Scan_relocs(this->symtab_, this->layout_,
|
||||
this->object_, rd,
|
||||
this->symtab_lock_,
|
||||
this->blocker_));
|
||||
this->this_blocker_,
|
||||
this->next_blocker_));
|
||||
}
|
||||
}
|
||||
|
||||
@ -97,13 +97,22 @@ Read_relocs::get_name() const
|
||||
|
||||
// Gc_process_relocs methods.
|
||||
|
||||
// These tasks process the relocations read by Read_relocs and
|
||||
Gc_process_relocs::~Gc_process_relocs()
|
||||
{
|
||||
if (this->this_blocker_ != NULL)
|
||||
delete this->this_blocker_;
|
||||
}
|
||||
|
||||
// These tasks process the relocations read by Read_relocs and
|
||||
// determine which sections are referenced and which are garbage.
|
||||
// This task is done only when --gc-sections is used.
|
||||
// This task is done only when --gc-sections is used. This is blocked
|
||||
// by THIS_BLOCKER_. It unblocks NEXT_BLOCKER_.
|
||||
|
||||
Task_token*
|
||||
Gc_process_relocs::is_runnable()
|
||||
{
|
||||
if (this->this_blocker_ != NULL && this->this_blocker_->is_blocked())
|
||||
return this->this_blocker_;
|
||||
if (this->object_->is_locked())
|
||||
return this->object_->token();
|
||||
return NULL;
|
||||
@ -113,7 +122,7 @@ void
|
||||
Gc_process_relocs::locks(Task_locker* tl)
|
||||
{
|
||||
tl->add(this, this->object_->token());
|
||||
tl->add(this, this->blocker_);
|
||||
tl->add(this, this->next_blocker_);
|
||||
}
|
||||
|
||||
void
|
||||
@ -133,6 +142,12 @@ Gc_process_relocs::get_name() const
|
||||
|
||||
// Scan_relocs methods.
|
||||
|
||||
Scan_relocs::~Scan_relocs()
|
||||
{
|
||||
if (this->this_blocker_ != NULL)
|
||||
delete this->this_blocker_;
|
||||
}
|
||||
|
||||
// These tasks scan the relocations read by Read_relocs and mark up
|
||||
// the symbol table to indicate which relocations are required. We
|
||||
// use a lock on the symbol table to keep them from interfering with
|
||||
@ -141,8 +156,8 @@ Gc_process_relocs::get_name() const
|
||||
Task_token*
|
||||
Scan_relocs::is_runnable()
|
||||
{
|
||||
if (!this->symtab_lock_->is_writable())
|
||||
return this->symtab_lock_;
|
||||
if (this->this_blocker_ != NULL && this->this_blocker_->is_blocked())
|
||||
return this->this_blocker_;
|
||||
if (this->object_->is_locked())
|
||||
return this->object_->token();
|
||||
return NULL;
|
||||
@ -155,8 +170,7 @@ void
|
||||
Scan_relocs::locks(Task_locker* tl)
|
||||
{
|
||||
tl->add(this, this->object_->token());
|
||||
tl->add(this, this->symtab_lock_);
|
||||
tl->add(this, this->blocker_);
|
||||
tl->add(this, this->next_blocker_);
|
||||
}
|
||||
|
||||
// Scan the relocs.
|
||||
|
49
gold/reloc.h
49
gold/reloc.h
@ -1,6 +1,6 @@
|
||||
// reloc.h -- relocate input files for gold -*- C++ -*-
|
||||
|
||||
// Copyright 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
|
||||
// Copyright 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
|
||||
// Written by Ian Lance Taylor <iant@google.com>.
|
||||
|
||||
// This file is part of gold.
|
||||
@ -62,12 +62,13 @@ class Output_data_reloc;
|
||||
class Read_relocs : public Task
|
||||
{
|
||||
public:
|
||||
// SYMTAB_LOCK is used to lock the symbol table. BLOCKER should be
|
||||
// unblocked when the Scan_relocs task completes.
|
||||
// THIS_BLOCKER and NEXT_BLOCKER are passed along to a Scan_relocs
|
||||
// or Gc_process_relocs task, so that they run in a deterministic
|
||||
// order.
|
||||
Read_relocs(Symbol_table* symtab, Layout* layout, Relobj* object,
|
||||
Task_token* symtab_lock, Task_token* blocker)
|
||||
Task_token* this_blocker, Task_token* next_blocker)
|
||||
: symtab_(symtab), layout_(layout), object_(object),
|
||||
symtab_lock_(symtab_lock), blocker_(blocker)
|
||||
this_blocker_(this_blocker), next_blocker_(next_blocker)
|
||||
{ }
|
||||
|
||||
// The standard Task methods.
|
||||
@ -88,8 +89,8 @@ class Read_relocs : public Task
|
||||
Symbol_table* symtab_;
|
||||
Layout* layout_;
|
||||
Relobj* object_;
|
||||
Task_token* symtab_lock_;
|
||||
Task_token* blocker_;
|
||||
Task_token* this_blocker_;
|
||||
Task_token* next_blocker_;
|
||||
};
|
||||
|
||||
// Process the relocs to figure out which sections are garbage.
|
||||
@ -98,15 +99,18 @@ class Read_relocs : public Task
|
||||
class Gc_process_relocs : public Task
|
||||
{
|
||||
public:
|
||||
// SYMTAB_LOCK is used to lock the symbol table. BLOCKER should be
|
||||
// unblocked when the task completes.
|
||||
// THIS_BLOCKER prevents this task from running until the previous
|
||||
// one is finished. NEXT_BLOCKER prevents the next task from
|
||||
// running.
|
||||
Gc_process_relocs(Symbol_table* symtab, Layout* layout, Relobj* object,
|
||||
Read_relocs_data* rd, Task_token* symtab_lock,
|
||||
Task_token* blocker)
|
||||
Read_relocs_data* rd, Task_token* this_blocker,
|
||||
Task_token* next_blocker)
|
||||
: symtab_(symtab), layout_(layout), object_(object), rd_(rd),
|
||||
symtab_lock_(symtab_lock), blocker_(blocker)
|
||||
this_blocker_(this_blocker), next_blocker_(next_blocker)
|
||||
{ }
|
||||
|
||||
~Gc_process_relocs();
|
||||
|
||||
// The standard Task methods.
|
||||
|
||||
Task_token*
|
||||
@ -126,8 +130,8 @@ class Gc_process_relocs : public Task
|
||||
Layout* layout_;
|
||||
Relobj* object_;
|
||||
Read_relocs_data* rd_;
|
||||
Task_token* symtab_lock_;
|
||||
Task_token* blocker_;
|
||||
Task_token* this_blocker_;
|
||||
Task_token* next_blocker_;
|
||||
};
|
||||
|
||||
// Scan the relocations for an object to see if they require any
|
||||
@ -136,15 +140,18 @@ class Gc_process_relocs : public Task
|
||||
class Scan_relocs : public Task
|
||||
{
|
||||
public:
|
||||
// SYMTAB_LOCK is used to lock the symbol table. BLOCKER should be
|
||||
// unblocked when the task completes.
|
||||
// THIS_BLOCKER prevents this task from running until the previous
|
||||
// one is finished. NEXT_BLOCKER prevents the next task from
|
||||
// running.
|
||||
Scan_relocs(Symbol_table* symtab, Layout* layout, Relobj* object,
|
||||
Read_relocs_data* rd, Task_token* symtab_lock,
|
||||
Task_token* blocker)
|
||||
Read_relocs_data* rd, Task_token* this_blocker,
|
||||
Task_token* next_blocker)
|
||||
: symtab_(symtab), layout_(layout), object_(object), rd_(rd),
|
||||
symtab_lock_(symtab_lock), blocker_(blocker)
|
||||
this_blocker_(this_blocker), next_blocker_(next_blocker)
|
||||
{ }
|
||||
|
||||
~Scan_relocs();
|
||||
|
||||
// The standard Task methods.
|
||||
|
||||
Task_token*
|
||||
@ -164,8 +171,8 @@ class Scan_relocs : public Task
|
||||
Layout* layout_;
|
||||
Relobj* object_;
|
||||
Read_relocs_data* rd_;
|
||||
Task_token* symtab_lock_;
|
||||
Task_token* blocker_;
|
||||
Task_token* this_blocker_;
|
||||
Task_token* next_blocker_;
|
||||
};
|
||||
|
||||
// A class to perform all the relocations for an object file.
|
||||
|
Loading…
x
Reference in New Issue
Block a user