more futures fixes
svn: r16874
This commit is contained in:
parent
54f5c14657
commit
da1a171ebe
|
@ -621,14 +621,13 @@ void *worker_thread_future_loop(void *arg)
|
|||
sema_signal(&ready_sema);
|
||||
|
||||
wait_for_work:
|
||||
//LOG("Waiting for new future work...");
|
||||
start_gc_not_ok();
|
||||
start_gc_not_ok();
|
||||
pthread_mutex_lock(&g_future_queue_mutex);
|
||||
while (!(ft = get_pending_future()))
|
||||
{
|
||||
end_gc_not_ok();
|
||||
end_gc_not_ok();
|
||||
pthread_cond_wait(&g_future_pending_cv, &g_future_queue_mutex);
|
||||
start_gc_not_ok();
|
||||
start_gc_not_ok();
|
||||
}
|
||||
|
||||
LOG("Got a signal that a future is pending...");
|
||||
|
@ -690,11 +689,12 @@ void *worker_thread_future_loop(void *arg)
|
|||
//call invocation.
|
||||
int future_do_runtimecall(
|
||||
void *func,
|
||||
int sigtype,
|
||||
void *args,
|
||||
//int sigtype,
|
||||
//void *args,
|
||||
void *retval)
|
||||
{
|
||||
future_t *future;
|
||||
|
||||
//If already running on the main thread
|
||||
//or no future is involved, do nothing
|
||||
//and return FALSE
|
||||
|
@ -726,9 +726,12 @@ int future_do_runtimecall(
|
|||
scheme_signal_received_at(g_signal_handle);
|
||||
|
||||
//Wait for the signal that the RT call is finished
|
||||
start_gc_not_ok();
|
||||
end_gc_not_ok();
|
||||
pthread_cond_wait(&future->can_continue_cv, &g_future_queue_mutex);
|
||||
end_gc_not_ok();
|
||||
start_gc_not_ok();
|
||||
|
||||
//Fetch the future instance again, in case the GC has moved the pointer
|
||||
future = get_my_future();
|
||||
|
||||
//Clear rt call fields before releasing the lock on the descriptor
|
||||
future->rt_prim = NULL;
|
||||
|
@ -753,14 +756,14 @@ int rtcall_void_void(void (*f)())
|
|||
return 0;
|
||||
}
|
||||
|
||||
data.prim_void_void = f;
|
||||
data.void_void = f;
|
||||
data.sigtype = SIG_VOID_VOID;
|
||||
|
||||
future = get_my_future();
|
||||
future->rt_prim = (void*)f;
|
||||
future->prim_data = data;
|
||||
|
||||
future_do_runtimecall((void*)f, SIG_VOID_VOID, NULL, NULL);
|
||||
future_do_runtimecall((void*)f, NULL);
|
||||
|
||||
return 1;
|
||||
END_XFORM_SKIP;
|
||||
|
@ -768,7 +771,7 @@ int rtcall_void_void(void (*f)())
|
|||
|
||||
|
||||
int rtcall_obj_int_pobj_obj(
|
||||
Scheme_Object* (*f)(Scheme_Object*, int, Scheme_Object**),
|
||||
prim_obj_int_pobj_obj_t f,
|
||||
Scheme_Object *rator,
|
||||
int argc,
|
||||
Scheme_Object **argv,
|
||||
|
@ -791,7 +794,7 @@ int rtcall_obj_int_pobj_obj(
|
|||
printf("stack address = %p\n", &future);
|
||||
#endif
|
||||
|
||||
data.prim_obj_int_pobj_obj = f;
|
||||
data.obj_int_pobj_obj = f;
|
||||
data.p = rator;
|
||||
data.argc = argc;
|
||||
data.argv = argv;
|
||||
|
@ -801,7 +804,7 @@ int rtcall_obj_int_pobj_obj(
|
|||
future->rt_prim = (void*)f;
|
||||
future->prim_data = data;
|
||||
|
||||
future_do_runtimecall((void*)f, SIG_OBJ_INT_POBJ_OBJ, NULL, NULL);
|
||||
future_do_runtimecall((void*)f, NULL);
|
||||
*retval = future->prim_data.retval;
|
||||
|
||||
return 1;
|
||||
|
@ -810,7 +813,7 @@ int rtcall_obj_int_pobj_obj(
|
|||
|
||||
|
||||
int rtcall_int_pobj_obj(
|
||||
Scheme_Object* (*f)(int, Scheme_Object**),
|
||||
prim_int_pobj_obj_t f,
|
||||
int argc,
|
||||
Scheme_Object **argv,
|
||||
Scheme_Object **retval)
|
||||
|
@ -832,7 +835,7 @@ int rtcall_int_pobj_obj(
|
|||
printf("stack address = %p\n", &future);
|
||||
#endif
|
||||
|
||||
data.prim_int_pobj_obj = f;
|
||||
data.int_pobj_obj = f;
|
||||
data.argc = argc;
|
||||
data.argv = argv;
|
||||
data.sigtype = SIG_INT_OBJARR_OBJ;
|
||||
|
@ -841,7 +844,7 @@ int rtcall_int_pobj_obj(
|
|||
future->rt_prim = (void*)f;
|
||||
future->prim_data = data;
|
||||
|
||||
future_do_runtimecall((void*)f, SIG_INT_OBJARR_OBJ, NULL, NULL);
|
||||
future_do_runtimecall((void*)f, NULL);
|
||||
*retval = future->prim_data.retval;
|
||||
|
||||
return 1;
|
||||
|
@ -849,8 +852,48 @@ int rtcall_int_pobj_obj(
|
|||
}
|
||||
|
||||
|
||||
int rtcall_pvoid_pvoid_pvoid(
|
||||
prim_pvoid_pvoid_pvoid_t f,
|
||||
void *a,
|
||||
void *b,
|
||||
void **retval)
|
||||
{
|
||||
START_XFORM_SKIP;
|
||||
future_t *future;
|
||||
prim_data_t data;
|
||||
memset(&data, 0, sizeof(prim_data_t));
|
||||
if (!IS_WORKER_THREAD)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_FUTURES
|
||||
printf("scheme_fuel_counter = %d\n", scheme_fuel_counter);
|
||||
printf("scheme_jit_stack_boundary = %p\n", (void*)scheme_jit_stack_boundary);
|
||||
printf("scheme_current_runstack = %p\n", scheme_current_runstack);
|
||||
printf("scheme_current_runstack_start = %p\n", scheme_current_runstack_start);
|
||||
printf("stack address = %p\n", &future);
|
||||
#endif
|
||||
|
||||
data.pvoid_pvoid_pvoid = f;
|
||||
data.a = a;
|
||||
data.b = b;
|
||||
data.sigtype = SIG_PVOID_PVOID_PVOID;
|
||||
|
||||
future = get_my_future();
|
||||
future->rt_prim = (void*)f;
|
||||
future->prim_data = data;
|
||||
|
||||
future_do_runtimecall((void*)f, NULL);
|
||||
*retval = future->prim_data.c;
|
||||
|
||||
return 1;
|
||||
END_XFORM_SKIP;
|
||||
}
|
||||
|
||||
|
||||
int rtcall_int_pobj_obj_obj(
|
||||
Scheme_Object* (*f)(int, Scheme_Object**, Scheme_Object*),
|
||||
prim_int_pobj_obj_obj_t f,
|
||||
int argc,
|
||||
Scheme_Object **argv,
|
||||
Scheme_Object *p,
|
||||
|
@ -873,7 +916,7 @@ int rtcall_int_pobj_obj_obj(
|
|||
printf("stack address = %p\n", &future);
|
||||
#endif
|
||||
|
||||
data.prim_int_pobj_obj_obj = f;
|
||||
data.int_pobj_obj_obj = f;
|
||||
data.argc = argc;
|
||||
data.argv = argv;
|
||||
data.p = p;
|
||||
|
@ -883,26 +926,23 @@ int rtcall_int_pobj_obj_obj(
|
|||
future->rt_prim = (void*)f;
|
||||
future->prim_data = data;
|
||||
|
||||
future_do_runtimecall((void*)f, SIG_INT_POBJ_OBJ_OBJ, NULL, NULL);
|
||||
future_do_runtimecall((void*)f, NULL);
|
||||
*retval = future->prim_data.retval;
|
||||
|
||||
return 1;
|
||||
END_XFORM_SKIP;
|
||||
}
|
||||
|
||||
|
||||
//Does the work of actually invoking a primitive on behalf of a
|
||||
//future. This function is always invoked on the main (runtime)
|
||||
//thread.
|
||||
void *invoke_rtcall(future_t *future)
|
||||
{
|
||||
START_XFORM_SKIP;
|
||||
void *ret = NULL, *dummy_ret;
|
||||
void **arr = NULL;
|
||||
void *pret = NULL, *dummy_ret;
|
||||
prim_data_t *pdata;
|
||||
MZ_MARK_STACK_TYPE lret = 0;
|
||||
|
||||
//Temporarily use the worker thread's runstack
|
||||
Scheme_Object *ret;
|
||||
Scheme_Object **old_rs = MZ_RUNSTACK, **old_rs_start = MZ_RUNSTACK_START;
|
||||
MZ_RUNSTACK = future->runstack;
|
||||
MZ_RUNSTACK_START = future->runstack_start;
|
||||
|
@ -910,48 +950,84 @@ void *invoke_rtcall(future_t *future)
|
|||
g_rtcall_count++;
|
||||
#endif
|
||||
|
||||
pdata = &future->prim_data;
|
||||
switch (future->prim_data.sigtype)
|
||||
{
|
||||
case SIG_VOID_VOID:
|
||||
{
|
||||
pdata = &future->prim_data;
|
||||
pdata->prim_void_void();
|
||||
prim_void_void_t func = pdata->void_void;
|
||||
func();
|
||||
|
||||
ret = &dummy_ret;
|
||||
pret = &dummy_ret;
|
||||
break;
|
||||
}
|
||||
case SIG_OBJ_INT_POBJ_OBJ:
|
||||
{
|
||||
pdata = &future->prim_data;
|
||||
pdata->retval = pdata->prim_obj_int_pobj_obj(
|
||||
prim_obj_int_pobj_obj_t func = pdata->obj_int_pobj_obj;
|
||||
ret = func(
|
||||
pdata->p,
|
||||
pdata->argc,
|
||||
pdata->argv);
|
||||
|
||||
pdata->retval = ret;
|
||||
|
||||
/*pdata->retval = pdata->prim_obj_int_pobj_obj(
|
||||
pdata->p,
|
||||
pdata->argc,
|
||||
pdata->argv); */
|
||||
|
||||
break;
|
||||
}
|
||||
case SIG_INT_OBJARR_OBJ:
|
||||
pdata = &future->prim_data;
|
||||
pdata->retval = pdata->prim_int_pobj_obj(
|
||||
{
|
||||
prim_int_pobj_obj_t func = pdata->int_pobj_obj;
|
||||
ret = func(
|
||||
pdata->argc,
|
||||
pdata->argv);
|
||||
|
||||
pdata->retval = ret;
|
||||
|
||||
/*pdata->retval = pdata->prim_int_pobj_obj(
|
||||
pdata->argc,
|
||||
pdata->argv);
|
||||
|
||||
*/
|
||||
break;
|
||||
}
|
||||
case SIG_INT_POBJ_OBJ_OBJ:
|
||||
pdata = &future->prim_data;
|
||||
pdata->retval = pdata->prim_int_pobj_obj_obj(
|
||||
{
|
||||
prim_int_pobj_obj_obj_t func = pdata->int_pobj_obj_obj;
|
||||
ret = func(
|
||||
pdata->argc,
|
||||
pdata->argv,
|
||||
pdata->p);
|
||||
break;
|
||||
}
|
||||
|
||||
pdata->retval = ret;
|
||||
/*pdata->retval = pdata->prim_int_pobj_obj_obj(
|
||||
pdata->argc,
|
||||
pdata->argv,
|
||||
pdata->p);
|
||||
*/
|
||||
break;
|
||||
}
|
||||
case SIG_PVOID_PVOID_PVOID:
|
||||
{
|
||||
prim_pvoid_pvoid_pvoid_t func = pdata->pvoid_pvoid_pvoid;
|
||||
pret = func(pdata->a, pdata->b);
|
||||
|
||||
pdata->c = pret;
|
||||
/*pdata->c = pdata->prim_pvoid_pvoid_pvoid(
|
||||
pdata->a,
|
||||
pdata->b);
|
||||
*/
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//Restore main thread's runstack
|
||||
MZ_RUNSTACK = old_rs;
|
||||
MZ_RUNSTACK_START = old_rs_start;
|
||||
|
||||
return ret;
|
||||
END_XFORM_SKIP;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -29,22 +29,39 @@ extern Scheme_Object *end_primitive_tracking(int argc, Scheme_Object *argv[]);
|
|||
extern Scheme_Object *future(int argc, Scheme_Object *argv[]);
|
||||
extern Scheme_Object *touch(int argc, Scheme_Object *argv[]);
|
||||
extern Scheme_Object *num_processors(int argc, Scheme_Object *argv[]);
|
||||
extern int future_do_runtimecall(void *func, int sigtype, void *args, void *retval);
|
||||
extern int future_do_runtimecall(void *func, void *retval);
|
||||
extern void futures_init(void);
|
||||
|
||||
typedef void (*prim_void_void_t)(void);
|
||||
typedef Scheme_Object* (*prim_obj_int_pobj_obj_t)(Scheme_Object*, int, Scheme_Object**);
|
||||
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*);
|
||||
|
||||
typedef struct {
|
||||
unsigned int sigtype;
|
||||
|
||||
Scheme_Object* (*prim_obj_int_pobj_obj)(Scheme_Object* rator, int argc, Scheme_Object** argv);
|
||||
Scheme_Object* (*prim_int_pobj_obj)(int argc, Scheme_Object** argv);
|
||||
Scheme_Object* (*prim_int_pobj_obj_obj)(int argc, Scheme_Object** argv, Scheme_Object* p);
|
||||
void (*prim_void_void)(void);
|
||||
prim_void_void_t void_void;
|
||||
prim_obj_int_pobj_obj_t obj_int_pobj_obj;
|
||||
prim_int_pobj_obj_t int_pobj_obj;
|
||||
prim_int_pobj_obj_obj_t int_pobj_obj_obj;
|
||||
prim_pvoid_pvoid_pvoid_t pvoid_pvoid_pvoid;
|
||||
|
||||
//Scheme_Object* (*prim_obj_int_pobj_obj)(Scheme_Object* rator, int argc, Scheme_Object** argv);
|
||||
//Scheme_Object* (*prim_int_pobj_obj)(int argc, Scheme_Object** argv);
|
||||
//Scheme_Object* (*prim_int_pobj_obj_obj)(int argc, Scheme_Object** argv, Scheme_Object* p);
|
||||
//void (*prim_void_void)(void);
|
||||
//void* (*prim_pvoid_pvoid_pvoid)(void *a, void *b);
|
||||
|
||||
Scheme_Object *p;
|
||||
int argc;
|
||||
Scheme_Object **argv;
|
||||
Scheme_Object *retval;
|
||||
|
||||
void *a;
|
||||
void *b;
|
||||
void *c;
|
||||
|
||||
} prim_data_t;
|
||||
|
||||
#define PENDING 0
|
||||
|
@ -135,7 +152,8 @@ extern void print_ms_and_us(void);
|
|||
#define SIG_VOID_VOID 1 //void -> void
|
||||
#define SIG_OBJ_INT_POBJ_OBJ 2 //Scheme_Object* -> int -> Scheme_Object** -> Scheme_Object*
|
||||
#define SIG_INT_OBJARR_OBJ 3 //int -> Scheme_Object*[] -> Scheme_Object
|
||||
#define SIG_INT_POBJ_OBJ_OBJ 17 //int -> Scheme_Object** -> Scheme_Object* -> Scheme_Object*
|
||||
#define SIG_INT_POBJ_OBJ_OBJ 17 //int -> Scheme_Object** -> Scheme_Object* -> Scheme_Object*
|
||||
#define SIG_PVOID_PVOID_PVOID 18 //void* -> void* -> void*
|
||||
|
||||
//Helper macros for argument marshaling
|
||||
#ifdef FUTURES_ENABLED
|
||||
|
|
|
@ -1378,6 +1378,7 @@ static int generate_alloc_retry(mz_jit_state *jitter, int i);
|
|||
THREAD_LOCAL_DECL(static double save_fp);
|
||||
#endif
|
||||
|
||||
|
||||
static void *prepare_retry_alloc(void *p, void *p2)
|
||||
{
|
||||
/* Alocate enough to trigger a new page */
|
||||
|
@ -2233,6 +2234,25 @@ static void ts_on_demand(void)
|
|||
|
||||
on_demand();
|
||||
}
|
||||
|
||||
#ifdef MZ_PRECISE_GC
|
||||
static void *ts_prepare_retry_alloc(void *p, void *p2)
|
||||
{
|
||||
void *ret;
|
||||
LOG_PRIM_START(&prepare_retry_alloc);
|
||||
if (rtcall_pvoid_pvoid_pvoid(prepare_retry_alloc,
|
||||
p,
|
||||
p2,
|
||||
&ret))
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = prepare_retry_alloc(p, p2);
|
||||
LOG_PRIM_END(&prepare_retry_alloc);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
#else
|
||||
/* futures not enabled */
|
||||
# define mz_prepare_direct_prim(n) mz_prepare(n)
|
||||
|
@ -9080,7 +9100,7 @@ static int generate_alloc_retry(mz_jit_state *jitter, int i)
|
|||
jit_pusharg_p(JIT_R0);
|
||||
jit_pusharg_p(JIT_R0);
|
||||
}
|
||||
(void)mz_finish(prepare_retry_alloc);
|
||||
(void)mz_finish(ts_prepare_retry_alloc);
|
||||
jit_retval(JIT_R0);
|
||||
if (i == 1) {
|
||||
mz_tl_ldi_l(JIT_R1, tl_retry_alloc_r1);
|
||||
|
|
Loading…
Reference in New Issue
Block a user