X-Git-Url: http://git.hcoop.net/bpt/guile.git/blobdiff_plain/e4d24f3af1c0cd1664912d3277f3f728d75d27d4..e7c5fb37707f8aaab93a7f27f43c544967b309fb:/libguile/async.c diff --git a/libguile/async.c b/libguile/async.c index 1409d155a..72f23e2ef 100644 --- a/libguile/async.c +++ b/libguile/async.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1995,1996 Free Software Foundation, Inc. +/* Copyright (C) 1995,1996,1997 Free Software Foundation, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -12,7 +12,8 @@ * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to - * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307 USA * * As a special exception, the Free Software Foundation gives permission * for additional uses of the text contained in its release of GUILE. @@ -36,8 +37,7 @@ * * If you write modifications of your own for GUILE, it is your choice * whether to permit this exception to apply to your modifications. - * If you do not wish that, delete this exception notice. - */ + * If you do not wish that, delete this exception notice. */ #include @@ -84,9 +84,10 @@ * */ - -#define min(A,B) ((A) < (B) ? (A) : (B)) - +/* True between SCM_DEFER_INTS and SCM_ALLOW_INTS, and + * when the interpreter is not running at all. + */ +int scm_ints_disabled = 1; unsigned int scm_async_clock = 20; static unsigned int scm_async_rate = 20; @@ -99,35 +100,14 @@ static unsigned int scm_switch_clock = 0; static unsigned int scm_switch_rate = 0; static unsigned int scm_desired_switch_rate = 0; -static SCM system_signal_asyncs[SCM_NUM_SIGS]; -static SCM handler_var; -static SCM symbol_signal; - - -struct scm_async -{ - int got_it; /* needs to be delivered? */ - SCM thunk; /* the handler. */ -}; - - static long scm_tc16_async; -#define SCM_ASYNCP(X) (scm_tc16_async == SCM_GCTYP16 (X)) -#define SCM_ASYNC(X) ((struct scm_async *)SCM_CDR (X)) - - - - -#ifdef __STDC__ -static int -asyncs_pending (void) -#else +static int asyncs_pending SCM_P ((void)); + static int asyncs_pending () -#endif { SCM pos; pos = scm_asyncs; @@ -144,14 +124,18 @@ asyncs_pending () return 0; } +#if 0 +static SCM scm_sys_tick_async_thunk SCM_P ((void)); +static SCM +scm_sys_tick_async_thunk () +{ + scm_deliver_signal (SCM_TICK_SIGNAL); + return SCM_BOOL_F; +} +#endif -#ifdef __STDC__ -void -scm_async_click (void) -#else void scm_async_click () -#endif { int owe_switch; int owe_tick; @@ -227,8 +211,10 @@ scm_async_click () } } - if (owe_tick) - scm_async_mark (system_signal_asyncs[SCM_SIG_ORD(SCM_TICK_SIGNAL)]); + /* + if (owe_tick) + scm_async_mark (system_signal_asyncs[SCM_SIG_ORD(SCM_TICK_SIGNAL)]); + */ SCM_DEFER_INTS; if (scm_tick_rate && scm_switch_rate) @@ -266,65 +252,39 @@ scm_async_click () -#ifdef __STDC__ -void -scm_switch (void) -#else + void scm_switch () -#endif -{} - - -#ifdef __STDC__ -static void -scm_deliver_signal (int num) -#else -static void -scm_deliver_signal (num) - int num; -#endif { - SCM handler; - handler = SCM_CDR (handler_var); - if (handler != SCM_BOOL_F) - scm_apply (handler, SCM_MAKINUM (num), scm_listofnull); - else - { - scm_mask_ints = 0; - scm_throw (symbol_signal, - scm_listify (SCM_MAKINUM (num), SCM_UNDEFINED)); - } +#if 0 /* Thread switching code should probably reside here, but the + async switching code doesn't seem to work, so it's put in the + SCM_ASYNC_TICK macro instead. /mdj */ + SCM_THREAD_SWITCHING_CODE; +#endif } - -#ifdef __STDC__ -static int -print_async (SCM exp, SCM port, scm_print_state *pstate) -#else +static int print_async SCM_P ((SCM exp, SCM port, scm_print_state *pstate)); + static int print_async (exp, port, pstate) SCM exp; SCM port; scm_print_state *pstate; -#endif { - scm_gen_puts (scm_regular_string, "#', port); + scm_putc('>', port); return 1; } -#ifdef __STDC__ -static SCM -mark_async (SCM obj) -#else + +static SCM mark_async SCM_P ((SCM obj)); + static SCM mark_async (obj) SCM obj; -#endif { struct scm_async * it; if (SCM_GC8MARKP (obj)) @@ -334,14 +294,12 @@ mark_async (obj) return it->thunk; } -#ifdef __STDC__ -static scm_sizet -free_async (SCM obj) -#else + +static scm_sizet free_async SCM_P ((SCM obj)); + static scm_sizet -free_async (SCM obj) +free_async (obj) SCM obj; -#endif { struct scm_async * it; it = SCM_ASYNC (obj); @@ -362,14 +320,10 @@ static scm_smobfuns async_smob = SCM_PROC(s_async, "async", 1, 0, 0, scm_async); -#ifdef __STDC__ -SCM -scm_async (SCM thunk) -#else + SCM scm_async (thunk) SCM thunk; -#endif { SCM it; struct scm_async * async; @@ -387,14 +341,10 @@ scm_async (thunk) } SCM_PROC(s_system_async, "system-async", 1, 0, 0, scm_system_async); -#ifdef __STDC__ -SCM -scm_system_async (SCM thunk) -#else + SCM scm_system_async (thunk) SCM thunk; -#endif { SCM it; SCM list; @@ -410,14 +360,10 @@ scm_system_async (thunk) } SCM_PROC(s_async_mark, "async-mark", 1, 0, 0, scm_async_mark); -#ifdef __STDC__ -SCM -scm_async_mark (SCM a) -#else + SCM scm_async_mark (a) SCM a; -#endif { struct scm_async * it; SCM_ASSERT (SCM_NIMP (a) && SCM_ASYNCP (a), a, SCM_ARG1, s_async_mark); @@ -428,14 +374,10 @@ scm_async_mark (a) SCM_PROC(s_system_async_mark, "system-async-mark", 1, 0, 0, scm_system_async_mark); -#ifdef __STDC__ -SCM -scm_system_async_mark (SCM a) -#else + SCM scm_system_async_mark (a) SCM a; -#endif { struct scm_async * it; SCM_ASSERT (SCM_NIMP (a) && SCM_ASYNCP (a), a, SCM_ARG1, s_async_mark); @@ -450,14 +392,10 @@ scm_system_async_mark (a) SCM_PROC(s_run_asyncs, "run-asyncs", 1, 0, 0, scm_run_asyncs); -#ifdef __STDC__ -SCM -scm_run_asyncs (SCM list_of_a) -#else + SCM scm_run_asyncs (list_of_a) SCM list_of_a; -#endif { SCM pos; @@ -488,14 +426,10 @@ scm_run_asyncs (list_of_a) SCM_PROC(s_noop, "noop", 0, 0, 1, scm_noop); -#ifdef __STDC__ -SCM -scm_noop (SCM args) -#else + SCM scm_noop (args) SCM args; -#endif { return (SCM_NULLP (args) ? SCM_BOOL_F @@ -506,14 +440,10 @@ scm_noop (args) SCM_PROC(s_set_tick_rate, "set-tick-rate", 1, 0, 0, scm_set_tick_rate); -#ifdef __STDC__ -SCM -scm_set_tick_rate (SCM n) -#else + SCM scm_set_tick_rate (n) SCM n; -#endif { unsigned int old_n; SCM_ASSERT (SCM_INUMP (n), n, SCM_ARG1, s_set_tick_rate); @@ -528,14 +458,10 @@ scm_set_tick_rate (n) SCM_PROC(s_set_switch_rate, "set-switch-rate", 1, 0, 0, scm_set_switch_rate); -#ifdef __STDC__ -SCM -scm_set_switch_rate (SCM n) -#else + SCM scm_set_switch_rate (n) SCM n; -#endif { unsigned int old_n; SCM_ASSERT (SCM_INUMP (n), n, SCM_ARG1, s_set_switch_rate); @@ -548,145 +474,33 @@ scm_set_switch_rate (n) -#ifdef __STDC__ -static SCM -scm_sys_hup_async_thunk (void) -#else -static SCM -scm_sys_hup_async_thunk () -#endif -{ - scm_deliver_signal (SCM_HUP_SIGNAL); - return SCM_BOOL_F; -} - -#ifdef __STDC__ -static SCM -scm_sys_int_async_thunk (void) -#else -static SCM -scm_sys_int_async_thunk () -#endif -{ - scm_deliver_signal (SCM_INT_SIGNAL); - return SCM_BOOL_F; -} - -#ifdef __STDC__ -static SCM -scm_sys_fpe_async_thunk (void) -#else -static SCM -scm_sys_fpe_async_thunk () -#endif -{ - scm_deliver_signal (SCM_FPE_SIGNAL); - return SCM_BOOL_F; -} +/* points to the GC system-async, so that scm_gc_end can find it. */ +SCM scm_gc_async; -#ifdef __STDC__ -static SCM -scm_sys_bus_async_thunk (void) -#else -static SCM -scm_sys_bus_async_thunk () -#endif -{ - scm_deliver_signal (SCM_BUS_SIGNAL); - return SCM_BOOL_F; -} - -#ifdef __STDC__ -static SCM -scm_sys_segv_async_thunk (void) -#else -static SCM -scm_sys_segv_async_thunk () -#endif -{ - scm_deliver_signal (SCM_SEGV_SIGNAL); - return SCM_BOOL_F; -} - -#ifdef __STDC__ -static SCM -scm_sys_alrm_async_thunk (void) -#else -static SCM -scm_sys_alrm_async_thunk () -#endif -{ - scm_deliver_signal (SCM_ALRM_SIGNAL); - return SCM_BOOL_F; -} +/* the vcell for gc-thunk. */ +static SCM scm_gc_vcell; -#ifdef __STDC__ +/* the thunk installed in the GC system-async, which is marked at the + end of garbage collection. */ static SCM scm_sys_gc_async_thunk (void) -#else -static SCM -scm_sys_gc_async_thunk () -#endif { - scm_deliver_signal (SCM_GC_SIGNAL); - return SCM_BOOL_F; -} - -#ifdef __STDC__ -static SCM -scm_sys_tick_async_thunk (void) -#else -static SCM -scm_sys_tick_async_thunk () -#endif -{ - scm_deliver_signal (SCM_TICK_SIGNAL); - return SCM_BOOL_F; -} - - - - - -#ifdef __STDC__ -SCM -scm_take_signal (int n) -#else -SCM -scm_take_signal (n) - int n; -#endif -{ - SCM ignored; - if (!scm_ints_disabled) + if (SCM_NFALSEP (scm_gc_vcell)) { - /* For reasons of speed, the SCM_NEWCELL macro doesn't defer - interrupts. Instead, it first sets its argument to point to - the first cell in the list, and then advances the freelist - pointer to the next cell. Now, if this procedure is - interrupted, the only anomalous state possible is to have - both SCM_NEWCELL's argument and scm_freelist pointing to the - same cell. To deal with this case, we always throw away the - first cell in scm_freelist here. - - At least, that's the theory. I'm not convinced that that's - the only anomalous path we need to worry about. */ - SCM_NEWCELL (ignored); + SCM proc = SCM_CDR (scm_gc_vcell); + + if (SCM_NFALSEP (proc) && !SCM_UNBNDP (proc)) + scm_apply (proc, SCM_EOL, SCM_EOL); } - scm_system_async_mark (system_signal_asyncs[SCM_SIG_ORD(n)]); - return SCM_BOOL_F; + return SCM_UNSPECIFIED; } SCM_PROC(s_unmask_signals, "unmask-signals", 0, 0, 0, scm_unmask_signals); -#ifdef __STDC__ -SCM -scm_unmask_signals (void) -#else + SCM scm_unmask_signals () -#endif { scm_mask_ints = 0; return SCM_UNSPECIFIED; @@ -694,13 +508,9 @@ scm_unmask_signals () SCM_PROC(s_mask_signals, "mask-signals", 0, 0, 0, scm_mask_signals); -#ifdef __STDC__ -SCM -scm_mask_signals (void) -#else + SCM scm_mask_signals () -#endif { scm_mask_ints = 1; return SCM_UNSPECIFIED; @@ -708,46 +518,15 @@ scm_mask_signals () -#ifdef __STDC__ -void -scm_init_async (void) -#else void scm_init_async () -#endif { SCM a_thunk; scm_tc16_async = scm_newsmob (&async_smob); - symbol_signal = SCM_CAR (scm_sysintern ("signal", SCM_UNDEFINED)); - scm_permanent_object (symbol_signal); - - /* These are in the opposite order of delivery priortity. - * - * Error conditions are given low priority: - */ - a_thunk = scm_make_gsubr ("%hup-thunk", 0, 0, 0, scm_sys_hup_async_thunk); - system_signal_asyncs[SCM_SIG_ORD(SCM_HUP_SIGNAL)] = scm_system_async (a_thunk); - a_thunk = scm_make_gsubr ("%int-thunk", 0, 0, 0, scm_sys_int_async_thunk); - system_signal_asyncs[SCM_SIG_ORD(SCM_INT_SIGNAL)] = scm_system_async (a_thunk); - a_thunk = scm_make_gsubr ("%fpe-thunk", 0, 0, 0, scm_sys_fpe_async_thunk); - system_signal_asyncs[SCM_SIG_ORD(SCM_FPE_SIGNAL)] = scm_system_async (a_thunk); - a_thunk = scm_make_gsubr ("%bus-thunk", 0, 0, 0, scm_sys_bus_async_thunk); - system_signal_asyncs[SCM_SIG_ORD(SCM_BUS_SIGNAL)] = scm_system_async (a_thunk); - a_thunk = scm_make_gsubr ("%segv-thunk", 0, 0, 0, scm_sys_segv_async_thunk); - system_signal_asyncs[SCM_SIG_ORD(SCM_SEGV_SIGNAL)] = scm_system_async (a_thunk); - + scm_gc_vcell = scm_sysintern ("gc-thunk", SCM_BOOL_F); a_thunk = scm_make_gsubr ("%gc-thunk", 0, 0, 0, scm_sys_gc_async_thunk); - system_signal_asyncs[SCM_SIG_ORD(SCM_GC_SIGNAL)] = scm_system_async (a_thunk); - - /* Clock and PC driven conditions are given highest priority. */ - a_thunk = scm_make_gsubr ("%tick-thunk", 0, 0, 0, scm_sys_tick_async_thunk); - system_signal_asyncs[SCM_SIG_ORD(SCM_TICK_SIGNAL)] = scm_system_async (a_thunk); - a_thunk = scm_make_gsubr ("%alrm-thunk", 0, 0, 0, scm_sys_alrm_async_thunk); - system_signal_asyncs[SCM_SIG_ORD(SCM_ALRM_SIGNAL)] = scm_system_async (a_thunk); + scm_gc_async = scm_system_async (a_thunk); - handler_var = scm_sysintern ("signal-handler", SCM_UNDEFINED); - SCM_SETCDR (handler_var, SCM_BOOL_F); - scm_permanent_object (handler_var); #include "async.x" }