Skip to content

Commit 9ba8617

Browse files
committed
rt: Store the task in TLS
1 parent 888e22a commit 9ba8617

File tree

3 files changed

+76
-1
lines changed

3 files changed

+76
-1
lines changed

src/rt/rust_scheduler.cpp

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,17 @@
11

22
#include <stdarg.h>
3+
#include <cassert>
34
#include "rust_internal.h"
45
#include "globals.h"
56

7+
#ifndef _WIN32
8+
pthread_key_t rust_scheduler::task_key;
9+
#else
10+
DWORD rust_scheduler::task_key;
11+
#endif
12+
13+
bool rust_scheduler::tls_initialized = false;
14+
615
rust_scheduler::rust_scheduler(rust_kernel *kernel,
716
rust_srv *srv,
817
int id) :
@@ -30,6 +39,9 @@ rust_scheduler::rust_scheduler(rust_kernel *kernel,
3039
pthread_attr_setstacksize(&attr, 1024 * 1024);
3140
pthread_attr_setdetachstate(&attr, true);
3241
#endif
42+
43+
if (!tls_initialized)
44+
init_tls();
3345
}
3446

3547
rust_scheduler::~rust_scheduler() {
@@ -275,6 +287,8 @@ rust_scheduler::start_main_loop() {
275287
scheduled_task->user.rust_sp,
276288
scheduled_task->state->name);
277289

290+
place_task_in_tls(scheduled_task);
291+
278292
interrupt_flag = 0;
279293

280294
DLOG(this, task,
@@ -347,6 +361,49 @@ void rust_scheduler::run() {
347361
this->start_main_loop();
348362
}
349363

364+
#ifndef _WIN32
365+
void
366+
rust_scheduler::init_tls() {
367+
int result = pthread_key_create(&task_key, NULL);
368+
assert(!result && "Couldn't create the TLS key!");
369+
tls_initialized = true;
370+
}
371+
372+
void
373+
rust_scheduler::place_task_in_tls(rust_task *task) {
374+
int result = pthread_setspecific(task_key, task);
375+
assert(!result && "Couldn't place the task in TLS!");
376+
}
377+
378+
rust_task *
379+
rust_scheduler::get_task() {
380+
rust_task *task = reinterpret_cast<rust_task *>
381+
(pthread_getspecific(task_key));
382+
assert(task && "Couldn't get the task from TLS!");
383+
return task;
384+
}
385+
#else
386+
void
387+
rust_scheduler::init_tls() {
388+
task_key = TlsAlloc();
389+
assert(task_key != TLS_OUT_OF_INDEXES && "Couldn't create the TLS key!");
390+
tls_initialized = true;
391+
}
392+
393+
void
394+
rust_scheduler::place_task_in_tls(rust_task *task) {
395+
BOOL result = TlsSetValue(task_key, task);
396+
assert(result && "Couldn't place the task in TLS!");
397+
}
398+
399+
rust_task *
400+
rust_scheduler::get_task() {
401+
rust_task *task = reinterpret_cast<rust_task *>(TlsGetValue(task_key));
402+
assert(task && "Couldn't get the task from TLS!");
403+
return task;
404+
}
405+
#endif
406+
350407
//
351408
// Local Variables:
352409
// mode: C++

src/rt/rust_scheduler.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
#ifndef RUST_SCHEDULER_H
22
#define RUST_SCHEDULER_H
33

4+
#ifndef _WIN32
5+
#include <pthread.h>
6+
#else
7+
#include <windows.h>
8+
#endif
9+
410
struct rust_scheduler;
511

612
class rust_crate_cache {
@@ -58,8 +64,13 @@ struct rust_scheduler : public kernel_owned<rust_scheduler>,
5864

5965
#ifndef __WIN32__
6066
pthread_attr_t attr;
67+
static pthread_key_t task_key;
68+
#else
69+
static DWORD task_key;
6170
#endif
6271

72+
static bool tls_initialized;
73+
6374
rust_env *env;
6475

6576
// Only a pointer to 'name' is kept, so it must live as long as this
@@ -92,6 +103,11 @@ struct rust_scheduler : public kernel_owned<rust_scheduler>,
92103
kernel->win32_require(fn, ok);
93104
}
94105
#endif
106+
107+
void init_tls();
108+
void place_task_in_tls(rust_task *task);
109+
110+
static rust_task *get_task();
95111
};
96112

97113
inline rust_log &

src/rt/rust_upcall.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#include "rust_cc.h"
22
#include "rust_gc.h"
33
#include "rust_internal.h"
4+
#include "rust_scheduler.h"
45
#include "rust_unwind.h"
56
#include "rust_upcall.h"
67
#include <stdint.h>
@@ -54,7 +55,8 @@ upcall_fail(rust_task *task,
5455
}
5556

5657
extern "C" CDECL uintptr_t
57-
upcall_malloc(rust_task *task, size_t nbytes, type_desc *td) {
58+
upcall_malloc(rust_task *unused_task, size_t nbytes, type_desc *td) {
59+
rust_task *task = rust_scheduler::get_task();
5860
LOG_UPCALL_ENTRY(task);
5961

6062
LOG(task, mem,

0 commit comments

Comments
 (0)