18static char SccsId[] =
"%W% %G%";
21#define HAS_CACHE_REGS 1
36#include "tab.macros.h"
50#ifdef LOW_LEVEL_TRACER
59static yap_signals InteractSIGINT(
int ch) {
70 Yap_ThrowError(ABORT_EVENT,TermDAbort,NULL);
71 return YAP_ABORT_SIGNAL;
74 Yap_suspend_goal(TermBreak);
75 return YAP_BREAK_SIGNAL;
81 Yap_suspend_goal(TermDebug);
82 return YAP_DEBUG_SIGNAL;
86 return YAP_EXIT_SIGNAL;
89 return YAP_STACK_DUMP_SIGNAL;
92 Yap_suspend_goal(TermTrace);
93 return YAP_TRACE_SIGNAL;
94#ifdef LOW_LEVEL_TRACER
96 toggle_low_level_trace();
101 Yap_suspend_goal(TermStatistics);
102 return YAP_STATISTICS_SIGNAL;
104 return YAP_NO_SIGNAL;
109 fprintf(stderr,
"Please press one of:\n");
110 fprintf(stderr,
" a for abort\n c for continue\n d for debug\n");
111 fprintf(stderr,
" e for exit\n g for stack dump\n s for statistics\n t "
113 fprintf(stderr,
" b for break\n");
114 return YAP_NO_SIGNAL;
124static yap_signals ProcessSIGINT(
void) {
130 return YAP_INT_SIGNAL;
134 return YAP_INT_SIGNAL;
137 LOCAL_PrologMode |= AsyncIntMode;
139 ch = Yap_GetCharForSIGINT();
140 }
while (!(out = InteractSIGINT(ch)));
141 LOCAL_PrologMode &= ~AsyncIntMode;
145inline static void do_signal(
int wid, yap_signals sig USES_REGS) {
147 __sync_fetch_and_or(&REMOTE(wid)->Signals_, SIGNAL_TO_BIT(sig));
148 if (!REMOTE_InterruptsDisabled(wid)) {
149 REMOTE_ThreadHandle(wid).current_yaam_regs->CreepFlag_ =
150 Unsigned(REMOTE_ThreadHandle(wid).current_yaam_regs->LCL0_);
153 if (!LOCAL_InterruptsDisabled) {
154 LOCAL_Signals |= SIGNAL_TO_BIT(sig);
155 CreepFlag = Unsigned(LCL0);
160inline static bool get_signal(yap_signals sig USES_REGS) {
165 CalculateStackGap(PASS_REGS1);
167 if ((old = __sync_fetch_and_and(&LOCAL_Signals, ~SIGNAL_TO_BIT(sig))) !=
168 SIGNAL_TO_BIT(sig)) {
169 if (!LOCAL_InterruptsDisabled && LOCAL_Signals != 0) {
170 CreepFlag = (CELL)LCL0;
172 if (!(old & SIGNAL_TO_BIT(sig))) {
183 if (LOCAL_Signals & SIGNAL_TO_BIT(sig)) {
184 LOCAL_Signals &= ~SIGNAL_TO_BIT(sig);
185 if (!LOCAL_InterruptsDisabled && LOCAL_Signals != 0) {
186 CreepFlag = (CELL)LCL0;
188 CalculateStackGap(PASS_REGS1);
197bool Yap_DisableInterrupts(
int wid) {
198 LOCAL_InterruptsDisabled =
true;
199 LOCAL_debugger_state[DEBUG_DEBUG] = TermFalse;
200 LOCAL_InterruptsDisabled =
true;
201 YAPEnterCriticalSection();
205bool Yap_EnableInterrupts(
int wid ) {
206 LOCAL_debugger_state[DEBUG_DEBUG]= getAtomicLocalPrologFlag(DEBUG_FLAG);
207 LOCAL_InterruptsDisabled =
false;
208 YAPLeaveCriticalSection();
215bool Yap_HandleSIGINT(
void) {
220 if ((sig = ProcessSIGINT()) != YAP_NO_SIGNAL)
221 LOCAL_PrologMode &= ~InterruptMode;
222 do_signal(worker_id, sig PASS_REGS);
224 }
while (get_signal(YAP_INT_SIGNAL PASS_REGS));
229void Yap_signal(yap_signals sig) {
231 do_signal(worker_id, sig PASS_REGS);
236static Int p_debug(USES_REGS1);
239void Yap_external_signal(
int wid, yap_signals sig) {
241 REGSTORE *regcache = REMOTE_ThreadHandle(wid).current_yaam_regs;
243 do_signal(wid, sig PASS_REGS);
244 LOCAL_PrologMode &= ~InterruptMode;
247int Yap_get_signal__(yap_signals sig USES_REGS) {
248 return get_signal(sig PASS_REGS);
252int Yap_has_signals__(yap_signals sig1, yap_signals sig2 USES_REGS) {
253 return LOCAL_Signals & (SIGNAL_TO_BIT(sig1) | SIGNAL_TO_BIT(sig2));
256int Yap_only_has_signals__(yap_signals sig1, yap_signals sig2 USES_REGS) {
257 uint64_t sigs = LOCAL_Signals;
258 return sigs & (SIGNAL_TO_BIT(sig1) | SIGNAL_TO_BIT(sig2)) &&
259 !(sigs & ~(SIGNAL_TO_BIT(sig1) | SIGNAL_TO_BIT(sig2)));
264volatile int volat = 0;
266static Int p_debug(USES_REGS1) {
267 int i = IntOfTerm(Deref(ARG1));
270 if (i >=
'a' && i <=
'z')
271 GLOBAL_Option[i - 96] = !GLOBAL_Option[i - 96];
275void Yap_debug_end_loop(
void);
282void Yap_debug_end_loop(
void) { volat = 1; }
285static Term sig_to_term(yap_signals sig)
291 case YAP_ABORT_SIGNAL:
293 case YAP_CREEP_SIGNAL:
295 case YAP_TRACE_SIGNAL:
297 case YAP_DEBUG_SIGNAL:
299 case YAP_BREAK_SIGNAL:
301 case YAP_FAIL_SIGNAL:
303 case YAP_STACK_DUMP_SIGNAL:
304 return TermSigStackDump;
305 case YAP_STATISTICS_SIGNAL:
306 return TermSigStatistics;
308 case YAP_ALARM_SIGNAL:
310 case YAP_WINTIMER_SIGNAL:
313 case YAP_VTALARM_SIGNAL:
314 return TermSigVTAlarm;
316 case YAP_EXIT_SIGNAL:
319 case YAP_WAKEUP_SIGNAL:
320 return TermSigWakeUp;
324 case YAP_PIPE_SIGNAL:
332 case YAP_USR1_SIGNAL:
336 case YAP_USR2_SIGNAL:
346 return MkAtomTerm(at);
350Term Yap_next_signal( USES_REGS1 )
353 uint64_t mask = LOCAL_Signals;
356#if HAVE___BUILTIN_FFSLL
357 sig = __builtin_ffsll(mask);
361 sig = Yap_msb(mask PASS_REGS) + 1;
363 if (get_signal(sig PASS_REGS))
364 return sig_to_term(sig);
371static Int first_signal(USES_REGS1) {
374 while((t = Yap_next_signal(PASS_REGS1))) {
375 if (t == TermSigInt) {
376 yap_signals sig = ProcessSIGINT();
377 if (sig == YAP_INT_SIGNAL) {
380 if (sig != YAP_NO_SIGNAL)
383 }
else if (t == TermDAbort) {
385 LOCAL_PrologMode &= ~AsyncIntMode;
386 if (LOCAL_PrologMode & (GCMode | ConsoleGetcMode | CritMode)) {
387 LOCAL_PrologMode |= AbortMode;
390 Yap_Error(ABORT_EVENT, TermNil,
"abort from console");
398 return Yap_unify(ARG1, t);
401static Int continue_signals(USES_REGS1) {
return first_signal(PASS_REGS1); }
403void Yap_InitSignalCPreds(
void) {
405 Yap_InitCPred(
"$first_signal", 1, first_signal, SafePredFlag | SyncPredFlag);
406 Yap_InitCPred(
"$continue_signals", 0, continue_signals,
407 SafePredFlag | SyncPredFlag);
409 Yap_InitCPred(
"sys_debug", 1, p_debug, SafePredFlag | SyncPredFlag);
413void * Yap_InitSignals(
int wid) {
414 void *ptr = (
void *)malloc(
sizeof(UInt) * REMOTE_MaxActiveSignals(wid));