// workqueue.cc -- the workqueue for gold
-// Copyright 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
+// Copyright (C) 2006-2020 Free Software Foundation, Inc.
// Written by Ian Lance Taylor <iant@google.com>.
// This file is part of gold.
#include "debug.h"
#include "options.h"
+#include "timer.h"
#include "workqueue.h"
#include "workqueue-internal.h"
{ gold_assert(thread_count > 0); }
bool
- should_cancel_thread()
+ should_cancel_thread(int)
{ return false; }
};
// waiting for a Token.
void
-Workqueue::add_to_queue(Task_list* que, Task* t, bool front)
+Workqueue::add_to_queue(Task_list* queue, Task* t, bool front)
{
Hold_lock hl(this->lock_);
else
{
if (front)
- que->push_front(t);
+ queue->push_front(t);
else
- que->push_back(t);
+ queue->push_back(t);
// Tell any waiting thread that there is work to do.
this->condvar_.signal();
}
// Return whether to cancel the current thread.
inline bool
-Workqueue::should_cancel_thread()
+Workqueue::should_cancel_thread(int thread_number)
{
- return this->threader_->should_cancel_thread();
+ return this->threader_->should_cancel_thread(thread_number);
}
// Find a runnable task in TASKS. Return NULL if none could be found.
return NULL;
}
- if (this->should_cancel_thread())
+ if (this->should_cancel_thread(thread_number))
return NULL;
gold_debug(DEBUG_TASK, "%3d sleeping", thread_number);
gold_debug(DEBUG_TASK, "%3d running task %s", thread_number,
t->name().c_str());
+ Timer timer;
+ if (is_debugging_enabled(DEBUG_TASK))
+ timer.start();
+
t->run(this);
- gold_debug(DEBUG_TASK, "%3d completed task %s", thread_number,
- t->name().c_str());
+ if (is_debugging_enabled(DEBUG_TASK))
+ {
+ Timer::TimeStats elapsed = timer.get_elapsed_time();
+
+ gold_debug(DEBUG_TASK,
+ "%3d completed task %s "
+ "(user: %ld.%06ld sys: %ld.%06ld wall: %ld.%06ld)",
+ thread_number, t->name().c_str(),
+ elapsed.user / 1000, (elapsed.user % 1000) * 1000,
+ elapsed.sys / 1000, (elapsed.sys % 1000) * 1000,
+ elapsed.wall / 1000, (elapsed.wall % 1000) * 1000);
+ }
Task* next;
{
{
// The token has been unblocked. Every waiting Task may
// now be runnable.
- Task* tok;
- while ((tok = token->remove_first_waiting()) != NULL)
+ Task* t;
+ while ((t = token->remove_first_waiting()) != NULL)
{
--this->waiting_;
- this->return_or_queue(tok, true, &ret);
+ this->return_or_queue(t, true, &ret);
}
}
}
// move all the Tasks to the runnable queue, to avoid a
// potential deadlock if the locking status changes before
// we run the next thread.
- Task* tok;
- while ((tok = token->remove_first_waiting()) != NULL)
+ Task* t;
+ while ((t = token->remove_first_waiting()) != NULL)
{
--this->waiting_;
- if (this->return_or_queue(tok, false, &ret))
+ if (this->return_or_queue(t, false, &ret))
break;
}
}