Commit fd62dc11 authored by Marius Gerbershagen's avatar Marius Gerbershagen
Browse files

threading: be more interrupt safe with thread local variables in environment

    Also add some comments and use the right interrupt disabling
    mechanism in get_aux_stream.
parent 9f8adbbe
......@@ -98,14 +98,14 @@ get_aux_stream(void)
cl_env_ptr env = ecl_process_env();
cl_object stream;
ecl_disable_interrupts_env(env);
if (env->fmt_aux_stream == ECL_NIL) {
stream = ecl_make_string_output_stream(64, 1);
} else {
stream = env->fmt_aux_stream;
env->fmt_aux_stream = ECL_NIL;
}
ecl_enable_interrupts_env(env);
ECL_WITHOUT_INTERRUPTS_BEGIN(env) {
if (env->fmt_aux_stream == ECL_NIL) {
stream = ecl_make_string_output_stream(64, 1);
} else {
stream = env->fmt_aux_stream;
env->fmt_aux_stream = ECL_NIL;
}
} ECL_WITHOUT_INTERRUPTS_END;
return stream;
}
......
......@@ -378,18 +378,31 @@ handle_all_queued_interrupt_safe(cl_env_ptr env)
/* We have to save and later restore thread-local variables to
* ensure that they don't get overwritten by the interrupting
* code */
/* INV: - Frame, Binding and IHS stack manipulations are
* interrupt safe
* - The rest of the thread local variables are
* guaranteed to be used in an interrupt safe way. This
* is not true for the compiler environment and ffi
* data, but it is unclear whether the DFFI or compiler
* are thread safe anyway. */
cl_object fun = env->function;
cl_index nvalues = env->nvalues;
cl_object* values = ecl_alloc_atomic(ECL_MULTIPLE_VALUES_LIMIT*sizeof(cl_object));
cl_object values[ECL_MULTIPLE_VALUES_LIMIT];
memcpy(values, env->values, ECL_MULTIPLE_VALUES_LIMIT*sizeof(cl_object));
cl_object big_register[3];
memcpy(big_register, env->big_register, 3*sizeof(cl_object));
cl_object packages_to_be_created = env->packages_to_be_created;
cl_object packages_to_be_created_p = env->packages_to_be_created_p;
/* We might have been interrupted while we push/pop in the
* stack. Increasing env->stack_top ensures that we don't
* overwrite the topmost stack value. */
env->stack_top++;
/* Finally we can handle the queued signals */
handle_all_queued(env);
/* And restore thread local variables again */
env->stack_top--;
env->packages_to_be_created_p = packages_to_be_created_p;
env->packages_to_be_created = packages_to_be_created;
memcpy(env->big_register, big_register, 3*sizeof(cl_object));
memcpy(env->values, values, ECL_MULTIPLE_VALUES_LIMIT*sizeof(cl_object));
env->nvalues = nvalues;
......
......@@ -87,14 +87,16 @@ struct cl_env_struct {
char *cs_barrier;
/* Private variables used by different parts of ECL: */
/* ... the reader ... */
/* ... the reader and printer ... */
cl_object string_pool;
/* ... the compiler ... */
struct cl_compiler_env *c_env;
/* ... the formatter ... */
#if !defined(ECL_CMU_FORMAT)
cl_object fmt_aux_stream;
#endif
/* ... arithmetics ... */
/* Note: if you change the size of these registers, change also
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment