| 
									
										
										
										
											2013-02-08 10:36:45 -06:00
										 |  |  | /*************************************************************************
 | 
					
						
							| 
									
										
										
										
											2014-09-02 14:19:23 -05:00
										 |  |  |  *									 * | 
					
						
							|  |  |  |  *	 YAP Prolog 							 * | 
					
						
							|  |  |  |  *									 * | 
					
						
							|  |  |  |  *	Yap Prolog was developed at NCCUP - Universidade do Porto	 * | 
					
						
							|  |  |  |  *									 * | 
					
						
							|  |  |  |  * Copyright L.Damas, V. Santos Costa and Universidade do Porto 1985--	 * | 
					
						
							|  |  |  |  *									 * | 
					
						
							|  |  |  |  ************************************************************************** | 
					
						
							|  |  |  |  *									 * | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |  * File:		signal.c * | 
					
						
							| 
									
										
										
										
											2014-09-02 14:19:23 -05:00
										 |  |  |  * comments:	Signal Handling & Debugger Support			 * | 
					
						
							|  |  |  |  *									 * | 
					
						
							|  |  |  |  *									 * | 
					
						
							|  |  |  |  *									 * | 
					
						
							|  |  |  |  *************************************************************************/ | 
					
						
							| 
									
										
										
										
											2013-02-08 10:36:45 -06:00
										 |  |  | #ifdef SCCS
 | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  | static char SccsId[] = "%W% %G%"; | 
					
						
							| 
									
										
										
										
											2013-02-08 10:36:45 -06:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define HAS_CACHE_REGS 1
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "Yap.h"
 | 
					
						
							| 
									
										
										
										
											2015-06-19 01:30:13 +01:00
										 |  |  | #if HAVE_UNISTD_H
 | 
					
						
							|  |  |  | #include <unistd.h>
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2014-10-24 15:18:32 +01:00
										 |  |  | #if _WIN32
 | 
					
						
							|  |  |  | #include <stdio.h>
 | 
					
						
							|  |  |  | #include <io.h>
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2013-02-08 10:36:45 -06:00
										 |  |  | #include "Yatom.h"
 | 
					
						
							|  |  |  | #include "YapHeap.h"
 | 
					
						
							|  |  |  | #include "eval.h"
 | 
					
						
							|  |  |  | #include "yapio.h"
 | 
					
						
							|  |  |  | #ifdef TABLING
 | 
					
						
							|  |  |  | #include "tab.macros.h"
 | 
					
						
							|  |  |  | #endif /* TABLING */
 | 
					
						
							| 
									
										
										
										
											2014-11-28 02:30:19 +00:00
										 |  |  | #include <stdlib.h>
 | 
					
						
							| 
									
										
										
										
											2013-02-08 10:36:45 -06:00
										 |  |  | #include <stdio.h>
 | 
					
						
							|  |  |  | #if HAVE_STRING_H
 | 
					
						
							|  |  |  | #include <string.h>
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2014-11-28 02:30:19 +00:00
										 |  |  | #if HAVE_STRINGS_H
 | 
					
						
							|  |  |  | #include <strings.h>
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2013-02-08 10:36:45 -06:00
										 |  |  | #if HAVE_MALLOC_H
 | 
					
						
							|  |  |  | #include <malloc.h>
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | #include <wchar.h>
 | 
					
						
							| 
									
										
										
										
											2014-09-02 14:19:23 -05:00
										 |  |  | #ifdef LOW_LEVEL_TRACER
 | 
					
						
							|  |  |  | #include <tracer.h>
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2013-02-08 10:36:45 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-02 14:19:23 -05:00
										 |  |  | /*
 | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |  * The InteractSIGINT function is called after a normal interrupt had been | 
					
						
							|  |  |  |  * caught. | 
					
						
							| 
									
										
										
										
											2014-09-02 14:19:23 -05:00
										 |  |  |  * It allows 6 possibilities: abort, continue, trace, debug, help, exit. | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  | static yap_signals InteractSIGINT(int ch) { | 
					
						
							| 
									
										
										
										
											2014-09-02 14:19:23 -05:00
										 |  |  | #ifdef HAVE_SETBUF
 | 
					
						
							|  |  |  |   /* make sure we are not waiting for the end of line */ | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |   setbuf(stdin, NULL); | 
					
						
							| 
									
										
										
										
											2014-09-02 14:19:23 -05:00
										 |  |  | #endif
 | 
					
						
							|  |  |  |   switch (ch) { | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |   case 'a': | 
					
						
							|  |  |  |     /* abort computation */ | 
					
						
							|  |  |  |     return YAP_ABORT_SIGNAL; | 
					
						
							|  |  |  |   case 'b': | 
					
						
							|  |  |  |     /* continue */ | 
					
						
							|  |  |  |     return YAP_BREAK_SIGNAL; | 
					
						
							|  |  |  |   case 'c': | 
					
						
							|  |  |  |     /* continue */ | 
					
						
							|  |  |  |     return YAP_NO_SIGNAL; | 
					
						
							|  |  |  |   case 'd': | 
					
						
							|  |  |  |     /* enter debug mode */ | 
					
						
							|  |  |  |     return YAP_DEBUG_SIGNAL; | 
					
						
							|  |  |  |   case 'e': | 
					
						
							|  |  |  |     /* exit */ | 
					
						
							|  |  |  |     Yap_exit(1); | 
					
						
							|  |  |  |     return YAP_EXIT_SIGNAL; | 
					
						
							|  |  |  |   case 'g': | 
					
						
							|  |  |  |     /* stack dump */ | 
					
						
							|  |  |  |     return YAP_STACK_DUMP_SIGNAL; | 
					
						
							|  |  |  |   case 't': | 
					
						
							|  |  |  |     /* start tracing */ | 
					
						
							|  |  |  |     return YAP_TRACE_SIGNAL; | 
					
						
							| 
									
										
										
										
											2014-09-02 14:19:23 -05:00
										 |  |  | #ifdef LOW_LEVEL_TRACER
 | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |   case 'T': | 
					
						
							|  |  |  |     toggle_low_level_trace(); | 
					
						
							|  |  |  |     return YAP_NO_SIGNAL; | 
					
						
							| 
									
										
										
										
											2014-09-02 14:19:23 -05:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |   case 's': | 
					
						
							|  |  |  |     /* show some statistics */ | 
					
						
							|  |  |  |     return YAP_STATISTICS_SIGNAL; | 
					
						
							|  |  |  |   case EOF: | 
					
						
							|  |  |  |     return YAP_NO_SIGNAL; | 
					
						
							|  |  |  |   case 'h': | 
					
						
							|  |  |  |   case '?': | 
					
						
							|  |  |  |   default: | 
					
						
							|  |  |  |     /* show an helpful message */ | 
					
						
							|  |  |  |     fprintf(stderr, "Please press one of:\n"); | 
					
						
							|  |  |  |     fprintf(stderr, "  a for abort\n  c for continue\n  d for debug\n"); | 
					
						
							|  |  |  |     fprintf(stderr, "  e for exit\n  g for stack dump\n  s for statistics\n  t " | 
					
						
							|  |  |  |                     "for trace\n"); | 
					
						
							|  |  |  |     fprintf(stderr, "  b for break\n"); | 
					
						
							|  |  |  |     return YAP_NO_SIGNAL; | 
					
						
							| 
									
										
										
										
											2014-09-02 14:19:23 -05:00
										 |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |   This function talks to the user about a signal. We assume we are in | 
					
						
							|  |  |  |   the context of the main Prolog thread (trivial in Unix, but hard in WIN32) | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  | static yap_signals ProcessSIGINT(void) { | 
					
						
							| 
									
										
										
										
											2014-09-02 14:19:23 -05:00
										 |  |  |   CACHE_REGS | 
					
						
							|  |  |  |   int ch, out; | 
					
						
							| 
									
										
										
										
											2014-10-24 15:18:32 +01:00
										 |  |  | #if _WIN32
 | 
					
						
							|  |  |  |   if (!_isatty(0)) { | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |     return YAP_INT_SIGNAL; | 
					
						
							| 
									
										
										
										
											2014-10-24 15:18:32 +01:00
										 |  |  |   } | 
					
						
							|  |  |  | #elif HAVE_ISATTY
 | 
					
						
							| 
									
										
										
										
											2014-09-02 14:19:23 -05:00
										 |  |  |   if (!isatty(0)) { | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |     return YAP_INT_SIGNAL; | 
					
						
							| 
									
										
										
										
											2014-09-02 14:19:23 -05:00
										 |  |  |   } | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  |   LOCAL_PrologMode |= AsyncIntMode; | 
					
						
							|  |  |  |   do { | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |     ch = Yap_GetCharForSIGINT(); | 
					
						
							| 
									
										
										
										
											2014-09-02 14:19:23 -05:00
										 |  |  |   } while (!(out = InteractSIGINT(ch))); | 
					
						
							|  |  |  |   LOCAL_PrologMode &= ~AsyncIntMode; | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |   return (out); | 
					
						
							| 
									
										
										
										
											2014-09-02 14:19:23 -05:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  | inline static void do_signal(int wid, yap_signals sig USES_REGS) { | 
					
						
							| 
									
										
										
										
											2014-03-06 14:07:33 +00:00
										 |  |  | #if THREADS
 | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |   __sync_fetch_and_or(&REMOTE(wid)->Signals_, SIGNAL_TO_BIT(sig)); | 
					
						
							| 
									
										
										
										
											2014-03-06 02:09:48 +00:00
										 |  |  |   if (!REMOTE_InterruptsDisabled(wid)) { | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |     REMOTE_ThreadHandle(wid).current_yaam_regs->CreepFlag_ = | 
					
						
							|  |  |  |         Unsigned(REMOTE_ThreadHandle(wid).current_yaam_regs->LCL0_); | 
					
						
							| 
									
										
										
										
											2014-03-06 14:07:33 +00:00
										 |  |  |   } | 
					
						
							|  |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2014-10-11 01:37:34 +01:00
										 |  |  |   LOCAL_Signals |= SIGNAL_TO_BIT(sig); | 
					
						
							| 
									
										
										
										
											2014-03-06 14:07:33 +00:00
										 |  |  |   if (!LOCAL_InterruptsDisabled) { | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |     CreepFlag = Unsigned(LCL0); | 
					
						
							| 
									
										
										
										
											2014-03-06 02:09:48 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2014-03-06 14:07:33 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2013-02-08 10:36:45 -06:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  | inline static bool get_signal(yap_signals sig USES_REGS) { | 
					
						
							| 
									
										
										
										
											2014-09-02 14:19:23 -05:00
										 |  |  | #if THREADS
 | 
					
						
							|  |  |  |   uint64_t old; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-18 01:32:13 +00:00
										 |  |  |   // first, clear the Creep Flag, now if someone sets it it is their problem
 | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |   CalculateStackGap(PASS_REGS1); | 
					
						
							| 
									
										
										
										
											2014-09-02 14:19:23 -05:00
										 |  |  |   // reset the flag
 | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |   if ((old = __sync_fetch_and_and(&LOCAL_Signals, ~SIGNAL_TO_BIT(sig))) != | 
					
						
							| 
									
										
										
										
											2014-09-02 14:19:23 -05:00
										 |  |  |       SIGNAL_TO_BIT(sig)) { | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |     if (!LOCAL_InterruptsDisabled && LOCAL_Signals != 0) { | 
					
						
							|  |  |  |       CreepFlag = (CELL)LCL0; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (!(old & SIGNAL_TO_BIT(sig))) { | 
					
						
							|  |  |  |       // not there?
 | 
					
						
							|  |  |  |       return FALSE; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     // more likely case, we have other interrupts.
 | 
					
						
							|  |  |  |     return TRUE; | 
					
						
							| 
									
										
										
										
											2014-03-06 02:09:48 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2014-09-02 14:19:23 -05:00
										 |  |  |   // success, we are good
 | 
					
						
							|  |  |  |   return TRUE; | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  | // should we set the flag?
 | 
					
						
							| 
									
										
										
										
											2014-09-02 14:19:23 -05:00
										 |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2014-09-03 11:02:28 -05:00
										 |  |  |   if (LOCAL_Signals & SIGNAL_TO_BIT(sig)) { | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |     LOCAL_Signals &= ~SIGNAL_TO_BIT(sig); | 
					
						
							|  |  |  |     if (!LOCAL_InterruptsDisabled && LOCAL_Signals != 0) { | 
					
						
							|  |  |  |       CreepFlag = (CELL)LCL0; | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |       CalculateStackGap(PASS_REGS1); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return TRUE; | 
					
						
							| 
									
										
										
										
											2014-09-02 14:19:23 -05:00
										 |  |  |   } else { | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |     return FALSE; | 
					
						
							| 
									
										
										
										
											2014-03-06 02:09:48 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2014-09-02 14:19:23 -05:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |   Function called to handle delayed interrupts. | 
					
						
							| 
									
										
										
										
											2014-09-02 14:19:23 -05:00
										 |  |  |  */ | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  | int Yap_HandleInterrupts(void) { | 
					
						
							| 
									
										
										
										
											2014-09-02 14:19:23 -05:00
										 |  |  |   CACHE_REGS | 
					
						
							|  |  |  |   yap_signals sig; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |   if (get_signal(YAP_INT_SIGNAL PASS_REGS)) { | 
					
						
							|  |  |  |     if ((sig = ProcessSIGINT()) != YAP_NO_SIGNAL) | 
					
						
							|  |  |  |       do_signal(worker_id, sig PASS_REGS); | 
					
						
							|  |  |  |     LOCAL_PrologMode &= ~InterruptMode; | 
					
						
							|  |  |  |     return 1; | 
					
						
							| 
									
										
										
										
											2013-02-08 10:36:45 -06:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2014-09-02 14:19:23 -05:00
										 |  |  |   return 0; | 
					
						
							| 
									
										
										
										
											2013-02-08 10:36:45 -06:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  | static Int p_creep(USES_REGS1) { | 
					
						
							|  |  |  |   Atom at; | 
					
						
							|  |  |  |   PredEntry *pred; | 
					
						
							| 
									
										
										
										
											2013-02-08 10:36:45 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  |   at = AtomCreep; | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |   pred = RepPredProp(PredPropByFunc(Yap_MkFunctor(at, 1), 0)); | 
					
						
							| 
									
										
										
										
											2013-02-08 10:36:45 -06:00
										 |  |  |   CreepCode = pred; | 
					
						
							| 
									
										
										
										
											2014-03-06 02:09:48 +00:00
										 |  |  |   do_signal(worker_id, YAP_CREEP_SIGNAL PASS_REGS); | 
					
						
							| 
									
										
										
										
											2013-02-08 10:36:45 -06:00
										 |  |  |   return TRUE; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  | static Int p_creep_fail(USES_REGS1) { | 
					
						
							|  |  |  |   Atom at; | 
					
						
							|  |  |  |   PredEntry *pred; | 
					
						
							| 
									
										
										
										
											2013-12-11 09:34:43 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   at = AtomCreep; | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |   pred = RepPredProp(PredPropByFunc(Yap_MkFunctor(at, 1), 0)); | 
					
						
							| 
									
										
										
										
											2013-12-11 09:34:43 +00:00
										 |  |  |   CreepCode = pred; | 
					
						
							| 
									
										
										
										
											2014-03-06 02:09:48 +00:00
										 |  |  |   do_signal(worker_id, YAP_CREEP_SIGNAL PASS_REGS); | 
					
						
							| 
									
										
										
										
											2013-12-11 09:34:43 +00:00
										 |  |  |   return FALSE; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  | static Int stop_creeping(USES_REGS1) { | 
					
						
							|  |  |  |   if (get_signal(YAP_CREEP_SIGNAL PASS_REGS)) { | 
					
						
							|  |  |  |     return Yap_unify(ARG1, TermTrue); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   return Yap_unify(ARG1, TermFalse); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static Int disable_debugging(USES_REGS1) { | 
					
						
							|  |  |  |   get_signal(YAP_CREEP_SIGNAL PASS_REGS); | 
					
						
							| 
									
										
										
										
											2015-09-21 17:05:36 -05:00
										 |  |  |   return true; | 
					
						
							| 
									
										
										
										
											2013-02-08 10:36:45 -06:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  | static Int creep_allowed(USES_REGS1) { | 
					
						
							| 
									
										
										
										
											2013-02-08 10:36:45 -06:00
										 |  |  |   if (PP != NULL) { | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |     get_signal(YAP_CREEP_SIGNAL PASS_REGS); | 
					
						
							|  |  |  |     return true; | 
					
						
							| 
									
										
										
										
											2013-02-08 10:36:45 -06:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2015-09-21 17:05:36 -05:00
										 |  |  |   return false; | 
					
						
							| 
									
										
										
										
											2013-02-08 10:36:45 -06:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  | void Yap_signal(yap_signals sig) { | 
					
						
							| 
									
										
										
										
											2013-02-08 10:36:45 -06:00
										 |  |  |   CACHE_REGS | 
					
						
							| 
									
										
										
										
											2014-09-02 14:19:23 -05:00
										 |  |  |   do_signal(worker_id, sig PASS_REGS); | 
					
						
							| 
									
										
										
										
											2013-02-08 10:36:45 -06:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-10 01:56:56 +00:00
										 |  |  | #ifdef DEBUG
 | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  | static Int p_debug(USES_REGS1); | 
					
						
							| 
									
										
										
										
											2014-11-10 01:56:56 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2014-09-02 14:19:23 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  | void Yap_external_signal(int wid, yap_signals sig) { | 
					
						
							| 
									
										
										
										
											2014-03-06 14:07:33 +00:00
										 |  |  | #if THREADS
 | 
					
						
							| 
									
										
										
										
											2014-03-06 02:09:48 +00:00
										 |  |  |   REGSTORE *regcache = REMOTE_ThreadHandle(wid).current_yaam_regs; | 
					
						
							| 
									
										
										
										
											2014-03-06 14:07:33 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2014-03-06 02:09:48 +00:00
										 |  |  |   do_signal(wid, sig PASS_REGS); | 
					
						
							| 
									
										
										
										
											2014-09-02 14:19:23 -05:00
										 |  |  |   LOCAL_PrologMode &= ~InterruptMode; | 
					
						
							| 
									
										
										
										
											2014-03-06 02:09:48 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  | int Yap_get_signal__(yap_signals sig USES_REGS) { | 
					
						
							| 
									
										
										
										
											2014-09-02 14:19:23 -05:00
										 |  |  |   return get_signal(sig PASS_REGS); | 
					
						
							| 
									
										
										
										
											2014-03-06 02:09:48 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-23 22:41:12 +01:00
										 |  |  | // the caller holds the lock.
 | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  | int Yap_has_signals__(yap_signals sig1, yap_signals sig2 USES_REGS) { | 
					
						
							|  |  |  |   return LOCAL_Signals & (SIGNAL_TO_BIT(sig1) | SIGNAL_TO_BIT(sig2)); | 
					
						
							| 
									
										
										
										
											2014-03-06 02:09:48 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  | int Yap_only_has_signals__(yap_signals sig1, yap_signals sig2 USES_REGS) { | 
					
						
							|  |  |  |   uint64_t sigs = LOCAL_Signals; | 
					
						
							| 
									
										
										
										
											2014-09-03 11:02:28 -05:00
										 |  |  |   return sigs & (SIGNAL_TO_BIT(sig1) | SIGNAL_TO_BIT(sig2)) && | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |          !(sigs & ~(SIGNAL_TO_BIT(sig1) | SIGNAL_TO_BIT(sig2))); | 
					
						
							| 
									
										
										
										
											2013-02-08 10:36:45 -06:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef DEBUG
 | 
					
						
							| 
									
										
										
										
											2014-09-02 14:19:23 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | volatile int volat = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  | static Int p_debug(USES_REGS1) { /* $debug(+Flag) */ | 
					
						
							|  |  |  |   int i = IntOfTerm(Deref(ARG1)); | 
					
						
							| 
									
										
										
										
											2014-09-02 14:19:23 -05:00
										 |  |  |   while (volat == 0) { | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2013-02-08 10:36:45 -06:00
										 |  |  |   if (i >= 'a' && i <= 'z') | 
					
						
							|  |  |  |     GLOBAL_Option[i - 96] = !GLOBAL_Option[i - 96]; | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |   return 1; | 
					
						
							| 
									
										
										
										
											2013-02-08 10:36:45 -06:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2014-09-02 14:19:23 -05:00
										 |  |  | void Yap_loop(void); | 
					
						
							|  |  |  | void Yap_debug_end_loop(void); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  | void Yap_loop(void) { | 
					
						
							|  |  |  |   while (volat == 0) | 
					
						
							|  |  |  |     ; | 
					
						
							| 
									
										
										
										
											2014-09-02 14:19:23 -05:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  | void Yap_debug_end_loop(void) { volat = 1; } | 
					
						
							| 
									
										
										
										
											2013-02-08 10:36:45 -06:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  | static Int first_signal(USES_REGS1) { | 
					
						
							| 
									
										
										
										
											2014-03-06 02:09:48 +00:00
										 |  |  |   Atom at; | 
					
						
							|  |  |  |   yap_signals sig; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-02 14:19:23 -05:00
										 |  |  |   while (TRUE) { | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |     uint64_t mask = LOCAL_Signals; | 
					
						
							|  |  |  |     if (mask == 0) | 
					
						
							|  |  |  |       return FALSE; | 
					
						
							| 
									
										
										
										
											2014-10-24 15:18:32 +01:00
										 |  |  | #if HAVE___BUILTIN_FFSLL
 | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |     sig = __builtin_ffsll(mask); | 
					
						
							| 
									
										
										
										
											2014-10-24 15:18:32 +01:00
										 |  |  | #elif HAVE_FFSLL
 | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |     sig = ffsll(mask); | 
					
						
							| 
									
										
										
										
											2014-10-24 15:18:32 +01:00
										 |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |     sig = Yap_msb(mask PASS_REGS) + 1; | 
					
						
							| 
									
										
										
										
											2014-10-24 15:18:32 +01:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |     if (get_signal(sig PASS_REGS)) { | 
					
						
							|  |  |  |       break; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2015-01-18 03:47:44 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  | loop: | 
					
						
							| 
									
										
										
										
											2014-03-06 02:09:48 +00:00
										 |  |  |   switch (sig) { | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |   case YAP_INT_SIGNAL: | 
					
						
							|  |  |  |     sig = ProcessSIGINT(); | 
					
						
							|  |  |  |     if (sig == YAP_INT_SIGNAL) { | 
					
						
							|  |  |  |       at = AtomSigInt; | 
					
						
							| 
									
										
										
										
											2014-09-02 14:19:23 -05:00
										 |  |  |       break; | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |     if (sig != YAP_NO_SIGNAL) | 
					
						
							|  |  |  |       goto loop; | 
					
						
							|  |  |  |     return FALSE; | 
					
						
							|  |  |  |   case YAP_ABORT_SIGNAL: | 
					
						
							|  |  |  |     /* abort computation */ | 
					
						
							|  |  |  |     LOCAL_PrologMode &= ~AsyncIntMode; | 
					
						
							|  |  |  |     if (LOCAL_PrologMode & (GCMode | ConsoleGetcMode | CritMode)) { | 
					
						
							|  |  |  |       LOCAL_PrologMode |= AbortMode; | 
					
						
							|  |  |  |       return -1; | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |       Yap_Error(ABORT_EVENT, TermNil, "abort from console"); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     Yap_RestartYap(1); | 
					
						
							|  |  |  |     return FALSE; | 
					
						
							|  |  |  |   case YAP_CREEP_SIGNAL: | 
					
						
							|  |  |  |     at = AtomSigCreep; | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  |   case YAP_TRACE_SIGNAL: | 
					
						
							|  |  |  |     at = AtomSigTrace; | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  |   case YAP_DEBUG_SIGNAL: | 
					
						
							|  |  |  |     at = AtomSigDebug; | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  |   case YAP_BREAK_SIGNAL: | 
					
						
							|  |  |  |     at = AtomSigBreak; | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  |   case YAP_FAIL_SIGNAL: | 
					
						
							|  |  |  |     at = AtomFail; | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  |   case YAP_STACK_DUMP_SIGNAL: | 
					
						
							|  |  |  |     at = AtomSigStackDump; | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  |   case YAP_STATISTICS_SIGNAL: | 
					
						
							|  |  |  |     at = AtomSigStatistics; | 
					
						
							|  |  |  |     break; | 
					
						
							| 
									
										
										
										
											2014-03-06 02:09:48 +00:00
										 |  |  | #ifdef SIGALRM
 | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |   case YAP_ALARM_SIGNAL: | 
					
						
							| 
									
										
										
										
											2014-03-06 02:09:48 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |   case YAP_WINTIMER_SIGNAL: | 
					
						
							|  |  |  |     at = AtomSigAlarm; | 
					
						
							|  |  |  |     break; | 
					
						
							| 
									
										
										
										
											2014-03-06 02:09:48 +00:00
										 |  |  | #ifdef SIGVTALRM
 | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |   case YAP_VTALARM_SIGNAL: | 
					
						
							|  |  |  |     at = AtomSigVTAlarm; | 
					
						
							|  |  |  |     break; | 
					
						
							| 
									
										
										
										
											2014-03-06 02:09:48 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |   case YAP_EXIT_SIGNAL: | 
					
						
							|  |  |  |     Yap_exit(1); | 
					
						
							|  |  |  |     return FALSE; | 
					
						
							|  |  |  |   case YAP_WAKEUP_SIGNAL: | 
					
						
							|  |  |  |     at = AtomSigWakeUp; | 
					
						
							|  |  |  |     break; | 
					
						
							|  |  |  |   case YAP_ITI_SIGNAL: | 
					
						
							|  |  |  |     at = AtomSigIti; | 
					
						
							|  |  |  |     break; | 
					
						
							| 
									
										
										
										
											2014-03-06 02:09:48 +00:00
										 |  |  | #ifdef SIGPIPE
 | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |   case YAP_PIPE_SIGNAL: | 
					
						
							|  |  |  |     at = AtomSigPipe; | 
					
						
							|  |  |  |     break; | 
					
						
							| 
									
										
										
										
											2014-03-06 02:09:48 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | #ifdef SIGHUP
 | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |   case YAP_HUP_SIGNAL: | 
					
						
							|  |  |  |     at = AtomSigHup; | 
					
						
							|  |  |  |     break; | 
					
						
							| 
									
										
										
										
											2014-03-06 02:09:48 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | #ifdef SIGUSR1
 | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |   case YAP_USR1_SIGNAL: | 
					
						
							|  |  |  |     at = AtomSigUsr1; | 
					
						
							|  |  |  |     break; | 
					
						
							| 
									
										
										
										
											2014-03-06 02:09:48 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | #ifdef SIGUSR2
 | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |   case YAP_USR2_SIGNAL: | 
					
						
							|  |  |  |     at = AtomSigUsr2; | 
					
						
							|  |  |  |     break; | 
					
						
							| 
									
										
										
										
											2014-10-15 11:06:07 +01:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | #ifdef SIGFPE
 | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |   case YAP_FPE_SIGNAL: | 
					
						
							|  |  |  |     at = AtomSigFPE; | 
					
						
							|  |  |  |     break; | 
					
						
							| 
									
										
										
										
											2014-03-06 02:09:48 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |   default: | 
					
						
							|  |  |  |     return FALSE; | 
					
						
							| 
									
										
										
										
											2013-02-08 10:36:45 -06:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2014-03-06 02:09:48 +00:00
										 |  |  |   return Yap_unify(ARG1, MkAtomTerm(at)); | 
					
						
							| 
									
										
										
										
											2013-02-08 10:36:45 -06:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  | static Int continue_signals(USES_REGS1) { return first_signal(PASS_REGS1); } | 
					
						
							| 
									
										
										
										
											2013-02-08 10:36:45 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  | void Yap_InitSignalCPreds(void) { | 
					
						
							| 
									
										
										
										
											2013-02-08 10:36:45 -06:00
										 |  |  |   /* Basic predicates for the debugger */ | 
					
						
							|  |  |  |   Yap_InitCPred("$creep", 0, p_creep, SafePredFlag); | 
					
						
							| 
									
										
										
										
											2013-12-11 09:34:43 +00:00
										 |  |  |   Yap_InitCPred("$creep_fail", 0, p_creep_fail, SafePredFlag); | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |   Yap_InitCPred("$stop_creeping", 1, stop_creeping, | 
					
						
							|  |  |  |                 NoTracePredFlag | HiddenPredFlag | SafePredFlag); | 
					
						
							|  |  |  |   Yap_InitCPred("$disable_debugging", 0, disable_debugging, | 
					
						
							|  |  |  |                 NoTracePredFlag | HiddenPredFlag | SafePredFlag); | 
					
						
							|  |  |  |   Yap_InitCPred("$first_signal", 1, first_signal, SafePredFlag | SyncPredFlag); | 
					
						
							|  |  |  |   Yap_InitCPred("$continue_signals", 0, continue_signals, | 
					
						
							|  |  |  |                 SafePredFlag | SyncPredFlag); | 
					
						
							| 
									
										
										
										
											2015-09-21 17:05:36 -05:00
										 |  |  |   Yap_InitCPred("creep_allowed", 0, creep_allowed, 0); | 
					
						
							| 
									
										
										
										
											2013-02-08 10:36:45 -06:00
										 |  |  | #ifdef DEBUG
 | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  |   Yap_InitCPred("sys_debug", 1, p_debug, SafePredFlag | SyncPredFlag); | 
					
						
							| 
									
										
										
										
											2013-02-08 10:36:45 -06:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2014-03-06 02:09:48 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-03 02:06:09 +00:00
										 |  |  | void *Yap_InitSignals(int wid) { | 
					
						
							|  |  |  |   void *ptr = (void *)malloc(sizeof(UInt) * REMOTE_MaxActiveSignals(wid)); | 
					
						
							| 
									
										
										
										
											2014-03-08 00:03:58 +00:00
										 |  |  |   return ptr; | 
					
						
							| 
									
										
										
										
											2014-03-06 02:09:48 +00:00
										 |  |  | } |