extern "C" CDECL void upcall_trace_str(rust_task *task, char const *c) { LOG_UPCALL_ENTRY(task); task->log(rust_log::UPCALL | rust_log::TRACE, "trace: %s", c); }
extern "C" CDECL void upcall_log_str(rust_task *task, rust_str *str) { LOG_UPCALL_ENTRY(task); const char *c = str_buf(task, str); task->log(rust_log::UPCALL | rust_log::ULOG, "rust: %s", c); }
extern "C" CDECL void upcall_trace_word(rust_task *task, uintptr_t i) { LOG_UPCALL_ENTRY(task); task->log(rust_log::UPCALL | rust_log::TRACE, "trace: 0x%" PRIxPTR "", i, i, (char) i); }
extern "C" void upcall_grow_task(rust_task *task, size_t n_frame_bytes) { LOG_UPCALL_ENTRY(task); task->grow(n_frame_bytes); }
extern "C" CDECL void upcall_log_int(rust_task *task, int32_t i) { LOG_UPCALL_ENTRY(task); task->log(rust_log::UPCALL | rust_log::ULOG, "rust: %" PRId32 " (0x%" PRIx32 ")", i, i); }
extern "C" CDECL void upcall_s_shared_realloc(s_shared_realloc_args *args) { rust_task *task = rust_task_thread::get_task(); LOG_UPCALL_ENTRY(task); args->retval = task->kernel->realloc(args->ptr, args->size); }
extern "C" CDECL void upcall_yield(rust_task *task) { LOG_UPCALL_ENTRY(task); task->log(rust_log::UPCALL | rust_log::COMM, "upcall yield()"); task->yield(1); }
extern "C" CDECL void upcall_trace_str(rust_task *task, char const *c) { LOG_UPCALL_ENTRY(task); task->dom->log(task, 2, "trace: %s", c); }
extern "C" CDECL void upcall_s_fail(s_fail_args *args) { rust_task *task = args->task; LOG_UPCALL_ENTRY(task); task->fail(args->expr, args->file, args->line); }
extern "C" CDECL void upcall_log_double(rust_task *task, uint32_t level, double *f) { LOG_UPCALL_ENTRY(task); if (task->dom->log_lvl >= level) task->dom->log(task, level, "rust: %12.12f", *f); }
extern "C" CDECL rust_vec * upcall_vec_grow(rust_task *task, rust_vec *v, size_t n_bytes, uintptr_t *need_copy, type_desc *td) { LOG_UPCALL_ENTRY(task); rust_dom *dom = task->dom; LOG(task, mem, "upcall vec_grow(0x%" PRIxPTR ", %" PRIdPTR "), rc=%" PRIdPTR " alloc=%" PRIdPTR ", fill=%" PRIdPTR ", need_copy=0x%" PRIxPTR, v, n_bytes, v->ref_count, v->alloc, v->fill, need_copy); *need_copy = 0; size_t alloc = next_power_of_two(sizeof(rust_vec) + v->fill + n_bytes); if (v->ref_count == 1) { // Fastest path: already large enough. if (v->alloc >= alloc) { LOG(task, mem, "no-growth path"); return v; } // Second-fastest path: can at least realloc. LOG(task, mem, "realloc path"); v = (rust_vec*) task->realloc(v, alloc, td->is_stateful); if (!v) { task->fail(4); return NULL; } v->alloc = alloc; } else { /** * Slowest path: make a new vec. * * 1. Allocate a new rust_vec with desired additional space. * 2. Down-ref the shared rust_vec, point to the new one instead. * 3. Copy existing elements into the new rust_vec. * * Step 3 is a bit tricky. We don't know how to properly copy the * elements in the runtime (all we have are bits in a buffer; no * type infromation and no copy glue). What we do instead is set the * need_copy outparam flag to indicate to our caller (vec-copy glue) * that we need the copies performed for us. */ LOG(task, mem, "new vec path"); void *mem = task->malloc(alloc, td); if (!mem) { task->fail(4); return NULL; } if (v->ref_count != CONST_REFCOUNT) v->deref(); v = new (mem) rust_vec(dom, alloc, 0, NULL); *need_copy = 1; } I(dom, sizeof(rust_vec) + v->fill <= v->alloc); return v; }
/** * Buffers a chunk of data in the specified channel. * * sptr: pointer to a chunk of data to buffer */ extern "C" CDECL void upcall_send(rust_task *task, rust_chan *chan, void *sptr) { LOG_UPCALL_ENTRY(task); chan->send(sptr); LOG(task, comm, "=== sent data ===>"); }
extern "C" CDECL void upcall_yield(rust_task *task) { LOG_UPCALL_ENTRY(task); LOG(task, comm, "upcall yield()"); task->yield(1); }
/** * Called whenever this channel needs to be flushed. This can happen due to a * flush statement, or automatically whenever a channel's ref count is * about to drop to zero. */ extern "C" CDECL void upcall_flush_chan(rust_task *task, rust_chan *chan) { LOG_UPCALL_ENTRY(task); // Nop. }