2004-12-10 22:47:03 -05:00
|
|
|
#include "../factor.h"
|
2004-10-17 19:01:16 -04:00
|
|
|
|
|
|
|
void signal_handler(int signal, siginfo_t* siginfo, void* uap)
|
|
|
|
{
|
2004-11-08 22:36:51 -05:00
|
|
|
if(active.here > active.limit)
|
2004-10-17 19:01:16 -04:00
|
|
|
{
|
|
|
|
fprintf(stderr,"Out of memory\n");
|
|
|
|
fprintf(stderr,"active.base = %ld\n",active.base);
|
|
|
|
fprintf(stderr,"active.here = %ld\n",active.here);
|
|
|
|
fprintf(stderr,"active.limit = %ld\n",active.limit);
|
|
|
|
fflush(stderr);
|
2005-01-25 19:40:57 -05:00
|
|
|
flip_zones();
|
|
|
|
dump_stacks();
|
2004-10-17 19:01:16 -04:00
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
else
|
2004-11-09 12:29:25 -05:00
|
|
|
signal_error(signal);
|
2004-10-17 19:01:16 -04:00
|
|
|
}
|
|
|
|
|
2004-12-29 03:35:46 -05:00
|
|
|
void dump_stack_signal(int signal, siginfo_t* siginfo, void* uap)
|
|
|
|
{
|
|
|
|
dump_stacks();
|
|
|
|
}
|
|
|
|
|
2004-10-17 19:01:16 -04:00
|
|
|
/* Called from a signal handler. XXX - is this safe? */
|
|
|
|
void call_profiling_step(int signal, siginfo_t* siginfo, void* uap)
|
|
|
|
{
|
|
|
|
CELL depth = (cs - cs_bot) / CELLS;
|
|
|
|
int i;
|
|
|
|
CELL obj;
|
|
|
|
for(i = profile_depth; i < depth; i++)
|
|
|
|
{
|
|
|
|
obj = get(cs_bot + i * CELLS);
|
2005-01-14 19:51:38 -05:00
|
|
|
if(type_of(obj) == WORD_TYPE)
|
2004-10-17 19:01:16 -04:00
|
|
|
untag_word(obj)->call_count++;
|
|
|
|
}
|
|
|
|
|
2004-12-31 02:38:58 -05:00
|
|
|
untag_word_fast(executing)->call_count++;
|
2004-10-17 19:01:16 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
void init_signals(void)
|
|
|
|
{
|
|
|
|
struct sigaction custom_sigaction;
|
|
|
|
struct sigaction profiling_sigaction;
|
|
|
|
struct sigaction ign_sigaction;
|
2004-12-29 03:35:46 -05:00
|
|
|
struct sigaction dump_sigaction;
|
2004-10-17 19:01:16 -04:00
|
|
|
custom_sigaction.sa_sigaction = signal_handler;
|
|
|
|
custom_sigaction.sa_flags = SA_SIGINFO;
|
|
|
|
profiling_sigaction.sa_sigaction = call_profiling_step;
|
|
|
|
profiling_sigaction.sa_flags = SA_SIGINFO;
|
2004-12-29 03:35:46 -05:00
|
|
|
dump_sigaction.sa_sigaction = dump_stack_signal;
|
|
|
|
dump_sigaction.sa_flags = SA_SIGINFO;
|
2004-10-17 19:01:16 -04:00
|
|
|
ign_sigaction.sa_handler = SIG_IGN;
|
|
|
|
sigaction(SIGABRT,&custom_sigaction,NULL);
|
|
|
|
sigaction(SIGFPE,&custom_sigaction,NULL);
|
2004-11-09 12:29:25 -05:00
|
|
|
sigaction(SIGBUS,&custom_sigaction,NULL);
|
|
|
|
sigaction(SIGSEGV,&custom_sigaction,NULL);
|
2004-10-17 19:01:16 -04:00
|
|
|
sigaction(SIGPIPE,&ign_sigaction,NULL);
|
|
|
|
sigaction(SIGPROF,&profiling_sigaction,NULL);
|
2004-12-29 03:35:46 -05:00
|
|
|
sigaction(SIGQUIT,&dump_sigaction,NULL);
|
2004-10-17 19:01:16 -04:00
|
|
|
}
|
|
|
|
|
2005-02-08 17:05:08 -05:00
|
|
|
void primitive_call_profiling(F_WORD *word)
|
2004-10-17 19:01:16 -04:00
|
|
|
{
|
|
|
|
CELL d = dpop();
|
|
|
|
if(d == F)
|
|
|
|
{
|
|
|
|
timerclear(&prof_timer.it_interval);
|
|
|
|
timerclear(&prof_timer.it_value);
|
|
|
|
|
|
|
|
profile_depth = 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
prof_timer.it_interval.tv_sec = 0;
|
|
|
|
prof_timer.it_interval.tv_usec = 1000;
|
|
|
|
prof_timer.it_value.tv_sec = 0;
|
|
|
|
prof_timer.it_value.tv_usec = 1000;
|
|
|
|
|
|
|
|
profile_depth = to_fixnum(d);
|
|
|
|
}
|
|
|
|
|
|
|
|
if(setitimer(ITIMER_PROF,&prof_timer,NULL) < 0)
|
2005-05-01 14:30:53 -04:00
|
|
|
io_error();
|
2004-10-17 19:01:16 -04:00
|
|
|
}
|