case t_spice:
break;
*/
+#ifdef ECL_LWP
+ case t_cont:
+ obj->cont.thread = OBJNULL;
+ break;
+ case t_thread:
+ obj->thread.entry = OBJNULL;
+ break;
+#endif
#ifdef ECL_THREADS
case t_process:
obj->process.name = OBJNULL;
printf("\ttype = %d\n", t);
ecl_internal_error("alloc botch.");
}
+#ifdef ECL_LWP
+ clwp->lwp_alloc_temporary = obj;
+#endif
ecl_enable_interrupts();
return(obj);
CALL_GC:
init_tm(t_cclosure, "cCCLOSURE", sizeof(struct ecl_cclosure), 1);
init_tm(t_instance, "IINSTANCE", sizeof(struct ecl_instance), 32);
init_tm(t_foreign, "LFOREIGN", sizeof(struct ecl_foreign), 1);
+#ifdef ECL_LWP
+ init_tm(t_cont, "?CONT", sizeof(struct ecl_cont), 2);
+ init_tm(t_thread, "tTHREAD", sizeof(struct ecl_thread), 2);
+#endif
#ifdef ECL_THREADS
init_tm(t_process, "tPROCESS", sizeof(struct ecl_process), 2);
init_tm(t_lock, "tLOCK", sizeof(struct ecl_lock), 2);
case t_cfunfixed:
case t_cclosure:
case t_instance:
+#ifdef ECL_LWP
+ case t_cont:
+ case t_thread:
+#endif
#ifdef ECL_THREADS
case t_process:
case t_lock:
init_tm(t_cfunfixed, "CFUNFIXED", sizeof(struct ecl_cfunfixed), -1);
init_tm(t_cclosure, "CCLOSURE", sizeof(struct ecl_cclosure), -1);
init_tm(t_instance, "INSTANCE", sizeof(struct ecl_instance), 4);
+#ifdef ECL_LWP /* XXX */
+ init_tm(t_cont, "CONT", sizeof(struct ecl_cont), 2);
+ init_tm(t_thread, "THREAD", sizeof(struct ecl_thread), 2);
+#endif
#ifdef ECL_THREADS
init_tm(t_process, "PROCESS", sizeof(struct ecl_process), 8);
init_tm(t_lock, "LOCK", sizeof(struct ecl_lock), 2);
to_bitmap(&o, &(o.instance.clas)) |
to_bitmap(&o, &(o.instance.sig)) |
to_bitmap(&o, &(o.instance.slots));
+# ifdef ECL_LWP /* XXX */
+ type_info[t_cont].descriptor = 0;
+ type_info[t_thread].descriptor = 0;
+# endif
# ifdef ECL_THREADS
type_info[t_process].descriptor =
to_bitmap(&o, &(o.process.name)) |
mark_object(x->cclosure.env);
break;
-#ifdef THREADS
+#ifdef ECL_LWP
case t_cont:
mark_next(x->cn.cn_thread);
break;
*/
mark_next(x->thread.entry);
break;
-#endif THREADS
+#endif ECL_LWP
case t_instance:
mark_object(x->instance.class);
p = x->instance.slots;
mark_object(ECL_NIL);
mark_object(ECL_T);
-#ifdef THREADS
+#ifdef ECL_LWP
{
pd *pdp;
lpd *old_clwp = clwp;
for (pdp = running_head; pdp != (pd *)NULL; pdp = pdp->pd_next) {
clwp = pdp->pd_lpd;
-#endif THREADS
-
+#endif ECL_LWP
+
for (i=0; i<NValues; i++)
mark_object(VALUES(i));
mark_object(bdp->bds_sym);
mark_object(bdp->bds_val);
}
-
+
for (frp = frs_org; frp <= frs_top; frp++) {
mark_object(frp->frs_val);
mark_object(frp->frs_lex);
}
-
+
for (ihsp = ihs_org; ihsp <= ihs_top; ihsp++) {
mark_object(ihsp->ihs_function);
mark_object(ihsp->ihs_base);
mark_object(lex_env);
-#ifdef THREADS
+#ifdef ECL_LWP
/* added to mark newly allocated objects */
mark_object(clwp->lwp_alloc_temporary);
mark_object(clwp->lwp_fmt_temporary_stream);
/* (current-thread) can return it at any time
*/
mark_object(clwp->lwp_thread);
-#endif THREADS
-
+#endif ECL_LWP
/* now collect from the c-stack of the thread ... */
-
{ int *where;
volatile jmp_buf buf;
/* ensure flushing of register caches */
if (ecl_setjmp(buf) == 0) ecl_longjmp(buf, 1);
-#ifdef THREADS
+#ifdef ECL_LWP
if (clwp != old_clwp) /* is not the executing stack */
# ifdef __linux
where = (int *)pdp->pd_env[0].__jmpbuf[0].__sp;
where = (int *)pdp->pd_env[JB_SP];
# endif
else
-#endif THREADS
+#endif ECL_LWP
where = (int *)&where ;
-
/* If the locals of type object in a C function could be
aligned other than on multiples of sizeof (char *)
we would have to mark twice */
-
+
if (where > cs_org)
mark_stack_conservative(where, cs_org);
else
mark_stack_conservative(cs_org, where);
}
-#ifdef THREADS
+#ifdef ECL_LWP
}
clwp = old_clwp;
}
-#endif THREADS
+#endif ECL_LWP
/* mark roots */
for (i = 0; i < gc_roots; i++)
for (j = i+1;
j < maxpage && type_map[j] == (int)t_contiguous;
j++)
- ;
+ ;
s = pagetochar(i);
e = pagetochar(j);
for (p = s; p < e;) {
cl_object (*GC_exit_hook)() = NULL;
-#ifdef THREADS
-/*
+#ifdef ECL_LWP
+/*
* We execute the GC routine in the main stack.
* The idea is to switch over the main stack that is stopped in the intha
- * and to call the GC from there on garbage_parameter. Then you can switch
+ * and to call the GC from there on garbage_parameter. Then you can switch
* back after.
* In addition the interrupt is disabled.
*/
int i, j;
int tm;
int gc_start = runtime();
-#endif THREADS
+#endif ECL_LWP
if (!GC_enabled())
return;
debug = symbol_value(siVgc_message) != ECL_NIL;
-#ifdef THREADS
+#ifdef ECL_LWP
if (clwp != &main_lpd) {
if (debug) {
printf("*STACK SWITCH*\n");
if (val == 1) {
-#endif THREADS
+#endif ECL_LWP
if (GC_enter_hook != NULL)
(*GC_enter_hook)(0);
if (GC_exit_hook != NULL)
(*GC_exit_hook)();
-#ifdef THREADS
+#ifdef ECL_LWP
- /*
+ /*
* Back in the right stack
*/
stack_switched = FALSE;
end_critical_section(); /* we get here from the GC call in scheduler */
-
+
clwp = old_clwp;
Values = clwp->lwp_Values;
siglongjmp(old_env, 2);
}
}
-#endif THREADS
+#endif ECL_LWP
gc_time += (gc_start = runtime() - gc_start);
if (interrupt_flag) sigint();
#endif unix
-#ifdef THREADS
+#ifdef ECL_LWP
end_critical_section();
-#endif THREADS
+#endif ECL_LWP
}
/*
mark_object(x->cfun.block);
mark_next(x->cclosure.env);
break;
-
+#ifdef ECL_LWP
+ case t_cont:
+ /* XXX */
+ mark_next(x->cont.thread);
+ break;
+ case t_thread:
+ /* Already marked by malloc */
+ /* mark_contblock(x->thread.data, x->thread.size); */
+ mark_next(x->thread.cont);
+ /* mark_next(x->thread.entry); */
+#endif
#ifdef ECL_THREADS
case t_process:
/* Already marked by malloc: x->process.env