write-barrier handling with multiple threads
svn: r16880
This commit is contained in:
parent
f921cf62cc
commit
3b92693146
|
@ -1698,8 +1698,13 @@ static int designate_modified_gc(NewGC *gc, void *p)
|
|||
page->mprotected = 0;
|
||||
vm_protect_pages(page->addr, (page->size_class > 1) ? round_to_apage_size(page->size) : APAGE_SIZE, 1);
|
||||
page->back_pointers = 1;
|
||||
return 1;
|
||||
}
|
||||
/* For a single mutator thread, we shouldn't get here
|
||||
(and a `return 1' in the braces above would make more
|
||||
sense). With multiple mutators, though, two threads might
|
||||
hit the same page at effectively the same time, and only
|
||||
the first one of them will handle the signal. */
|
||||
return 1;
|
||||
} else {
|
||||
if (gc->primoridal_gc) {
|
||||
return designate_modified_gc(gc->primoridal_gc, p);
|
||||
|
|
|
@ -50,7 +50,7 @@ void scheme_init_futures(Scheme_Env *env)
|
|||
|
||||
extern void *on_demand_jit_code;
|
||||
|
||||
#define THREAD_POOL_SIZE 3
|
||||
#define THREAD_POOL_SIZE 1
|
||||
#define INITIAL_C_STACK_SIZE 500000
|
||||
static pthread_t g_pool_threads[THREAD_POOL_SIZE];
|
||||
static int *g_fuel_pointers[THREAD_POOL_SIZE];
|
||||
|
@ -59,6 +59,7 @@ static int g_num_avail_threads = 0;
|
|||
static unsigned long g_cur_cpu_mask = 1;
|
||||
static void *g_signal_handle = NULL;
|
||||
|
||||
static struct NewGC *g_shared_GC;
|
||||
future_t *g_future_queue = NULL;
|
||||
int g_next_futureid = 0;
|
||||
pthread_t g_rt_threadid = 0;
|
||||
|
@ -86,7 +87,7 @@ static void register_traversers(void);
|
|||
extern void scheme_on_demand_generate_lambda(Scheme_Native_Closure *nc, int argc, Scheme_Object **argv);
|
||||
|
||||
static void start_gc_not_ok();
|
||||
static void end_gc_not_ok();
|
||||
static void end_gc_not_ok(future_t *ft);
|
||||
|
||||
THREAD_LOCAL_DECL(static future_t *current_ft);
|
||||
|
||||
|
@ -310,6 +311,7 @@ void futures_init(void)
|
|||
for (i = 0; i < THREAD_POOL_SIZE; i++)
|
||||
{
|
||||
gc_counter_ptr = &scheme_did_gc_count;
|
||||
g_shared_GC = GC;
|
||||
pthread_create(&threadid, &attr, worker_thread_future_loop, &i);
|
||||
sema_wait(&ready_sema);
|
||||
|
||||
|
@ -337,8 +339,14 @@ static void start_gc_not_ok()
|
|||
#endif
|
||||
}
|
||||
|
||||
static void end_gc_not_ok()
|
||||
static void end_gc_not_ok(future_t *ft)
|
||||
{
|
||||
if (ft) {
|
||||
scheme_set_runstack_limits(ft->runstack_start,
|
||||
ft->runstack_size,
|
||||
ft->runstack - ft->runstack_start,
|
||||
ft->runstack_size);
|
||||
}
|
||||
pthread_mutex_lock(&gc_ok_m);
|
||||
--gc_not_ok;
|
||||
pthread_cond_signal(&gc_ok_c);
|
||||
|
@ -465,6 +473,7 @@ Scheme_Object *future(int argc, Scheme_Object *argv[])
|
|||
rs = rs_start XFORM_OK_PLUS init_runstack_size;
|
||||
ft->runstack_start = rs_start;
|
||||
ft->runstack = rs;
|
||||
ft->runstack_size = init_runstack_size;
|
||||
}
|
||||
|
||||
//pthread_mutex_unlock(&g_future_queue_mutex);
|
||||
|
@ -603,6 +612,8 @@ void *worker_thread_future_loop(void *arg)
|
|||
|
||||
scheme_init_os_thread();
|
||||
|
||||
GC = g_shared_GC;
|
||||
|
||||
//Set processor affinity
|
||||
/*pthread_mutex_lock(&g_future_queue_mutex);
|
||||
if (pthread_setaffinity_np(pthread_self(), sizeof(g_cur_cpu_mask), &g_cur_cpu_mask))
|
||||
|
@ -635,7 +646,7 @@ void *worker_thread_future_loop(void *arg)
|
|||
pthread_mutex_lock(&g_future_queue_mutex);
|
||||
while (!(ft = get_pending_future()))
|
||||
{
|
||||
end_gc_not_ok();
|
||||
end_gc_not_ok(NULL);
|
||||
pthread_cond_wait(&g_future_pending_cv, &g_future_queue_mutex);
|
||||
start_gc_not_ok();
|
||||
}
|
||||
|
@ -679,12 +690,15 @@ void *worker_thread_future_loop(void *arg)
|
|||
ft->work_completed = 1;
|
||||
ft->retval = v;
|
||||
|
||||
ft->runstack = NULL;
|
||||
ft->runstack_start = NULL;
|
||||
|
||||
//Update the status
|
||||
ft->status = FINISHED;
|
||||
scheme_signal_received_at(g_signal_handle);
|
||||
pthread_mutex_unlock(&g_future_queue_mutex);
|
||||
|
||||
end_gc_not_ok();
|
||||
end_gc_not_ok(NULL);
|
||||
|
||||
goto wait_for_work;
|
||||
|
||||
|
@ -737,7 +751,7 @@ int future_do_runtimecall(
|
|||
|
||||
//Wait for the signal that the RT call is finished
|
||||
future->can_continue_cv = &worker_can_continue_cv;
|
||||
end_gc_not_ok();
|
||||
end_gc_not_ok(future);
|
||||
pthread_cond_wait(&worker_can_continue_cv, &g_future_queue_mutex);
|
||||
start_gc_not_ok();
|
||||
|
||||
|
|
|
@ -80,6 +80,7 @@ typedef struct future {
|
|||
int work_completed;
|
||||
pthread_cond_t *can_continue_cv;
|
||||
|
||||
long runstack_size;
|
||||
Scheme_Object **runstack;
|
||||
Scheme_Object **runstack_start;
|
||||
Scheme_Object *orig_lambda;
|
||||
|
|
|
@ -65,6 +65,9 @@ THREAD_LOCAL Thread_Local_Variables scheme_thread_locals;
|
|||
extern int scheme_num_copied_stacks;
|
||||
static unsigned long scheme_primordial_os_thread_stack_base;
|
||||
THREAD_LOCAL_DECL(static unsigned long scheme_os_thread_stack_base);
|
||||
#ifdef USE_THREAD_LOCAL
|
||||
Thread_Local_Variables *scheme_vars; /* for debugging */
|
||||
#endif
|
||||
|
||||
static Scheme_Report_Out_Of_Memory_Proc more_report_out_of_memory;
|
||||
|
||||
|
@ -164,7 +167,12 @@ int scheme_main_stack_setup(int no_auto_statics, Scheme_Nested_Main _main, void
|
|||
fprintf(stderr, "pthread key create failed");
|
||||
abort();
|
||||
}
|
||||
#endif
|
||||
|
||||
scheme_init_os_thread();
|
||||
|
||||
#ifdef USE_THREAD_LOCAL
|
||||
scheme_vars = scheme_get_thread_local_variables();
|
||||
#endif
|
||||
|
||||
scheme_set_stack_base(PROMPT_STACK(stack_start), no_auto_statics);
|
||||
|
|
Loading…
Reference in New Issue
Block a user