factor/native/unix/signal.c

75 lines
1.8 KiB
C

#include "../factor.h"
void signal_handler(int signal, siginfo_t* siginfo, void* uap)
{
if(active.here > active.limit)
{
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);
exit(1);
}
else
signal_error(signal);
}
/* 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);
if(TAG(obj) == WORD_TYPE)
untag_word(obj)->call_count++;
}
executing->call_count++;
}
void init_signals(void)
{
struct sigaction custom_sigaction;
struct sigaction profiling_sigaction;
struct sigaction ign_sigaction;
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;
ign_sigaction.sa_handler = SIG_IGN;
sigaction(SIGABRT,&custom_sigaction,NULL);
sigaction(SIGFPE,&custom_sigaction,NULL);
sigaction(SIGBUS,&custom_sigaction,NULL);
sigaction(SIGSEGV,&custom_sigaction,NULL);
sigaction(SIGPIPE,&ign_sigaction,NULL);
sigaction(SIGPROF,&profiling_sigaction,NULL);
}
void primitive_call_profiling(void)
{
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)
io_error(__FUNCTION__);
}