futures: future-local handling of stack overflow
Includes the addition of 'overflow and 'start-overflow-work events, whcih are effectively specializations of 'sync and 'start-work to expose overflow handling. Also, fix a bug related to a potential GC during mark-stack restore from a lightweight continuation.
This commit is contained in:
parent
f91dc81bf5
commit
40c892ff80
|
@ -188,7 +188,11 @@ a data value that is an instance of a @racket[future-event]
|
|||
@tech{prefab} structure:
|
||||
|
||||
@racketblock[
|
||||
(define-struct future-event (future-id proc-id action time unsafe-op-name)
|
||||
(define-struct future-event (future-id
|
||||
proc-id
|
||||
action
|
||||
time
|
||||
unsafe-op-name)
|
||||
#:prefab)
|
||||
]
|
||||
|
||||
|
@ -222,6 +226,10 @@ The @racket[action] field is a symbol:
|
|||
started in a process other than 0 (e.g., the thunk requires too
|
||||
much local storage to start).}
|
||||
|
||||
@item{@racket['start-overflow-work]: like @racket['start-work], where
|
||||
the future thunk's work was previously stopped due to an
|
||||
internal stack overflow.}
|
||||
|
||||
@item{@racket['sync]: blocking (processes other than 0) or initiation
|
||||
of handing (process 0) for an ``unsafe'' operation in a future
|
||||
thunk's evaluation; the operation must run in process 0.}
|
||||
|
@ -235,6 +243,10 @@ The @racket[action] field is a symbol:
|
|||
@racket['block], but for a @racket[touch] operation within a
|
||||
future thunk.}
|
||||
|
||||
@item{@racket['overflow] (never in process 0): like @racket['sync] or
|
||||
@racket['block], but for the case that a process encountered an
|
||||
internal stack overflow while evaluating a future thunk.}
|
||||
|
||||
@item{@racket['result] or @racket['abort]: waiting or handling for
|
||||
@racket['sync], @racket['block], or @racket['touch] ended with
|
||||
a value or an error, respectively.}
|
||||
|
@ -255,15 +267,15 @@ The @racket[action] field is a symbol:
|
|||
|
||||
]
|
||||
|
||||
Assuming no @racket['missing] events, then @racket['start-work] or
|
||||
@racket['start-0-work] is always paired with @racket['end-work],
|
||||
Assuming no @racket['missing] events, then @racket['start-work],
|
||||
@racket['start-0-work], @racket['start-overflow-work] is always paired with @racket['end-work];
|
||||
@racket['sync], @racket['block], and @racket['touch] are always paired
|
||||
with @racket['result], @racket['abort], or @racket['suspend], and
|
||||
with @racket['result], @racket['abort], or @racket['suspend]; and
|
||||
@racket['touch-pause] is always paired with @racket['touch-resume].
|
||||
|
||||
In process 0, some event pairs can be nested within other event pairs:
|
||||
@racket['sync], @racket['block], or @racket['touch] with
|
||||
@racket['result] or @racket['abort], and @racket['touch-pause] with
|
||||
@racket['result] or @racket['abort]; and @racket['touch-pause] with
|
||||
@racket['touch-resume].
|
||||
|
||||
An @racket[block] in process 0 is generated when an unsafe operation
|
||||
|
|
|
@ -819,6 +819,37 @@ We should also test deep continuations.
|
|||
(check-equal? (unbox b2) #false)
|
||||
(neg-good)
|
||||
(check-equal? (unbox b2) #true))
|
||||
|
||||
;; check handling of marks in stack-overflow handling:
|
||||
(let ()
|
||||
(define (maybe-add1 n)
|
||||
(if (number? n)
|
||||
(add1 n)
|
||||
n))
|
||||
(define (loop n)
|
||||
(if (zero? n)
|
||||
(continuation-mark-set->list (current-continuation-marks) 'x)
|
||||
(with-continuation-mark
|
||||
'x
|
||||
n
|
||||
(maybe-add1 (loop (sub1 n))))))
|
||||
(define f (func (lambda () (loop 10000))))
|
||||
(check-equal? 10000 (length (touch f))))
|
||||
|
||||
;; check arity error in overflow handling:
|
||||
(let ()
|
||||
(define (loop n)
|
||||
(if (zero? n)
|
||||
(values 0 0)
|
||||
(add1 (loop (sub1 n)))))
|
||||
|
||||
(for ([i (in-range 1340 1320 -1)])
|
||||
(define f (func (lambda () (loop i))))
|
||||
(sleep 0.1)
|
||||
(with-handlers ([exn:fail? (lambda (exn)
|
||||
(unless (regexp-match #rx"context" (exn-message exn))
|
||||
(raise exn)))])
|
||||
(touch f))))
|
||||
)
|
||||
|
||||
(run-tests future)
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
Version 5.3.0.11
|
||||
racket/base: added impersonate-prompt-tag & chaperone-prompt-tag
|
||||
racket/control: added call/prompt, call/comp, abort/cc and
|
||||
allow #:tag argument for % and f-control
|
||||
allow #:tag argument for % and f-control
|
||||
racket/future: handling of internal stack overflow without
|
||||
necessarily blocking on process 0; added 'overflow and
|
||||
'start-overflow-work log events
|
||||
|
||||
Version 5.3.0.10
|
||||
racket/base: add progress-evt?, thread-cell-values?, prefab-key?,
|
||||
|
|
|
@ -238,7 +238,7 @@ typedef struct Thread_Local_Variables {
|
|||
int scheme_did_gc_count_;
|
||||
struct Scheme_Future_State *scheme_future_state_;
|
||||
struct Scheme_Future_Thread_State *scheme_future_thread_state_;
|
||||
void *jit_future_storage_[2];
|
||||
void *jit_future_storage_[4];
|
||||
struct Scheme_Object **scheme_current_runstack_start_;
|
||||
struct Scheme_Object **scheme_current_runstack_;
|
||||
intptr_t scheme_current_cont_mark_stack_;
|
||||
|
|
|
@ -7855,8 +7855,7 @@ Scheme_Object *scheme_apply_lightweight_continuation(Scheme_Lightweight_Continua
|
|||
intptr_t min_stacksize)
|
||||
XFORM_SKIP_PROC
|
||||
{
|
||||
intptr_t len, cm_len, cm_pos_delta, cm_delta, i, cm;
|
||||
Scheme_Cont_Mark *seg;
|
||||
intptr_t len, cm_delta, i, cm;
|
||||
Scheme_Object **rs;
|
||||
|
||||
len = lw->saved_lwc->runstack_start - lw->saved_lwc->runstack_end;
|
||||
|
@ -7882,18 +7881,13 @@ Scheme_Object *scheme_apply_lightweight_continuation(Scheme_Lightweight_Continua
|
|||
scheme_current_lwc->cont_mark_stack_start = MZ_CONT_MARK_STACK;
|
||||
scheme_current_lwc->cont_mark_pos_start = MZ_CONT_MARK_POS + 2;
|
||||
|
||||
cm_len = lw->saved_lwc->cont_mark_stack_end - lw->saved_lwc->cont_mark_stack_start;
|
||||
if (cm_len) {
|
||||
/* install captured continuation marks, adjusting the pos
|
||||
to match the new context: */
|
||||
seg = lw->cont_mark_stack_slice;
|
||||
cm_pos_delta = MZ_CONT_MARK_POS + 2 - lw->saved_lwc->cont_mark_pos_start;
|
||||
for (i = 0; i < cm_len; i++) {
|
||||
MZ_CONT_MARK_POS = seg[i].pos + cm_pos_delta;
|
||||
scheme_set_cont_mark(seg[i].key, seg[i].val);
|
||||
}
|
||||
MZ_CONT_MARK_POS = lw->saved_lwc->cont_mark_pos_end + cm_pos_delta;
|
||||
}
|
||||
#ifdef MZ_USE_FUTURES
|
||||
jit_future_storage[3] = result;
|
||||
#endif
|
||||
lw = scheme_restore_lightweight_continuation_marks(lw); /* can trigger GC */
|
||||
#ifdef MZ_USE_FUTURES
|
||||
result = (Scheme_Object *)jit_future_storage[3];
|
||||
#endif
|
||||
|
||||
cm_delta = (intptr_t)MZ_CONT_MARK_STACK - (intptr_t)lw->saved_lwc->cont_mark_stack_end;
|
||||
|
||||
|
@ -7918,6 +7912,35 @@ Scheme_Object *scheme_apply_lightweight_continuation(Scheme_Lightweight_Continua
|
|||
return scheme_apply_lightweight_continuation_stack(lw->saved_lwc, lw->stack_slice, result);
|
||||
}
|
||||
|
||||
Scheme_Lightweight_Continuation *scheme_restore_lightweight_continuation_marks(Scheme_Lightweight_Continuation *lw)
|
||||
XFORM_SKIP_PROC
|
||||
/* Called by any thread, but this function can trigger a GC in the runtime thread */
|
||||
{
|
||||
intptr_t cm_len, i, cm_pos_delta;
|
||||
Scheme_Cont_Mark *seg;
|
||||
|
||||
cm_len = lw->saved_lwc->cont_mark_stack_end - lw->saved_lwc->cont_mark_stack_start;
|
||||
if (cm_len) {
|
||||
/* install captured continuation marks, adjusting the pos
|
||||
to match the new context: */
|
||||
seg = lw->cont_mark_stack_slice;
|
||||
cm_pos_delta = MZ_CONT_MARK_POS + 2 - lw->saved_lwc->cont_mark_pos_start;
|
||||
for (i = 0; i < cm_len; i++) {
|
||||
MZ_CONT_MARK_POS = seg[i].pos + cm_pos_delta;
|
||||
#ifdef MZ_USE_FUTURES
|
||||
jit_future_storage[2] = lw;
|
||||
#endif
|
||||
scheme_set_cont_mark(seg[i].key, seg[i].val); /* can trigger a GC */
|
||||
#ifdef MZ_USE_FUTURES
|
||||
lw = (Scheme_Lightweight_Continuation *)jit_future_storage[2];
|
||||
#endif
|
||||
}
|
||||
MZ_CONT_MARK_POS = lw->saved_lwc->cont_mark_pos_end + cm_pos_delta;
|
||||
}
|
||||
|
||||
return lw;
|
||||
}
|
||||
|
||||
int scheme_push_marks_from_lightweight_continuation(Scheme_Lightweight_Continuation *lw,
|
||||
Scheme_Cont_Frame_Data *d)
|
||||
{
|
||||
|
|
|
@ -303,8 +303,10 @@ static void requeue_future(struct future_t *future, struct Scheme_Future_State *
|
|||
static void future_do_runtimecall(Scheme_Future_Thread_State *fts,
|
||||
void *func,
|
||||
int is_atomic,
|
||||
int can_suspend);
|
||||
static int capture_future_continuation(struct Scheme_Future_State *fs, future_t *ft, void **storage, int need_lock);
|
||||
int can_suspend,
|
||||
int for_overflow);
|
||||
static int capture_future_continuation(struct Scheme_Future_State *fs, future_t *ft, void **storage,
|
||||
int need_lock, int for_overflow);
|
||||
|
||||
#define FUTURE_C_STACK_SIZE 500000
|
||||
#define FUTURE_RUNSTACK_SIZE 2000
|
||||
|
@ -316,6 +318,7 @@ enum {
|
|||
FEVENT_COMPLETE,
|
||||
FEVENT_START_WORK,
|
||||
FEVENT_START_RTONLY_WORK,
|
||||
FEVENT_RESUME_WORK,
|
||||
FEVENT_END_WORK,
|
||||
FEVENT_RTCALL_ATOMIC,
|
||||
FEVENT_HANDLE_RTCALL_ATOMIC,
|
||||
|
@ -327,6 +330,7 @@ enum {
|
|||
FEVENT_RTCALL_ABORT,
|
||||
FEVENT_HANDLE_RTCALL_ABORT,
|
||||
FEVENT_RTCALL_SUSPEND,
|
||||
FEVENT_OVERFLOW,
|
||||
FEVENT_TOUCH_PAUSE,
|
||||
FEVENT_TOUCH_RESUME,
|
||||
FEVENT_MISSING,
|
||||
|
@ -334,18 +338,20 @@ enum {
|
|||
};
|
||||
|
||||
static const char * const fevent_strs[] = { "create", "complete",
|
||||
"start-work", "start-0-work", "end-work",
|
||||
"start-work", "start-0-work", "start-overflow-work",
|
||||
"end-work",
|
||||
"sync", "sync", "block", "touch", "block",
|
||||
"result", "result", "abort", "abort",
|
||||
"suspend",
|
||||
"suspend", "overflow",
|
||||
"touch-pause", "touch-resume", "missing" };
|
||||
static const char * const fevent_long_strs[] = { "created", "completed",
|
||||
"started work", "started (process 0, only)", "ended work",
|
||||
"started work", "started (process 0, only)", "started (overflow)",
|
||||
"ended work",
|
||||
"synchronizing with process 0", "synchronizing",
|
||||
"BLOCKING on process 0", "touching future", "HANDLING",
|
||||
"result from process 0", "result determined",
|
||||
"abort from process 0", "abort determined",
|
||||
"suspended",
|
||||
"suspended", "overflow",
|
||||
"paused for touch", "resumed for touch",
|
||||
"events missing" };
|
||||
|
||||
|
@ -384,7 +390,7 @@ typedef struct Scheme_Future_State {
|
|||
|
||||
|
||||
THREAD_LOCAL_DECL(static Scheme_Future_State *scheme_future_state);
|
||||
THREAD_LOCAL_DECL(void *jit_future_storage[2]);
|
||||
THREAD_LOCAL_DECL(void *jit_future_storage[4]);
|
||||
|
||||
#ifdef MZ_PRECISE_GC
|
||||
THREAD_LOCAL_DECL(extern uintptr_t GC_gen0_alloc_page_ptr);
|
||||
|
@ -408,8 +414,13 @@ static Scheme_Object *apply_future_lw(future_t *ft);
|
|||
static int fsemaphore_ready(Scheme_Object *obj);
|
||||
static void init_fevent(Fevent_Buffer *b);
|
||||
static void free_fevent(Fevent_Buffer *b);
|
||||
static void future_in_runtime(Scheme_Future_State *fs, future_t * volatile ft, int what);
|
||||
static int future_in_runtime(Scheme_Future_State *fs, future_t * volatile ft, int what);
|
||||
static Scheme_Object *would_be_future(int argc, Scheme_Object *argv[]);
|
||||
static void push_suspended_lw(Scheme_Future_State *fs, future_t *ft);
|
||||
static void pop_suspended_lw(Scheme_Future_State *fs, future_t *ft);
|
||||
|
||||
static Scheme_Object *bad_multi_result_proc;
|
||||
static Scheme_Object *bad_multi_result(int argc, Scheme_Object **argv);
|
||||
|
||||
READ_ONLY static int cpucount;
|
||||
static void init_cpucount(void);
|
||||
|
@ -543,6 +554,9 @@ void scheme_init_futures(Scheme_Env *newenv)
|
|||
void scheme_init_futures_once()
|
||||
{
|
||||
init_cpucount();
|
||||
|
||||
REGISTER_SO(bad_multi_result_proc);
|
||||
bad_multi_result_proc = scheme_make_prim(bad_multi_result);
|
||||
}
|
||||
|
||||
void scheme_init_futures_per_place()
|
||||
|
@ -664,7 +678,7 @@ static void init_future_thread(Scheme_Future_State *fs, int i)
|
|||
|
||||
scheme_register_static(params.scheme_current_runstack_ptr, sizeof(void*));
|
||||
scheme_register_static(params.scheme_current_runstack_start_ptr, sizeof(void*));
|
||||
scheme_register_static(params.jit_future_storage_ptr, 2 * sizeof(void*));
|
||||
scheme_register_static(params.jit_future_storage_ptr, 4 * sizeof(void*));
|
||||
scheme_register_static(params.current_thread_ptr, sizeof(void*));
|
||||
|
||||
fs->pool_threads[i] = fts;
|
||||
|
@ -1205,8 +1219,6 @@ static Scheme_Object *make_future(Scheme_Object *lambda, int enqueue)
|
|||
/* Can't even call it in a future thread */
|
||||
ft->status = PENDING_OVERSIZE;
|
||||
}
|
||||
|
||||
ft->code = (void*)ncd->start_code;
|
||||
} else
|
||||
ft->status = PENDING_OVERSIZE;
|
||||
|
||||
|
@ -1226,6 +1238,12 @@ static Scheme_Object *make_future(Scheme_Object *lambda, int enqueue)
|
|||
return (Scheme_Object*)ft;
|
||||
}
|
||||
|
||||
int scheme_can_apply_native_in_future(Scheme_Object *proc)
|
||||
XFORM_SKIP_PROC /* can be called from future thread */
|
||||
{
|
||||
return (((Scheme_Native_Closure *)proc)->code->max_let_depth < FUTURE_RUNSTACK_SIZE * sizeof(void*));
|
||||
}
|
||||
|
||||
static Scheme_Object *do_make_future(int argc, Scheme_Object *argv[])
|
||||
{
|
||||
scheme_check_proc_arity("future", 0, 0, argc, argv);
|
||||
|
@ -1244,7 +1262,7 @@ Scheme_Object *scheme_future(int argc, Scheme_Object *argv[])
|
|||
if (SAME_TYPE(SCHEME_TYPE(proc), scheme_native_closure_type)
|
||||
&& scheme_native_arity_check(proc, 0)
|
||||
&& (((Scheme_Native_Closure *)proc)->code->start_code != scheme_on_demand_jit_code)
|
||||
&& (((Scheme_Native_Closure *)proc)->code->max_let_depth < FUTURE_RUNSTACK_SIZE * sizeof(void*))) {
|
||||
&& scheme_can_apply_native_in_future(proc)) {
|
||||
/* try to alocate a future in the future thread */
|
||||
future_t *ft;
|
||||
ft = MALLOC_ONE_TAGGED(future_t);
|
||||
|
@ -1255,7 +1273,6 @@ Scheme_Object *scheme_future(int argc, Scheme_Object *argv[])
|
|||
ft->orig_lambda = proc;
|
||||
ft->status = PENDING;
|
||||
ft->cust = scheme_current_thread->current_ft->cust;
|
||||
ft->code = ((Scheme_Native_Closure *)proc)->code->start_code;
|
||||
|
||||
mzrt_mutex_lock(fs->future_mutex);
|
||||
ft->id = ++fs->next_futureid;
|
||||
|
@ -1490,7 +1507,7 @@ Scheme_Object *scheme_fsemaphore_wait(int argc, Scheme_Object **argv)
|
|||
fsemaphore_t *sema;
|
||||
Scheme_Future_Thread_State *fts = scheme_future_thread_state;
|
||||
Scheme_Future_State *fs = scheme_future_state;
|
||||
void *storage[3];
|
||||
void *storage[4];
|
||||
|
||||
if (!SAME_TYPE(SCHEME_TYPE(argv[0]), scheme_fsemaphore_type)) {
|
||||
SCHEME_WRONG_CONTRACT_MAYBE_IN_FT("fsemaphore-wait", "fsemaphore?", 0, argc, argv);
|
||||
|
@ -1541,7 +1558,7 @@ Scheme_Object *scheme_fsemaphore_wait(int argc, Scheme_Object **argv)
|
|||
|
||||
/* Try to capture it locally (on this thread) */
|
||||
if (GC_gen0_alloc_page_ptr
|
||||
&& capture_future_continuation(fs, future, storage, 0)) {
|
||||
&& capture_future_continuation(fs, future, storage, 0, 0)) {
|
||||
/* capture sets fts->thread->current_ft to NULL */
|
||||
mzrt_mutex_lock(fs->future_mutex);
|
||||
} else {
|
||||
|
@ -1759,12 +1776,13 @@ static Scheme_Object *shallower_apply_future_lw_k(void)
|
|||
return apply_future_lw(ft);
|
||||
}
|
||||
|
||||
static void future_in_runtime(Scheme_Future_State *fs, future_t * volatile ft, int what)
|
||||
{
|
||||
static int future_in_runtime(Scheme_Future_State *fs, future_t * volatile ft, int what)
|
||||
{
|
||||
mz_jmp_buf newbuf, * volatile savebuf;
|
||||
Scheme_Thread *p = scheme_current_thread;
|
||||
Scheme_Object * volatile retval;
|
||||
future_t * volatile old_ft;
|
||||
int done;
|
||||
|
||||
old_ft = p->current_ft;
|
||||
p->current_ft = ft;
|
||||
|
@ -1785,7 +1803,25 @@ static void future_in_runtime(Scheme_Future_State *fs, future_t * volatile ft, i
|
|||
} else
|
||||
retval = apply_future_lw(ft);
|
||||
} else {
|
||||
retval = scheme_apply_multi(ft->orig_lambda, 0, NULL);
|
||||
if (ft->suspended_lw_stack) {
|
||||
Scheme_Object *rator, **argv;
|
||||
int argc;
|
||||
Scheme_Lightweight_Continuation *lc;
|
||||
rator = (Scheme_Object *)ft->suspended_lw_stack[2];
|
||||
argc = SCHEME_INT_VAL((Scheme_Object *)ft->suspended_lw_stack[3]);
|
||||
argv = (Scheme_Object **)ft->suspended_lw_stack[4];
|
||||
ft->suspended_lw_stack[2] = NULL;
|
||||
ft->suspended_lw_stack[4] = NULL;
|
||||
|
||||
lc = (Scheme_Lightweight_Continuation *)ft->suspended_lw_stack[1];
|
||||
scheme_restore_lightweight_continuation_marks(lc);
|
||||
|
||||
if (ft->suspended_lw_stack[5])
|
||||
retval = _scheme_apply_multi(rator, argc, argv);
|
||||
else
|
||||
retval = _scheme_apply(rator, argc, argv);
|
||||
} else
|
||||
retval = scheme_apply_multi(ft->orig_lambda, 0, NULL);
|
||||
}
|
||||
send_special_result(ft, retval);
|
||||
}
|
||||
|
@ -1796,17 +1832,27 @@ static void future_in_runtime(Scheme_Future_State *fs, future_t * volatile ft, i
|
|||
ft->retval = retval;
|
||||
|
||||
mzrt_mutex_lock(fs->future_mutex);
|
||||
ft->status = FINISHED;
|
||||
trigger_added_touches(fs, ft);
|
||||
mzrt_mutex_unlock(fs->future_mutex);
|
||||
|
||||
if (ft->suspended_lw_stack && retval) {
|
||||
pop_suspended_lw(fs, ft);
|
||||
done = 0;
|
||||
} else {
|
||||
if (!retval)
|
||||
ft->suspended_lw_stack = NULL;
|
||||
ft->status = FINISHED;
|
||||
trigger_added_touches(fs, ft);
|
||||
done = 1;
|
||||
}
|
||||
record_fevent(FEVENT_COMPLETE, ft->id);
|
||||
mzrt_mutex_unlock(fs->future_mutex);
|
||||
|
||||
record_fevent(FEVENT_END_WORK, ft->id);
|
||||
|
||||
if (!retval) {
|
||||
scheme_longjmp(*savebuf, 1);
|
||||
}
|
||||
|
||||
return done;
|
||||
}
|
||||
|
||||
static int prefer_to_apply_future_in_runtime()
|
||||
|
@ -1851,18 +1897,21 @@ Scheme_Object *general_touch(int argc, Scheme_Object *argv[])
|
|||
what = FEVENT_START_RTONLY_WORK;
|
||||
} else if (ft->status != SUSPENDED) {
|
||||
dequeue_future(fs, ft);
|
||||
if (ft->suspended_lw_stack)
|
||||
what = FEVENT_RESUME_WORK;
|
||||
}
|
||||
ft->status = RUNNING;
|
||||
mzrt_mutex_unlock(fs->future_mutex);
|
||||
if (ft->in_tracing_mode) {
|
||||
run_would_be_future(ft);
|
||||
retval = ft->retval;
|
||||
break;
|
||||
} else {
|
||||
future_in_runtime(fs, ft, what);
|
||||
if (future_in_runtime(fs, ft, what)) {
|
||||
retval = ft->retval;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
retval = ft->retval;
|
||||
|
||||
break;
|
||||
}
|
||||
else if ((ft->status == RUNNING)
|
||||
|| (ft->status == WAITING_FOR_FSEMA)
|
||||
|
@ -1900,7 +1949,7 @@ Scheme_Object *general_touch(int argc, Scheme_Object *argv[])
|
|||
ft->status = RUNNING;
|
||||
/* may raise an exception or escape: */
|
||||
mzrt_mutex_unlock(fs->future_mutex);
|
||||
future_in_runtime(fs, ft, FEVENT_START_WORK);
|
||||
(void)future_in_runtime(fs, ft, FEVENT_START_WORK);
|
||||
} else {
|
||||
/* Someone needs to handle the future. We're banking on some
|
||||
future thread eventually picking up the future, which is
|
||||
|
@ -2079,7 +2128,7 @@ void *worker_thread_future_loop(void *arg)
|
|||
Scheme_Native_Proc *jitcode;
|
||||
future_t *ft;
|
||||
mz_jmp_buf newbuf;
|
||||
int fid;
|
||||
int fid, what;
|
||||
|
||||
scheme_future_state = fs;
|
||||
scheme_future_thread_state = fts;
|
||||
|
@ -2137,8 +2186,13 @@ void *worker_thread_future_loop(void *arg)
|
|||
|
||||
if (ft) {
|
||||
fs->busy_thread_count++;
|
||||
|
||||
if (ft->suspended_lw_stack)
|
||||
what = FEVENT_RESUME_WORK;
|
||||
else
|
||||
what = FEVENT_START_WORK;
|
||||
fid = ft->id;
|
||||
record_fevent(FEVENT_START_WORK, fid);
|
||||
record_fevent(what, fid);
|
||||
|
||||
/* Work is available for this thread */
|
||||
ft->status = RUNNING;
|
||||
|
@ -2166,8 +2220,6 @@ void *worker_thread_future_loop(void *arg)
|
|||
v = _apply_future_lw(ft);
|
||||
}
|
||||
} else {
|
||||
jitcode = ft->code;
|
||||
|
||||
/* Run the code:
|
||||
The lambda passed to a future will always be a parameterless
|
||||
function.
|
||||
|
@ -2182,8 +2234,30 @@ void *worker_thread_future_loop(void *arg)
|
|||
/* failed or suspended */
|
||||
v = NULL;
|
||||
} else {
|
||||
Scheme_Object *rator, **argv;
|
||||
int argc;
|
||||
|
||||
if (ft->suspended_lw_stack) {
|
||||
Scheme_Lightweight_Continuation *lc;
|
||||
|
||||
lc = (Scheme_Lightweight_Continuation *)ft->suspended_lw_stack[1];
|
||||
scheme_restore_lightweight_continuation_marks(lc); /* might trigger GC */
|
||||
ft = fts->thread->current_ft;
|
||||
|
||||
rator = (Scheme_Object *)ft->suspended_lw_stack[2];
|
||||
argc = SCHEME_INT_VAL((Scheme_Object *)ft->suspended_lw_stack[3]);
|
||||
argv = (Scheme_Object **)ft->suspended_lw_stack[4];
|
||||
ft->suspended_lw_stack[2] = NULL;
|
||||
ft->suspended_lw_stack[4] = NULL;
|
||||
} else {
|
||||
rator = ft->orig_lambda;
|
||||
argc = 0;
|
||||
argv = NULL;
|
||||
}
|
||||
|
||||
scheme_fill_lwc_start();
|
||||
v = scheme_call_as_lightweight_continuation(jitcode, ft->orig_lambda, 0, NULL);
|
||||
jitcode = ((Scheme_Native_Closure *)rator)->code->start_code;
|
||||
v = scheme_call_as_lightweight_continuation(jitcode, rator, argc, argv);
|
||||
if (SAME_OBJ(v, SCHEME_TAIL_CALL_WAITING)) {
|
||||
v = scheme_ts_scheme_force_value_same_mark(v);
|
||||
}
|
||||
|
@ -2205,15 +2279,29 @@ void *worker_thread_future_loop(void *arg)
|
|||
if (ft->no_retval >= 0) {
|
||||
/* Set the return val in the descriptor */
|
||||
ft->retval = v;
|
||||
|
||||
/* In case of multiple values: */
|
||||
send_special_result(ft, v);
|
||||
|
||||
/* Update the status */
|
||||
ft->status = FINISHED;
|
||||
trigger_added_touches(fs, ft);
|
||||
|
||||
if (ft->suspended_lw_stack) {
|
||||
if (!ft->suspended_lw_stack[5] && SAME_OBJ(v, SCHEME_MULTIPLE_VALUES)) {
|
||||
/* multiple results are not allowed; keep the same lw stack,
|
||||
but replace the function to call: */
|
||||
ft->status = PENDING_OVERSIZE;
|
||||
ft->suspended_lw_stack[2] = bad_multi_result_proc;
|
||||
ft->suspended_lw_stack[3] = scheme_make_integer(ft->multiple_count);
|
||||
ft->suspended_lw_stack[4] = ft->multiple_array;
|
||||
ft->retval_s = NULL;
|
||||
ft->multiple_array = NULL;
|
||||
} else
|
||||
pop_suspended_lw(fs, ft);
|
||||
} else {
|
||||
/* Update the status */
|
||||
ft->status = FINISHED;
|
||||
trigger_added_touches(fs, ft);
|
||||
}
|
||||
record_fevent(FEVENT_COMPLETE, fid);
|
||||
} else {
|
||||
ft->suspended_lw_stack = NULL;
|
||||
}
|
||||
|
||||
fts->thread->current_ft = NULL;
|
||||
|
@ -2290,7 +2378,8 @@ static Scheme_Object *apply_future_lw(future_t *ft)
|
|||
return (Scheme_Object *)scheme_top_level_do(apply_future_lw_k, 0);
|
||||
}
|
||||
|
||||
static int capture_future_continuation(Scheme_Future_State *fs, future_t *ft, void **storage, int need_lock)
|
||||
static int capture_future_continuation(Scheme_Future_State *fs, future_t *ft, void **storage,
|
||||
int need_lock, int for_overflow)
|
||||
XFORM_SKIP_PROC
|
||||
/* The lock is *not* held when calling this function.
|
||||
This function explicitly cooperates with the GC by storing the
|
||||
|
@ -2300,13 +2389,23 @@ static int capture_future_continuation(Scheme_Future_State *fs, future_t *ft, vo
|
|||
{
|
||||
Scheme_Lightweight_Continuation *lw;
|
||||
Scheme_Object **arg_S;
|
||||
void **stack;
|
||||
|
||||
storage[2] = ft;
|
||||
|
||||
if (for_overflow) {
|
||||
stack = MALLOC_N(void*, 6);
|
||||
if (!stack) return 0;
|
||||
storage[3] = stack;
|
||||
ft = (future_t *)storage[2];
|
||||
} else
|
||||
stack = NULL;
|
||||
|
||||
lw = scheme_capture_lightweight_continuation(ft->fts->thread, ft->lwc, storage);
|
||||
if (!lw) return 0;
|
||||
|
||||
ft = (future_t *)storage[2];
|
||||
stack = (void **)storage[3];
|
||||
|
||||
if (need_lock) {
|
||||
mzrt_mutex_lock(fs->future_mutex);
|
||||
|
@ -2342,9 +2441,48 @@ static int capture_future_continuation(Scheme_Future_State *fs, future_t *ft, vo
|
|||
ft->arg_S2 = arg_S;
|
||||
}
|
||||
|
||||
if (for_overflow) {
|
||||
stack[0] = ft->suspended_lw_stack;
|
||||
stack[5] = ((for_overflow > 1) ? scheme_true : NULL);
|
||||
ft->suspended_lw_stack = stack;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void push_suspended_lw(Scheme_Future_State *fs, future_t *ft)
|
||||
XFORM_SKIP_PROC
|
||||
/* called in any thread; needs lock */
|
||||
{
|
||||
ft->suspended_lw_stack[1] = ft->suspended_lw;
|
||||
ft->suspended_lw = NULL;
|
||||
|
||||
ft->suspended_lw_stack[2] = ft->arg_s0;
|
||||
ft->arg_s0 = NULL;
|
||||
ft->suspended_lw_stack[3] = scheme_make_integer(ft->arg_i0);
|
||||
ft->suspended_lw_stack[4] = ft->arg_S0;
|
||||
ft->arg_S0 = NULL;
|
||||
|
||||
ft->status = PENDING;
|
||||
(void)enqueue_future(fs, ft);
|
||||
}
|
||||
|
||||
static void pop_suspended_lw(Scheme_Future_State *fs, future_t *ft)
|
||||
XFORM_SKIP_PROC
|
||||
/* called in any thread; needs lock */
|
||||
{
|
||||
ft->retval_s = ft->retval;
|
||||
ft->retval = NULL;
|
||||
|
||||
ft->suspended_lw = (Scheme_Lightweight_Continuation *)ft->suspended_lw_stack[1];
|
||||
ft->maybe_suspended_lw = 1;
|
||||
|
||||
ft->suspended_lw_stack = (void **)ft->suspended_lw_stack[0];
|
||||
|
||||
ft->status = PENDING;
|
||||
(void)enqueue_future(fs, ft);
|
||||
}
|
||||
|
||||
void scheme_check_future_work()
|
||||
/* Called in the runtime thread by the scheduler */
|
||||
{
|
||||
|
@ -2448,14 +2586,21 @@ void scheme_check_future_work()
|
|||
mzrt_mutex_unlock(fs->future_mutex);
|
||||
|
||||
if (ft) {
|
||||
void *storage[3];
|
||||
void *storage[4];
|
||||
|
||||
if (capture_future_continuation(fs, ft, storage, 1)) {
|
||||
if (capture_future_continuation(fs, ft, storage, 1,
|
||||
((ft->status == WAITING_FOR_OVERFLOW)
|
||||
? ft->arg_i1
|
||||
: 0))) {
|
||||
/* capture performs mzrt_mutex_lock(fs->future_mutex) on success. */
|
||||
if (ft->suspended_lw)
|
||||
FUTURE_ASSERT((ft->status == WAITING_FOR_PRIM)
|
||||
|| (ft->status == WAITING_FOR_FSEMA));
|
||||
else
|
||||
if (ft->suspended_lw) {
|
||||
FUTURE_ASSERT((ft->status == WAITING_FOR_PRIM)
|
||||
|| (ft->status == WAITING_FOR_FSEMA)
|
||||
|| (ft->status == WAITING_FOR_OVERFLOW));
|
||||
if (ft->status == WAITING_FOR_OVERFLOW) {
|
||||
push_suspended_lw(fs, ft);
|
||||
}
|
||||
} else
|
||||
FUTURE_ASSERT(ft->status != RUNNING);
|
||||
mzrt_mutex_unlock(fs->future_mutex);
|
||||
} else {
|
||||
|
@ -2503,7 +2648,8 @@ void scheme_check_future_work()
|
|||
static void future_do_runtimecall(Scheme_Future_Thread_State *fts,
|
||||
void *func,
|
||||
int is_atomic,
|
||||
int can_suspend)
|
||||
int can_suspend,
|
||||
int for_overflow)
|
||||
XFORM_SKIP_PROC
|
||||
/* Called in either future or runtime thread. Can only be called in the runtime thread
|
||||
if we are in slow-path trace mode (i.e. we are running a future that is bound to the
|
||||
|
@ -2511,7 +2657,7 @@ static void future_do_runtimecall(Scheme_Future_Thread_State *fts,
|
|||
{
|
||||
future_t *future;
|
||||
Scheme_Future_State *fs = scheme_future_state;
|
||||
void *storage[3];
|
||||
void *storage[4];
|
||||
int insist_to_suspend, prefer_to_suspend, fid;
|
||||
|
||||
/* Fetch the future descriptor for this thread */
|
||||
|
@ -2534,7 +2680,8 @@ static void future_do_runtimecall(Scheme_Future_Thread_State *fts,
|
|||
|
||||
fid = future->id;
|
||||
|
||||
/* Policy question: When should the future thread suspend
|
||||
/* If for_overflow, then a suspend is required. Otherwise...
|
||||
Policy question: When should the future thread suspend
|
||||
the current future? It costs something to suspend and
|
||||
resume a future.
|
||||
The current policy:
|
||||
|
@ -2544,7 +2691,7 @@ static void future_do_runtimecall(Scheme_Future_Thread_State *fts,
|
|||
more work available in the future queue, and only if we
|
||||
can suspend ourselves (because asking the runtime thread
|
||||
to suspend wouldn't accomplish anything). */
|
||||
insist_to_suspend = !is_atomic;
|
||||
insist_to_suspend = !is_atomic || for_overflow;
|
||||
prefer_to_suspend = (insist_to_suspend || fs->future_queue_count);
|
||||
|
||||
if (!scheme_custodian_is_available(future->cust)) {
|
||||
|
@ -2559,7 +2706,7 @@ static void future_do_runtimecall(Scheme_Future_Thread_State *fts,
|
|||
|
||||
if (prefer_to_suspend
|
||||
&& GC_gen0_alloc_page_ptr
|
||||
&& capture_future_continuation(fs, future, storage, 0)) {
|
||||
&& capture_future_continuation(fs, future, storage, 0, for_overflow)) {
|
||||
/* this future thread will suspend handling the future
|
||||
continuation until the result of the blocking call is ready;
|
||||
fts->thread->current_ft was set to NULL */
|
||||
|
@ -2567,17 +2714,29 @@ static void future_do_runtimecall(Scheme_Future_Thread_State *fts,
|
|||
|
||||
mzrt_mutex_lock(fs->future_mutex);
|
||||
|
||||
if (func == touch) {
|
||||
if (for_overflow) {
|
||||
record_fevent(FEVENT_OVERFLOW, fid);
|
||||
} else if (func == touch) {
|
||||
record_fevent(FEVENT_RTCALL_TOUCH, fid);
|
||||
} else {
|
||||
record_fevent(is_atomic ? FEVENT_RTCALL_ATOMIC : FEVENT_RTCALL, fid);
|
||||
}
|
||||
|
||||
/* Set up the arguments for the runtime call
|
||||
to be picked up by the main rt thread */
|
||||
future->prim_func = func;
|
||||
future->rt_prim_is_atomic = is_atomic;
|
||||
future->status = WAITING_FOR_PRIM;
|
||||
if (for_overflow) {
|
||||
if (!fts->thread->current_ft) {
|
||||
/* capture complete; re-enqueue so that it continues on fresh stack */
|
||||
push_suspended_lw(fs, future);
|
||||
} else {
|
||||
future->status = WAITING_FOR_OVERFLOW;
|
||||
future->arg_i1 = for_overflow;
|
||||
}
|
||||
} else {
|
||||
/* Set up the arguments for the runtime call
|
||||
to be picked up by the main rt thread */
|
||||
future->prim_func = func;
|
||||
future->rt_prim_is_atomic = is_atomic;
|
||||
future->status = WAITING_FOR_PRIM;
|
||||
}
|
||||
|
||||
if (is_atomic) {
|
||||
future->next_waiting_atomic = fs->future_waiting_atomic;
|
||||
|
@ -2594,6 +2753,8 @@ static void future_do_runtimecall(Scheme_Future_Thread_State *fts,
|
|||
future->in_queue_waiting_for_lwc = 1;
|
||||
}
|
||||
future->want_lw = 1;
|
||||
/* In case of for_overflow, runtime thread is responsible for
|
||||
enqueuing the future to continue. */
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2631,6 +2792,7 @@ static void future_do_runtimecall(Scheme_Future_Thread_State *fts,
|
|||
future = fts->thread->current_ft;
|
||||
|
||||
FUTURE_ASSERT(!future || !future->can_continue_sema);
|
||||
FUTURE_ASSERT(!future || !for_overflow);
|
||||
|
||||
if (future) {
|
||||
future->want_lw = 0;
|
||||
|
@ -2644,7 +2806,8 @@ static void future_do_runtimecall(Scheme_Future_Thread_State *fts,
|
|||
future->status = RUNNING;
|
||||
}
|
||||
} else {
|
||||
record_fevent(FEVENT_RTCALL_SUSPEND, fid);
|
||||
if (!for_overflow)
|
||||
record_fevent(FEVENT_RTCALL_SUSPEND, fid);
|
||||
}
|
||||
|
||||
mzrt_mutex_unlock(fs->future_mutex);
|
||||
|
@ -2661,6 +2824,12 @@ static void future_do_runtimecall(Scheme_Future_Thread_State *fts,
|
|||
}
|
||||
}
|
||||
|
||||
static Scheme_Object *bad_multi_result(int argc, Scheme_Object **argv)
|
||||
{
|
||||
scheme_wrong_return_arity(NULL, 1, argc, argv, NULL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**********************************************************************/
|
||||
/* Functions for primitive invocation */
|
||||
/**********************************************************************/
|
||||
|
@ -2680,7 +2849,7 @@ void scheme_wrong_contract_from_ft(const char *who, const char *expected_type, i
|
|||
|
||||
future->time_of_request = get_future_timestamp();
|
||||
future->source_of_request = who;
|
||||
future_do_runtimecall(fts, NULL, 0, 1);
|
||||
future_do_runtimecall(fts, NULL, 0, 1, 0);
|
||||
|
||||
/* Fetch the future again, in case moved by a GC */
|
||||
future = fts->thread->current_ft;
|
||||
|
@ -2709,7 +2878,7 @@ Scheme_Object **scheme_rtcall_on_demand(Scheme_Object **argv)
|
|||
future->source_of_request = "[jit_on_demand]";
|
||||
future->source_type = FSRC_OTHER;
|
||||
|
||||
future_do_runtimecall(fts, NULL, 1, 1);
|
||||
future_do_runtimecall(fts, NULL, 1, 1, 0);
|
||||
|
||||
/* Fetch the future again, in case moved by a GC */
|
||||
future = fts->thread->current_ft;
|
||||
|
@ -2743,7 +2912,7 @@ Scheme_Object *scheme_rtcall_make_fsemaphore(Scheme_Object *ready)
|
|||
else
|
||||
is_atomic = 0;
|
||||
|
||||
future_do_runtimecall(fts, NULL, is_atomic, 1);
|
||||
future_do_runtimecall(fts, NULL, is_atomic, 1, 0);
|
||||
|
||||
/* Fetch the future again, in case moved by a GC */
|
||||
future = fts->thread->current_ft;
|
||||
|
@ -2774,7 +2943,7 @@ Scheme_Object *scheme_rtcall_make_future(Scheme_Object *proc)
|
|||
future->source_of_request = "future";
|
||||
future->source_type = FSRC_OTHER;
|
||||
|
||||
future_do_runtimecall(fts, NULL, is_atomic, 1);
|
||||
future_do_runtimecall(fts, NULL, is_atomic, 1, 0);
|
||||
|
||||
/* Fetch the future again, in case moved by a GC */
|
||||
future = fts->thread->current_ft;
|
||||
|
@ -2801,7 +2970,7 @@ void scheme_rtcall_allocate_values(int count, Scheme_Thread *t)
|
|||
future->source_of_request = "[allocate_values]";
|
||||
future->source_type = FSRC_OTHER;
|
||||
|
||||
future_do_runtimecall(fts, NULL, 1, 0);
|
||||
future_do_runtimecall(fts, NULL, 1, 0, 0);
|
||||
|
||||
/* Fetch the future again, in case moved by a GC */
|
||||
future = fts->thread->current_ft;
|
||||
|
@ -2827,7 +2996,43 @@ Scheme_Object *scheme_rtcall_tail_apply(Scheme_Object *rator, int argc, Scheme_O
|
|||
future->source_of_request = "[tail-call]";
|
||||
future->source_type = FSRC_OTHER;
|
||||
|
||||
future_do_runtimecall(fts, NULL, 1, 0);
|
||||
future_do_runtimecall(fts, NULL, 1, 0, 0);
|
||||
|
||||
/* Fetch the future again, in case moved by a GC */
|
||||
future = fts->thread->current_ft;
|
||||
|
||||
future->arg_s0 = NULL;
|
||||
future->arg_S0 = NULL;
|
||||
|
||||
retval = future->retval_s;
|
||||
future->retval_s = NULL;
|
||||
|
||||
receive_special_result(future, retval, 1);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
Scheme_Object *scheme_rtcall_apply_with_new_stack(Scheme_Object *rator, int argc, Scheme_Object **argv,
|
||||
int multi)
|
||||
XFORM_SKIP_PROC
|
||||
/* Called in future thread; rator is a native closure with a runstack limit that fits */
|
||||
{
|
||||
Scheme_Future_Thread_State *fts = scheme_future_thread_state;
|
||||
future_t *future = fts->thread->current_ft;
|
||||
Scheme_Object *retval;
|
||||
|
||||
future->prim_protocol = SIG_APPLY_AFRESH;
|
||||
|
||||
future->arg_s0 = rator;
|
||||
future->arg_i0 = argc;
|
||||
future->arg_S0 = argv;
|
||||
future->arg_i1 = multi;
|
||||
|
||||
future->time_of_request = get_future_timestamp();
|
||||
future->source_of_request = "[stack-overflow]";
|
||||
future->source_type = FSRC_OTHER;
|
||||
|
||||
future_do_runtimecall(fts, NULL, 1, 1, (multi ? 2 : 1));
|
||||
|
||||
/* Fetch the future again, in case moved by a GC */
|
||||
future = fts->thread->current_ft;
|
||||
|
@ -2883,7 +3088,7 @@ uintptr_t scheme_rtcall_alloc()
|
|||
future->prim_protocol = SIG_ALLOC;
|
||||
future->arg_i0 = fts->gen0_size;
|
||||
|
||||
future_do_runtimecall(fts, NULL, 1, 0);
|
||||
future_do_runtimecall(fts, NULL, 1, 0, 0);
|
||||
|
||||
future = fts->thread->current_ft;
|
||||
retval = future->alloc_retval;
|
||||
|
@ -2919,7 +3124,7 @@ void scheme_rtcall_new_mark_segment(Scheme_Thread *p)
|
|||
future->prim_protocol = SIG_ALLOC_MARK_SEGMENT;
|
||||
future->arg_s0 = (Scheme_Object *)p;
|
||||
|
||||
future_do_runtimecall(fts, NULL, 1, 0);
|
||||
future_do_runtimecall(fts, NULL, 1, 0, 0);
|
||||
}
|
||||
|
||||
static int push_marks(future_t *f, Scheme_Cont_Frame_Data *d)
|
||||
|
@ -3033,7 +3238,7 @@ static void do_invoke_rtcall(Scheme_Future_State *fs, future_t *future)
|
|||
|
||||
flush_future_logs(fs);
|
||||
|
||||
/* use lg_future_event so we can include `str' in the message: */
|
||||
/* use log_future_event so we can include `str' in the message: */
|
||||
log_future_event(fs,
|
||||
"future %d, process %d: %s: %s; time: %f",
|
||||
src,
|
||||
|
@ -3153,6 +3358,28 @@ static void do_invoke_rtcall(Scheme_Future_State *fs, future_t *future)
|
|||
|
||||
/* doesn't return */
|
||||
|
||||
break;
|
||||
}
|
||||
case SIG_APPLY_AFRESH:
|
||||
{
|
||||
GC_CAN_IGNORE Scheme_Object *arg_s0 = future->arg_s0;
|
||||
GC_CAN_IGNORE Scheme_Object **arg_S0 = future->arg_S0;
|
||||
GC_CAN_IGNORE Scheme_Object *retval;
|
||||
|
||||
/* This code is used only for would-be futures: */
|
||||
FUTURE_ASSERT(future->in_tracing_mode);
|
||||
|
||||
future->arg_s0 = NULL;
|
||||
future->arg_S0 = NULL;
|
||||
|
||||
if (future->arg_i1)
|
||||
retval = _scheme_apply_multi(arg_s0, future->arg_i0, arg_S0);
|
||||
else
|
||||
retval = _scheme_apply(arg_s0, future->arg_i0, arg_S0);
|
||||
|
||||
future->retval_s = retval;
|
||||
send_special_result(future, retval);
|
||||
|
||||
break;
|
||||
}
|
||||
# define JIT_TS_LOCALIZE(t, f) GC_CAN_IGNORE t f = future->f
|
||||
|
|
|
@ -8,14 +8,27 @@ typedef Scheme_Object* (*prim_int_pobj_obj_t)(int, Scheme_Object**);
|
|||
typedef Scheme_Object* (*prim_int_pobj_obj_obj_t)(int, Scheme_Object**, Scheme_Object*);
|
||||
typedef void* (*prim_pvoid_pvoid_pvoid_t)(void*, void*);
|
||||
|
||||
/* PENDING is ready to run: */
|
||||
#define PENDING 0
|
||||
/* RUNNING is running in some thread: */
|
||||
#define RUNNING 1
|
||||
/* WAITING_FOR_PRIM is waiting for the runtime thread to start runnin
|
||||
a primitive -- possibiliy atomic, possibly not, and possibly a LWC
|
||||
capture happens while waiting: */
|
||||
#define WAITING_FOR_PRIM 2
|
||||
/* FINISHED means the result (or failure) is ready: */
|
||||
#define FINISHED 3
|
||||
/* PENDING is ready to run, but won't work in a future thread: */
|
||||
#define PENDING_OVERSIZE 4
|
||||
/* WAITING_FOR_PRIM is the runtime thread working on a primitive: */
|
||||
#define HANDLING_PRIM 5
|
||||
/* WAITING_FOR_FSEMA is in the queue of an fsemaphore: */
|
||||
#define WAITING_FOR_FSEMA 6
|
||||
/* SUSPENDED is the owning custodian is gone, so the future will never finish: */
|
||||
#define SUSPENDED 7
|
||||
/* WAITING_FOR_OVERFLOW is waiting for an LCW capture to continue
|
||||
for a stack overflow: */
|
||||
#define WAITING_FOR_OVERFLOW 8
|
||||
|
||||
/* FSRC_OTHER means: descriptive string is provided for logging,
|
||||
called function *DOES NOT NEED* to lookup continuation marks. */
|
||||
|
@ -88,7 +101,6 @@ typedef struct future_t {
|
|||
that case */
|
||||
|
||||
Scheme_Object *orig_lambda;
|
||||
void *code;
|
||||
|
||||
Scheme_Custodian *cust; /* an approximate custodian; don't use a future
|
||||
thread if this custodian is shut down */
|
||||
|
@ -178,6 +190,8 @@ typedef struct future_t {
|
|||
extra flag avoids spinning if the suspended continuation
|
||||
cannot be resumed in the main thread for some reason */
|
||||
|
||||
void **suspended_lw_stack; /* for overflow handling */
|
||||
|
||||
Scheme_Object *retval_s;
|
||||
void *retval_p; /* use only with conservative GC */
|
||||
MZ_MARK_STACK_TYPE retval_m;
|
||||
|
@ -228,6 +242,7 @@ typedef struct fsemaphore_t {
|
|||
#define SIG_FUTURE 6
|
||||
#define SIG_WRONG_TYPE_EXN 7
|
||||
#define SIG_TAIL_APPLY 8
|
||||
#define SIG_APPLY_AFRESH 9
|
||||
|
||||
# include "jit_ts_protos.h"
|
||||
|
||||
|
@ -240,6 +255,9 @@ extern void scheme_rtcall_allocate_values(int count, Scheme_Thread *t);
|
|||
extern Scheme_Object *scheme_rtcall_make_fsemaphore(Scheme_Object *ready);
|
||||
extern Scheme_Object *scheme_rtcall_make_future(Scheme_Object *proc);
|
||||
extern Scheme_Object *scheme_rtcall_tail_apply(Scheme_Object *rator, int argc, Scheme_Object **argv);
|
||||
extern Scheme_Object *scheme_rtcall_apply_with_new_stack(Scheme_Object *rator, int argc, Scheme_Object **argv, int multi);
|
||||
|
||||
int scheme_can_apply_native_in_future(Scheme_Object *proc);
|
||||
|
||||
void scheme_future_block_until_gc();
|
||||
void scheme_future_continue_after_gc();
|
||||
|
|
|
@ -98,7 +98,7 @@
|
|||
@string-append{ future->arg_@|(string t)|@|(number->string i)| = @|a|;})
|
||||
"\n")
|
||||
@(if (equal? arg-types '("Scheme_Object*")) @string-append{send_special_result(future, @(car arg-names));} "")
|
||||
future_do_runtimecall(fts, (void*)f, 0, 1);
|
||||
future_do_runtimecall(fts, (void*)f, 0, 1, 0);
|
||||
fts->thread = scheme_current_thread;
|
||||
future = fts->thread->current_ft;
|
||||
@(if (string=? result-type "void") "" @string-append{retval = @|fretval|;})
|
||||
|
|
|
@ -1,38 +1,38 @@
|
|||
#define define_ts_siS_s(id, src_type) \
|
||||
static Scheme_Object* ts_ ## id(Scheme_Object* g5, int g6, Scheme_Object** g7) \
|
||||
static Scheme_Object* ts_ ## id(Scheme_Object* g7, int g8, Scheme_Object** g9) \
|
||||
XFORM_SKIP_PROC \
|
||||
{ \
|
||||
if (scheme_use_rtcall) \
|
||||
return scheme_rtcall_siS_s("[" #id "]", src_type, id, g5, g6, g7); \
|
||||
return scheme_rtcall_siS_s("[" #id "]", src_type, id, g7, g8, g9); \
|
||||
else \
|
||||
return id(g5, g6, g7); \
|
||||
return id(g7, g8, g9); \
|
||||
}
|
||||
#define define_ts_iSs_s(id, src_type) \
|
||||
static Scheme_Object* ts_ ## id(int g8, Scheme_Object** g9, Scheme_Object* g10) \
|
||||
static Scheme_Object* ts_ ## id(int g10, Scheme_Object** g11, Scheme_Object* g12) \
|
||||
XFORM_SKIP_PROC \
|
||||
{ \
|
||||
if (scheme_use_rtcall) \
|
||||
return scheme_rtcall_iSs_s("[" #id "]", src_type, id, g8, g9, g10); \
|
||||
return scheme_rtcall_iSs_s("[" #id "]", src_type, id, g10, g11, g12); \
|
||||
else \
|
||||
return id(g8, g9, g10); \
|
||||
return id(g10, g11, g12); \
|
||||
}
|
||||
#define define_ts_s_s(id, src_type) \
|
||||
static Scheme_Object* ts_ ## id(Scheme_Object* g11) \
|
||||
static Scheme_Object* ts_ ## id(Scheme_Object* g13) \
|
||||
XFORM_SKIP_PROC \
|
||||
{ \
|
||||
if (scheme_use_rtcall) \
|
||||
return scheme_rtcall_s_s("[" #id "]", src_type, id, g11); \
|
||||
return scheme_rtcall_s_s("[" #id "]", src_type, id, g13); \
|
||||
else \
|
||||
return id(g11); \
|
||||
return id(g13); \
|
||||
}
|
||||
#define define_ts_n_s(id, src_type) \
|
||||
static Scheme_Object* ts_ ## id(Scheme_Native_Closure_Data* g12) \
|
||||
static Scheme_Object* ts_ ## id(Scheme_Native_Closure_Data* g14) \
|
||||
XFORM_SKIP_PROC \
|
||||
{ \
|
||||
if (scheme_use_rtcall) \
|
||||
return scheme_rtcall_n_s("[" #id "]", src_type, id, g12); \
|
||||
return scheme_rtcall_n_s("[" #id "]", src_type, id, g14); \
|
||||
else \
|
||||
return id(g12); \
|
||||
return id(g14); \
|
||||
}
|
||||
#define define_ts__s(id, src_type) \
|
||||
static Scheme_Object* ts_ ## id() \
|
||||
|
@ -44,200 +44,200 @@ static Scheme_Object* ts_ ## id() \
|
|||
return id(); \
|
||||
}
|
||||
#define define_ts_ss_s(id, src_type) \
|
||||
static Scheme_Object* ts_ ## id(Scheme_Object* g13, Scheme_Object* g14) \
|
||||
static Scheme_Object* ts_ ## id(Scheme_Object* g15, Scheme_Object* g16) \
|
||||
XFORM_SKIP_PROC \
|
||||
{ \
|
||||
if (scheme_use_rtcall) \
|
||||
return scheme_rtcall_ss_s("[" #id "]", src_type, id, g13, g14); \
|
||||
return scheme_rtcall_ss_s("[" #id "]", src_type, id, g15, g16); \
|
||||
else \
|
||||
return id(g13, g14); \
|
||||
return id(g15, g16); \
|
||||
}
|
||||
#define define_ts_ssi_s(id, src_type) \
|
||||
static Scheme_Object* ts_ ## id(Scheme_Object* g15, Scheme_Object* g16, int g17) \
|
||||
static Scheme_Object* ts_ ## id(Scheme_Object* g17, Scheme_Object* g18, int g19) \
|
||||
XFORM_SKIP_PROC \
|
||||
{ \
|
||||
if (scheme_use_rtcall) \
|
||||
return scheme_rtcall_ssi_s("[" #id "]", src_type, id, g15, g16, g17); \
|
||||
return scheme_rtcall_ssi_s("[" #id "]", src_type, id, g17, g18, g19); \
|
||||
else \
|
||||
return id(g15, g16, g17); \
|
||||
return id(g17, g18, g19); \
|
||||
}
|
||||
#define define_ts_tt_s(id, src_type) \
|
||||
static Scheme_Object* ts_ ## id(const Scheme_Object* g18, const Scheme_Object* g19) \
|
||||
static Scheme_Object* ts_ ## id(const Scheme_Object* g20, const Scheme_Object* g21) \
|
||||
XFORM_SKIP_PROC \
|
||||
{ \
|
||||
if (scheme_use_rtcall) \
|
||||
return scheme_rtcall_tt_s("[" #id "]", src_type, id, g18, g19); \
|
||||
else \
|
||||
return id(g18, g19); \
|
||||
}
|
||||
#define define_ts_ss_m(id, src_type) \
|
||||
static MZ_MARK_STACK_TYPE ts_ ## id(Scheme_Object* g20, Scheme_Object* g21) \
|
||||
XFORM_SKIP_PROC \
|
||||
{ \
|
||||
if (scheme_use_rtcall) \
|
||||
return scheme_rtcall_ss_m("[" #id "]", src_type, id, g20, g21); \
|
||||
return scheme_rtcall_tt_s("[" #id "]", src_type, id, g20, g21); \
|
||||
else \
|
||||
return id(g20, g21); \
|
||||
}
|
||||
#define define_ts_Sl_s(id, src_type) \
|
||||
static Scheme_Object* ts_ ## id(Scheme_Object** g22, intptr_t g23) \
|
||||
#define define_ts_ss_m(id, src_type) \
|
||||
static MZ_MARK_STACK_TYPE ts_ ## id(Scheme_Object* g22, Scheme_Object* g23) \
|
||||
XFORM_SKIP_PROC \
|
||||
{ \
|
||||
if (scheme_use_rtcall) \
|
||||
return scheme_rtcall_Sl_s("[" #id "]", src_type, id, g22, g23); \
|
||||
return scheme_rtcall_ss_m("[" #id "]", src_type, id, g22, g23); \
|
||||
else \
|
||||
return id(g22, g23); \
|
||||
}
|
||||
#define define_ts_l_s(id, src_type) \
|
||||
static Scheme_Object* ts_ ## id(intptr_t g24) \
|
||||
#define define_ts_Sl_s(id, src_type) \
|
||||
static Scheme_Object* ts_ ## id(Scheme_Object** g24, intptr_t g25) \
|
||||
XFORM_SKIP_PROC \
|
||||
{ \
|
||||
if (scheme_use_rtcall) \
|
||||
return scheme_rtcall_l_s("[" #id "]", src_type, id, g24); \
|
||||
return scheme_rtcall_Sl_s("[" #id "]", src_type, id, g24, g25); \
|
||||
else \
|
||||
return id(g24); \
|
||||
return id(g24, g25); \
|
||||
}
|
||||
#define define_ts_l_s(id, src_type) \
|
||||
static Scheme_Object* ts_ ## id(intptr_t g26) \
|
||||
XFORM_SKIP_PROC \
|
||||
{ \
|
||||
if (scheme_use_rtcall) \
|
||||
return scheme_rtcall_l_s("[" #id "]", src_type, id, g26); \
|
||||
else \
|
||||
return id(g26); \
|
||||
}
|
||||
#define define_ts_bsi_v(id, src_type) \
|
||||
static void ts_ ## id(Scheme_Bucket* g25, Scheme_Object* g26, int g27) \
|
||||
static void ts_ ## id(Scheme_Bucket* g27, Scheme_Object* g28, int g29) \
|
||||
XFORM_SKIP_PROC \
|
||||
{ \
|
||||
if (scheme_use_rtcall) \
|
||||
scheme_rtcall_bsi_v("[" #id "]", src_type, id, g25, g26, g27); \
|
||||
scheme_rtcall_bsi_v("[" #id "]", src_type, id, g27, g28, g29); \
|
||||
else \
|
||||
id(g25, g26, g27); \
|
||||
id(g27, g28, g29); \
|
||||
}
|
||||
#define define_ts_iiS_v(id, src_type) \
|
||||
static void ts_ ## id(int g28, int g29, Scheme_Object** g30) \
|
||||
static void ts_ ## id(int g30, int g31, Scheme_Object** g32) \
|
||||
XFORM_SKIP_PROC \
|
||||
{ \
|
||||
if (scheme_use_rtcall) \
|
||||
scheme_rtcall_iiS_v("[" #id "]", src_type, id, g28, g29, g30); \
|
||||
scheme_rtcall_iiS_v("[" #id "]", src_type, id, g30, g31, g32); \
|
||||
else \
|
||||
id(g28, g29, g30); \
|
||||
id(g30, g31, g32); \
|
||||
}
|
||||
#define define_ts_ss_v(id, src_type) \
|
||||
static void ts_ ## id(Scheme_Object* g31, Scheme_Object* g32) \
|
||||
static void ts_ ## id(Scheme_Object* g33, Scheme_Object* g34) \
|
||||
XFORM_SKIP_PROC \
|
||||
{ \
|
||||
if (scheme_use_rtcall) \
|
||||
scheme_rtcall_ss_v("[" #id "]", src_type, id, g31, g32); \
|
||||
scheme_rtcall_ss_v("[" #id "]", src_type, id, g33, g34); \
|
||||
else \
|
||||
id(g31, g32); \
|
||||
id(g33, g34); \
|
||||
}
|
||||
#define define_ts_b_v(id, src_type) \
|
||||
static void ts_ ## id(Scheme_Bucket* g33) \
|
||||
static void ts_ ## id(Scheme_Bucket* g35) \
|
||||
XFORM_SKIP_PROC \
|
||||
{ \
|
||||
if (scheme_use_rtcall) \
|
||||
scheme_rtcall_b_v("[" #id "]", src_type, id, g33); \
|
||||
scheme_rtcall_b_v("[" #id "]", src_type, id, g35); \
|
||||
else \
|
||||
id(g33); \
|
||||
id(g35); \
|
||||
}
|
||||
#define define_ts_sl_s(id, src_type) \
|
||||
static Scheme_Object* ts_ ## id(Scheme_Object* g34, intptr_t g35) \
|
||||
static Scheme_Object* ts_ ## id(Scheme_Object* g36, intptr_t g37) \
|
||||
XFORM_SKIP_PROC \
|
||||
{ \
|
||||
if (scheme_use_rtcall) \
|
||||
return scheme_rtcall_sl_s("[" #id "]", src_type, id, g34, g35); \
|
||||
else \
|
||||
return id(g34, g35); \
|
||||
}
|
||||
#define define_ts_iS_s(id, src_type) \
|
||||
static Scheme_Object* ts_ ## id(int g36, Scheme_Object** g37) \
|
||||
XFORM_SKIP_PROC \
|
||||
{ \
|
||||
if (scheme_use_rtcall) \
|
||||
return scheme_rtcall_iS_s("[" #id "]", src_type, id, g36, g37); \
|
||||
return scheme_rtcall_sl_s("[" #id "]", src_type, id, g36, g37); \
|
||||
else \
|
||||
return id(g36, g37); \
|
||||
}
|
||||
#define define_ts_S_s(id, src_type) \
|
||||
static Scheme_Object* ts_ ## id(Scheme_Object** g38) \
|
||||
#define define_ts_iS_s(id, src_type) \
|
||||
static Scheme_Object* ts_ ## id(int g38, Scheme_Object** g39) \
|
||||
XFORM_SKIP_PROC \
|
||||
{ \
|
||||
if (scheme_use_rtcall) \
|
||||
return scheme_rtcall_S_s("[" #id "]", src_type, id, g38); \
|
||||
return scheme_rtcall_iS_s("[" #id "]", src_type, id, g38, g39); \
|
||||
else \
|
||||
return id(g38); \
|
||||
return id(g38, g39); \
|
||||
}
|
||||
#define define_ts_S_s(id, src_type) \
|
||||
static Scheme_Object* ts_ ## id(Scheme_Object** g40) \
|
||||
XFORM_SKIP_PROC \
|
||||
{ \
|
||||
if (scheme_use_rtcall) \
|
||||
return scheme_rtcall_S_s("[" #id "]", src_type, id, g40); \
|
||||
else \
|
||||
return id(g40); \
|
||||
}
|
||||
#define define_ts_s_v(id, src_type) \
|
||||
static void ts_ ## id(Scheme_Object* g39) \
|
||||
static void ts_ ## id(Scheme_Object* g41) \
|
||||
XFORM_SKIP_PROC \
|
||||
{ \
|
||||
if (scheme_use_rtcall) \
|
||||
scheme_rtcall_s_v("[" #id "]", src_type, id, g39); \
|
||||
scheme_rtcall_s_v("[" #id "]", src_type, id, g41); \
|
||||
else \
|
||||
id(g39); \
|
||||
id(g41); \
|
||||
}
|
||||
#define define_ts_iSi_s(id, src_type) \
|
||||
static Scheme_Object* ts_ ## id(int g40, Scheme_Object** g41, int g42) \
|
||||
static Scheme_Object* ts_ ## id(int g42, Scheme_Object** g43, int g44) \
|
||||
XFORM_SKIP_PROC \
|
||||
{ \
|
||||
if (scheme_use_rtcall) \
|
||||
return scheme_rtcall_iSi_s("[" #id "]", src_type, id, g40, g41, g42); \
|
||||
return scheme_rtcall_iSi_s("[" #id "]", src_type, id, g42, g43, g44); \
|
||||
else \
|
||||
return id(g40, g41, g42); \
|
||||
return id(g42, g43, g44); \
|
||||
}
|
||||
#define define_ts_siS_v(id, src_type) \
|
||||
static void ts_ ## id(Scheme_Object* g43, int g44, Scheme_Object** g45) \
|
||||
static void ts_ ## id(Scheme_Object* g45, int g46, Scheme_Object** g47) \
|
||||
XFORM_SKIP_PROC \
|
||||
{ \
|
||||
if (scheme_use_rtcall) \
|
||||
scheme_rtcall_siS_v("[" #id "]", src_type, id, g43, g44, g45); \
|
||||
scheme_rtcall_siS_v("[" #id "]", src_type, id, g45, g46, g47); \
|
||||
else \
|
||||
id(g43, g44, g45); \
|
||||
id(g45, g46, g47); \
|
||||
}
|
||||
#define define_ts_z_p(id, src_type) \
|
||||
static void* ts_ ## id(size_t g46) \
|
||||
static void* ts_ ## id(size_t g48) \
|
||||
XFORM_SKIP_PROC \
|
||||
{ \
|
||||
if (scheme_use_rtcall) \
|
||||
return scheme_rtcall_z_p("[" #id "]", src_type, id, g46); \
|
||||
return scheme_rtcall_z_p("[" #id "]", src_type, id, g48); \
|
||||
else \
|
||||
return id(g46); \
|
||||
return id(g48); \
|
||||
}
|
||||
#define define_ts_si_s(id, src_type) \
|
||||
static Scheme_Object* ts_ ## id(Scheme_Object* g47, int g48) \
|
||||
static Scheme_Object* ts_ ## id(Scheme_Object* g49, int g50) \
|
||||
XFORM_SKIP_PROC \
|
||||
{ \
|
||||
if (scheme_use_rtcall) \
|
||||
return scheme_rtcall_si_s("[" #id "]", src_type, id, g47, g48); \
|
||||
return scheme_rtcall_si_s("[" #id "]", src_type, id, g49, g50); \
|
||||
else \
|
||||
return id(g47, g48); \
|
||||
return id(g49, g50); \
|
||||
}
|
||||
#define define_ts_sis_v(id, src_type) \
|
||||
static void ts_ ## id(Scheme_Object* g49, int g50, Scheme_Object* g51) \
|
||||
static void ts_ ## id(Scheme_Object* g51, int g52, Scheme_Object* g53) \
|
||||
XFORM_SKIP_PROC \
|
||||
{ \
|
||||
if (scheme_use_rtcall) \
|
||||
scheme_rtcall_sis_v("[" #id "]", src_type, id, g49, g50, g51); \
|
||||
scheme_rtcall_sis_v("[" #id "]", src_type, id, g51, g52, g53); \
|
||||
else \
|
||||
id(g49, g50, g51); \
|
||||
id(g51, g52, g53); \
|
||||
}
|
||||
#define define_ts_ss_i(id, src_type) \
|
||||
static int ts_ ## id(Scheme_Object* g52, Scheme_Object* g53) \
|
||||
static int ts_ ## id(Scheme_Object* g54, Scheme_Object* g55) \
|
||||
XFORM_SKIP_PROC \
|
||||
{ \
|
||||
if (scheme_use_rtcall) \
|
||||
return scheme_rtcall_ss_i("[" #id "]", src_type, id, g52, g53); \
|
||||
return scheme_rtcall_ss_i("[" #id "]", src_type, id, g54, g55); \
|
||||
else \
|
||||
return id(g52, g53); \
|
||||
return id(g54, g55); \
|
||||
}
|
||||
#define define_ts_iSp_v(id, src_type) \
|
||||
static void ts_ ## id(int g54, Scheme_Object** g55, void* g56) \
|
||||
static void ts_ ## id(int g56, Scheme_Object** g57, void* g58) \
|
||||
XFORM_SKIP_PROC \
|
||||
{ \
|
||||
if (scheme_use_rtcall) \
|
||||
scheme_rtcall_iSp_v("[" #id "]", src_type, id, g54, g55, g56); \
|
||||
scheme_rtcall_iSp_v("[" #id "]", src_type, id, g56, g57, g58); \
|
||||
else \
|
||||
id(g54, g55, g56); \
|
||||
id(g56, g57, g58); \
|
||||
}
|
||||
#define define_ts_sss_s(id, src_type) \
|
||||
static Scheme_Object* ts_ ## id(Scheme_Object* g57, Scheme_Object* g58, Scheme_Object* g59) \
|
||||
static Scheme_Object* ts_ ## id(Scheme_Object* g59, Scheme_Object* g60, Scheme_Object* g61) \
|
||||
XFORM_SKIP_PROC \
|
||||
{ \
|
||||
if (scheme_use_rtcall) \
|
||||
return scheme_rtcall_sss_s("[" #id "]", src_type, id, g57, g58, g59); \
|
||||
return scheme_rtcall_sss_s("[" #id "]", src_type, id, g59, g60, g61); \
|
||||
else \
|
||||
return id(g57, g58, g59); \
|
||||
return id(g59, g60, g61); \
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
Scheme_Object* scheme_rtcall_siS_s(const char *who, int src_type, prim_siS_s f, Scheme_Object* g60, int g61, Scheme_Object** g62)
|
||||
Scheme_Object* scheme_rtcall_siS_s(const char *who, int src_type, prim_siS_s f, Scheme_Object* g62, int g63, Scheme_Object** g64)
|
||||
XFORM_SKIP_PROC
|
||||
{
|
||||
Scheme_Future_Thread_State *fts = scheme_future_thread_state;
|
||||
|
@ -13,11 +13,11 @@
|
|||
future->time_of_request = tm;
|
||||
future->source_of_request = who;
|
||||
future->source_type = src_type;
|
||||
future->arg_s0 = g60;
|
||||
future->arg_i1 = g61;
|
||||
future->arg_S2 = g62;
|
||||
future->arg_s0 = g62;
|
||||
future->arg_i1 = g63;
|
||||
future->arg_S2 = g64;
|
||||
|
||||
future_do_runtimecall(fts, (void*)f, 0, 1);
|
||||
future_do_runtimecall(fts, (void*)f, 0, 1, 0);
|
||||
fts->thread = scheme_current_thread;
|
||||
future = fts->thread->current_ft;
|
||||
retval = future->retval_s;
|
||||
|
@ -25,7 +25,7 @@
|
|||
receive_special_result(future, retval, 1);
|
||||
return retval;
|
||||
}
|
||||
Scheme_Object* scheme_rtcall_iSs_s(const char *who, int src_type, prim_iSs_s f, int g63, Scheme_Object** g64, Scheme_Object* g65)
|
||||
Scheme_Object* scheme_rtcall_iSs_s(const char *who, int src_type, prim_iSs_s f, int g65, Scheme_Object** g66, Scheme_Object* g67)
|
||||
XFORM_SKIP_PROC
|
||||
{
|
||||
Scheme_Future_Thread_State *fts = scheme_future_thread_state;
|
||||
|
@ -40,11 +40,11 @@
|
|||
future->time_of_request = tm;
|
||||
future->source_of_request = who;
|
||||
future->source_type = src_type;
|
||||
future->arg_i0 = g63;
|
||||
future->arg_S1 = g64;
|
||||
future->arg_s2 = g65;
|
||||
future->arg_i0 = g65;
|
||||
future->arg_S1 = g66;
|
||||
future->arg_s2 = g67;
|
||||
|
||||
future_do_runtimecall(fts, (void*)f, 0, 1);
|
||||
future_do_runtimecall(fts, (void*)f, 0, 1, 0);
|
||||
fts->thread = scheme_current_thread;
|
||||
future = fts->thread->current_ft;
|
||||
retval = future->retval_s;
|
||||
|
@ -52,7 +52,7 @@
|
|||
receive_special_result(future, retval, 1);
|
||||
return retval;
|
||||
}
|
||||
Scheme_Object* scheme_rtcall_s_s(const char *who, int src_type, prim_s_s f, Scheme_Object* g66)
|
||||
Scheme_Object* scheme_rtcall_s_s(const char *who, int src_type, prim_s_s f, Scheme_Object* g68)
|
||||
XFORM_SKIP_PROC
|
||||
{
|
||||
Scheme_Future_Thread_State *fts = scheme_future_thread_state;
|
||||
|
@ -67,9 +67,9 @@
|
|||
future->time_of_request = tm;
|
||||
future->source_of_request = who;
|
||||
future->source_type = src_type;
|
||||
future->arg_s0 = g66;
|
||||
send_special_result(future, g66);
|
||||
future_do_runtimecall(fts, (void*)f, 0, 1);
|
||||
future->arg_s0 = g68;
|
||||
send_special_result(future, g68);
|
||||
future_do_runtimecall(fts, (void*)f, 0, 1, 0);
|
||||
fts->thread = scheme_current_thread;
|
||||
future = fts->thread->current_ft;
|
||||
retval = future->retval_s;
|
||||
|
@ -77,7 +77,7 @@
|
|||
receive_special_result(future, retval, 1);
|
||||
return retval;
|
||||
}
|
||||
Scheme_Object* scheme_rtcall_n_s(const char *who, int src_type, prim_n_s f, Scheme_Native_Closure_Data* g67)
|
||||
Scheme_Object* scheme_rtcall_n_s(const char *who, int src_type, prim_n_s f, Scheme_Native_Closure_Data* g69)
|
||||
XFORM_SKIP_PROC
|
||||
{
|
||||
Scheme_Future_Thread_State *fts = scheme_future_thread_state;
|
||||
|
@ -92,9 +92,9 @@
|
|||
future->time_of_request = tm;
|
||||
future->source_of_request = who;
|
||||
future->source_type = src_type;
|
||||
future->arg_n0 = g67;
|
||||
future->arg_n0 = g69;
|
||||
|
||||
future_do_runtimecall(fts, (void*)f, 0, 1);
|
||||
future_do_runtimecall(fts, (void*)f, 0, 1, 0);
|
||||
fts->thread = scheme_current_thread;
|
||||
future = fts->thread->current_ft;
|
||||
retval = future->retval_s;
|
||||
|
@ -119,7 +119,7 @@
|
|||
future->source_type = src_type;
|
||||
|
||||
|
||||
future_do_runtimecall(fts, (void*)f, 0, 1);
|
||||
future_do_runtimecall(fts, (void*)f, 0, 1, 0);
|
||||
fts->thread = scheme_current_thread;
|
||||
future = fts->thread->current_ft;
|
||||
retval = future->retval_s;
|
||||
|
@ -127,7 +127,7 @@
|
|||
receive_special_result(future, retval, 1);
|
||||
return retval;
|
||||
}
|
||||
Scheme_Object* scheme_rtcall_ss_s(const char *who, int src_type, prim_ss_s f, Scheme_Object* g68, Scheme_Object* g69)
|
||||
Scheme_Object* scheme_rtcall_ss_s(const char *who, int src_type, prim_ss_s f, Scheme_Object* g70, Scheme_Object* g71)
|
||||
XFORM_SKIP_PROC
|
||||
{
|
||||
Scheme_Future_Thread_State *fts = scheme_future_thread_state;
|
||||
|
@ -142,10 +142,10 @@
|
|||
future->time_of_request = tm;
|
||||
future->source_of_request = who;
|
||||
future->source_type = src_type;
|
||||
future->arg_s0 = g68;
|
||||
future->arg_s1 = g69;
|
||||
future->arg_s0 = g70;
|
||||
future->arg_s1 = g71;
|
||||
|
||||
future_do_runtimecall(fts, (void*)f, 0, 1);
|
||||
future_do_runtimecall(fts, (void*)f, 0, 1, 0);
|
||||
fts->thread = scheme_current_thread;
|
||||
future = fts->thread->current_ft;
|
||||
retval = future->retval_s;
|
||||
|
@ -153,7 +153,7 @@
|
|||
receive_special_result(future, retval, 1);
|
||||
return retval;
|
||||
}
|
||||
Scheme_Object* scheme_rtcall_ssi_s(const char *who, int src_type, prim_ssi_s f, Scheme_Object* g70, Scheme_Object* g71, int g72)
|
||||
Scheme_Object* scheme_rtcall_ssi_s(const char *who, int src_type, prim_ssi_s f, Scheme_Object* g72, Scheme_Object* g73, int g74)
|
||||
XFORM_SKIP_PROC
|
||||
{
|
||||
Scheme_Future_Thread_State *fts = scheme_future_thread_state;
|
||||
|
@ -168,11 +168,11 @@
|
|||
future->time_of_request = tm;
|
||||
future->source_of_request = who;
|
||||
future->source_type = src_type;
|
||||
future->arg_s0 = g70;
|
||||
future->arg_s1 = g71;
|
||||
future->arg_i2 = g72;
|
||||
future->arg_s0 = g72;
|
||||
future->arg_s1 = g73;
|
||||
future->arg_i2 = g74;
|
||||
|
||||
future_do_runtimecall(fts, (void*)f, 0, 1);
|
||||
future_do_runtimecall(fts, (void*)f, 0, 1, 0);
|
||||
fts->thread = scheme_current_thread;
|
||||
future = fts->thread->current_ft;
|
||||
retval = future->retval_s;
|
||||
|
@ -180,7 +180,7 @@
|
|||
receive_special_result(future, retval, 1);
|
||||
return retval;
|
||||
}
|
||||
Scheme_Object* scheme_rtcall_tt_s(const char *who, int src_type, prim_tt_s f, const Scheme_Object* g73, const Scheme_Object* g74)
|
||||
Scheme_Object* scheme_rtcall_tt_s(const char *who, int src_type, prim_tt_s f, const Scheme_Object* g75, const Scheme_Object* g76)
|
||||
XFORM_SKIP_PROC
|
||||
{
|
||||
Scheme_Future_Thread_State *fts = scheme_future_thread_state;
|
||||
|
@ -195,10 +195,10 @@
|
|||
future->time_of_request = tm;
|
||||
future->source_of_request = who;
|
||||
future->source_type = src_type;
|
||||
future->arg_t0 = g73;
|
||||
future->arg_t1 = g74;
|
||||
future->arg_t0 = g75;
|
||||
future->arg_t1 = g76;
|
||||
|
||||
future_do_runtimecall(fts, (void*)f, 0, 1);
|
||||
future_do_runtimecall(fts, (void*)f, 0, 1, 0);
|
||||
fts->thread = scheme_current_thread;
|
||||
future = fts->thread->current_ft;
|
||||
retval = future->retval_s;
|
||||
|
@ -206,7 +206,7 @@
|
|||
receive_special_result(future, retval, 1);
|
||||
return retval;
|
||||
}
|
||||
MZ_MARK_STACK_TYPE scheme_rtcall_ss_m(const char *who, int src_type, prim_ss_m f, Scheme_Object* g75, Scheme_Object* g76)
|
||||
MZ_MARK_STACK_TYPE scheme_rtcall_ss_m(const char *who, int src_type, prim_ss_m f, Scheme_Object* g77, Scheme_Object* g78)
|
||||
XFORM_SKIP_PROC
|
||||
{
|
||||
Scheme_Future_Thread_State *fts = scheme_future_thread_state;
|
||||
|
@ -221,10 +221,10 @@
|
|||
future->time_of_request = tm;
|
||||
future->source_of_request = who;
|
||||
future->source_type = src_type;
|
||||
future->arg_s0 = g75;
|
||||
future->arg_s1 = g76;
|
||||
future->arg_s0 = g77;
|
||||
future->arg_s1 = g78;
|
||||
|
||||
future_do_runtimecall(fts, (void*)f, 0, 1);
|
||||
future_do_runtimecall(fts, (void*)f, 0, 1, 0);
|
||||
fts->thread = scheme_current_thread;
|
||||
future = fts->thread->current_ft;
|
||||
retval = future->retval_m;
|
||||
|
@ -232,7 +232,7 @@
|
|||
|
||||
return retval;
|
||||
}
|
||||
Scheme_Object* scheme_rtcall_Sl_s(const char *who, int src_type, prim_Sl_s f, Scheme_Object** g77, intptr_t g78)
|
||||
Scheme_Object* scheme_rtcall_Sl_s(const char *who, int src_type, prim_Sl_s f, Scheme_Object** g79, intptr_t g80)
|
||||
XFORM_SKIP_PROC
|
||||
{
|
||||
Scheme_Future_Thread_State *fts = scheme_future_thread_state;
|
||||
|
@ -247,10 +247,10 @@
|
|||
future->time_of_request = tm;
|
||||
future->source_of_request = who;
|
||||
future->source_type = src_type;
|
||||
future->arg_S0 = g77;
|
||||
future->arg_l1 = g78;
|
||||
future->arg_S0 = g79;
|
||||
future->arg_l1 = g80;
|
||||
|
||||
future_do_runtimecall(fts, (void*)f, 0, 1);
|
||||
future_do_runtimecall(fts, (void*)f, 0, 1, 0);
|
||||
fts->thread = scheme_current_thread;
|
||||
future = fts->thread->current_ft;
|
||||
retval = future->retval_s;
|
||||
|
@ -258,7 +258,7 @@
|
|||
receive_special_result(future, retval, 1);
|
||||
return retval;
|
||||
}
|
||||
Scheme_Object* scheme_rtcall_l_s(const char *who, int src_type, prim_l_s f, intptr_t g79)
|
||||
Scheme_Object* scheme_rtcall_l_s(const char *who, int src_type, prim_l_s f, intptr_t g81)
|
||||
XFORM_SKIP_PROC
|
||||
{
|
||||
Scheme_Future_Thread_State *fts = scheme_future_thread_state;
|
||||
|
@ -273,9 +273,9 @@
|
|||
future->time_of_request = tm;
|
||||
future->source_of_request = who;
|
||||
future->source_type = src_type;
|
||||
future->arg_l0 = g79;
|
||||
future->arg_l0 = g81;
|
||||
|
||||
future_do_runtimecall(fts, (void*)f, 0, 1);
|
||||
future_do_runtimecall(fts, (void*)f, 0, 1, 0);
|
||||
fts->thread = scheme_current_thread;
|
||||
future = fts->thread->current_ft;
|
||||
retval = future->retval_s;
|
||||
|
@ -283,7 +283,7 @@
|
|||
receive_special_result(future, retval, 1);
|
||||
return retval;
|
||||
}
|
||||
void scheme_rtcall_bsi_v(const char *who, int src_type, prim_bsi_v f, Scheme_Bucket* g80, Scheme_Object* g81, int g82)
|
||||
void scheme_rtcall_bsi_v(const char *who, int src_type, prim_bsi_v f, Scheme_Bucket* g82, Scheme_Object* g83, int g84)
|
||||
XFORM_SKIP_PROC
|
||||
{
|
||||
Scheme_Future_Thread_State *fts = scheme_future_thread_state;
|
||||
|
@ -298,11 +298,11 @@
|
|||
future->time_of_request = tm;
|
||||
future->source_of_request = who;
|
||||
future->source_type = src_type;
|
||||
future->arg_b0 = g80;
|
||||
future->arg_s1 = g81;
|
||||
future->arg_i2 = g82;
|
||||
future->arg_b0 = g82;
|
||||
future->arg_s1 = g83;
|
||||
future->arg_i2 = g84;
|
||||
|
||||
future_do_runtimecall(fts, (void*)f, 0, 1);
|
||||
future_do_runtimecall(fts, (void*)f, 0, 1, 0);
|
||||
fts->thread = scheme_current_thread;
|
||||
future = fts->thread->current_ft;
|
||||
|
||||
|
@ -310,7 +310,7 @@
|
|||
|
||||
|
||||
}
|
||||
void scheme_rtcall_iiS_v(const char *who, int src_type, prim_iiS_v f, int g83, int g84, Scheme_Object** g85)
|
||||
void scheme_rtcall_iiS_v(const char *who, int src_type, prim_iiS_v f, int g85, int g86, Scheme_Object** g87)
|
||||
XFORM_SKIP_PROC
|
||||
{
|
||||
Scheme_Future_Thread_State *fts = scheme_future_thread_state;
|
||||
|
@ -325,11 +325,11 @@
|
|||
future->time_of_request = tm;
|
||||
future->source_of_request = who;
|
||||
future->source_type = src_type;
|
||||
future->arg_i0 = g83;
|
||||
future->arg_i1 = g84;
|
||||
future->arg_S2 = g85;
|
||||
future->arg_i0 = g85;
|
||||
future->arg_i1 = g86;
|
||||
future->arg_S2 = g87;
|
||||
|
||||
future_do_runtimecall(fts, (void*)f, 0, 1);
|
||||
future_do_runtimecall(fts, (void*)f, 0, 1, 0);
|
||||
fts->thread = scheme_current_thread;
|
||||
future = fts->thread->current_ft;
|
||||
|
||||
|
@ -337,7 +337,7 @@
|
|||
|
||||
|
||||
}
|
||||
void scheme_rtcall_ss_v(const char *who, int src_type, prim_ss_v f, Scheme_Object* g86, Scheme_Object* g87)
|
||||
void scheme_rtcall_ss_v(const char *who, int src_type, prim_ss_v f, Scheme_Object* g88, Scheme_Object* g89)
|
||||
XFORM_SKIP_PROC
|
||||
{
|
||||
Scheme_Future_Thread_State *fts = scheme_future_thread_state;
|
||||
|
@ -352,10 +352,10 @@
|
|||
future->time_of_request = tm;
|
||||
future->source_of_request = who;
|
||||
future->source_type = src_type;
|
||||
future->arg_s0 = g86;
|
||||
future->arg_s1 = g87;
|
||||
future->arg_s0 = g88;
|
||||
future->arg_s1 = g89;
|
||||
|
||||
future_do_runtimecall(fts, (void*)f, 0, 1);
|
||||
future_do_runtimecall(fts, (void*)f, 0, 1, 0);
|
||||
fts->thread = scheme_current_thread;
|
||||
future = fts->thread->current_ft;
|
||||
|
||||
|
@ -363,7 +363,7 @@
|
|||
|
||||
|
||||
}
|
||||
void scheme_rtcall_b_v(const char *who, int src_type, prim_b_v f, Scheme_Bucket* g88)
|
||||
void scheme_rtcall_b_v(const char *who, int src_type, prim_b_v f, Scheme_Bucket* g90)
|
||||
XFORM_SKIP_PROC
|
||||
{
|
||||
Scheme_Future_Thread_State *fts = scheme_future_thread_state;
|
||||
|
@ -378,9 +378,9 @@
|
|||
future->time_of_request = tm;
|
||||
future->source_of_request = who;
|
||||
future->source_type = src_type;
|
||||
future->arg_b0 = g88;
|
||||
future->arg_b0 = g90;
|
||||
|
||||
future_do_runtimecall(fts, (void*)f, 0, 1);
|
||||
future_do_runtimecall(fts, (void*)f, 0, 1, 0);
|
||||
fts->thread = scheme_current_thread;
|
||||
future = fts->thread->current_ft;
|
||||
|
||||
|
@ -388,7 +388,7 @@
|
|||
|
||||
|
||||
}
|
||||
Scheme_Object* scheme_rtcall_sl_s(const char *who, int src_type, prim_sl_s f, Scheme_Object* g89, intptr_t g90)
|
||||
Scheme_Object* scheme_rtcall_sl_s(const char *who, int src_type, prim_sl_s f, Scheme_Object* g91, intptr_t g92)
|
||||
XFORM_SKIP_PROC
|
||||
{
|
||||
Scheme_Future_Thread_State *fts = scheme_future_thread_state;
|
||||
|
@ -403,10 +403,10 @@
|
|||
future->time_of_request = tm;
|
||||
future->source_of_request = who;
|
||||
future->source_type = src_type;
|
||||
future->arg_s0 = g89;
|
||||
future->arg_l1 = g90;
|
||||
future->arg_s0 = g91;
|
||||
future->arg_l1 = g92;
|
||||
|
||||
future_do_runtimecall(fts, (void*)f, 0, 1);
|
||||
future_do_runtimecall(fts, (void*)f, 0, 1, 0);
|
||||
fts->thread = scheme_current_thread;
|
||||
future = fts->thread->current_ft;
|
||||
retval = future->retval_s;
|
||||
|
@ -414,7 +414,7 @@
|
|||
receive_special_result(future, retval, 1);
|
||||
return retval;
|
||||
}
|
||||
Scheme_Object* scheme_rtcall_iS_s(const char *who, int src_type, prim_iS_s f, int g91, Scheme_Object** g92)
|
||||
Scheme_Object* scheme_rtcall_iS_s(const char *who, int src_type, prim_iS_s f, int g93, Scheme_Object** g94)
|
||||
XFORM_SKIP_PROC
|
||||
{
|
||||
Scheme_Future_Thread_State *fts = scheme_future_thread_state;
|
||||
|
@ -429,10 +429,10 @@
|
|||
future->time_of_request = tm;
|
||||
future->source_of_request = who;
|
||||
future->source_type = src_type;
|
||||
future->arg_i0 = g91;
|
||||
future->arg_S1 = g92;
|
||||
future->arg_i0 = g93;
|
||||
future->arg_S1 = g94;
|
||||
|
||||
future_do_runtimecall(fts, (void*)f, 0, 1);
|
||||
future_do_runtimecall(fts, (void*)f, 0, 1, 0);
|
||||
fts->thread = scheme_current_thread;
|
||||
future = fts->thread->current_ft;
|
||||
retval = future->retval_s;
|
||||
|
@ -440,7 +440,7 @@
|
|||
receive_special_result(future, retval, 1);
|
||||
return retval;
|
||||
}
|
||||
Scheme_Object* scheme_rtcall_S_s(const char *who, int src_type, prim_S_s f, Scheme_Object** g93)
|
||||
Scheme_Object* scheme_rtcall_S_s(const char *who, int src_type, prim_S_s f, Scheme_Object** g95)
|
||||
XFORM_SKIP_PROC
|
||||
{
|
||||
Scheme_Future_Thread_State *fts = scheme_future_thread_state;
|
||||
|
@ -455,9 +455,9 @@
|
|||
future->time_of_request = tm;
|
||||
future->source_of_request = who;
|
||||
future->source_type = src_type;
|
||||
future->arg_S0 = g93;
|
||||
future->arg_S0 = g95;
|
||||
|
||||
future_do_runtimecall(fts, (void*)f, 0, 1);
|
||||
future_do_runtimecall(fts, (void*)f, 0, 1, 0);
|
||||
fts->thread = scheme_current_thread;
|
||||
future = fts->thread->current_ft;
|
||||
retval = future->retval_s;
|
||||
|
@ -465,7 +465,7 @@
|
|||
receive_special_result(future, retval, 1);
|
||||
return retval;
|
||||
}
|
||||
void scheme_rtcall_s_v(const char *who, int src_type, prim_s_v f, Scheme_Object* g94)
|
||||
void scheme_rtcall_s_v(const char *who, int src_type, prim_s_v f, Scheme_Object* g96)
|
||||
XFORM_SKIP_PROC
|
||||
{
|
||||
Scheme_Future_Thread_State *fts = scheme_future_thread_state;
|
||||
|
@ -480,9 +480,9 @@
|
|||
future->time_of_request = tm;
|
||||
future->source_of_request = who;
|
||||
future->source_type = src_type;
|
||||
future->arg_s0 = g94;
|
||||
send_special_result(future, g94);
|
||||
future_do_runtimecall(fts, (void*)f, 0, 1);
|
||||
future->arg_s0 = g96;
|
||||
send_special_result(future, g96);
|
||||
future_do_runtimecall(fts, (void*)f, 0, 1, 0);
|
||||
fts->thread = scheme_current_thread;
|
||||
future = fts->thread->current_ft;
|
||||
|
||||
|
@ -490,7 +490,7 @@
|
|||
|
||||
|
||||
}
|
||||
Scheme_Object* scheme_rtcall_iSi_s(const char *who, int src_type, prim_iSi_s f, int g95, Scheme_Object** g96, int g97)
|
||||
Scheme_Object* scheme_rtcall_iSi_s(const char *who, int src_type, prim_iSi_s f, int g97, Scheme_Object** g98, int g99)
|
||||
XFORM_SKIP_PROC
|
||||
{
|
||||
Scheme_Future_Thread_State *fts = scheme_future_thread_state;
|
||||
|
@ -505,11 +505,11 @@
|
|||
future->time_of_request = tm;
|
||||
future->source_of_request = who;
|
||||
future->source_type = src_type;
|
||||
future->arg_i0 = g95;
|
||||
future->arg_S1 = g96;
|
||||
future->arg_i2 = g97;
|
||||
future->arg_i0 = g97;
|
||||
future->arg_S1 = g98;
|
||||
future->arg_i2 = g99;
|
||||
|
||||
future_do_runtimecall(fts, (void*)f, 0, 1);
|
||||
future_do_runtimecall(fts, (void*)f, 0, 1, 0);
|
||||
fts->thread = scheme_current_thread;
|
||||
future = fts->thread->current_ft;
|
||||
retval = future->retval_s;
|
||||
|
@ -517,7 +517,7 @@
|
|||
receive_special_result(future, retval, 1);
|
||||
return retval;
|
||||
}
|
||||
void scheme_rtcall_siS_v(const char *who, int src_type, prim_siS_v f, Scheme_Object* g98, int g99, Scheme_Object** g100)
|
||||
void scheme_rtcall_siS_v(const char *who, int src_type, prim_siS_v f, Scheme_Object* g100, int g101, Scheme_Object** g102)
|
||||
XFORM_SKIP_PROC
|
||||
{
|
||||
Scheme_Future_Thread_State *fts = scheme_future_thread_state;
|
||||
|
@ -532,11 +532,11 @@
|
|||
future->time_of_request = tm;
|
||||
future->source_of_request = who;
|
||||
future->source_type = src_type;
|
||||
future->arg_s0 = g98;
|
||||
future->arg_i1 = g99;
|
||||
future->arg_S2 = g100;
|
||||
future->arg_s0 = g100;
|
||||
future->arg_i1 = g101;
|
||||
future->arg_S2 = g102;
|
||||
|
||||
future_do_runtimecall(fts, (void*)f, 0, 1);
|
||||
future_do_runtimecall(fts, (void*)f, 0, 1, 0);
|
||||
fts->thread = scheme_current_thread;
|
||||
future = fts->thread->current_ft;
|
||||
|
||||
|
@ -544,7 +544,7 @@
|
|||
|
||||
|
||||
}
|
||||
void* scheme_rtcall_z_p(const char *who, int src_type, prim_z_p f, size_t g101)
|
||||
void* scheme_rtcall_z_p(const char *who, int src_type, prim_z_p f, size_t g103)
|
||||
XFORM_SKIP_PROC
|
||||
{
|
||||
Scheme_Future_Thread_State *fts = scheme_future_thread_state;
|
||||
|
@ -559,9 +559,9 @@
|
|||
future->time_of_request = tm;
|
||||
future->source_of_request = who;
|
||||
future->source_type = src_type;
|
||||
future->arg_z0 = g101;
|
||||
future->arg_z0 = g103;
|
||||
|
||||
future_do_runtimecall(fts, (void*)f, 0, 1);
|
||||
future_do_runtimecall(fts, (void*)f, 0, 1, 0);
|
||||
fts->thread = scheme_current_thread;
|
||||
future = fts->thread->current_ft;
|
||||
retval = future->retval_p;
|
||||
|
@ -569,7 +569,7 @@
|
|||
|
||||
return retval;
|
||||
}
|
||||
Scheme_Object* scheme_rtcall_si_s(const char *who, int src_type, prim_si_s f, Scheme_Object* g102, int g103)
|
||||
Scheme_Object* scheme_rtcall_si_s(const char *who, int src_type, prim_si_s f, Scheme_Object* g104, int g105)
|
||||
XFORM_SKIP_PROC
|
||||
{
|
||||
Scheme_Future_Thread_State *fts = scheme_future_thread_state;
|
||||
|
@ -584,10 +584,10 @@
|
|||
future->time_of_request = tm;
|
||||
future->source_of_request = who;
|
||||
future->source_type = src_type;
|
||||
future->arg_s0 = g102;
|
||||
future->arg_i1 = g103;
|
||||
future->arg_s0 = g104;
|
||||
future->arg_i1 = g105;
|
||||
|
||||
future_do_runtimecall(fts, (void*)f, 0, 1);
|
||||
future_do_runtimecall(fts, (void*)f, 0, 1, 0);
|
||||
fts->thread = scheme_current_thread;
|
||||
future = fts->thread->current_ft;
|
||||
retval = future->retval_s;
|
||||
|
@ -595,7 +595,7 @@
|
|||
receive_special_result(future, retval, 1);
|
||||
return retval;
|
||||
}
|
||||
void scheme_rtcall_sis_v(const char *who, int src_type, prim_sis_v f, Scheme_Object* g104, int g105, Scheme_Object* g106)
|
||||
void scheme_rtcall_sis_v(const char *who, int src_type, prim_sis_v f, Scheme_Object* g106, int g107, Scheme_Object* g108)
|
||||
XFORM_SKIP_PROC
|
||||
{
|
||||
Scheme_Future_Thread_State *fts = scheme_future_thread_state;
|
||||
|
@ -610,11 +610,11 @@
|
|||
future->time_of_request = tm;
|
||||
future->source_of_request = who;
|
||||
future->source_type = src_type;
|
||||
future->arg_s0 = g104;
|
||||
future->arg_i1 = g105;
|
||||
future->arg_s2 = g106;
|
||||
future->arg_s0 = g106;
|
||||
future->arg_i1 = g107;
|
||||
future->arg_s2 = g108;
|
||||
|
||||
future_do_runtimecall(fts, (void*)f, 0, 1);
|
||||
future_do_runtimecall(fts, (void*)f, 0, 1, 0);
|
||||
fts->thread = scheme_current_thread;
|
||||
future = fts->thread->current_ft;
|
||||
|
||||
|
@ -622,7 +622,7 @@
|
|||
|
||||
|
||||
}
|
||||
int scheme_rtcall_ss_i(const char *who, int src_type, prim_ss_i f, Scheme_Object* g107, Scheme_Object* g108)
|
||||
int scheme_rtcall_ss_i(const char *who, int src_type, prim_ss_i f, Scheme_Object* g109, Scheme_Object* g110)
|
||||
XFORM_SKIP_PROC
|
||||
{
|
||||
Scheme_Future_Thread_State *fts = scheme_future_thread_state;
|
||||
|
@ -637,10 +637,10 @@
|
|||
future->time_of_request = tm;
|
||||
future->source_of_request = who;
|
||||
future->source_type = src_type;
|
||||
future->arg_s0 = g107;
|
||||
future->arg_s1 = g108;
|
||||
future->arg_s0 = g109;
|
||||
future->arg_s1 = g110;
|
||||
|
||||
future_do_runtimecall(fts, (void*)f, 0, 1);
|
||||
future_do_runtimecall(fts, (void*)f, 0, 1, 0);
|
||||
fts->thread = scheme_current_thread;
|
||||
future = fts->thread->current_ft;
|
||||
retval = future->retval_i;
|
||||
|
@ -648,7 +648,7 @@
|
|||
|
||||
return retval;
|
||||
}
|
||||
void scheme_rtcall_iSp_v(const char *who, int src_type, prim_iSp_v f, int g109, Scheme_Object** g110, void* g111)
|
||||
void scheme_rtcall_iSp_v(const char *who, int src_type, prim_iSp_v f, int g111, Scheme_Object** g112, void* g113)
|
||||
XFORM_SKIP_PROC
|
||||
{
|
||||
Scheme_Future_Thread_State *fts = scheme_future_thread_state;
|
||||
|
@ -663,11 +663,11 @@
|
|||
future->time_of_request = tm;
|
||||
future->source_of_request = who;
|
||||
future->source_type = src_type;
|
||||
future->arg_i0 = g109;
|
||||
future->arg_S1 = g110;
|
||||
future->arg_p2 = g111;
|
||||
future->arg_i0 = g111;
|
||||
future->arg_S1 = g112;
|
||||
future->arg_p2 = g113;
|
||||
|
||||
future_do_runtimecall(fts, (void*)f, 0, 1);
|
||||
future_do_runtimecall(fts, (void*)f, 0, 1, 0);
|
||||
fts->thread = scheme_current_thread;
|
||||
future = fts->thread->current_ft;
|
||||
|
||||
|
@ -675,7 +675,7 @@
|
|||
|
||||
|
||||
}
|
||||
Scheme_Object* scheme_rtcall_sss_s(const char *who, int src_type, prim_sss_s f, Scheme_Object* g112, Scheme_Object* g113, Scheme_Object* g114)
|
||||
Scheme_Object* scheme_rtcall_sss_s(const char *who, int src_type, prim_sss_s f, Scheme_Object* g114, Scheme_Object* g115, Scheme_Object* g116)
|
||||
XFORM_SKIP_PROC
|
||||
{
|
||||
Scheme_Future_Thread_State *fts = scheme_future_thread_state;
|
||||
|
@ -690,11 +690,11 @@
|
|||
future->time_of_request = tm;
|
||||
future->source_of_request = who;
|
||||
future->source_type = src_type;
|
||||
future->arg_s0 = g112;
|
||||
future->arg_s1 = g113;
|
||||
future->arg_s2 = g114;
|
||||
future->arg_s0 = g114;
|
||||
future->arg_s1 = g115;
|
||||
future->arg_s2 = g116;
|
||||
|
||||
future_do_runtimecall(fts, (void*)f, 0, 1);
|
||||
future_do_runtimecall(fts, (void*)f, 0, 1, 0);
|
||||
fts->thread = scheme_current_thread;
|
||||
future = fts->thread->current_ft;
|
||||
retval = future->retval_s;
|
||||
|
|
|
@ -1,81 +1,81 @@
|
|||
#define SIG_siS_s 10
|
||||
typedef Scheme_Object* (*prim_siS_s)(Scheme_Object*, int, Scheme_Object**);
|
||||
Scheme_Object* scheme_rtcall_siS_s(const char *who, int src_type, prim_siS_s f, Scheme_Object* g170, int g171, Scheme_Object** g172);
|
||||
Scheme_Object* scheme_rtcall_siS_s(const char *who, int src_type, prim_siS_s f, Scheme_Object* g172, int g173, Scheme_Object** g174);
|
||||
#define SIG_iSs_s 11
|
||||
typedef Scheme_Object* (*prim_iSs_s)(int, Scheme_Object**, Scheme_Object*);
|
||||
Scheme_Object* scheme_rtcall_iSs_s(const char *who, int src_type, prim_iSs_s f, int g173, Scheme_Object** g174, Scheme_Object* g175);
|
||||
Scheme_Object* scheme_rtcall_iSs_s(const char *who, int src_type, prim_iSs_s f, int g175, Scheme_Object** g176, Scheme_Object* g177);
|
||||
#define SIG_s_s 12
|
||||
typedef Scheme_Object* (*prim_s_s)(Scheme_Object*);
|
||||
Scheme_Object* scheme_rtcall_s_s(const char *who, int src_type, prim_s_s f, Scheme_Object* g176);
|
||||
Scheme_Object* scheme_rtcall_s_s(const char *who, int src_type, prim_s_s f, Scheme_Object* g178);
|
||||
#define SIG_n_s 13
|
||||
typedef Scheme_Object* (*prim_n_s)(Scheme_Native_Closure_Data*);
|
||||
Scheme_Object* scheme_rtcall_n_s(const char *who, int src_type, prim_n_s f, Scheme_Native_Closure_Data* g177);
|
||||
Scheme_Object* scheme_rtcall_n_s(const char *who, int src_type, prim_n_s f, Scheme_Native_Closure_Data* g179);
|
||||
#define SIG__s 14
|
||||
typedef Scheme_Object* (*prim__s)();
|
||||
Scheme_Object* scheme_rtcall__s(const char *who, int src_type, prim__s f );
|
||||
#define SIG_ss_s 15
|
||||
typedef Scheme_Object* (*prim_ss_s)(Scheme_Object*, Scheme_Object*);
|
||||
Scheme_Object* scheme_rtcall_ss_s(const char *who, int src_type, prim_ss_s f, Scheme_Object* g178, Scheme_Object* g179);
|
||||
Scheme_Object* scheme_rtcall_ss_s(const char *who, int src_type, prim_ss_s f, Scheme_Object* g180, Scheme_Object* g181);
|
||||
#define SIG_ssi_s 16
|
||||
typedef Scheme_Object* (*prim_ssi_s)(Scheme_Object*, Scheme_Object*, int);
|
||||
Scheme_Object* scheme_rtcall_ssi_s(const char *who, int src_type, prim_ssi_s f, Scheme_Object* g180, Scheme_Object* g181, int g182);
|
||||
Scheme_Object* scheme_rtcall_ssi_s(const char *who, int src_type, prim_ssi_s f, Scheme_Object* g182, Scheme_Object* g183, int g184);
|
||||
#define SIG_tt_s 17
|
||||
typedef Scheme_Object* (*prim_tt_s)(const Scheme_Object*, const Scheme_Object*);
|
||||
Scheme_Object* scheme_rtcall_tt_s(const char *who, int src_type, prim_tt_s f, const Scheme_Object* g183, const Scheme_Object* g184);
|
||||
Scheme_Object* scheme_rtcall_tt_s(const char *who, int src_type, prim_tt_s f, const Scheme_Object* g185, const Scheme_Object* g186);
|
||||
#define SIG_ss_m 18
|
||||
typedef MZ_MARK_STACK_TYPE (*prim_ss_m)(Scheme_Object*, Scheme_Object*);
|
||||
MZ_MARK_STACK_TYPE scheme_rtcall_ss_m(const char *who, int src_type, prim_ss_m f, Scheme_Object* g185, Scheme_Object* g186);
|
||||
MZ_MARK_STACK_TYPE scheme_rtcall_ss_m(const char *who, int src_type, prim_ss_m f, Scheme_Object* g187, Scheme_Object* g188);
|
||||
#define SIG_Sl_s 19
|
||||
typedef Scheme_Object* (*prim_Sl_s)(Scheme_Object**, intptr_t);
|
||||
Scheme_Object* scheme_rtcall_Sl_s(const char *who, int src_type, prim_Sl_s f, Scheme_Object** g187, intptr_t g188);
|
||||
Scheme_Object* scheme_rtcall_Sl_s(const char *who, int src_type, prim_Sl_s f, Scheme_Object** g189, intptr_t g190);
|
||||
#define SIG_l_s 20
|
||||
typedef Scheme_Object* (*prim_l_s)(intptr_t);
|
||||
Scheme_Object* scheme_rtcall_l_s(const char *who, int src_type, prim_l_s f, intptr_t g189);
|
||||
Scheme_Object* scheme_rtcall_l_s(const char *who, int src_type, prim_l_s f, intptr_t g191);
|
||||
#define SIG_bsi_v 21
|
||||
typedef void (*prim_bsi_v)(Scheme_Bucket*, Scheme_Object*, int);
|
||||
void scheme_rtcall_bsi_v(const char *who, int src_type, prim_bsi_v f, Scheme_Bucket* g190, Scheme_Object* g191, int g192);
|
||||
void scheme_rtcall_bsi_v(const char *who, int src_type, prim_bsi_v f, Scheme_Bucket* g192, Scheme_Object* g193, int g194);
|
||||
#define SIG_iiS_v 22
|
||||
typedef void (*prim_iiS_v)(int, int, Scheme_Object**);
|
||||
void scheme_rtcall_iiS_v(const char *who, int src_type, prim_iiS_v f, int g193, int g194, Scheme_Object** g195);
|
||||
void scheme_rtcall_iiS_v(const char *who, int src_type, prim_iiS_v f, int g195, int g196, Scheme_Object** g197);
|
||||
#define SIG_ss_v 23
|
||||
typedef void (*prim_ss_v)(Scheme_Object*, Scheme_Object*);
|
||||
void scheme_rtcall_ss_v(const char *who, int src_type, prim_ss_v f, Scheme_Object* g196, Scheme_Object* g197);
|
||||
void scheme_rtcall_ss_v(const char *who, int src_type, prim_ss_v f, Scheme_Object* g198, Scheme_Object* g199);
|
||||
#define SIG_b_v 24
|
||||
typedef void (*prim_b_v)(Scheme_Bucket*);
|
||||
void scheme_rtcall_b_v(const char *who, int src_type, prim_b_v f, Scheme_Bucket* g198);
|
||||
void scheme_rtcall_b_v(const char *who, int src_type, prim_b_v f, Scheme_Bucket* g200);
|
||||
#define SIG_sl_s 25
|
||||
typedef Scheme_Object* (*prim_sl_s)(Scheme_Object*, intptr_t);
|
||||
Scheme_Object* scheme_rtcall_sl_s(const char *who, int src_type, prim_sl_s f, Scheme_Object* g199, intptr_t g200);
|
||||
Scheme_Object* scheme_rtcall_sl_s(const char *who, int src_type, prim_sl_s f, Scheme_Object* g201, intptr_t g202);
|
||||
#define SIG_iS_s 26
|
||||
typedef Scheme_Object* (*prim_iS_s)(int, Scheme_Object**);
|
||||
Scheme_Object* scheme_rtcall_iS_s(const char *who, int src_type, prim_iS_s f, int g201, Scheme_Object** g202);
|
||||
Scheme_Object* scheme_rtcall_iS_s(const char *who, int src_type, prim_iS_s f, int g203, Scheme_Object** g204);
|
||||
#define SIG_S_s 27
|
||||
typedef Scheme_Object* (*prim_S_s)(Scheme_Object**);
|
||||
Scheme_Object* scheme_rtcall_S_s(const char *who, int src_type, prim_S_s f, Scheme_Object** g203);
|
||||
Scheme_Object* scheme_rtcall_S_s(const char *who, int src_type, prim_S_s f, Scheme_Object** g205);
|
||||
#define SIG_s_v 28
|
||||
typedef void (*prim_s_v)(Scheme_Object*);
|
||||
void scheme_rtcall_s_v(const char *who, int src_type, prim_s_v f, Scheme_Object* g204);
|
||||
void scheme_rtcall_s_v(const char *who, int src_type, prim_s_v f, Scheme_Object* g206);
|
||||
#define SIG_iSi_s 29
|
||||
typedef Scheme_Object* (*prim_iSi_s)(int, Scheme_Object**, int);
|
||||
Scheme_Object* scheme_rtcall_iSi_s(const char *who, int src_type, prim_iSi_s f, int g205, Scheme_Object** g206, int g207);
|
||||
Scheme_Object* scheme_rtcall_iSi_s(const char *who, int src_type, prim_iSi_s f, int g207, Scheme_Object** g208, int g209);
|
||||
#define SIG_siS_v 30
|
||||
typedef void (*prim_siS_v)(Scheme_Object*, int, Scheme_Object**);
|
||||
void scheme_rtcall_siS_v(const char *who, int src_type, prim_siS_v f, Scheme_Object* g208, int g209, Scheme_Object** g210);
|
||||
void scheme_rtcall_siS_v(const char *who, int src_type, prim_siS_v f, Scheme_Object* g210, int g211, Scheme_Object** g212);
|
||||
#define SIG_z_p 31
|
||||
typedef void* (*prim_z_p)(size_t);
|
||||
void* scheme_rtcall_z_p(const char *who, int src_type, prim_z_p f, size_t g211);
|
||||
void* scheme_rtcall_z_p(const char *who, int src_type, prim_z_p f, size_t g213);
|
||||
#define SIG_si_s 32
|
||||
typedef Scheme_Object* (*prim_si_s)(Scheme_Object*, int);
|
||||
Scheme_Object* scheme_rtcall_si_s(const char *who, int src_type, prim_si_s f, Scheme_Object* g212, int g213);
|
||||
Scheme_Object* scheme_rtcall_si_s(const char *who, int src_type, prim_si_s f, Scheme_Object* g214, int g215);
|
||||
#define SIG_sis_v 33
|
||||
typedef void (*prim_sis_v)(Scheme_Object*, int, Scheme_Object*);
|
||||
void scheme_rtcall_sis_v(const char *who, int src_type, prim_sis_v f, Scheme_Object* g214, int g215, Scheme_Object* g216);
|
||||
void scheme_rtcall_sis_v(const char *who, int src_type, prim_sis_v f, Scheme_Object* g216, int g217, Scheme_Object* g218);
|
||||
#define SIG_ss_i 34
|
||||
typedef int (*prim_ss_i)(Scheme_Object*, Scheme_Object*);
|
||||
int scheme_rtcall_ss_i(const char *who, int src_type, prim_ss_i f, Scheme_Object* g217, Scheme_Object* g218);
|
||||
int scheme_rtcall_ss_i(const char *who, int src_type, prim_ss_i f, Scheme_Object* g219, Scheme_Object* g220);
|
||||
#define SIG_iSp_v 35
|
||||
typedef void (*prim_iSp_v)(int, Scheme_Object**, void*);
|
||||
void scheme_rtcall_iSp_v(const char *who, int src_type, prim_iSp_v f, int g219, Scheme_Object** g220, void* g221);
|
||||
void scheme_rtcall_iSp_v(const char *who, int src_type, prim_iSp_v f, int g221, Scheme_Object** g222, void* g223);
|
||||
#define SIG_sss_s 36
|
||||
typedef Scheme_Object* (*prim_sss_s)(Scheme_Object*, Scheme_Object*, Scheme_Object*);
|
||||
Scheme_Object* scheme_rtcall_sss_s(const char *who, int src_type, prim_sss_s f, Scheme_Object* g222, Scheme_Object* g223, Scheme_Object* g224);
|
||||
Scheme_Object* scheme_rtcall_sss_s(const char *who, int src_type, prim_sss_s f, Scheme_Object* g224, Scheme_Object* g225, Scheme_Object* g226);
|
||||
|
|
|
@ -199,6 +199,45 @@ static Scheme_Object *_scheme_tail_apply_from_native_fixup_args(Scheme_Object *r
|
|||
return ts__scheme_tail_apply_from_native(rator, argc + already, base);
|
||||
}
|
||||
|
||||
#if defined(MZ_USE_FUTURES) && defined(MZ_PRECISE_GC)
|
||||
|
||||
static Scheme_Object *try_future_local_stack_overflow(Scheme_Object *rator, int argc, Scheme_Object **argv, int multi)
|
||||
XFORM_SKIP_PROC
|
||||
{
|
||||
if (SAME_TYPE(SCHEME_TYPE(rator), scheme_native_closure_type)
|
||||
&& scheme_can_apply_native_in_future(rator)) {
|
||||
/* the only reason to get here is stack overflow,
|
||||
either for the runstack or C stack */
|
||||
return scheme_rtcall_apply_with_new_stack(rator, argc, argv, multi);
|
||||
} else if (multi)
|
||||
return ts__scheme_apply_multi_from_native(rator, argc, argv);
|
||||
else
|
||||
return ts__scheme_apply_from_native(rator, argc, argv);
|
||||
}
|
||||
|
||||
static Scheme_Object *x_ts__scheme_apply_multi_from_native(Scheme_Object *rator, int argc, Scheme_Object **argv)
|
||||
XFORM_SKIP_PROC
|
||||
{
|
||||
if (scheme_use_rtcall)
|
||||
return try_future_local_stack_overflow(rator, argc, argv, 1);
|
||||
else
|
||||
return _scheme_apply_multi_from_native(rator, argc, argv);
|
||||
}
|
||||
|
||||
static Scheme_Object *x_ts__scheme_apply_from_native(Scheme_Object *rator, int argc, Scheme_Object **argv)
|
||||
XFORM_SKIP_PROC
|
||||
{
|
||||
if (scheme_use_rtcall)
|
||||
return try_future_local_stack_overflow(rator, argc, argv, 0);
|
||||
else
|
||||
return _scheme_apply_from_native(rator, argc, argv);
|
||||
}
|
||||
|
||||
#else
|
||||
# define x_ts__scheme_apply_multi_from_native ts__scheme_apply_multi_from_native
|
||||
# define x_ts__scheme_apply_from_native ts__scheme_apply_from_native
|
||||
#endif
|
||||
|
||||
static int generate_pause_for_gc_and_retry(mz_jit_state *jitter,
|
||||
int in_short_jumps,
|
||||
int gc_reg, /* must not be JIT_R1 */
|
||||
|
@ -913,9 +952,9 @@ int scheme_generate_non_tail_call(mz_jit_state *jitter, int num_rands, int direc
|
|||
jit_pusharg_p(JIT_V1);
|
||||
if (num_rands < 0) { jit_movr_p(JIT_V1, JIT_R0); } /* save argc to manually pop runstack */
|
||||
if (multi_ok) {
|
||||
(void)mz_finish_lwe(ts__scheme_apply_multi_from_native, refrts);
|
||||
(void)mz_finish_lwe(x_ts__scheme_apply_multi_from_native, refrts);
|
||||
} else {
|
||||
(void)mz_finish_lwe(ts__scheme_apply_from_native, refrts);
|
||||
(void)mz_finish_lwe(x_ts__scheme_apply_from_native, refrts);
|
||||
}
|
||||
CHECK_LIMIT();
|
||||
mz_patch_ucbranch(ref5);
|
||||
|
|
|
@ -33,6 +33,7 @@ static int future_MARK(void *p, struct NewGC *gc) {
|
|||
gcMARK2(f->next_waiting_lwc, gc);
|
||||
gcMARK2(f->next_waiting_touch, gc);
|
||||
gcMARK2(f->suspended_lw, gc);
|
||||
gcMARK2(f->suspended_lw_stack, gc);
|
||||
gcMARK2(f->prev_in_fsema_queue, gc);
|
||||
gcMARK2(f->next_in_fsema_queue, gc);
|
||||
gcMARK2(f->touching, gc);
|
||||
|
@ -66,6 +67,7 @@ static int future_FIXUP(void *p, struct NewGC *gc) {
|
|||
gcFIXUP2(f->next_waiting_lwc, gc);
|
||||
gcFIXUP2(f->next_waiting_touch, gc);
|
||||
gcFIXUP2(f->suspended_lw, gc);
|
||||
gcFIXUP2(f->suspended_lw_stack, gc);
|
||||
gcFIXUP2(f->prev_in_fsema_queue, gc);
|
||||
gcFIXUP2(f->next_in_fsema_queue, gc);
|
||||
gcFIXUP2(f->touching, gc);
|
||||
|
|
|
@ -2474,6 +2474,7 @@ future {
|
|||
gcMARK2(f->next_waiting_lwc, gc);
|
||||
gcMARK2(f->next_waiting_touch, gc);
|
||||
gcMARK2(f->suspended_lw, gc);
|
||||
gcMARK2(f->suspended_lw_stack, gc);
|
||||
gcMARK2(f->prev_in_fsema_queue, gc);
|
||||
gcMARK2(f->next_in_fsema_queue, gc);
|
||||
gcMARK2(f->touching, gc);
|
||||
|
|
|
@ -2457,6 +2457,8 @@ Scheme_Object *scheme_apply_lightweight_continuation(Scheme_Lightweight_Continua
|
|||
Scheme_Object **scheme_adjust_runstack_argument(Scheme_Lightweight_Continuation *captured,
|
||||
Scheme_Object **arg);
|
||||
|
||||
Scheme_Lightweight_Continuation *scheme_restore_lightweight_continuation_marks(Scheme_Lightweight_Continuation *lw);
|
||||
|
||||
int scheme_can_apply_lightweight_continuation(Scheme_Lightweight_Continuation *captured,
|
||||
int check_overflow);
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user