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