diff options
Diffstat (limited to 'src/rt/rust_task.cpp')
| -rw-r--r-- | src/rt/rust_task.cpp | 26 |
1 files changed, 26 insertions, 0 deletions
diff --git a/src/rt/rust_task.cpp b/src/rt/rust_task.cpp index 17faeec1a1c..5043f9ec4b0 100644 --- a/src/rt/rust_task.cpp +++ b/src/rt/rust_task.cpp @@ -8,6 +8,8 @@ #ifndef __WIN32__ #include <execinfo.h> #endif +#include <cassert> +#include <cstring> #include "globals.h" @@ -36,22 +38,46 @@ new_stk(rust_scheduler *sched, rust_task *task, size_t minsz) stk_seg *stk = (stk_seg *)task->malloc(sz, "stack"); LOGPTR(task->sched, "new stk", (uintptr_t)stk); memset(stk, 0, sizeof(stk_seg)); + stk->next = task->stk; stk->limit = (uintptr_t) &stk->data[minsz]; LOGPTR(task->sched, "stk limit", stk->limit); stk->valgrind_id = VALGRIND_STACK_REGISTER(&stk->data[0], &stk->data[minsz]); + task->stk = stk; return stk; } static void del_stk(rust_task *task, stk_seg *stk) { + assert(stk == task->stk && "Freeing stack segments out of order!"); + + task->stk = stk->next; + VALGRIND_STACK_DEREGISTER(stk->valgrind_id); LOGPTR(task->sched, "freeing stk segment", (uintptr_t)stk); task->free(stk); } +// Entry points for `__morestack` (see arch/*/morestack.S). +extern "C" void * +rust_new_stack(size_t stk_sz, void *args_addr, size_t args_sz) { + rust_task *task = rust_scheduler::get_task(); + stk_seg *stk_seg = new_stk(task->sched, task, stk_sz); + memcpy(stk_seg->data, args_addr, args_sz); + return stk_seg->data; +} + +extern "C" void * +rust_del_stack() { + rust_task *task = rust_scheduler::get_task(); + stk_seg *next_seg = task->stk->next; + del_stk(task, task->stk); + return next_seg->data; +} + + // Tasks rust_task::rust_task(rust_scheduler *sched, rust_task_list *state, rust_task *spawner, const char *name) : |
