Skip to content

Commit d7e0c43

Browse files
committed
---
yaml --- r: 14132 b: refs/heads/try c: f2a1aa2 h: refs/heads/master v: v3
1 parent da45ff9 commit d7e0c43

File tree

3 files changed

+59
-11
lines changed

3 files changed

+59
-11
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@
22
refs/heads/master: 61b1875c16de39c166b0f4d54bba19f9c6777d1a
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
44
refs/heads/snap-stage3: 4a81779abd786ff22d71434c6d9a5917ea4cdfff
5-
refs/heads/try: 028af5cb6c588a33b0bf5cbf451236407f5ba110
5+
refs/heads/try: f2a1aa2649ad030f189c54245ee182a0aa6983ed
66
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105

branches/try/src/rt/rust_kernel.cpp

Lines changed: 52 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
#include <vector>
12
#include "rust_internal.h"
23
#include "rust_util.h"
34
#include "rust_scheduler.h"
@@ -15,6 +16,7 @@ rust_kernel::rust_kernel(rust_srv *srv) :
1516
max_task_id(0),
1617
rval(0),
1718
live_schedulers(0),
19+
max_sched_id(0),
1820
env(srv->env)
1921
{
2022
}
@@ -56,25 +58,45 @@ void rust_kernel::free(void *mem) {
5658

5759
rust_sched_id
5860
rust_kernel::create_scheduler(size_t num_threads) {
59-
I(this, live_schedulers == 0);
60-
sched = new (this, "rust_scheduler")
61-
rust_scheduler(this, srv, num_threads, 0);
62-
live_schedulers = 1;
61+
I(this, !sched_lock.lock_held_by_current_thread());
62+
rust_scheduler *sched;
63+
{
64+
scoped_lock with(sched_lock);
65+
rust_sched_id id = max_sched_id++;
66+
K(srv, id != INTPTR_MAX, "Hit the maximum scheduler id");
67+
sched = new (this, "rust_scheduler")
68+
rust_scheduler(this, srv, num_threads, id);
69+
bool is_new = sched_table
70+
.insert(std::pair<rust_sched_id, rust_scheduler*>(id, sched)).second;
71+
A(this, is_new, "Reusing a sched id?");
72+
live_schedulers++;
73+
}
6374
sched->start_task_threads();
6475
return 0;
6576
}
6677

6778
rust_scheduler *
6879
rust_kernel::get_scheduler_by_id(rust_sched_id id) {
69-
return sched;
80+
I(this, !sched_lock.lock_held_by_current_thread());
81+
scoped_lock with(sched_lock);
82+
sched_map::iterator iter = sched_table.find(id);
83+
if (iter != sched_table.end()) {
84+
return iter->second;
85+
} else {
86+
return NULL;
87+
}
7088
}
7189

7290
void
7391
rust_kernel::release_scheduler_id(rust_sched_id id) {
7492
I(this, !sched_lock.lock_held_by_current_thread());
7593
scoped_lock with(sched_lock);
94+
sched_map::iterator iter = sched_table.find(id);
95+
I(this, iter != sched_table.end());
96+
rust_scheduler *sched = iter->second;
97+
sched_table.erase(iter);
7698
delete sched;
77-
--live_schedulers;
99+
live_schedulers--;
78100
if (live_schedulers == 0) {
79101
// We're all done. Tell the main thread to continue
80102
sched_lock.signal();
@@ -93,6 +115,7 @@ rust_kernel::wait_for_schedulers()
93115
return rval;
94116
}
95117

118+
// FIXME: Fix all these FIXMEs
96119
void
97120
rust_kernel::fail() {
98121
// FIXME: On windows we're getting "Application has requested the
@@ -102,7 +125,29 @@ rust_kernel::fail() {
102125
#if defined(__WIN32__)
103126
exit(rval);
104127
#endif
105-
sched->kill_all_tasks();
128+
// Copy the list of schedulers so that we don't hold the lock while
129+
// running kill_all_tasks.
130+
// FIXME: There's a lot that happens under kill_all_tasks, and I don't
131+
// know that holding sched_lock here is ok, but we need to hold the
132+
// sched lock to prevent the scheduler from being destroyed while
133+
// we are using it. Probably we need to make rust_scheduler atomicly
134+
// reference counted.
135+
std::vector<rust_scheduler*> scheds;
136+
{
137+
scoped_lock with(sched_lock);
138+
for (sched_map::iterator iter = sched_table.begin();
139+
iter != sched_table.end(); iter++) {
140+
scheds.push_back(iter->second);
141+
}
142+
}
143+
144+
// FIXME: This is not a foolproof way to kill all tasks while ensuring
145+
// that no new tasks or schedulers are created in the meantime that
146+
// keep the scheduler alive.
147+
for (std::vector<rust_scheduler*>::iterator iter = scheds.begin();
148+
iter != scheds.end(); iter++) {
149+
(*iter)->kill_all_tasks();
150+
}
106151
}
107152

108153
void

branches/try/src/rt/rust_kernel.h

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,15 @@
22
#ifndef RUST_KERNEL_H
33
#define RUST_KERNEL_H
44

5+
#include <map>
56
#include "memory_region.h"
67
#include "rust_log.h"
78

89
struct rust_task_thread;
910
struct rust_scheduler;
1011

12+
typedef std::map<rust_sched_id, rust_scheduler*> sched_map;
13+
1114
/**
1215
* A global object shared by all thread domains. Most of the data structures
1316
* in this class are synchronized since they are accessed from multiple
@@ -20,8 +23,6 @@ class rust_kernel {
2023
public:
2124
rust_srv *srv;
2225
private:
23-
rust_scheduler *sched;
24-
2526
// Protects live_tasks, max_task_id and task_table
2627
lock_and_signal task_lock;
2728
// Tracks the number of tasks that are being managed by
@@ -35,12 +36,14 @@ class rust_kernel {
3536
lock_and_signal rval_lock;
3637
int rval;
3738

38-
// Protects live_schedulers
39+
// Protects live_schedulers, max_sched_id and sched_table
3940
lock_and_signal sched_lock;
4041
// Tracks the number of schedulers currently running.
4142
// When this hits 0 we will signal the sched_lock and the
4243
// kernel will terminate.
4344
uintptr_t live_schedulers;
45+
rust_sched_id max_sched_id;
46+
sched_map sched_table;
4447

4548
public:
4649

0 commit comments

Comments
 (0)