This repository has been archived on 2023-08-20. You can view files and clone it, but cannot push or open issues or pull requests.
Vitor Santos Costa d163cadda1 pass regs when constructing long ints and floats.
fix small gcc complaints.
2013-03-26 15:01:52 -05:00

379 lines
9.9 KiB
C

/*************************************************************************
* *
* YAP Prolog *
* *
* Yap Prolog was developed at NCCUP - Universidade do Porto *
* *
* Copyright L.Damas, V. Santos Costa and Universidade do Porto 1985-- *
* *
**************************************************************************
* *
* File: signal.c *
* comments: Signal Handling & Debugger Support *
* *
* *
* *
*************************************************************************/
#ifdef SCCS
static char SccsId[] = "%W% %G%";
#endif
#define HAS_CACHE_REGS 1
#include "Yap.h"
#include "Yatom.h"
#include "YapHeap.h"
#include "eval.h"
#include "yapio.h"
#ifdef TABLING
#include "tab.macros.h"
#endif /* TABLING */
#include <stdio.h>
#if HAVE_STRING_H
#include <string.h>
#endif
#if HAVE_MALLOC_H
#include <malloc.h>
#endif
#include <wchar.h>
inline static void
do_signal(yap_signals sig USES_REGS)
{
LOCK(LOCAL_SignalLock);
if (!LOCAL_InterruptsDisabled)
CreepFlag = Unsigned(LCL0);
LOCAL_ActiveSignals |= sig;
UNLOCK(LOCAL_SignalLock);
}
inline static void
undo_signal(yap_signals sig USES_REGS)
{
LOCK(LOCAL_SignalLock);
if ((LOCAL_ActiveSignals & ~(YAP_CREEP_SIGNAL|YAP_DELAY_CREEP_SIGNAL)) == sig) {
CreepFlag = CalculateStackGap();
}
LOCAL_ActiveSignals &= ~sig;
UNLOCK(LOCAL_SignalLock);
}
static Int
p_creep( USES_REGS1 )
{
Atom at;
PredEntry *pred;
at = AtomCreep;
pred = RepPredProp(PredPropByFunc(Yap_MkFunctor(at, 1),0));
CreepCode = pred;
do_signal(YAP_CREEP_SIGNAL PASS_REGS);
return TRUE;
}
static Int
p_stop_creeping( USES_REGS1 )
{
LOCK(LOCAL_SignalLock);
LOCAL_ActiveSignals &= ~(YAP_CREEP_SIGNAL|YAP_DELAY_CREEP_SIGNAL);
if (!LOCAL_ActiveSignals) {
CreepFlag = CalculateStackGap();
}
UNLOCK(LOCAL_SignalLock);
return TRUE;
}
static Int
p_meta_creep( USES_REGS1 )
{
Atom at;
PredEntry *pred;
at = AtomCreep;
pred = RepPredProp(PredPropByFunc(Yap_MkFunctor(at, 1),0));
CreepCode = pred;
LOCK(LOCAL_SignalLock);
LOCAL_ActiveSignals |= YAP_DELAY_CREEP_SIGNAL;
UNLOCK(LOCAL_SignalLock);
return TRUE;
}
static Int
p_creep_allowed( USES_REGS1 )
{
if (PP != NULL) {
LOCK(LOCAL_SignalLock);
if (LOCAL_ActiveSignals & YAP_CREEP_SIGNAL && !LOCAL_InterruptsDisabled) {
LOCAL_ActiveSignals &= ~YAP_CREEP_SIGNAL;
if (!LOCAL_ActiveSignals)
CreepFlag = CalculateStackGap();
UNLOCK(LOCAL_SignalLock);
} else {
UNLOCK(LOCAL_SignalLock);
}
return TRUE;
}
return FALSE;
}
static Int
p_debug_on( USES_REGS1 )
{
Term t = Deref(ARG1);
if (IsVarTerm(t)) {
if (LOCAL_DebugOn)
return Yap_unify(MkAtomTerm(AtomTrue),ARG1);
else
return Yap_unify(MkAtomTerm(AtomFalse),ARG1);
}
if (t == MkAtomTerm(AtomTrue))
LOCAL_DebugOn = TRUE;
else
LOCAL_DebugOn = FALSE;
return TRUE;
}
void
Yap_signal(yap_signals sig)
{
CACHE_REGS
do_signal(sig PASS_REGS);
}
void
Yap_undo_signal(yap_signals sig)
{
CACHE_REGS
undo_signal(sig PASS_REGS);
}
#ifdef DEBUG
static Int
p_debug( USES_REGS1 )
{ /* $debug(+Flag) */
int i = IntOfTerm(Deref(ARG1));
if (i >= 'a' && i <= 'z')
GLOBAL_Option[i - 96] = !GLOBAL_Option[i - 96];
return (1);
}
#endif
static Int
p_first_signal( USES_REGS1 )
{
LOCK(LOCAL_SignalLock);
#ifdef THREADS
pthread_mutex_lock(&(LOCAL_ThreadHandle.tlock));
#endif
/* always do wakeups first, because you don't want to keep the
non-backtrackable variable bad */
if (LOCAL_ActiveSignals & YAP_WAKEUP_SIGNAL) {
LOCAL_ActiveSignals &= ~YAP_WAKEUP_SIGNAL;
#ifdef THREADS
pthread_mutex_unlock(&(LOCAL_ThreadHandle.tlock));
#endif
UNLOCK(LOCAL_SignalLock);
return Yap_unify(ARG1, MkAtomTerm(AtomSigWakeUp));
}
if (LOCAL_ActiveSignals & YAP_ITI_SIGNAL) {
LOCAL_ActiveSignals &= ~YAP_ITI_SIGNAL;
#ifdef THREADS
pthread_mutex_unlock(&(LOCAL_ThreadHandle.tlock));
#endif
UNLOCK(LOCAL_SignalLock);
return Yap_unify(ARG1, MkAtomTerm(AtomSigIti));
}
if (LOCAL_ActiveSignals & YAP_INT_SIGNAL) {
LOCAL_ActiveSignals &= ~YAP_INT_SIGNAL;
#ifdef THREADS
pthread_mutex_unlock(&(LOCAL_ThreadHandle.tlock));
#endif
UNLOCK(LOCAL_SignalLock);
return Yap_unify(ARG1, MkAtomTerm(AtomSigInt));
}
if (LOCAL_ActiveSignals & YAP_USR2_SIGNAL) {
LOCAL_ActiveSignals &= ~YAP_USR2_SIGNAL;
#ifdef THREADS
pthread_mutex_unlock(&(LOCAL_ThreadHandle.tlock));
#endif
UNLOCK(LOCAL_SignalLock);
return Yap_unify(ARG1, MkAtomTerm(AtomSigUsr2));
}
if (LOCAL_ActiveSignals & YAP_USR1_SIGNAL) {
LOCAL_ActiveSignals &= ~YAP_USR1_SIGNAL;
#ifdef THREADS
pthread_mutex_unlock(&(LOCAL_ThreadHandle.tlock));
#endif
UNLOCK(LOCAL_SignalLock);
return Yap_unify(ARG1, MkAtomTerm(AtomSigUsr1));
}
if (LOCAL_ActiveSignals & YAP_PIPE_SIGNAL) {
LOCAL_ActiveSignals &= ~YAP_PIPE_SIGNAL;
#ifdef THREADS
pthread_mutex_unlock(&(LOCAL_ThreadHandle.tlock));
#endif
UNLOCK(LOCAL_SignalLock);
return Yap_unify(ARG1, MkAtomTerm(AtomSigPipe));
}
if (LOCAL_ActiveSignals & YAP_HUP_SIGNAL) {
LOCAL_ActiveSignals &= ~YAP_HUP_SIGNAL;
#ifdef THREADS
pthread_mutex_unlock(&(LOCAL_ThreadHandle.tlock));
#endif
UNLOCK(LOCAL_SignalLock);
return Yap_unify(ARG1, MkAtomTerm(AtomSigHup));
}
if (LOCAL_ActiveSignals & YAP_ALARM_SIGNAL) {
LOCAL_ActiveSignals &= ~YAP_ALARM_SIGNAL;
UNLOCK(LOCAL_SignalLock);
return Yap_unify(ARG1, MkAtomTerm(AtomSigAlarm));
}
if (LOCAL_ActiveSignals & YAP_VTALARM_SIGNAL) {
LOCAL_ActiveSignals &= ~YAP_VTALARM_SIGNAL;
UNLOCK(LOCAL_SignalLock);
return Yap_unify(ARG1, MkAtomTerm(AtomSigVTAlarm));
}
if (LOCAL_ActiveSignals & YAP_DELAY_CREEP_SIGNAL) {
LOCAL_ActiveSignals &= ~(YAP_CREEP_SIGNAL|YAP_DELAY_CREEP_SIGNAL);
#ifdef THREADS
pthread_mutex_unlock(&(LOCAL_ThreadHandle.tlock));
#endif
UNLOCK(LOCAL_SignalLock);
return Yap_unify(ARG1, MkAtomTerm(AtomSigDelayCreep));
}
if (LOCAL_ActiveSignals & YAP_CREEP_SIGNAL) {
LOCAL_ActiveSignals &= ~YAP_CREEP_SIGNAL;
#ifdef THREADS
pthread_mutex_unlock(&(LOCAL_ThreadHandle.tlock));
#endif
UNLOCK(LOCAL_SignalLock);
return Yap_unify(ARG1, MkAtomTerm(AtomSigCreep));
}
if (LOCAL_ActiveSignals & YAP_TRACE_SIGNAL) {
LOCAL_ActiveSignals &= ~YAP_TRACE_SIGNAL;
#ifdef THREADS
pthread_mutex_unlock(&(LOCAL_ThreadHandle.tlock));
#endif
UNLOCK(LOCAL_SignalLock);
return Yap_unify(ARG1, MkAtomTerm(AtomSigTrace));
}
if (LOCAL_ActiveSignals & YAP_DEBUG_SIGNAL) {
LOCAL_ActiveSignals &= ~YAP_DEBUG_SIGNAL;
#ifdef THREADS
pthread_mutex_unlock(&(LOCAL_ThreadHandle.tlock));
#endif
UNLOCK(LOCAL_SignalLock);
return Yap_unify(ARG1, MkAtomTerm(AtomSigDebug));
}
if (LOCAL_ActiveSignals & YAP_BREAK_SIGNAL) {
LOCAL_ActiveSignals &= ~YAP_BREAK_SIGNAL;
#ifdef THREADS
pthread_mutex_unlock(&(LOCAL_ThreadHandle.tlock));
#endif
UNLOCK(LOCAL_SignalLock);
return Yap_unify(ARG1, MkAtomTerm(AtomSigBreak));
}
if (LOCAL_ActiveSignals & YAP_STACK_DUMP_SIGNAL) {
LOCAL_ActiveSignals &= ~YAP_STACK_DUMP_SIGNAL;
#ifdef THREADS
pthread_mutex_unlock(&(LOCAL_ThreadHandle.tlock));
#endif
UNLOCK(LOCAL_SignalLock);
return Yap_unify(ARG1, MkAtomTerm(AtomSigStackDump));
}
if (LOCAL_ActiveSignals & YAP_STATISTICS_SIGNAL) {
LOCAL_ActiveSignals &= ~YAP_STATISTICS_SIGNAL;
#ifdef THREADS
pthread_mutex_unlock(&(LOCAL_ThreadHandle.tlock));
#endif
UNLOCK(LOCAL_SignalLock);
return Yap_unify(ARG1, MkAtomTerm(AtomSigStatistics));
}
if (LOCAL_ActiveSignals & YAP_FAIL_SIGNAL) {
LOCAL_ActiveSignals &= ~YAP_FAIL_SIGNAL;
#ifdef THREADS
pthread_mutex_unlock(&(LOCAL_ThreadHandle.tlock));
#endif
UNLOCK(LOCAL_SignalLock);
return Yap_unify(ARG1, MkAtomTerm(AtomFail));
}
#ifdef THREADS
pthread_mutex_unlock(&(LOCAL_ThreadHandle.tlock));
#endif
UNLOCK(LOCAL_SignalLock);
return FALSE;
}
static Int
p_continue_signals( USES_REGS1 )
{
/* hack to force the signal anew */
if (LOCAL_ActiveSignals & YAP_ITI_SIGNAL) {
Yap_signal(YAP_ITI_SIGNAL);
}
if (LOCAL_ActiveSignals & YAP_INT_SIGNAL) {
Yap_signal(YAP_INT_SIGNAL);
}
if (LOCAL_ActiveSignals & YAP_USR2_SIGNAL) {
Yap_signal(YAP_USR2_SIGNAL);
}
if (LOCAL_ActiveSignals & YAP_USR1_SIGNAL) {
Yap_signal(YAP_USR1_SIGNAL);
}
if (LOCAL_ActiveSignals & YAP_HUP_SIGNAL) {
Yap_signal(YAP_HUP_SIGNAL);
}
if (LOCAL_ActiveSignals & YAP_ALARM_SIGNAL) {
Yap_signal(YAP_ALARM_SIGNAL);
}
if (LOCAL_ActiveSignals & YAP_VTALARM_SIGNAL) {
Yap_signal(YAP_VTALARM_SIGNAL);
}
if (LOCAL_ActiveSignals & YAP_CREEP_SIGNAL) {
Yap_signal(YAP_CREEP_SIGNAL);
}
if (LOCAL_ActiveSignals & YAP_DELAY_CREEP_SIGNAL) {
Yap_signal(YAP_DELAY_CREEP_SIGNAL|YAP_CREEP_SIGNAL);
}
if (LOCAL_ActiveSignals & YAP_TRACE_SIGNAL) {
Yap_signal(YAP_TRACE_SIGNAL);
}
if (LOCAL_ActiveSignals & YAP_DEBUG_SIGNAL) {
Yap_signal(YAP_DEBUG_SIGNAL);
}
if (LOCAL_ActiveSignals & YAP_BREAK_SIGNAL) {
Yap_signal(YAP_BREAK_SIGNAL);
}
if (LOCAL_ActiveSignals & YAP_STACK_DUMP_SIGNAL) {
Yap_signal(YAP_STACK_DUMP_SIGNAL);
}
if (LOCAL_ActiveSignals & YAP_STATISTICS_SIGNAL) {
Yap_signal(YAP_STATISTICS_SIGNAL);
}
if (LOCAL_ActiveSignals & YAP_FAIL_SIGNAL) {
Yap_signal(YAP_FAIL_SIGNAL);
}
#ifdef THREADS
pthread_mutex_unlock(&(LOCAL_ThreadHandle.tlock));
#endif
return TRUE;
}
void
Yap_InitSignalCPreds(void)
{
/* Basic predicates for the debugger */
Yap_InitCPred("$creep", 0, p_creep, SafePredFlag);
Yap_InitCPred("$meta_creep", 0, p_meta_creep, SafePredFlag);
Yap_InitCPred("$stop_creeping", 0, p_stop_creeping, SafePredFlag);
Yap_InitCPred ("$first_signal", 1, p_first_signal, SafePredFlag|SyncPredFlag);
Yap_InitCPred ("$continue_signals", 0, p_continue_signals, SafePredFlag|SyncPredFlag);
Yap_InitCPred("$debug_on", 1, p_debug_on, 0);
Yap_InitCPred("$creep_allowed", 0, p_creep_allowed, 0);
#ifdef DEBUG
Yap_InitCPred("$debug", 1, p_debug, SafePredFlag|SyncPredFlag);
#endif
}