more on thread-local allocation
svn: r16879
This commit is contained in:
parent
bdca9c1e8f
commit
f921cf62cc
|
@ -279,25 +279,16 @@ void exception_thread(void *shared_thread_state)
|
|||
}
|
||||
}
|
||||
|
||||
/* this initializes the subsystem (sets the exception port, starts the
|
||||
exception handling thread, etc) */
|
||||
static void macosx_init_exception_handler()
|
||||
void GC_attach_current_thread_exceptions_to_handler()
|
||||
{
|
||||
mach_port_t thread_self, exc_port_s;
|
||||
mach_msg_type_name_t type;
|
||||
kern_return_t retval;
|
||||
|
||||
/* get ids for ourself */
|
||||
if(!task_self) task_self = mach_task_self();
|
||||
thread_self = mach_thread_self();
|
||||
if (!task_self) return;
|
||||
|
||||
/* allocate the port we're going to get exceptions on */
|
||||
retval = mach_port_allocate(task_self, MACH_PORT_RIGHT_RECEIVE, &exc_port);
|
||||
if(retval != KERN_SUCCESS) {
|
||||
GCPRINT(GCOUTF, "Couldn't allocate exception port: %s\n",
|
||||
mach_error_string(retval));
|
||||
abort();
|
||||
}
|
||||
/* get ids for ourself */
|
||||
thread_self = mach_thread_self();
|
||||
|
||||
/* extract out the send rights for that port, which the OS needs */
|
||||
retval = mach_port_extract_right(task_self, exc_port, MACH_MSG_TYPE_MAKE_SEND,
|
||||
|
@ -315,6 +306,25 @@ static void macosx_init_exception_handler()
|
|||
GCPRINT(GCOUTF, "Couldn't set exception ports: %s\n", mach_error_string(retval));
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
/* this initializes the subsystem (sets the exception port, starts the
|
||||
exception handling thread, etc) */
|
||||
static void macosx_init_exception_handler()
|
||||
{
|
||||
kern_return_t retval;
|
||||
|
||||
if(!task_self) task_self = mach_task_self();
|
||||
|
||||
/* allocate the port we're going to get exceptions on */
|
||||
retval = mach_port_allocate(task_self, MACH_PORT_RIGHT_RECEIVE, &exc_port);
|
||||
if(retval != KERN_SUCCESS) {
|
||||
GCPRINT(GCOUTF, "Couldn't allocate exception port: %s\n",
|
||||
mach_error_string(retval));
|
||||
abort();
|
||||
}
|
||||
|
||||
GC_attach_current_thread_exceptions_to_handler();
|
||||
|
||||
#ifdef PPC_HAND_ROLLED_THREAD
|
||||
/* Old hand-rolled thread creation. */
|
||||
|
|
|
@ -181,7 +181,8 @@ typedef struct Thread_Local_Variables {
|
|||
int num_running_threads_;
|
||||
int swap_no_setjmp_;
|
||||
int thread_swap_count_;
|
||||
int did_gc_count_;
|
||||
int scheme_did_gc_count_;
|
||||
int worker_gc_counter_;
|
||||
struct Scheme_Object **scheme_current_runstack_start_;
|
||||
struct Scheme_Object **scheme_current_runstack_;
|
||||
MZ_MARK_STACK_TYPE scheme_current_cont_mark_stack_;
|
||||
|
@ -344,7 +345,8 @@ XFORM_GC_VARIABLE_STACK_THROUGH_THREAD_LOCAL;
|
|||
#define num_running_threads XOA (scheme_get_thread_local_variables()->num_running_threads_)
|
||||
#define swap_no_setjmp XOA (scheme_get_thread_local_variables()->swap_no_setjmp_)
|
||||
#define thread_swap_count XOA (scheme_get_thread_local_variables()->thread_swap_count_)
|
||||
#define did_gc_count XOA (scheme_get_thread_local_variables()->did_gc_count_)
|
||||
#define scheme_did_gc_count XOA (scheme_get_thread_local_variables()->scheme_did_gc_count_)
|
||||
#define worker_gc_counter XOA (scheme_get_thread_local_variables()->worker_gc_counter_)
|
||||
#define scheme_current_runstack_start XOA (scheme_get_thread_local_variables()->scheme_current_runstack_start_)
|
||||
#define scheme_current_runstack XOA (scheme_get_thread_local_variables()->scheme_current_runstack_)
|
||||
#define scheme_current_cont_mark_stack XOA (scheme_get_thread_local_variables()->scheme_current_cont_mark_stack_)
|
||||
|
|
|
@ -75,10 +75,12 @@ static int gc_not_ok;
|
|||
THREAD_LOCAL_DECL(extern unsigned long GC_gen0_alloc_page_ptr);
|
||||
#endif
|
||||
|
||||
future_t **g_current_ft;
|
||||
Scheme_Object ***g_scheme_current_runstack;
|
||||
Scheme_Object ***g_scheme_current_runstack_start;
|
||||
void **g_jit_future_storage;
|
||||
static future_t **g_current_ft;
|
||||
static Scheme_Object ***g_scheme_current_runstack;
|
||||
static Scheme_Object ***g_scheme_current_runstack_start;
|
||||
static void **g_jit_future_storage;
|
||||
static int *gc_counter_ptr;
|
||||
THREAD_LOCAL_DECL(static int worker_gc_counter);
|
||||
|
||||
static void register_traversers(void);
|
||||
extern void scheme_on_demand_generate_lambda(Scheme_Native_Closure *nc, int argc, Scheme_Object **argv);
|
||||
|
@ -307,6 +309,7 @@ void futures_init(void)
|
|||
pthread_attr_setstacksize(&attr, INITIAL_C_STACK_SIZE);
|
||||
for (i = 0; i < THREAD_POOL_SIZE; i++)
|
||||
{
|
||||
gc_counter_ptr = &scheme_did_gc_count;
|
||||
pthread_create(&threadid, &attr, worker_thread_future_loop, &i);
|
||||
sema_wait(&ready_sema);
|
||||
|
||||
|
@ -326,6 +329,12 @@ static void start_gc_not_ok()
|
|||
pthread_mutex_lock(&gc_ok_m);
|
||||
gc_not_ok++;
|
||||
pthread_mutex_unlock(&gc_ok_m);
|
||||
#ifdef MZ_PRECISE_GC
|
||||
if (worker_gc_counter != *gc_counter_ptr) {
|
||||
GC_gen0_alloc_page_ptr = 0; /* forces future to ask for memory */
|
||||
worker_gc_counter = *gc_counter_ptr;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void end_gc_not_ok()
|
||||
|
@ -581,7 +590,6 @@ Scheme_Object *touch(int argc, Scheme_Object *argv[])
|
|||
return retval;
|
||||
}
|
||||
|
||||
|
||||
//Entry point for a worker thread allocated for
|
||||
//executing futures. This function will never terminate
|
||||
//(until the process dies).
|
||||
|
@ -616,10 +624,6 @@ void *worker_thread_future_loop(void *arg)
|
|||
g_fuel_pointers[id] = &scheme_fuel_counter;
|
||||
g_stack_boundary_pointers[id] = &scheme_jit_stack_boundary;
|
||||
|
||||
#ifdef MZ_PRECISE_GC
|
||||
GC_gen0_alloc_page_ptr = 0; /* disables inline allocation */
|
||||
#endif
|
||||
|
||||
g_current_ft = ¤t_ft;
|
||||
g_scheme_current_runstack = &scheme_current_runstack;
|
||||
g_scheme_current_runstack_start = &scheme_current_runstack_start;
|
||||
|
@ -744,6 +748,7 @@ int future_do_runtimecall(
|
|||
future->rt_prim = NULL;
|
||||
|
||||
retval = future->rt_prim_retval;
|
||||
future->rt_prim_retval = NULL;
|
||||
pthread_mutex_unlock(&g_future_queue_mutex);
|
||||
return 1;
|
||||
}
|
||||
|
@ -777,27 +782,34 @@ int rtcall_void_void(void (*f)())
|
|||
}
|
||||
|
||||
|
||||
int rtcall_void_pvoid(void (*f)(), void **retval)
|
||||
int rtcall_alloc_void_pvoid(void (*f)(), 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;
|
||||
}
|
||||
|
||||
data.void_pvoid = f;
|
||||
data.sigtype = SIG_VOID_PVOID;
|
||||
while (1) {
|
||||
memset(&data, 0, sizeof(prim_data_t));
|
||||
if (!IS_WORKER_THREAD)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
future = get_my_future();
|
||||
future->rt_prim = (void*)f;
|
||||
future->prim_data = data;
|
||||
data.alloc_void_pvoid = f;
|
||||
data.sigtype = SIG_ALLOC_VOID_PVOID;
|
||||
|
||||
future_do_runtimecall((void*)f, NULL);
|
||||
future = get_my_future();
|
||||
future->rt_prim = (void*)f;
|
||||
future->prim_data = data;
|
||||
|
||||
*retval = future->prim_data.retval;
|
||||
future_do_runtimecall((void*)f, NULL);
|
||||
|
||||
*retval = future->alloc_retval;
|
||||
future->alloc_retval = NULL;
|
||||
|
||||
if (*gc_counter_ptr == future->alloc_retval_counter)
|
||||
break;
|
||||
}
|
||||
|
||||
return 1;
|
||||
END_XFORM_SKIP;
|
||||
|
@ -840,6 +852,7 @@ int rtcall_obj_int_pobj_obj(
|
|||
|
||||
future_do_runtimecall((void*)f, NULL);
|
||||
*retval = future->prim_data.retval;
|
||||
future->prim_data.retval = NULL;
|
||||
|
||||
return 1;
|
||||
END_XFORM_SKIP;
|
||||
|
@ -880,6 +893,7 @@ int rtcall_int_pobj_obj(
|
|||
|
||||
future_do_runtimecall((void*)f, NULL);
|
||||
*retval = future->prim_data.retval;
|
||||
future->prim_data.retval = NULL;
|
||||
|
||||
return 1;
|
||||
END_XFORM_SKIP;
|
||||
|
@ -962,6 +976,7 @@ int rtcall_int_pobj_obj_obj(
|
|||
|
||||
future_do_runtimecall((void*)f, NULL);
|
||||
*retval = future->prim_data.retval;
|
||||
future->prim_data.retval = NULL;
|
||||
|
||||
return 1;
|
||||
END_XFORM_SKIP;
|
||||
|
@ -995,11 +1010,12 @@ void *invoke_rtcall(future_t *future)
|
|||
pret = &dummy_ret;
|
||||
break;
|
||||
}
|
||||
case SIG_VOID_PVOID:
|
||||
case SIG_ALLOC_VOID_PVOID:
|
||||
{
|
||||
prim_void_pvoid_t func = pdata->void_pvoid;
|
||||
prim_alloc_void_pvoid_t func = pdata->alloc_void_pvoid;
|
||||
ret = func();
|
||||
pdata->retval = ret;
|
||||
future->alloc_retval = ret;
|
||||
future->alloc_retval_counter = scheme_did_gc_count;
|
||||
break;
|
||||
}
|
||||
case SIG_OBJ_INT_POBJ_OBJ:
|
||||
|
|
|
@ -33,7 +33,7 @@ extern int future_do_runtimecall(void *func, void *retval);
|
|||
extern void futures_init(void);
|
||||
|
||||
typedef void (*prim_void_void_t)(void);
|
||||
typedef void *(*prim_void_pvoid_t)(void);
|
||||
typedef void *(*prim_alloc_void_pvoid_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*);
|
||||
|
@ -43,7 +43,7 @@ typedef struct {
|
|||
unsigned int sigtype;
|
||||
|
||||
prim_void_void_t void_void;
|
||||
prim_void_pvoid_t void_pvoid;
|
||||
prim_alloc_void_pvoid_t alloc_void_pvoid;
|
||||
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;
|
||||
|
@ -90,6 +90,8 @@ typedef struct future {
|
|||
void *rt_prim_retval;
|
||||
|
||||
prim_data_t prim_data;
|
||||
void *alloc_retval;
|
||||
int alloc_retval_counter;
|
||||
|
||||
Scheme_Object *retval;
|
||||
struct future *prev;
|
||||
|
@ -152,7 +154,7 @@ extern void print_ms_and_us(void);
|
|||
//Signature flags for primitive invocations
|
||||
//Here the convention is SIG_[arg1type]_[arg2type]..._[return type]
|
||||
#define SIG_VOID_VOID 1 //void -> void
|
||||
#define SIG_VOID_PVOID 2 //void -> void*
|
||||
#define SIG_ALLOC_VOID_PVOID 2 //void -> void*
|
||||
#define SIG_OBJ_INT_POBJ_OBJ 3 //Scheme_Object* -> int -> Scheme_Object** -> Scheme_Object*
|
||||
#define SIG_INT_OBJARR_OBJ 4 //int -> Scheme_Object*[] -> Scheme_Object
|
||||
#define SIG_INT_POBJ_OBJ_OBJ 17 //int -> Scheme_Object** -> Scheme_Object* -> Scheme_Object*
|
||||
|
@ -169,7 +171,7 @@ extern void print_ms_and_us(void);
|
|||
}
|
||||
|
||||
extern int rtcall_void_void(void (*f)());
|
||||
extern int rtcall_void_pvoid(void (*f)(), void **retval);
|
||||
extern int rtcall_alloc_void_pvoid(void (*f)(), void **retval);
|
||||
extern int rtcall_obj_int_pobj_obj(
|
||||
Scheme_Object* (*f)(Scheme_Object*, int, Scheme_Object**),
|
||||
Scheme_Object *a,
|
||||
|
@ -195,7 +197,7 @@ extern int rtcall_int_pobj_obj(
|
|||
#define LOG_THISCALL LOG(__FUNCTION__)
|
||||
|
||||
#define LOG_RTCALL_VOID_VOID(f) LOG("(function=%p)", f)
|
||||
#define LOG_RTCALL_VOID_PVOID(f) LOG("(function=%p)", f)
|
||||
#define LOG_RTCALL_ALLOC_VOID_PVOID(f) LOG("(function=%p)", f)
|
||||
#define LOG_RTCALL_OBJ_INT_POBJ_OBJ(f,a,b,c) LOG("(function = %p, a=%p, b=%d, c=%p)", f, a, b, c)
|
||||
#define LOG_RTCALL_OBJ_INT_POBJ_VOID(a,b,c) LOG("(%p, %d, %p)", a, b,c)
|
||||
#define LOG_RTCALL_INT_OBJARR_OBJ(a,b) LOG("(%d, %p)", a, b)
|
||||
|
@ -218,7 +220,7 @@ extern int rtcall_int_pobj_obj(
|
|||
#define LOG_THISCALL
|
||||
|
||||
#define LOG_RTCALL_VOID_VOID(f)
|
||||
#define LOG_RTCALL_VOID_PVOID(f)
|
||||
#define LOG_RTCALL_ALLOC_VOID_PVOID(f)
|
||||
#define LOG_RTCALL_OBJ_INT_POBJ_OBJ(f,a,b,c)
|
||||
#define LOG_RTCALL_OBJ_INT_POBJ_VOID(a,b,c)
|
||||
#define LOG_RTCALL_INT_OBJARR_OBJ(a,b)
|
||||
|
|
|
@ -2256,8 +2256,8 @@ static void *ts_prepare_retry_alloc(void *p, void *p2)
|
|||
LOG_PRIM_START(&prepare_retry_alloc);
|
||||
jit_future_storage[0] = p;
|
||||
jit_future_storage[1] = p2;
|
||||
if (rtcall_void_pvoid(GC_make_jit_nursery_page,
|
||||
&ret)) {
|
||||
if (rtcall_alloc_void_pvoid(GC_make_jit_nursery_page,
|
||||
&ret)) {
|
||||
GC_gen0_alloc_page_ptr = ret;
|
||||
retry_alloc_r1 = jit_future_storage[1];
|
||||
p = jit_future_storage[0];
|
||||
|
@ -2284,6 +2284,7 @@ static void *ts_prepare_retry_alloc(void *p, void *p2)
|
|||
# define ts_scheme_apply_from_native _scheme_apply_from_native
|
||||
# define ts_scheme_tail_apply_from_native _scheme_tail_apply_from_native
|
||||
# define ts_on_demand on_demand
|
||||
# define ts_prepare_retry_alloc prepare_retry_alloc
|
||||
#endif
|
||||
|
||||
static int generate_direct_prim_tail_call(mz_jit_state *jitter, int num_rands)
|
||||
|
|
|
@ -220,6 +220,9 @@ void scheme_set_report_out_of_memory(Scheme_Report_Out_Of_Memory_Proc p)
|
|||
|
||||
#ifdef OS_X
|
||||
#include <mach/mach.h>
|
||||
# ifdef MZ_PRECISE_GC
|
||||
extern void GC_attach_current_thread_exceptions_to_handler();
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef MZ_XFORM
|
||||
|
@ -241,6 +244,11 @@ void scheme_init_os_thread()
|
|||
}
|
||||
# endif
|
||||
#endif
|
||||
#ifdef OS_X
|
||||
# ifdef MZ_PRECISE_GC
|
||||
GC_attach_current_thread_exceptions_to_handler();
|
||||
# endif
|
||||
#endif
|
||||
}
|
||||
#ifdef MZ_XFORM
|
||||
END_XFORM_SKIP;
|
||||
|
|
|
@ -160,7 +160,7 @@ volatile int *scheme_fuel_counter_ptr;
|
|||
THREAD_LOCAL_DECL(static int swap_no_setjmp = 0);
|
||||
|
||||
THREAD_LOCAL_DECL(static int thread_swap_count);
|
||||
THREAD_LOCAL_DECL(static int did_gc_count);
|
||||
THREAD_LOCAL_DECL(int scheme_did_gc_count);
|
||||
|
||||
static int init_load_on_demand = 1;
|
||||
|
||||
|
@ -7390,7 +7390,7 @@ static void get_ready_for_GC()
|
|||
scheme_current_thread->gmp_tls_data = data;
|
||||
}
|
||||
|
||||
did_gc_count++;
|
||||
scheme_did_gc_count++;
|
||||
}
|
||||
|
||||
extern int GC_words_allocd;
|
||||
|
@ -7575,7 +7575,7 @@ static Scheme_Object *current_stats(int argc, Scheme_Object *argv[])
|
|||
case 5:
|
||||
SCHEME_VEC_ELS(v)[4] = scheme_make_integer(thread_swap_count);
|
||||
case 4:
|
||||
SCHEME_VEC_ELS(v)[3] = scheme_make_integer(did_gc_count);
|
||||
SCHEME_VEC_ELS(v)[3] = scheme_make_integer(scheme_did_gc_count);
|
||||
case 3:
|
||||
SCHEME_VEC_ELS(v)[2] = scheme_make_integer(gcend);
|
||||
case 2:
|
||||
|
|
Loading…
Reference in New Issue
Block a user