#include "interrupt.h"
#include "lispregs.h"
-/* Temporarily, this macro is a wrapper for FSHOW_SIGNAL. Ultimately,
- * it will be restored to its full win32 branch functionality, where it
- * provides a very useful tracing mechanism that is configurable at
- * runtime. */
-#define odxprint_show(what, fmt, args...) \
- do { \
- struct thread *__self = arch_os_get_current_thread(); \
- FSHOW_SIGNAL((stderr, "[%p/%p:%s] " fmt "\n", \
- __self, \
- __self->os_thread, \
- #what, \
- ##args)); \
- } while (0)
-
-#if QSHOW_SIGNALS
-# define odxprint odxprint_show
-#else
-# define odxprint(what, fmt, args...) do {} while (0)
-#endif
-
#if !defined(LISP_FEATURE_WIN32)
/* win32-os.c covers these, but there is no unixlike-os.c, so the normal
* definition goes here. Fixme: (Why) don't these work for Windows?
{
struct thread *p = arch_os_get_current_thread();
- gc_assert(!os_get_csp(p));
+#ifdef LISP_FEATURE_WIN32
+ pthread_t pself = p->os_thread;
+ sigset_t oldset;
+ /* On Windows, wake_thread/kill_safely does not set THRUPTION_PENDING
+ * in the self-kill case; instead we do it here while also clearing the
+ * "signal". */
+ if (pself->pending_signal_set)
+ if (__sync_fetch_and_and(&pself->pending_signal_set,0))
+ SetSymbolValue(THRUPTION_PENDING, T, p);
+#endif
if (!thread_may_thrupt(ctx))
return 0;
return 0;
SetSymbolValue(THRUPTION_PENDING, NIL, p);
+#ifdef LISP_FEATURE_WIN32
+ oldset = pself->blocked_signal_set;
+ pself->blocked_signal_set = deferrable_sigset;
+ if (ctx) fake_foreign_function_call(ctx);
+#else
sigset_t oldset;
block_deferrable_signals(0, &oldset);
+#endif
funcall0(StaticSymbolFunction(RUN_INTERRUPTION));
+#ifdef LISP_FEATURE_WIN32
+ if (ctx) undo_fake_foreign_function_call(ctx);
+ pself->blocked_signal_set = oldset;
+ if (ctx) ctx->sigmask = oldset;
+#else
pthread_sigmask(SIG_SETMASK, &oldset, 0);
+#endif
return 1;
}
#endif
set_csp_from_context(struct thread *self, os_context_t *ctx)
{
void **sp = (void **) *os_context_register_addr(ctx, reg_SP);
+ /* On POSIX platforms, it is sufficient to investigate only the part
+ * of the stack that was live before the interrupt, because in
+ * addition, we consider interrupt contexts explicitly. On Windows,
+ * however, we do not keep an explicit stack of exception contexts,
+ * and instead arrange for the conservative stack scan to also cover
+ * the context implicitly. The obvious way to do that is to start
+ * at the context itself: */
+#ifdef LISP_FEATURE_WIN32
+ gc_assert((void **) ctx < sp);
+ sp = (void**) ctx;
+#endif
gc_assert((void **)self->control_stack_start
<= sp && sp
< (void **)self->control_stack_end);
/* wake_thread(thread) -- ensure a thruption delivery to
* `thread'. */
+# ifdef LISP_FEATURE_WIN32
+
+void
+wake_thread_io(struct thread * thread)
+{
+ SetEvent(thread->private_events.events[1]);
+}
+
+void
+wake_thread_win32(struct thread *thread)
+{
+ wake_thread_io(thread);
+
+ if (SymbolTlValue(THRUPTION_PENDING,thread)==T)
+ return;
+
+ SetTlSymbolValue(THRUPTION_PENDING,T,thread);
+
+ if ((SymbolTlValue(GC_PENDING,thread)==T)||
+ (SymbolTlValue(STOP_FOR_GC_PENDING,thread)==T))
+ return;
+
+ pthread_mutex_unlock(&all_threads_lock);
+
+ if (maybe_become_stw_initiator(1) && !in_race_p()) {
+ gc_stop_the_world();
+ gc_start_the_world();
+ }
+ pthread_mutex_lock(&all_threads_lock);
+ return;
+}
+# else
int
wake_thread_posix(os_thread_t os_thread)
{
pthread_sigmask(SIG_SETMASK, &oldset, 0);
return found ? 0 : -1;
}
+#endif /* !LISP_FEATURE_WIN32 */
#endif /* LISP_FEATURE_SB_THRUPTION */
void