From da1a171ebe2d85d23c16ee8e02b26ef52b48c5c4 Mon Sep 17 00:00:00 2001 From: James Swaine Date: Wed, 18 Nov 2009 17:13:50 +0000 Subject: [PATCH] more futures fixes svn: r16874 --- src/mzscheme/src/future.c | 150 ++++++++++++++++++++++++++++---------- src/mzscheme/src/future.h | 30 ++++++-- src/mzscheme/src/jit.c | 22 +++++- 3 files changed, 158 insertions(+), 44 deletions(-) diff --git a/src/mzscheme/src/future.c b/src/mzscheme/src/future.c index 0c3c629932..cf2c4c58c7 100644 --- a/src/mzscheme/src/future.c +++ b/src/mzscheme/src/future.c @@ -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; } diff --git a/src/mzscheme/src/future.h b/src/mzscheme/src/future.h index a390b343fd..55a17dbbbc 100644 --- a/src/mzscheme/src/future.h +++ b/src/mzscheme/src/future.h @@ -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 diff --git a/src/mzscheme/src/jit.c b/src/mzscheme/src/jit.c index 6d5bcefc41..850ddd55f0 100644 --- a/src/mzscheme/src/jit.c +++ b/src/mzscheme/src/jit.c @@ -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);