diff options
| author | Philipp Brüschweiler <blei42@gmail.com> | 2012-09-14 15:01:17 +0200 |
|---|---|---|
| committer | Brian Anderson <banderson@mozilla.com> | 2012-09-19 14:01:53 -0700 |
| commit | 68e755b1c26db09cf8e121bbbea2075f6116e279 (patch) | |
| tree | 8d48dc089bb9effd2090117fd6033c4ca81470d1 /src/rt/rust_scheduler.cpp | |
| parent | 35a935377483823ca1fbaede5a87406b494b0488 (diff) | |
| download | rust-68e755b1c26db09cf8e121bbbea2075f6116e279.tar.gz rust-68e755b1c26db09cf8e121bbbea2075f6116e279.zip | |
core: Allocate threads on demand, not on scheduler startup
API change: rust_kernel::create_scheduler() or rust_scheduler::rust_scheduler() respecitevly now take ownership of the launch factory argument, it is needed to create new threads on demand. Also renames rustrt::sched_threads() to rustrt::rust_sched_threads() for consistency. Added rustrt::rust_max_sched_threads() to return the maximal number of scheduled threads of the current scheduler. Fixes #3493.
Diffstat (limited to 'src/rt/rust_scheduler.cpp')
| -rw-r--r-- | src/rt/rust_scheduler.cpp | 75 |
1 files changed, 47 insertions, 28 deletions
diff --git a/src/rt/rust_scheduler.cpp b/src/rt/rust_scheduler.cpp index 5dd1a261c0e..aa288cf3b94 100644 --- a/src/rt/rust_scheduler.cpp +++ b/src/rt/rust_scheduler.cpp @@ -6,34 +6,39 @@ #include "rust_sched_launcher.h" rust_scheduler::rust_scheduler(rust_kernel *kernel, - size_t num_threads, + size_t max_num_threads, rust_sched_id id, bool allow_exit, bool killed, rust_sched_launcher_factory *launchfac) : ref_count(1), kernel(kernel), - live_threads(num_threads), + live_threads(0), live_tasks(0), cur_thread(0), may_exit(allow_exit), - num_threads(num_threads), + killed(killed), + launchfac(launchfac), + max_num_threads(max_num_threads), id(id) { - create_task_threads(launchfac, killed); + // Create the first thread + threads.push(create_task_thread(0)); } void rust_scheduler::delete_this() { destroy_task_threads(); + delete launchfac; delete this; } rust_sched_launcher * -rust_scheduler::create_task_thread(rust_sched_launcher_factory *launchfac, - int id, bool killed) { +rust_scheduler::create_task_thread(int id) { + live_threads++; rust_sched_launcher *thread = launchfac->create(this, id, killed); - KLOG(kernel, kern, "created task thread: " PTR ", id: %d", - thread, id); + KLOG(kernel, kern, "created task thread: " PTR + ", id: %d, live_threads: %d", + thread, id, live_threads); return thread; } @@ -44,18 +49,8 @@ rust_scheduler::destroy_task_thread(rust_sched_launcher *thread) { } void -rust_scheduler::create_task_threads(rust_sched_launcher_factory *launchfac, - bool killed) { - KLOG(kernel, kern, "Using %d scheduler threads.", num_threads); - - for(size_t i = 0; i < num_threads; ++i) { - threads.push(create_task_thread(launchfac, i, killed)); - } -} - -void rust_scheduler::destroy_task_threads() { - for(size_t i = 0; i < num_threads; ++i) { + for(size_t i = 0; i < threads.size(); ++i) { destroy_task_thread(threads[i]); } } @@ -63,7 +58,7 @@ rust_scheduler::destroy_task_threads() { void rust_scheduler::start_task_threads() { - for(size_t i = 0; i < num_threads; ++i) { + for(size_t i = 0; i < threads.size(); ++i) { rust_sched_launcher *thread = threads[i]; thread->start(); } @@ -72,7 +67,7 @@ rust_scheduler::start_task_threads() void rust_scheduler::join_task_threads() { - for(size_t i = 0; i < num_threads; ++i) { + for(size_t i = 0; i < threads.size(); ++i) { rust_sched_launcher *thread = threads[i]; thread->join(); } @@ -80,7 +75,7 @@ rust_scheduler::join_task_threads() void rust_scheduler::kill_all_tasks() { - for(size_t i = 0; i < num_threads; ++i) { + for(size_t i = 0; i < threads.size(); ++i) { rust_sched_launcher *thread = threads[i]; thread->get_loop()->kill_all_tasks(); } @@ -92,10 +87,29 @@ rust_scheduler::create_task(rust_task *spawner, const char *name) { { scoped_lock with(lock); live_tasks++; - thread_no = cur_thread++; - if (cur_thread >= num_threads) - cur_thread = 0; + + // Find unoccupied thread + for (thread_no = 0; thread_no < threads.size(); ++thread_no) { + if (threads[thread_no]->get_loop()->number_of_live_tasks() == 0) + break; + } + + if (thread_no == threads.size()) { + if (threads.size() < max_num_threads) { + // Else create new thread + thread_no = threads.size(); + rust_sched_launcher *thread = create_task_thread(thread_no); + thread->start(); + threads.push(thread); + } else { + // Or use round robin allocation + thread_no = cur_thread++; + if (cur_thread >= max_num_threads) + cur_thread = 0; + } + } } + KLOG(kernel, kern, "Creating task %s, on thread %d.", name, thread_no); kernel->register_task(); rust_sched_launcher *thread = threads[thread_no]; return thread->get_loop()->create_task(spawner, name); @@ -119,17 +133,22 @@ rust_scheduler::release_task() { void rust_scheduler::exit() { - // Take a copy of num_threads. After the last thread exits this + // Take a copy of the number of threads. After the last thread exits this // scheduler will get destroyed, and our fields will cease to exist. - size_t current_num_threads = num_threads; + size_t current_num_threads = threads.size(); for(size_t i = 0; i < current_num_threads; ++i) { threads[i]->get_loop()->exit(); } } size_t +rust_scheduler::max_number_of_threads() { + return max_num_threads; +} + +size_t rust_scheduler::number_of_threads() { - return num_threads; + return threads.size(); } void |
