Skip to content

Commit 8d88196

Browse files
committed
rt: Extract rust_scheduler from rust_task_thread
1 parent f94339c commit 8d88196

File tree

9 files changed

+182
-112
lines changed

9 files changed

+182
-112
lines changed

mk/rt.mk

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ RUNTIME_CS_$(1) := \
4343
rt/rust_crate_cache.cpp \
4444
rt/rust_env.cpp \
4545
rt/rust_task_thread.cpp \
46+
rt/rust_scheduler.cpp \
4647
rt/rust_task.cpp \
4748
rt/rust_task_list.cpp \
4849
rt/rust_port.cpp \
@@ -80,6 +81,7 @@ RUNTIME_HDR_$(1) := rt/globals.h \
8081
rt/rust_upcall.h \
8182
rt/rust_port.h \
8283
rt/rust_task_thread.h \
84+
rt/rust_scheduler.h \
8385
rt/rust_shape.h \
8486
rt/rust_task.h \
8587
rt/rust_task_list.h \

src/rt/rust.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ rust_start(uintptr_t main_fn, int argc, char **argv, void* crate_map) {
105105
root_task->deref();
106106
root_task = NULL;
107107

108-
int ret = kernel->start_task_threads();
108+
int ret = kernel->start_schedulers();
109109
delete args;
110110
delete kernel;
111111
delete srv;

src/rt/rust_builtin.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include "rust_task_thread.h"
55
#include "rust_task.h"
66
#include "rust_util.h"
7+
#include "rust_scheduler.h"
78
#include "sync/timer.h"
89

910
#if !defined(__WIN32__)
@@ -416,7 +417,7 @@ start_task(rust_task_id id, fn_env_pair *f) {
416417
extern "C" CDECL int
417418
sched_threads() {
418419
rust_task *task = rust_task_thread::get_task();
419-
return task->kernel->num_threads;
420+
return task->thread->sched->number_of_threads();
420421
}
421422

422423
extern "C" CDECL rust_port*

src/rt/rust_kernel.cpp

Lines changed: 16 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#include "rust_internal.h"
22
#include "rust_util.h"
3+
#include "rust_scheduler.h"
34

45
#define KLOG_(...) \
56
KLOG(this, kern, __VA_ARGS__)
@@ -12,64 +13,11 @@ rust_kernel::rust_kernel(rust_srv *srv, size_t num_threads) :
1213
srv(srv),
1314
max_id(0),
1415
rval(0),
15-
num_threads(num_threads),
1616
live_tasks(0),
1717
env(srv->env)
1818
{
19-
isaac_init(this, &rctx);
20-
create_schedulers();
21-
}
22-
23-
rust_task_thread *
24-
rust_kernel::create_scheduler(int id) {
25-
_kernel_lock.lock();
26-
rust_srv *srv = this->srv->clone();
27-
rust_task_thread *thread =
28-
new (this, "rust_task_thread") rust_task_thread(this, srv, id);
29-
KLOG_("created scheduler: " PTR ", id: %d, index: %d",
30-
thread, id, thread->list_index);
31-
_kernel_lock.unlock();
32-
return thread;
33-
}
34-
35-
void
36-
rust_kernel::destroy_scheduler(rust_task_thread *thread) {
37-
_kernel_lock.lock();
38-
KLOG_("deleting scheduler: " PTR ", name: %s, index: %d",
39-
thread, thread->name, thread->list_index);
40-
rust_srv *srv = thread->srv;
41-
delete thread;
42-
delete srv;
43-
_kernel_lock.unlock();
44-
}
45-
46-
void rust_kernel::create_schedulers() {
47-
KLOG_("Using %d scheduler threads.", num_threads);
48-
49-
for(size_t i = 0; i < num_threads; ++i) {
50-
threads.push(create_scheduler(i));
51-
}
52-
}
53-
54-
void rust_kernel::destroy_schedulers() {
55-
for(size_t i = 0; i < num_threads; ++i) {
56-
destroy_scheduler(threads[i]);
57-
}
58-
}
59-
60-
void
61-
rust_kernel::log_all_scheduler_state() {
62-
for(size_t i = 0; i < num_threads; ++i) {
63-
threads[i]->log_state();
64-
}
65-
}
66-
67-
/**
68-
* Checks for simple deadlocks.
69-
*/
70-
bool
71-
rust_kernel::is_deadlocked() {
72-
return false;
19+
sched = new (this, "rust_scheduler")
20+
rust_scheduler(this, srv, num_threads);
7321
}
7422

7523
void
@@ -94,7 +42,7 @@ rust_kernel::fatal(char const *fmt, ...) {
9442
}
9543

9644
rust_kernel::~rust_kernel() {
97-
destroy_schedulers();
45+
delete sched;
9846
}
9947

10048
void *
@@ -111,24 +59,9 @@ void rust_kernel::free(void *mem) {
11159
_region.free(mem);
11260
}
11361

114-
void
115-
rust_kernel::signal_kernel_lock() {
116-
_kernel_lock.lock();
117-
_kernel_lock.unlock();
118-
}
119-
120-
int rust_kernel::start_task_threads()
62+
int rust_kernel::start_schedulers()
12163
{
122-
for(size_t i = 0; i < num_threads; ++i) {
123-
rust_task_thread *thread = threads[i];
124-
thread->start();
125-
}
126-
127-
for(size_t i = 0; i < num_threads; ++i) {
128-
rust_task_thread *thread = threads[i];
129-
thread->join();
130-
}
131-
64+
sched->start_task_threads();
13265
return rval;
13366
}
13467

@@ -141,28 +74,27 @@ rust_kernel::fail() {
14174
#if defined(__WIN32__)
14275
exit(rval);
14376
#endif
144-
for(size_t i = 0; i < num_threads; ++i) {
145-
rust_task_thread *thread = threads[i];
146-
thread->kill_all_tasks();
147-
}
77+
sched->kill_all_tasks();
14878
}
14979

15080
rust_task_id
15181
rust_kernel::create_task(rust_task *spawner, const char *name,
15282
size_t init_stack_sz) {
153-
scoped_lock with(_kernel_lock);
154-
rust_task_thread *thread = threads[isaac_rand(&rctx) % num_threads];
155-
rust_task *t = thread->create_task(spawner, name, init_stack_sz);
156-
t->user.id = max_id++;
157-
task_table.put(t->user.id, t);
158-
return t->user.id;
83+
return sched->create_task(spawner, name, init_stack_sz);
15984
}
16085

16186
rust_task_id
16287
rust_kernel::create_task(rust_task *spawner, const char *name) {
16388
return create_task(spawner, name, env->min_stack_size);
16489
}
16590

91+
void
92+
rust_kernel::register_task(rust_task *task) {
93+
scoped_lock with(_kernel_lock);
94+
task->user.id = max_id++;
95+
task_table.put(task->user.id, task);
96+
}
97+
16698
rust_task *
16799
rust_kernel::get_task_by_id(rust_task_id id) {
168100
scoped_lock with(_kernel_lock);
@@ -190,9 +122,7 @@ rust_kernel::release_task_id(rust_task_id id) {
190122
}
191123

192124
void rust_kernel::exit_schedulers() {
193-
for(size_t i = 0; i < num_threads; ++i) {
194-
threads[i]->exit();
195-
}
125+
sched->exit();
196126
}
197127

198128
#ifdef __WIN32__

src/rt/rust_kernel.h

Lines changed: 4 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include "rust_log.h"
77

88
struct rust_task_thread;
9+
struct rust_scheduler;
910

1011
/**
1112
* A global object shared by all thread domains. Most of the data structures
@@ -20,36 +21,21 @@ class rust_kernel {
2021
rust_srv *srv;
2122
private:
2223
lock_and_signal _kernel_lock;
23-
24-
array_list<rust_task_thread *> threads;
25-
26-
randctx rctx;
27-
28-
rust_task_thread *create_scheduler(int id);
29-
void destroy_scheduler(rust_task_thread *thread);
30-
31-
void create_schedulers();
32-
void destroy_schedulers();
24+
rust_scheduler *sched;
3325

3426
rust_task_id max_id;
3527
hash_map<rust_task_id, rust_task *> task_table;
36-
3728
int rval;
3829

3930
public:
40-
const size_t num_threads;
4131

4232
volatile int live_tasks;
4333
struct rust_env *env;
4434

4535
rust_kernel(rust_srv *srv, size_t num_threads);
4636

47-
bool is_deadlocked();
48-
49-
void signal_kernel_lock();
5037
void exit_schedulers();
5138

52-
void log_all_scheduler_state();
5339
void log(uint32_t level, char const *fmt, ...);
5440
void fatal(char const *fmt, ...);
5541
virtual ~rust_kernel();
@@ -60,7 +46,7 @@ class rust_kernel {
6046

6147
void fail();
6248

63-
int start_task_threads();
49+
int start_schedulers();
6450

6551
#ifdef __WIN32__
6652
void win32_require(LPCTSTR fn, BOOL ok);
@@ -69,6 +55,7 @@ class rust_kernel {
6955
rust_task_id create_task(rust_task *spawner, const char *name,
7056
size_t init_stack_size);
7157
rust_task_id create_task(rust_task * spawner, const char *name);
58+
void register_task(rust_task *task);
7259
rust_task *get_task_by_id(rust_task_id id);
7360
void release_task_id(rust_task_id tid);
7461
void set_exit_status(int code);

src/rt/rust_scheduler.cpp

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
#include "rust_scheduler.h"
2+
#include "rust_util.h"
3+
4+
rust_scheduler::rust_scheduler(rust_kernel *kernel,
5+
rust_srv *srv,
6+
size_t num_threads) :
7+
kernel(kernel),
8+
srv(srv),
9+
env(srv->env),
10+
num_threads(num_threads)
11+
{
12+
isaac_init(this, &rctx);
13+
create_task_threads();
14+
}
15+
16+
rust_scheduler::~rust_scheduler() {
17+
destroy_task_threads();
18+
}
19+
20+
rust_task_thread *
21+
rust_scheduler::create_task_thread(int id) {
22+
lock.lock();
23+
rust_srv *srv = this->srv->clone();
24+
rust_task_thread *thread =
25+
new (kernel, "rust_task_thread") rust_task_thread(this, srv, id);
26+
KLOG(kernel, kern, "created task thread: " PTR ", id: %d, index: %d",
27+
thread, id, thread->list_index);
28+
lock.unlock();
29+
return thread;
30+
}
31+
32+
void
33+
rust_scheduler::destroy_task_thread(rust_task_thread *thread) {
34+
lock.lock();
35+
KLOG(kernel, kern, "deleting task thread: " PTR ", name: %s, index: %d",
36+
thread, thread->name, thread->list_index);
37+
rust_srv *srv = thread->srv;
38+
delete thread;
39+
delete srv;
40+
lock.unlock();
41+
}
42+
43+
void
44+
rust_scheduler::create_task_threads() {
45+
KLOG(kernel, kern, "Using %d scheduler threads.", num_threads);
46+
47+
for(size_t i = 0; i < num_threads; ++i) {
48+
threads.push(create_task_thread(i));
49+
}
50+
}
51+
52+
void
53+
rust_scheduler::destroy_task_threads() {
54+
for(size_t i = 0; i < num_threads; ++i) {
55+
destroy_task_thread(threads[i]);
56+
}
57+
}
58+
59+
void
60+
rust_scheduler::start_task_threads()
61+
{
62+
for(size_t i = 0; i < num_threads; ++i) {
63+
rust_task_thread *thread = threads[i];
64+
thread->start();
65+
}
66+
67+
for(size_t i = 0; i < num_threads; ++i) {
68+
rust_task_thread *thread = threads[i];
69+
thread->join();
70+
}
71+
}
72+
73+
void
74+
rust_scheduler::kill_all_tasks() {
75+
for(size_t i = 0; i < num_threads; ++i) {
76+
rust_task_thread *thread = threads[i];
77+
thread->kill_all_tasks();
78+
}
79+
}
80+
81+
rust_task_id
82+
rust_scheduler::create_task(rust_task *spawner, const char *name,
83+
size_t init_stack_sz) {
84+
size_t thread_no;
85+
{
86+
scoped_lock with(lock);
87+
thread_no = isaac_rand(&rctx) % num_threads;
88+
}
89+
rust_task_thread *thread = threads[thread_no];
90+
rust_task *t = thread->create_task(spawner, name, init_stack_sz);
91+
kernel->register_task(t);
92+
return t->user.id;
93+
}
94+
95+
rust_task_id
96+
rust_scheduler::create_task(rust_task *spawner, const char *name) {
97+
return create_task(spawner, name, env->min_stack_size);
98+
}
99+
100+
void
101+
rust_scheduler::exit() {
102+
for(size_t i = 0; i < num_threads; ++i) {
103+
threads[i]->exit();
104+
}
105+
}
106+
107+
size_t
108+
rust_scheduler::number_of_threads() {
109+
return num_threads;
110+
}

0 commit comments

Comments
 (0)