fix check for on-demand JITting

svn: r16892
This commit is contained in:
Matthew Flatt 2009-11-19 16:12:04 +00:00
parent a2ad57e732
commit a88c481b02
4 changed files with 27 additions and 14 deletions

View File

@ -50,7 +50,7 @@ void scheme_init_futures(Scheme_Env *env)
extern void *on_demand_jit_code; extern void *on_demand_jit_code;
#define THREAD_POOL_SIZE 1 #define THREAD_POOL_SIZE 7
#define INITIAL_C_STACK_SIZE 500000 #define INITIAL_C_STACK_SIZE 500000
static pthread_t g_pool_threads[THREAD_POOL_SIZE]; static pthread_t g_pool_threads[THREAD_POOL_SIZE];
static int *g_fuel_pointers[THREAD_POOL_SIZE]; static int *g_fuel_pointers[THREAD_POOL_SIZE];
@ -103,7 +103,7 @@ THREAD_LOCAL_DECL(static future_t *current_ft);
#ifndef UNIT_TEST #ifndef UNIT_TEST
static void *worker_thread_future_loop(void *arg); static void *worker_thread_future_loop(void *arg);
static void invoke_rtcall(future_t *future); static void invoke_rtcall(future_t *future);
static future_t *enqueue_future(void); static future_t *enqueue_future(future_t *ft);;
static future_t *get_pending_future(void); static future_t *get_pending_future(void);
static future_t *get_my_future(void); static future_t *get_my_future(void);
static future_t *get_last_future(void); static future_t *get_last_future(void);
@ -455,8 +455,9 @@ Scheme_Object *future(int argc, Scheme_Object *argv[])
ncd = nc->code; ncd = nc->code;
//Create the future descriptor and add to the queue as 'pending' //Create the future descriptor and add to the queue as 'pending'
pthread_mutex_lock(&g_future_queue_mutex); ft = MALLOC_ONE_TAGGED(future_t);
ft = enqueue_future(); ft->so.type = scheme_future_type;
futureid = ++g_next_futureid; futureid = ++g_next_futureid;
ft->id = futureid; ft->id = futureid;
ft->orig_lambda = lambda; ft->orig_lambda = lambda;
@ -479,8 +480,6 @@ Scheme_Object *future(int argc, Scheme_Object *argv[])
ft->runstack_size = init_runstack_size; ft->runstack_size = init_runstack_size;
} }
//pthread_mutex_unlock(&g_future_queue_mutex);
//JIT compile the code if not already jitted //JIT compile the code if not already jitted
//Temporarily repoint MZ_RUNSTACK //Temporarily repoint MZ_RUNSTACK
//to the worker thread's runstack - //to the worker thread's runstack -
@ -491,9 +490,10 @@ Scheme_Object *future(int argc, Scheme_Object *argv[])
scheme_on_demand_generate_lambda(nc, 0, NULL); scheme_on_demand_generate_lambda(nc, 0, NULL);
} }
//pthread_mutex_lock(&g_future_queue_mutex);
ft->code = (void*)ncd->code; ft->code = (void*)ncd->code;
pthread_mutex_lock(&g_future_queue_mutex);
enqueue_future(ft);
//Signal that a future is pending //Signal that a future is pending
pthread_cond_signal(&g_future_pending_cv); pthread_cond_signal(&g_future_pending_cv);
pthread_mutex_unlock(&g_future_queue_mutex); pthread_mutex_unlock(&g_future_queue_mutex);
@ -683,6 +683,8 @@ void *worker_thread_future_loop(void *arg)
//Work is available for this thread //Work is available for this thread
ft->status = RUNNING; ft->status = RUNNING;
pthread_mutex_unlock(&g_future_queue_mutex);
ft->threadid = pthread_self(); ft->threadid = pthread_self();
//Decrement the number of available pool threads //Decrement the number of available pool threads
@ -697,7 +699,6 @@ void *worker_thread_future_loop(void *arg)
scheme_jit_fill_threadlocal_table(); scheme_jit_fill_threadlocal_table();
jitcode = (Scheme_Object* (*)(Scheme_Object*, int, Scheme_Object**))(ft->code); jitcode = (Scheme_Object* (*)(Scheme_Object*, int, Scheme_Object**))(ft->code);
pthread_mutex_unlock(&g_future_queue_mutex);
current_ft = ft; current_ft = ft;
@ -738,6 +739,15 @@ void *worker_thread_future_loop(void *arg)
END_XFORM_SKIP; END_XFORM_SKIP;
} }
void scheme_check_future_work()
/* Called in the runtime thread by the scheduler */
{
/* Check for work that future threads need from the runtime thread
and that can be done in any Scheme thread (e.g., get a new page
for allocation). */
}
//Returns 0 if the call isn't actually executed by this function, //Returns 0 if the call isn't actually executed by this function,
//i.e. if we are already running on the runtime thread. Otherwise returns //i.e. if we are already running on the runtime thread. Otherwise returns
@ -1146,13 +1156,11 @@ void invoke_rtcall(future_t *future)
/* Helpers for manipulating the futures queue */ /* Helpers for manipulating the futures queue */
/**********************************************************************/ /**********************************************************************/
future_t *enqueue_future(void) future_t *enqueue_future(future_t *ft)
/* Called in runtime thread */ /* Called in runtime thread */
{ {
future_t *last, *ft; future_t *last;
last = get_last_future(); last = get_last_future();
ft = MALLOC_ONE_TAGGED(future_t);
ft->so.type = scheme_future_type;
if (NULL == last) if (NULL == last)
{ {
g_future_queue = ft; g_future_queue = ft;

View File

@ -242,7 +242,7 @@ extern int rtcall_int_pobj_obj(
void scheme_future_block_until_gc(); void scheme_future_block_until_gc();
void scheme_future_continue_after_gc(); void scheme_future_continue_after_gc();
void scheme_check_future_work();
#ifdef UNIT_TEST #ifdef UNIT_TEST
//These forwarding decls only need to be here to make //These forwarding decls only need to be here to make

View File

@ -9511,7 +9511,8 @@ static void on_demand_with_args(Scheme_Object **in_argv)
argc = in_argv[1]; argc = in_argv[1];
argv = (Scheme_Object **)in_argv[2]; argv = (Scheme_Object **)in_argv[2];
scheme_on_demand_generate_lambda((Scheme_Native_Closure *)c, SCHEME_INT_VAL(argc), argv); if (((Scheme_Native_Closure *)c)->code->code == on_demand_jit_code)
scheme_on_demand_generate_lambda((Scheme_Native_Closure *)c, SCHEME_INT_VAL(argc), argv);
} }
static void on_demand() static void on_demand()

View File

@ -4107,6 +4107,10 @@ void scheme_thread_block(float sleep_time)
/* Check scheduled_kills early and often. */ /* Check scheduled_kills early and often. */
check_scheduled_kills(); check_scheduled_kills();
#ifdef FUTURES_ENABLED
scheme_check_future_work();
#endif
if (!do_atomic && (sleep_end >= 0.0)) { if (!do_atomic && (sleep_end >= 0.0)) {
find_next_thread(&next); find_next_thread(&next);
} else } else