Skip to content

Commit aee83d2

Browse files
committed
rt: Only wake up all schedulers when no tasks are left
At the moment there's not really any reason to be raising this signal, since they schedulers wake up periodically anyway, but once we remove the timer this will be how the schedulers know to exit.
1 parent 5c3c8d4 commit aee83d2

File tree

4 files changed

+25
-9
lines changed

4 files changed

+25
-9
lines changed

src/rt/rust_kernel.cpp

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -189,11 +189,9 @@ rust_kernel::release_task_id(rust_task_id id) {
189189
task_table.remove(id);
190190
}
191191

192-
void rust_kernel::wakeup_schedulers() {
192+
void rust_kernel::exit_schedulers() {
193193
for(size_t i = 0; i < num_threads; ++i) {
194-
rust_scheduler *sched = threads[i];
195-
scoped_lock with(sched->lock);
196-
sched->lock.signal_all();
194+
threads[i]->exit();
197195
}
198196
}
199197

src/rt/rust_kernel.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ class rust_kernel {
4747
bool is_deadlocked();
4848

4949
void signal_kernel_lock();
50-
void wakeup_schedulers();
50+
void exit_schedulers();
5151

5252
void log_all_scheduler_state();
5353
void log(uint32_t level, char const *fmt, ...);

src/rt/rust_scheduler.cpp

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@ rust_scheduler::rust_scheduler(rust_kernel *kernel,
3232
kernel(kernel),
3333
id(id),
3434
min_stack_size(kernel->env->min_stack_size),
35-
env(kernel->env)
35+
env(kernel->env),
36+
should_exit(false)
3637
{
3738
LOGPTR(this, "new dom", (uintptr_t)this);
3839
isaac_init(this, &rctx);
@@ -160,8 +161,12 @@ rust_scheduler::reap_dead_tasks(int id) {
160161
rust_task *task = dead_tasks_copy[i];
161162
if (task) {
162163
task->deref();
163-
sync::decrement(kernel->live_tasks);
164-
kernel->wakeup_schedulers();
164+
int live_tasks = sync::decrement(kernel->live_tasks);
165+
if (live_tasks == 0) {
166+
// There are no more tasks and there never will be.
167+
// Tell all the schedulers to exit.
168+
kernel->exit_schedulers();
169+
}
165170
}
166171
}
167172
srv->free(dead_tasks_copy);
@@ -236,7 +241,7 @@ rust_scheduler::start_main_loop() {
236241

237242
DLOG(this, dom, "started domain loop %d", id);
238243

239-
while (kernel->live_tasks > 0) {
244+
while (!should_exit) {
240245
A(this, kernel->is_deadlocked() == false, "deadlock");
241246

242247
DLOG(this, dom, "worker %d, number_of_live_tasks = %d, total = %d",
@@ -375,6 +380,14 @@ rust_scheduler::get_task() {
375380
}
376381
#endif
377382

383+
void
384+
rust_scheduler::exit() {
385+
A(this, !lock.lock_held_by_current_thread(), "Shouldn't have lock");
386+
scoped_lock with(lock);
387+
should_exit = true;
388+
lock.signal_all();
389+
}
390+
378391
//
379392
// Local Variables:
380393
// mode: C++

src/rt/rust_scheduler.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,8 @@ struct rust_scheduler : public kernel_owned<rust_scheduler>,
9191
rust_env *env;
9292
context c_context;
9393

94+
bool should_exit;
95+
9496
// Only a pointer to 'name' is kept, so it must live as long as this
9597
// domain.
9698
rust_scheduler(rust_kernel *kernel, rust_srv *srv, int id);
@@ -127,6 +129,9 @@ struct rust_scheduler : public kernel_owned<rust_scheduler>,
127129
void place_task_in_tls(rust_task *task);
128130

129131
static rust_task *get_task();
132+
133+
// Tells the scheduler to exit it's scheduling loop and thread
134+
void exit();
130135
};
131136

132137
inline rust_log &

0 commit comments

Comments
 (0)