more thread-local repairs

svn: r16873
This commit is contained in:
Matthew Flatt 2009-11-18 17:05:46 +00:00
parent 424aa90491
commit 54f5c14657
13 changed files with 119 additions and 116 deletions

6
src/configure vendored
View File

@ -10712,11 +10712,7 @@ fi
if test "${enable_places}" = "yes" ; then
PREFLAGS="$PREFLAGS -DMZ_USE_PLACES"
if test "${CGC_X86_64}" = "1" ; then
PLACE_CGC_FLAGS="$GC_THREADS_FLAG -DTHREAD_LOCAL_ALLOC"
else
PLACE_CGC_FLAGS="$GC_THREADS_FLAG -DPARALLEL_MARK -DTHREAD_LOCAL_ALLOC"
fi
PLACE_CGC_FLAGS="$GC_THREADS_FLAG -DTHREAD_LOCAL_ALLOC"
LDFLAGS="$LDFLAGS -pthread"
LIBATOM="LIBATOM_USE"
fi

View File

@ -1142,11 +1142,7 @@ fi
if test "${enable_places}" = "yes" ; then
PREFLAGS="$PREFLAGS -DMZ_USE_PLACES"
if test "${CGC_X86_64}" = "1" ; then
PLACE_CGC_FLAGS="$GC_THREADS_FLAG -DTHREAD_LOCAL_ALLOC"
else
PLACE_CGC_FLAGS="$GC_THREADS_FLAG -DPARALLEL_MARK -DTHREAD_LOCAL_ALLOC"
fi
PLACE_CGC_FLAGS="$GC_THREADS_FLAG -DTHREAD_LOCAL_ALLOC"
LDFLAGS="$LDFLAGS -pthread"
LIBATOM="LIBATOM_USE"
fi

View File

@ -14,7 +14,6 @@
/* This file should be linked with any MzScheme extension dynamic
object. */
#include "escheme.h"
#ifdef INCLUDE_WITHOUT_PATHS
# include "schvers.h"

View File

@ -409,6 +409,11 @@ GC2_EXTERN void GC_switch_back_from_master(void *gc);
Switches to back to gc from the master GC
*/
GC2_EXTERN void *GC_make_jit_nursery_page();
/*
obtains a nursery page from the GC for thread local allocation
*/
# ifdef __cplusplus
};

View File

@ -28,8 +28,6 @@
*/
#define MZ_PRECISE_GC /* required for mz includes to work right */
#define XFORM_OK_ASSIGN /* annotation used when thread-local variables are needed */
#define SKIP_THREAD_LOCAL_XFORM_DECL
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
@ -40,20 +38,6 @@
#include "gc2.h"
#include "gc2_dump.h"
/*
#ifdef FUTURES_ENABLED
extern pthread_t g_rt_threadid;
#ifdef DEBUG_FUTURES
extern void dump_state(void);
#endif
#endif
*/
#if defined(FUTURES_ENABLED) || defined(INSTRUMENT_PRIMITIVES)
#include "../src/future.h"
#endif
/* the number of tags to use for tagged objects */
#define NUMBER_OF_TAGS 512
@ -719,24 +703,52 @@ static void *allocate_medium(const size_t request_size_bytes, const int type)
}
inline static mpage *gen0_create_new_mpage(NewGC *gc) {
inline static mpage *gen0_create_new_nursery_mpage(NewGC *gc, const size_t page_size) {
mpage *newmpage;
newmpage = malloc_mpage();
newmpage->addr = malloc_dirty_pages(gc, GEN0_PAGE_SIZE, APAGE_SIZE);
newmpage->addr = malloc_dirty_pages(gc, page_size, APAGE_SIZE);
newmpage->size_class = 0;
newmpage->size = PREFIX_SIZE;
pagemap_add_with_size(gc->page_maps, newmpage, GEN0_PAGE_SIZE);
pagemap_add_with_size(gc->page_maps, newmpage, page_size);
return newmpage;
}
inline static void gen0_free_mpage(NewGC *gc, mpage *page) {
pagemap_remove_with_size(gc->page_maps, page, GEN0_PAGE_SIZE);
free_pages(gc, page->addr, GEN0_PAGE_SIZE);
inline static void gen0_free_nursery_mpage(NewGC *gc, mpage *page, size_t page_size) {
pagemap_remove_with_size(gc->page_maps, page, page_size);
free_pages(gc, page->addr, page_size);
free_mpage(page);
}
void *GC_make_jit_nursery_page() {
NewGC *gc = GC_get_GC();
mpage *new_mpage;
{
new_mpage = gen0_create_new_nursery_mpage(gc, APAGE_SIZE);
/* push page */
new_mpage->next = gc->thread_local_pages;
new_mpage->next->prev = new_mpage;
gc->thread_local_pages = new_mpage;
}
return new_mpage->addr;
}
inline static void gen0_free_jit_nursery_page(NewGC *gc, mpage *page) {
gen0_free_nursery_mpage(gc, page, APAGE_SIZE);
}
inline static mpage *gen0_create_new_mpage(NewGC *gc) {
return gen0_create_new_nursery_mpage(gc, GEN0_PAGE_SIZE);
}
inline static void gen0_free_mpage(NewGC *gc, mpage *page) {
gen0_free_nursery_mpage(gc, page, GEN0_PAGE_SIZE);
}
//#define OVERFLOWS_GEN0(ptr) ((ptr) > (NUM(gc->gen0.curr_alloc_page->addr) + GEN0_PAGE_SIZE))
#define OVERFLOWS_GEN0(ptr) ((ptr) > GC_gen0_alloc_page_end)
@ -978,6 +990,7 @@ long GC_malloc_stays_put_threshold() { return MAX_OBJECT_SIZE; }
to the size we've computed as ideal */
inline static void resize_gen0(NewGC *gc, unsigned long new_size)
{
mpage *work = gc->gen0.pages;
mpage *prev = NULL;
unsigned long alloced_size = 0;
@ -1026,6 +1039,15 @@ inline static void resize_gen0(NewGC *gc, unsigned long new_size)
/* set the two size variables */
gc->gen0.max_size = alloced_size;
gc->gen0.current_size = 0;
{
mpage *work = gc->thread_local_pages;
while(work) {
gen0_free_jit_nursery_page(gc, work);
}
gc->thread_local_pages = NULL;
}
}
inline static void reset_nursery(NewGC *gc)
@ -1722,6 +1744,7 @@ static void NewGC_initialize(NewGC *newgc, NewGC *parentgc) {
newgc->fixup_table = parentgc->fixup_table;
}
else {
#ifdef MZ_USE_PLACES
NewGCMasterInfo_initialize();
#endif
@ -3080,14 +3103,6 @@ extern double scheme_get_inexact_milliseconds(void);
static void garbage_collect(NewGC *gc, int force_full)
{
#ifdef FUTURES_ENABLED
//Sanity check for FUTURES
if (g_rt_threadid != 0 && pthread_self() != g_rt_threadid)
{
printf("garbage_collect invoked on wrong thread!!!\n");
}
#endif
unsigned long old_mem_use = gc->memory_in_use;
unsigned long old_gen0 = gc->gen0.current_size;
int next_gc_full;

View File

@ -173,6 +173,7 @@ typedef struct NewGC {
objhead saved_GC_objhead_template;
#endif
struct mpage *thread_local_pages;
/* Callbacks */
void (*GC_collect_start_callback)(void);

View File

@ -29,14 +29,3 @@
#ifndef GC_ALIGN_EIGHT
# define GC_ALIGN_EIGHT
#endif
#ifdef MZ_USE_PLACES
# if _MSC_VER
# define THREAD_LOCAL __declspec(thread)
# else
# define THREAD_LOCAL __thread
# endif
#else
# define THREAD_LOCAL /* empty */
#endif

View File

@ -54,6 +54,13 @@ typedef struct {
typedef long rxpos;
struct gmp_tmp_stack
{
void *end;
void *alloc_point;
struct gmp_tmp_stack *prev;
};
#ifndef MZ_PRECISE_GC
typedef long objhead;
#endif
@ -196,6 +203,11 @@ typedef struct Thread_Local_Variables {
struct Scheme_Object *maybe_recycle_cell_;
int recycle_cc_count_;
mz_jmp_buf main_init_error_buf_;
void *gmp_mem_pool_;
unsigned long max_total_allocation_;
unsigned long current_total_allocation_;
struct gmp_tmp_stack gmp_tmp_xxx_;
struct gmp_tmp_stack *gmp_tmp_current_;
} Thread_Local_Variables;
#if defined(IMPLEMENT_THREAD_LOCAL_VIA_PTHREADS)
@ -203,21 +215,21 @@ typedef struct Thread_Local_Variables {
# include <pthread.h>
MZ_EXTERN pthread_key_t scheme_thread_local_key;
# define scheme_get_thread_local_variables() ((Thread_Local_Variables *)pthread_getspecific(scheme_thread_local_key))
# if defined(MZ_PRECISE_GC) && !defined(SKIP_THREAD_LOCAL_XFORM_DECL)
#ifdef MZ_XFORM
XFORM_GC_VARIABLE_STACK_THROUGH_GETSPECIFIC;
# endif
#else
/* Using `THREAD_LOCAL' variable: */
MZ_EXTERN THREAD_LOCAL Thread_Local_Variables scheme_thread_locals;
# define scheme_get_thread_local_variables() (&scheme_thread_locals)
# if defined(MZ_PRECISE_GC) && !defined(SKIP_THREAD_LOCAL_XFORM_DECL)
#ifdef MZ_XFORM
XFORM_GC_VARIABLE_STACK_THROUGH_THREAD_LOCAL;
# endif
#endif
/* **************************************** */
#ifdef MZ_PRECISE_GC
#ifdef MZ_XFORM
# define XOA XFORM_OK_ASSIGN
#else
# define XOA /* empty */
@ -350,6 +362,11 @@ XFORM_GC_VARIABLE_STACK_THROUGH_THREAD_LOCAL;
#define maybe_recycle_cell XOA (scheme_get_thread_local_variables()->maybe_recycle_cell_)
#define recycle_cc_count XOA (scheme_get_thread_local_variables()->recycle_cc_count_)
#define main_init_error_buf XOA (scheme_get_thread_local_variables()->main_init_error_buf_)
#define gmp_mem_pool XOA (scheme_get_thread_local_variables()->gmp_mem_pool_)
#define max_total_allocation XOA (scheme_get_thread_local_variables()->max_total_allocation_)
#define current_total_allocation XOA (scheme_get_thread_local_variables()->current_total_allocation_)
#define gmp_tmp_xxx XOA (scheme_get_thread_local_variables()->gmp_tmp_xxx_)
#define gmp_tmp_current XOA (scheme_get_thread_local_variables()->gmp_tmp_current_)
/* **************************************** */

View File

@ -98,16 +98,10 @@ MA 02111-1307, USA.
#undef HAVE_ALLOCA
#if ! defined (HAVE_ALLOCA) || USE_STACK_ALLOC
struct tmp_stack
{
void *end;
void *alloc_point;
struct tmp_stack *prev;
};
struct tmp_marker
{
struct tmp_stack *which_chunk;
struct gmp_tmp_stack *which_chunk;
void *alloc_point;
};

View File

@ -17,31 +17,20 @@ along with the GNU MP Library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
MA 02111-1307, USA. */
#ifdef MZ_USE_PLACES
# if _MSC_VER
# define THREAD_LOCAL __declspec(thread)
# else
# define THREAD_LOCAL __thread
# endif
#else
# define THREAD_LOCAL /* empty */
#endif
#define _FORCE_INLINES
#define _EXTERN_INLINE /* empty */
extern void *scheme_malloc_gmp(unsigned long, void **mem_pool);
extern void scheme_free_gmp(void *, void **mem_pool);
static THREAD_LOCAL void *mem_pool = 0;
#define MALLOC(amt) scheme_malloc_gmp(amt, &mem_pool)
#define FREE(p, s) scheme_free_gmp(p, &mem_pool)
#include "../../sconfig.h"
#include "mzconfig.h"
#include "../schpriv.h"
#include "gmp.h"
#include "gmp-impl.h"
#include "gmplonglong.h"
extern void *scheme_malloc_gmp(unsigned long, void **mem_pool);
extern void scheme_free_gmp(void *, void **mem_pool);
THREAD_LOCAL_DECL(static void *gmp_mem_pool);
#define MALLOC(amt) scheme_malloc_gmp(amt, &gmp_mem_pool)
#define FREE(p, s) scheme_free_gmp(p, &gmp_mem_pool)
#define GMP_NAIL_BITS 0
#define GMP_LIMB_BITS BITS_PER_MP_LIMB
#define GMP_NUMB_BITS BITS_PER_MP_LIMB
@ -5695,13 +5684,13 @@ unsigned char __clz_tab[] =
#ifndef HAVE_ALLOCA
typedef struct tmp_stack tmp_stack;
typedef struct gmp_tmp_stack tmp_stack;
static THREAD_LOCAL unsigned long max_total_allocation = 0;
static THREAD_LOCAL unsigned long current_total_allocation = 0;
THREAD_LOCAL_DECL(static unsigned long max_total_allocation);
THREAD_LOCAL_DECL(static unsigned long current_total_allocation);
static THREAD_LOCAL tmp_stack xxx = {0, 0, 0};
static THREAD_LOCAL tmp_stack *current = 0;
THREAD_LOCAL_DECL(static tmp_stack gmp_tmp_xxx);
THREAD_LOCAL_DECL(static tmp_stack *gmp_tmp_current = 0);
/* The rounded size of the header of each allocation block. */
#define HSIZ ((sizeof (tmp_stack) + __TMP_ALIGN - 1) & -__TMP_ALIGN)
@ -5718,7 +5707,7 @@ __gmp_tmp_alloc (size)
{
void *that;
if (size > (char *) current->end - (char *) current->alloc_point)
if (size > (char *) gmp_tmp_current->end - (char *) gmp_tmp_current->alloc_point)
{
void *chunk;
tmp_stack *header;
@ -5749,12 +5738,12 @@ __gmp_tmp_alloc (size)
header = (tmp_stack *) chunk;
header->end = (char *) chunk + chunk_size;
header->alloc_point = (char *) chunk + HSIZ;
header->prev = current;
current = header;
header->prev = gmp_tmp_current;
gmp_tmp_current = header;
}
that = current->alloc_point;
current->alloc_point = (char *) that + size;
that = gmp_tmp_current->alloc_point;
gmp_tmp_current->alloc_point = (char *) that + size;
return that;
}
@ -5769,8 +5758,8 @@ __gmp_tmp_mark (mark)
tmp_marker *mark;
#endif
{
mark->which_chunk = current;
mark->alloc_point = current->alloc_point;
mark->which_chunk = gmp_tmp_current;
mark->alloc_point = gmp_tmp_current->alloc_point;
}
/* Free everything allocated since <mark> was assigned by __gmp_tmp_mark */
@ -5782,49 +5771,49 @@ __gmp_tmp_free (mark)
tmp_marker *mark;
#endif
{
while (mark->which_chunk != current)
while (mark->which_chunk != gmp_tmp_current)
{
tmp_stack *tmp;
tmp = current;
current = tmp->prev;
tmp = gmp_tmp_current;
gmp_tmp_current = tmp->prev;
current_total_allocation -= (((char *) (tmp->end) - (char *) tmp) - HSIZ);
FREE (tmp, (char *) tmp->end - (char *) tmp);
}
current->alloc_point = mark->alloc_point;
gmp_tmp_current->alloc_point = mark->alloc_point;
}
void scheme_init_gmp_places() {
xxx.end = &xxx;
xxx.alloc_point = &xxx;
xxx.prev = 0;
current = &xxx;
gmp_tmp_xxx.end = &gmp_tmp_xxx;
gmp_tmp_xxx.alloc_point = &gmp_tmp_xxx;
gmp_tmp_xxx.prev = 0;
gmp_tmp_current = &gmp_tmp_xxx;
}
void scheme_gmp_tls_init(long *s)
{
s[0] = 0;
s[1] = 0;
s[2] = (long)&xxx;
((tmp_marker *)(s + 3))->which_chunk = &xxx;
((tmp_marker *)(s + 3))->alloc_point = &xxx;
s[2] = (long)&gmp_tmp_xxx;
((tmp_marker *)(s + 3))->which_chunk = &gmp_tmp_xxx;
((tmp_marker *)(s + 3))->alloc_point = &gmp_tmp_xxx;
}
void *scheme_gmp_tls_load(long *s)
{
s[0] = (long)current_total_allocation;
s[1] = (long)max_total_allocation;
s[2] = (long)current;
return mem_pool;
s[2] = (long)gmp_tmp_current;
return gmp_mem_pool;
}
void scheme_gmp_tls_unload(long *s, void *data)
{
current_total_allocation = (unsigned long)s[0];
max_total_allocation = (unsigned long)s[1];
current = (tmp_stack *)s[2];
gmp_tmp_current = (tmp_stack *)s[2];
s[0] = 0;
mem_pool = data;
gmp_mem_pool = data;
}
void scheme_gmp_tls_snapshot(long *s, long *save)

View File

@ -10265,8 +10265,8 @@ void scheme_jit_fill_threadlocal_table() {
# endif
thread_local_pointers[tl_fixup_runstack_base] = (&fixup_runstack_base);
thread_local_pointers[tl_fixup_already_in_place] = (&fixup_already_in_place);
thread_local_pointers[tl_scheme_fuel_counter] = (&scheme_fuel_counter);
thread_local_pointers[tl_scheme_jit_stack_boundary] = (&scheme_jit_stack_boundary);
thread_local_pointers[tl_scheme_fuel_counter] = (void *) (&scheme_fuel_counter);
thread_local_pointers[tl_scheme_jit_stack_boundary] = (void *) (&scheme_jit_stack_boundary);
#endif
}

View File

@ -5424,9 +5424,9 @@ static int future_MARK(void *p) {
gcMARK(f->runstack_start);
gcMARK(f->orig_lambda);
gcMARK(f->rt_prim_retval);
gcMARK(f->prim_data.p);
gcMARK(f->prim_data.argv);
gcMARK(f->prim_data.retval);
gcMARK(f->prim_data.p);
gcMARK(f->prim_data.argv);
gcMARK(f->prim_data.retval);
gcMARK(f->retval);
gcMARK(f->prev);
gcMARK(f->next);
@ -5440,9 +5440,9 @@ static int future_FIXUP(void *p) {
gcFIXUP(f->runstack_start);
gcFIXUP(f->orig_lambda);
gcFIXUP(f->rt_prim_retval);
gcFIXUP(f->prim_data.p);
gcFIXUP(f->prim_data.argv);
gcFIXUP(f->prim_data.retval);
gcFIXUP(f->prim_data.p);
gcFIXUP(f->prim_data.argv);
gcFIXUP(f->prim_data.retval);
gcFIXUP(f->retval);
gcFIXUP(f->prev);
gcFIXUP(f->next);

View File

@ -2226,8 +2226,10 @@ future {
gcMARK(f->runstack);
gcMARK(f->runstack_start);
gcMARK(f->orig_lambda);
gcMARK(f->rt_prim_args);
gcMARK(f->rt_prim_retval);
gcMARK(f->prim_data.p);
gcMARK(f->prim_data.argv);
gcMARK(f->prim_data.retval);
gcMARK(f->retval);
gcMARK(f->prev);
gcMARK(f->next);