rt: Allow some schedulers to stay alive even without tasks to execute

This commit is contained in:
Brian Anderson 2012-04-01 16:38:42 -07:00
parent 0a5e9d45e1
commit fb528dd7d6
3 changed files with 26 additions and 8 deletions

View file

@ -69,7 +69,7 @@ rust_kernel::create_scheduler(size_t num_threads) {
id = max_sched_id++; id = max_sched_id++;
K(srv, id != INTPTR_MAX, "Hit the maximum scheduler id"); K(srv, id != INTPTR_MAX, "Hit the maximum scheduler id");
sched = new (this, "rust_scheduler") sched = new (this, "rust_scheduler")
rust_scheduler(this, srv, num_threads, id); rust_scheduler(this, srv, num_threads, id, true);
bool is_new = sched_table bool is_new = sched_table
.insert(std::pair<rust_sched_id, .insert(std::pair<rust_sched_id,
rust_scheduler*>(id, sched)).second; rust_scheduler*>(id, sched)).second;

View file

@ -5,14 +5,16 @@
rust_scheduler::rust_scheduler(rust_kernel *kernel, rust_scheduler::rust_scheduler(rust_kernel *kernel,
rust_srv *srv, rust_srv *srv,
size_t num_threads, size_t num_threads,
rust_sched_id id) : rust_sched_id id,
bool allow_exit) :
kernel(kernel), kernel(kernel),
srv(srv), srv(srv),
env(srv->env), env(srv->env),
live_threads(num_threads), live_threads(num_threads),
live_tasks(0), live_tasks(0),
num_threads(num_threads),
cur_thread(0), cur_thread(0),
may_exit(allow_exit),
num_threads(num_threads),
id(id) id(id)
{ {
create_task_threads(); create_task_threads();
@ -103,12 +105,11 @@ rust_scheduler::release_task() {
{ {
scoped_lock with(lock); scoped_lock with(lock);
live_tasks--; live_tasks--;
if (live_tasks == 0) { if (live_tasks == 0 && may_exit) {
need_exit = true; need_exit = true;
} }
} }
if (need_exit) { if (need_exit) {
// There are no more tasks on this scheduler. Time to leave
exit(); exit();
} }
} }
@ -139,3 +140,16 @@ rust_scheduler::release_task_thread() {
kernel->release_scheduler_id(id); kernel->release_scheduler_id(id);
} }
} }
void
rust_scheduler::allow_exit() {
bool need_exit = false;
{
scoped_lock with(lock);
may_exit = true;
need_exit = live_tasks == 0;
}
if (need_exit) {
exit();
}
}

View file

@ -12,16 +12,17 @@ public:
rust_srv *srv; rust_srv *srv;
rust_env *env; rust_env *env;
private: private:
// Protects live_threads and cur_thread increments // Protects live_threads, live_tasks, cur_thread, may_exit
lock_and_signal lock; lock_and_signal lock;
// When this hits zero we'll tell the kernel to release us // When this hits zero we'll tell the kernel to release us
uintptr_t live_threads; uintptr_t live_threads;
// When this hits zero we'll tell the threads to exit // When this hits zero we'll tell the threads to exit
uintptr_t live_tasks; uintptr_t live_tasks;
size_t cur_thread;
bool may_exit;
array_list<rust_sched_launcher *> threads; array_list<rust_sched_launcher *> threads;
const size_t num_threads; const size_t num_threads;
size_t cur_thread;
rust_sched_id id; rust_sched_id id;
@ -35,7 +36,7 @@ private:
public: public:
rust_scheduler(rust_kernel *kernel, rust_srv *srv, size_t num_threads, rust_scheduler(rust_kernel *kernel, rust_srv *srv, size_t num_threads,
rust_sched_id id); rust_sched_id id, bool allow_exit);
~rust_scheduler(); ~rust_scheduler();
void start_task_threads(); void start_task_threads();
@ -51,6 +52,9 @@ public:
void release_task_thread(); void release_task_thread();
rust_sched_id get_id() { return id; } rust_sched_id get_id() { return id; }
// Tells the scheduler that as soon as it runs out of tasks
// to run it should exit
void allow_exit();
}; };
#endif /* RUST_SCHEDULER_H */ #endif /* RUST_SCHEDULER_H */