diff --git a/src/rt/rust_builtin.cpp b/src/rt/rust_builtin.cpp index 7226171e9f1..314e85eecc4 100644 --- a/src/rt/rust_builtin.cpp +++ b/src/rt/rust_builtin.cpp @@ -1,14 +1,16 @@ +/* Native builtins. */ #include "rust_internal.h" +#include "rust_scheduler.h" #if !defined(__WIN32__) #include #endif -/* Native builtins. */ - extern "C" CDECL rust_str* -last_os_error(rust_task *task) { +last_os_error(void *unused_task) { + rust_task *task = rust_scheduler::get_task(); + LOG(task, task, "last_os_error()"); #if defined(__WIN32__) @@ -49,7 +51,8 @@ last_os_error(rust_task *task) { } extern "C" CDECL rust_str * -rust_getcwd(rust_task *task) { +rust_getcwd(void *unused_task) { + rust_task *task = rust_scheduler::get_task(); LOG(task, task, "rust_getcwd()"); char cbuf[BUF_BYTES]; @@ -66,29 +69,30 @@ rust_getcwd(rust_task *task) { return make_str(task->kernel, cbuf, strlen(cbuf), "rust_str(getcwd"); } +// TODO: Allow calling native functions that return double results. extern "C" CDECL -void squareroot(rust_task *task, double *input, double *output) { +void squareroot(void *unused_task, double *input, double *output) { *output = sqrt(*input); } extern "C" CDECL size_t -size_of(rust_task *task, type_desc *t) { +size_of(void *unused_task, type_desc *t) { return t->size; } extern "C" CDECL size_t -align_of(rust_task *task, type_desc *t) { +align_of(void *unused_task, type_desc *t) { return t->align; } extern "C" CDECL void -leak(rust_task *task, type_desc *t, void *thing) { +leak(void *unused_task, type_desc *t, void *thing) { // Do nothing. Call this with move-mode in order to say "Don't worry rust, // I'll take care of this." } extern "C" CDECL intptr_t -refcount(rust_task *task, type_desc *t, intptr_t *v) { +refcount(void *unused_task, type_desc *t, intptr_t *v) { // Passed-in value has refcount 1 too high // because it was ref'ed while making the call. @@ -96,18 +100,20 @@ refcount(rust_task *task, type_desc *t, intptr_t *v) { } extern "C" CDECL void -do_gc(rust_task *task) { +do_gc(void *unused_task) { // TODO } extern "C" CDECL void -unsupervise(rust_task *task) { +unsupervise(void *unused_task) { + rust_task *task = rust_scheduler::get_task(); task->unsupervise(); } extern "C" CDECL void -vec_reserve_shared(rust_task* task, type_desc* ty, rust_vec** vp, - size_t n_elts) { +vec_reserve_shared(void *unused_task, type_desc* ty, rust_vec** vp, + size_t n_elts) { + rust_task *task = rust_scheduler::get_task(); reserve_vec(task, vp, n_elts * ty->size); } @@ -116,8 +122,9 @@ vec_reserve_shared(rust_task* task, type_desc* ty, rust_vec** vp, * vector must have size zero. */ extern "C" CDECL rust_vec* -vec_from_buf_shared(rust_task *task, type_desc *ty, - void *ptr, size_t count) { +vec_from_buf_shared(void *unused_task, type_desc *ty, + void *ptr, size_t count) { + rust_task *task = rust_scheduler::get_task(); size_t fill = ty->size * count; rust_vec* v = (rust_vec*)task->kernel->malloc(fill + sizeof(rust_vec), "vec_from_buf"); @@ -127,7 +134,8 @@ vec_from_buf_shared(rust_task *task, type_desc *ty, } extern "C" CDECL void -rust_str_push(rust_task* task, rust_vec** sp, uint8_t byte) { +rust_str_push(void *unused_task, rust_vec** sp, uint8_t byte) { + rust_task *task = rust_scheduler::get_task(); size_t fill = (*sp)->fill; reserve_vec(task, sp, fill + 1); (*sp)->data[fill-1] = byte; @@ -136,8 +144,9 @@ rust_str_push(rust_task* task, rust_vec** sp, uint8_t byte) { } extern "C" CDECL void * -rand_new(rust_task *task) +rand_new(void *unused_task) { + rust_task *task = rust_scheduler::get_task(); rust_scheduler *sched = task->sched; randctx *rctx = (randctx *) task->malloc(sizeof(randctx), "randctx"); if (!rctx) { @@ -149,29 +158,33 @@ rand_new(rust_task *task) } extern "C" CDECL size_t -rand_next(rust_task *task, randctx *rctx) +rand_next(void *unused_task, randctx *rctx) { return isaac_rand(rctx); } extern "C" CDECL void -rand_free(rust_task *task, randctx *rctx) +rand_free(void *unused_task, randctx *rctx) { + rust_task *task = rust_scheduler::get_task(); task->free(rctx); } extern "C" CDECL void -task_sleep(rust_task *task, size_t time_in_us) { +task_sleep(void *unused_task, size_t time_in_us) { + rust_task *task = rust_scheduler::get_task(); task->yield(time_in_us); } extern "C" CDECL void -task_yield(rust_task *task) { +task_yield(void *unused_task) { + rust_task *task = rust_scheduler::get_task(); task->yield(1); } extern "C" CDECL intptr_t -task_join(rust_task *task, rust_task_id tid) { +task_join(void *unused_task, rust_task_id tid) { + rust_task *task = rust_scheduler::get_task(); // If the other task is already dying, we don't have to wait for it. rust_task *join_task = task->kernel->get_task_by_id(tid); // FIXME: find task exit status and return that. @@ -195,26 +208,29 @@ task_join(rust_task *task, rust_task_id tid) { } } -/* Debug builtins for std.dbg. */ +/* Debug builtins for std::dbg. */ static void -debug_tydesc_helper(rust_task *task, type_desc *t) +debug_tydesc_helper(void *unused_task, type_desc *t) { + rust_task *task = rust_scheduler::get_task(); LOG(task, stdlib, " size %" PRIdPTR ", align %" PRIdPTR ", first_param 0x%" PRIxPTR, t->size, t->align, t->first_param); } extern "C" CDECL void -debug_tydesc(rust_task *task, type_desc *t) +debug_tydesc(void *unused_task, type_desc *t) { + rust_task *task = rust_scheduler::get_task(); LOG(task, stdlib, "debug_tydesc"); debug_tydesc_helper(task, t); } extern "C" CDECL void -debug_opaque(rust_task *task, type_desc *t, uint8_t *front) +debug_opaque(void *unused_task, type_desc *t, uint8_t *front) { + rust_task *task = rust_scheduler::get_task(); LOG(task, stdlib, "debug_opaque"); debug_tydesc_helper(task, t); // FIXME may want to actually account for alignment. `front` may not @@ -232,8 +248,9 @@ struct rust_box { }; extern "C" CDECL void -debug_box(rust_task *task, type_desc *t, rust_box *box) +debug_box(void *unused_task, type_desc *t, rust_box *box) { + rust_task *task = rust_scheduler::get_task(); LOG(task, stdlib, "debug_box(0x%" PRIxPTR ")", box); debug_tydesc_helper(task, t); LOG(task, stdlib, " refcount %" PRIdPTR, @@ -249,8 +266,10 @@ struct rust_tag { }; extern "C" CDECL void -debug_tag(rust_task *task, type_desc *t, rust_tag *tag) +debug_tag(void *unused_task, type_desc *t, rust_tag *tag) { + rust_task *task = rust_scheduler::get_task(); + LOG(task, stdlib, "debug_tag"); debug_tydesc_helper(task, t); LOG(task, stdlib, " discriminant %" PRIdPTR, tag->discriminant); @@ -266,9 +285,11 @@ struct rust_obj { }; extern "C" CDECL void -debug_obj(rust_task *task, type_desc *t, rust_obj *obj, +debug_obj(void *unused_task, type_desc *t, rust_obj *obj, size_t nmethods, size_t nbytes) { + rust_task *task = rust_scheduler::get_task(); + LOG(task, stdlib, "debug_obj with %" PRIdPTR " methods", nmethods); debug_tydesc_helper(task, t); LOG(task, stdlib, " vtbl at 0x%" PRIxPTR, obj->vtbl); @@ -288,8 +309,9 @@ struct rust_fn { }; extern "C" CDECL void -debug_fn(rust_task *task, type_desc *t, rust_fn *fn) +debug_fn(void *unused_task, type_desc *t, rust_fn *fn) { + rust_task *task = rust_scheduler::get_task(); LOG(task, stdlib, "debug_fn"); debug_tydesc_helper(task, t); LOG(task, stdlib, " thunk at 0x%" PRIxPTR, fn->thunk); @@ -300,11 +322,12 @@ debug_fn(rust_task *task, type_desc *t, rust_fn *fn) } extern "C" CDECL void * -debug_ptrcast(rust_task *task, +debug_ptrcast(void *unused_task, type_desc *from_ty, type_desc *to_ty, void *ptr) { + rust_task *task = rust_scheduler::get_task(); LOG(task, stdlib, "debug_ptrcast from"); debug_tydesc_helper(task, from_ty); LOG(task, stdlib, "to"); @@ -313,7 +336,8 @@ debug_ptrcast(rust_task *task, } extern "C" CDECL rust_vec* -rust_list_files(rust_task *task, rust_vec **path) { +rust_list_files(void *unused_task, rust_vec **path) { + rust_task *task = rust_scheduler::get_task(); array_list strings; #if defined(__WIN32__) WIN32_FIND_DATA FindFileData; @@ -351,7 +375,7 @@ rust_list_files(rust_task *task, rust_vec **path) { } extern "C" CDECL int -rust_file_is_dir(rust_task *task, char *path) { +rust_file_is_dir(void *unused_task, char *path) { struct stat buf; if (stat(path, &buf)) { return 0; @@ -364,13 +388,14 @@ extern "C" CDECL FILE* rust_get_stdout() {return stdout;} extern "C" CDECL FILE* rust_get_stderr() {return stderr;} extern "C" CDECL int -rust_ptr_eq(rust_task *task, type_desc *t, rust_box *a, rust_box *b) { +rust_ptr_eq(void *unused_task, type_desc *t, rust_box *a, rust_box *b) { return a == b; } #if defined(__WIN32__) extern "C" CDECL void -get_time(rust_task *task, uint32_t *sec, uint32_t *usec) { +get_time(void *unused_task, uint32_t *sec, uint32_t *usec) { + rust_task *task = rust_scheduler::get_task(); SYSTEMTIME systemTime; FILETIME fileTime; GetSystemTime(&systemTime); @@ -385,7 +410,7 @@ get_time(rust_task *task, uint32_t *sec, uint32_t *usec) { } #else extern "C" CDECL void -get_time(rust_task *task, uint32_t *sec, uint32_t *usec) { +get_time(void *unused_task, uint32_t *sec, uint32_t *usec) { struct timeval tv; gettimeofday(&tv, NULL); *sec = tv.tv_sec; @@ -394,46 +419,51 @@ get_time(rust_task *task, uint32_t *sec, uint32_t *usec) { #endif extern "C" CDECL void -nano_time(rust_task *task, uint64_t *ns) { +nano_time(void *unused_task, uint64_t *ns) { timer t; *ns = t.time_ns(); } extern "C" CDECL void -pin_task(rust_task *task) { +pin_task(void *unused_task) { + rust_task *task = rust_scheduler::get_task(); task->pin(); } extern "C" CDECL void -unpin_task(rust_task *task) { +unpin_task(void *unused_task) { + rust_task *task = rust_scheduler::get_task(); task->unpin(); } extern "C" CDECL rust_task_id -get_task_id(rust_task *task) { +get_task_id(void *unused_task) { + rust_task *task = rust_scheduler::get_task(); return task->user.id; } extern "C" CDECL rust_task_id -new_task(rust_task *task) { +new_task(void *unused_task) { + rust_task *task = rust_scheduler::get_task(); return task->kernel->create_task(task, NULL); } extern "C" CDECL void -drop_task(rust_task *task, rust_task *target) { +drop_task(void *unused_task, rust_task *target) { if(target) { target->deref(); } } extern "C" CDECL rust_task * -get_task_pointer(rust_task *task, rust_task_id id) { +get_task_pointer(void *unused_task, rust_task_id id) { + rust_task *task = rust_scheduler::get_task(); return task->kernel->get_task_by_id(id); } // FIXME: Transitional. Remove extern "C" CDECL void ** -get_task_trampoline(rust_task *task) { +get_task_trampoline(void *unused_task) { return NULL; } @@ -445,14 +475,16 @@ struct fn_env_pair { extern "C" CDECL uintptr_t get_spawn_wrapper(); extern "C" CDECL void -start_task(rust_task *task, rust_task_id id, fn_env_pair *f) { +start_task(void *unused_task, rust_task_id id, fn_env_pair *f) { + rust_task *task = rust_scheduler::get_task(); rust_task *target = task->kernel->get_task_by_id(id); target->start(get_spawn_wrapper(), f->f, f->env); target->deref(); } extern "C" CDECL void -migrate_alloc(rust_task *task, void *alloc, rust_task_id tid) { +migrate_alloc(void *unused_task, void *alloc, rust_task_id tid) { + rust_task *task = rust_scheduler::get_task(); if(!alloc) return; rust_task *target = task->kernel->get_task_by_id(tid); if(target) { @@ -469,17 +501,19 @@ migrate_alloc(rust_task *task, void *alloc, rust_task_id tid) { // defined in rust_task.cpp extern size_t g_custom_min_stack_size; extern "C" CDECL void -set_min_stack(rust_task *task, uintptr_t stack_size) { +set_min_stack(void *unused_task, uintptr_t stack_size) { g_custom_min_stack_size = stack_size; } extern "C" CDECL int -sched_threads(rust_task *task) { +sched_threads(void *unused_task) { + rust_task *task = rust_scheduler::get_task(); return task->kernel->num_threads; } extern "C" CDECL rust_port* -new_port(rust_task *task, size_t unit_sz) { +new_port(void *unused_task, size_t unit_sz) { + rust_task *task = rust_scheduler::get_task(); LOG(task, comm, "new_port(task=0x%" PRIxPTR " (%s), unit_sz=%d)", (uintptr_t) task, task->name, unit_sz); // take a reference on behalf of the port @@ -488,7 +522,8 @@ new_port(rust_task *task, size_t unit_sz) { } extern "C" CDECL void -del_port(rust_task *task, rust_port *port) { +del_port(void *unused_task, rust_port *port) { + rust_task *task = rust_scheduler::get_task(); LOG(task, comm, "del_port(0x%" PRIxPTR ")", (uintptr_t) port); I(task->sched, !port->ref_count); delete port; @@ -498,12 +533,13 @@ del_port(rust_task *task, rust_port *port) { } extern "C" CDECL rust_port_id -get_port_id(rust_task *task, rust_port *port) { +get_port_id(void *unused_task, rust_port *port) { return port->id; } extern "C" CDECL rust_chan* -new_chan(rust_task *task, rust_port *port) { +new_chan(void *unused_task, rust_port *port) { + rust_task *task = rust_scheduler::get_task(); rust_scheduler *sched = task->sched; LOG(task, comm, "new_chan(" "task=0x%" PRIxPTR " (%s), port=0x%" PRIxPTR ")", @@ -514,35 +550,37 @@ new_chan(rust_task *task, rust_port *port) { } extern "C" CDECL -void del_chan(rust_task *task, rust_chan *chan) { +void del_chan(void *unused_task, rust_chan *chan) { + rust_task *task = rust_scheduler::get_task(); LOG(task, comm, "del_chan(0x%" PRIxPTR ")", (uintptr_t) chan); I(task->sched, false); } extern "C" CDECL -void take_chan(rust_task *task, rust_chan *chan) { +void take_chan(void *unused_task, rust_chan *chan) { chan->ref(); } extern "C" CDECL -void drop_chan(rust_task *task, rust_chan *chan) { +void drop_chan(void *unused_task, rust_chan *chan) { chan->deref(); } extern "C" CDECL -void drop_port(rust_task *, rust_port *port) { +void drop_port(void *, rust_port *port) { port->ref_count--; } extern "C" CDECL void -chan_send(rust_task *task, rust_chan *chan, void *sptr) { +chan_send(void *unused_task, rust_chan *chan, void *sptr) { chan->send(sptr); } extern "C" CDECL void -chan_id_send(rust_task *task, type_desc *t, rust_task_id target_task_id, +chan_id_send(void *unused_task, type_desc *t, rust_task_id target_task_id, rust_port_id target_port_id, void *sptr) { // FIXME: make sure this is thread-safe + rust_task *task = rust_scheduler::get_task(); rust_task *target_task = task->kernel->get_task_by_id(target_task_id); if(target_task) { rust_port *port = target_task->get_port_by_id(target_port_id); @@ -555,7 +593,8 @@ chan_id_send(rust_task *task, type_desc *t, rust_task_id target_task_id, } extern "C" CDECL void -port_recv(rust_task *task, uintptr_t *dptr, rust_port *port) { +port_recv(void *unused_task, uintptr_t *dptr, rust_port *port) { + rust_task *task = rust_scheduler::get_task(); { scoped_lock with(port->lock); diff --git a/src/rt/rust_internal.h b/src/rt/rust_internal.h index 8688cedc857..b76592b429a 100644 --- a/src/rt/rust_internal.h +++ b/src/rt/rust_internal.h @@ -288,7 +288,7 @@ struct type_desc { #include "memory.h" extern "C" CDECL void -port_recv(rust_task *task, uintptr_t *dptr, rust_port *port); +port_recv(void *unused_task, uintptr_t *dptr, rust_port *port); #include "test/rust_test_harness.h" #include "test/rust_test_util.h"