When resizing the stack, enclose the update in an interrupts-free region

This commit is contained in:
Juan Jose Garcia Ripoll 2008-10-10 22:56:15 +02:00
parent 5bda4b4f61
commit 8bf59c96ad
2 changed files with 23 additions and 15 deletions

View file

@ -26,35 +26,31 @@ void
cl_stack_set_size(cl_index tentative_new_size)
{
cl_index top = cl_env.stack_top - cl_env.stack;
cl_object *new_stack;
cl_object *new_stack, *old_stack;
cl_index safety_area = ecl_get_option(ECL_OPT_LISP_STACK_SAFETY_AREA);
cl_index new_size = tentative_new_size + 2*safety_area;
if (top > new_size)
FEerror("Internal error: cannot shrink stack that much.",0);
start_critical_section();
old_stack = cl_env.stack;
new_stack = (cl_object *)ecl_alloc_atomic(new_size * sizeof(cl_object));
memcpy(new_stack, cl_env.stack, cl_env.stack_size * sizeof(cl_object));
#ifdef BOEHM_GBC
GC_free(cl_env.stack);
#else
cl_dealloc(cl_env.stack);
#endif
ecl_disable_interrupts();
memcpy(new_stack, old_stack, cl_env.stack_size * sizeof(cl_object));
cl_env.stack_size = new_size;
cl_env.stack = new_stack;
cl_env.stack_top = cl_env.stack + top;
cl_env.stack_limit = cl_env.stack + (new_size - 2*safety_area);
ecl_enable_interrupts();
cl_dealloc(old_stack);
/* A stack always has at least one element. This is assumed by cl__va_start
* and friends, which take a sp=0 to have no arguments.
*/
if (top == 0)
cl_stack_push(MAKE_FIXNUM(0));
end_critical_section();
}
static void

View file

@ -171,7 +171,8 @@ bds_unwind_n(int n)
static void
bds_set_size(cl_index size)
{
cl_index limit = (cl_env.bds_top - cl_env.bds_org);
bds_ptr old_org = cl_env.bds_org;
cl_index limit = cl_env.bds_top - old_org;
if (size <= limit) {
FEerror("Cannot shrink the binding stack below ~D.", 1,
ecl_make_unsigned_integer(limit));
@ -179,11 +180,16 @@ bds_set_size(cl_index size)
cl_index margin = ecl_get_option(ECL_OPT_BIND_STACK_SAFETY_AREA);
bds_ptr org;
org = ecl_alloc_atomic(size * sizeof(*org));
memcpy(org, cl_env.bds_org, (limit + 1) * sizeof(*org));
ecl_disable_interrupts();
memcpy(org, old_org, (limit + 1) * sizeof(*org));
cl_env.bds_top = org + limit;
cl_env.bds_org = org;
cl_env.bds_limit = org + (size - 2*margin);
cl_env.bds_size = size;
ecl_enable_interrupts();
cl_dealloc(old_org);
}
}
@ -339,7 +345,8 @@ new_frame_id(void)
static void
frs_set_size(cl_index size)
{
cl_index limit = (cl_env.frs_top - cl_env.frs_org);
ecl_frame_ptr old_org = cl_env.frs_top;
cl_index limit = cl_env.frs_top - old_org;
if (size <= limit) {
FEerror("Cannot shrink frame stack below ~D.", 1,
ecl_make_unsigned_integer(limit));
@ -348,11 +355,16 @@ frs_set_size(cl_index size)
ecl_frame_ptr org;
size += 2*margin;
org = ecl_alloc_atomic(size * sizeof(*org));
memcpy(org, cl_env.frs_org, (limit + 1) * sizeof(*org));
ecl_disable_interrupts();
memcpy(org, old_org, (limit + 1) * sizeof(*org));
cl_env.frs_top = org + limit;
cl_env.frs_org = org;
cl_env.frs_limit = org + (size - 2*margin);
cl_env.frs_size = size;
ecl_enable_interrupts();
cl_dealloc(old_org);
}
}