2 * This software is part of the SBCL system. See the README file for
5 * This software is derived from the CMU CL system, which was
6 * written at Carnegie Mellon University and released into the
7 * public domain. The software is in the public domain and is
8 * provided with absolutely no warranty. See the COPYING and CREDITS
9 * files for more information.
13 #ifdef LISP_FEATURE_SB_SAFEPOINT /* entire file */
17 #ifndef LISP_FEATURE_WIN32
23 #include <sys/types.h>
24 #ifndef LISP_FEATURE_WIN32
31 #include "target-arch-os.h"
35 #include "genesis/cons.h"
36 #include "genesis/fdefn.h"
39 #include "gc-internal.h"
40 #include "pseudo-atomic.h"
41 #include "interrupt.h"
44 const char* gc_phase_names
[GC_NPHASES
] = {
54 /* States and transitions:
56 * GC_NONE: Free running code.
58 * GC_NONE -> GC_FLIGHT: unmap_gc_page(), arming the GSP trap.
60 * GC_FLIGHT: GC triggered normally, waiting for post-allocation
63 * GC_FLIGHT -> GC_MESSAGE: gc_notify_early(), arming the per-thread
66 * GC_MESSAGE: Waiting for lisp threads to stop (WITHOUT-GCING threads
67 * will resume at GC_INVOKED).
69 * GC_MESSAGE -> GC_INVOKED: map_gc_page(), disarming the GSP trap.
71 * GC_INVOKED: Waiting for WITHOUT-GCING threads to leave
74 * GC_INVOKED -> GC_QUIET: nothing changes.
76 * GC_QUIET: GCing threads race to stop the world (and melt with you).
78 * GC_QUIET -> GC_SETTLED: unmap_gc_page(), gc_notify_final(), arming
79 * GSP and CSP traps again.
81 * GC_SETTLED: Waiting for remaining lisp threads to stop.
83 * GC_SETTLED -> GC_COLLECT: map_gc_page(), disarming the GSP trap.
85 * GC_COLLECT: World is stopped, save for one thread in SUB-GC / FLET
86 * PERFORM-GC, running the garbage collector.
88 * GC_COLLECT -> GC_NONE: gc_none(), clearing CSP traps and possibly
91 * GC_NONE: Free running code.
93 * Note that the system may not actually stop in every state for a GC.
94 * For example, a system with only one thread directly invoking
95 * SB-EXT:GC will advance quickly from GC_NONE to GC_COLLECT, simply
96 * because no other threads exist to prevent it. That same scenario
97 * with a thread inside WITHOUT-GCING sitting in alien code at the
98 * time will move to GC_INVOKED and then wait for the WITHOUT-GCING
99 * thread to finish up, then proceed to GC_COLLECT. */
101 #ifdef LISP_FEATURE_SB_THREAD
102 #define CURRENT_THREAD_VAR(name) \
103 struct thread *name = arch_os_get_current_thread()
104 #define THREAD_STOP_PENDING(th) \
105 read_TLS(STOP_FOR_GC_PENDING, th)
106 #define SET_THREAD_STOP_PENDING(th,state) \
107 write_TLS(STOP_FOR_GC_PENDING,state,th)
108 #define WITH_ALL_THREADS_LOCK \
109 pthread_mutex_lock(&all_threads_lock); \
110 RUN_BODY_ONCE(all_threads_lock, pthread_mutex_unlock(&all_threads_lock))
112 #define CURRENT_THREAD_VAR(name)
113 #define THREAD_STOP_PENDING(th) NIL
114 #define SET_THREAD_STOP_PENDING(th,state)
115 #define WITH_ALL_THREADS_LOCK
118 #if !defined(LISP_FEATURE_WIN32)
119 /* win32-os.c covers these, but there is no unixlike-os.c, so the normal
120 * definition goes here. Fixme: (Why) don't these work for Windows?
125 os_validate(NOT_MOVABLE
, GC_SAFEPOINT_PAGE_ADDR
, BACKEND_PAGE_BYTES
);
131 odxprint(misc
, "map_gc_page");
132 os_protect((void *) GC_SAFEPOINT_PAGE_ADDR
,
140 odxprint(misc
, "unmap_gc_page");
141 os_protect((void *) GC_SAFEPOINT_PAGE_ADDR
, BACKEND_PAGE_BYTES
, OS_VM_PROT_NONE
);
143 #endif /* !LISP_FEATURE_WIN32 */
146 #ifdef LISP_FEATURE_SB_THREAD
147 /* Flag: conditions are initialized */
150 /* Per-process lock for gc_state */
151 pthread_mutex_t lock
;
153 /* Conditions: one per phase */
154 pthread_cond_t phase_cond
[GC_NPHASES
];
157 /* For each [current or future] phase, a number of threads not yet ready to
159 int phase_wait
[GC_NPHASES
];
161 /* Master thread controlling the topmost stop/gc/start sequence */
162 struct thread
* master
;
163 struct thread
* collector
;
165 /* Current GC phase */
169 static struct gc_state gc_state
= {
170 #ifdef LISP_FEATURE_SB_THREAD
171 .lock
= PTHREAD_MUTEX_INITIALIZER
,
179 odxprint(safepoints
,"GC state to be locked");
180 #ifdef LISP_FEATURE_SB_THREAD
181 int result
= pthread_mutex_lock(&gc_state
.lock
);
184 if (gc_state
.master
) {
185 fprintf(stderr
,"GC state lock glitch [%p] in thread %p phase %d (%s)\n",
186 gc_state
.master
,arch_os_get_current_thread(),gc_state
.phase
,
187 gc_phase_names
[gc_state
.phase
]);
188 odxprint(safepoints
,"GC state lock glitch [%p]",gc_state
.master
);
190 gc_assert(!gc_state
.master
);
191 gc_state
.master
= arch_os_get_current_thread();
192 #ifdef LISP_FEATURE_SB_THREAD
193 if (!gc_state
.initialized
) {
195 for (i
=GC_NONE
; i
<GC_NPHASES
; ++i
)
196 pthread_cond_init(&gc_state
.phase_cond
[i
],NULL
);
197 gc_state
.initialized
= 1;
200 odxprint(safepoints
,"GC state locked in phase %d (%s)",
201 gc_state
.phase
, gc_phase_names
[gc_state
.phase
]);
207 odxprint(safepoints
,"GC state to be unlocked in phase %d (%s)",
208 gc_state
.phase
, gc_phase_names
[gc_state
.phase
]);
209 gc_assert(arch_os_get_current_thread()==gc_state
.master
);
210 gc_state
.master
= NULL
;
211 #ifdef LISP_FEATURE_SB_THREAD
212 int result
= pthread_mutex_unlock(&gc_state
.lock
);
215 odxprint(safepoints
,"%s","GC state unlocked");
219 gc_state_wait(gc_phase_t phase
)
221 struct thread
* self
= arch_os_get_current_thread();
222 odxprint(safepoints
,"Waiting for %d (%s) -> %d (%s) [%d holders]",
223 gc_state
.phase
, gc_phase_names
[gc_state
.phase
],
224 phase
, gc_phase_names
[phase
],
225 gc_state
.phase_wait
[gc_state
.phase
]);
226 gc_assert(gc_state
.master
== self
);
227 gc_state
.master
= NULL
;
228 while(gc_state
.phase
!= phase
&& !(phase
== GC_QUIET
&& (gc_state
.phase
> GC_QUIET
))) {
229 #ifdef LISP_FEATURE_SB_THREAD
230 pthread_cond_wait(&gc_state
.phase_cond
[phase
],&gc_state
.lock
);
232 lose("gc_state_wait() blocks, but we're #-SB-THREAD");
235 gc_assert(gc_state
.master
== NULL
);
236 gc_state
.master
= self
;
240 gc_cycle_active(void)
242 return gc_state
.phase
!= GC_NONE
;
246 set_csp_from_context(struct thread
*self
, os_context_t
*ctx
)
248 #ifdef LISP_FEATURE_C_STACK_IS_CONTROL_STACK
249 void **sp
= (void **) *os_context_register_addr(ctx
, reg_SP
);
250 /* On POSIX platforms, it is sufficient to investigate only the part
251 * of the stack that was live before the interrupt, because in
252 * addition, we consider interrupt contexts explicitly. On Windows,
253 * however, we do not keep an explicit stack of exception contexts,
254 * and instead arrange for the conservative stack scan to also cover
255 * the context implicitly. The obvious way to do that is to start
256 * at the context itself: */
257 #ifdef LISP_FEATURE_WIN32
258 gc_assert((void **) ctx
< sp
);
261 gc_assert((void **)self
->control_stack_start
263 < (void **)self
->control_stack_end
);
265 /* Note that the exact value doesn't matter much here, since
266 * platforms with precise GC use get_csp() only as a boolean -- the
267 * precise GC already keeps track of the stack pointer itself.
268 * That said, we're either in a foreign function call or have
269 * called fake_foreign_function_call(), and having accurate values
270 * here makes the debugging experience easier and less
272 void **sp
= (void **) access_control_stack_pointer(self
);
274 *self
->csp_around_foreign_call
= (lispobj
) sp
;
278 static inline gc_phase_t
gc_phase_next(gc_phase_t old
) {
279 return (old
+1) % GC_NPHASES
;
282 static inline boolean
283 thread_blocks_gc(struct thread
*thread
)
285 /* Note that, unlike thread_may_gc(), this may be called on
286 * another thread, and that other thread may be in any state */
288 boolean inhibit
= (read_TLS(GC_INHIBIT
,thread
)==T
)||
289 (read_TLS(IN_WITHOUT_GCING
,thread
)==IN_WITHOUT_GCING
);
294 /* set_thread_csp_access -- alter page permissions for not-in-Lisp
295 flag (Lisp Stack Top) of the thread `p'. The flag may be modified
296 if `writable' is true.
298 Return true if there is a non-null value in the flag.
300 When a thread enters C code or leaves it, a per-thread location is
301 modified. That machine word serves as a not-in-Lisp flag; for
302 convenience, when in C, it's filled with a topmost stack location
303 that may contain Lisp data. When thread is in Lisp, the word
306 GENCGC uses each thread's flag value for conservative garbage collection.
308 There is a full VM page reserved for this word; page permissions
309 are switched to read-only for race-free examine + wait + use
311 static inline boolean
312 set_thread_csp_access(struct thread
* p
, boolean writable
)
314 os_protect((char *) p
->csp_around_foreign_call
+ N_WORD_BYTES
- THREAD_CSP_PAGE_SIZE
,
315 THREAD_CSP_PAGE_SIZE
,
316 writable
? (OS_VM_PROT_READ
|OS_VM_PROT_WRITE
)
317 : (OS_VM_PROT_READ
));
318 return !!*p
->csp_around_foreign_call
;
321 static inline void gc_notify_early()
323 struct thread
*self
= arch_os_get_current_thread(), *p
;
324 odxprint(safepoints
,"%s","global notification");
325 gc_assert(gc_state
.phase
== GC_MESSAGE
);
326 /* We're setting up the per-thread traps to make sure that all
327 * lisp-side threads get stopped (if they are WITHOUT-GCING then
328 * they can resume once the GSP trap is disarmed), and all
329 * alien-side threads that are inside WITHOUT-GCING get their
330 * chance to run until they exit WITHOUT-GCING. */
331 WITH_ALL_THREADS_LOCK
{
333 /* This thread is already on a waitcount somewhere. */
336 /* If there's a collector thread then it is already on a
337 * waitcount somewhere. And it may-or-may-not be this
339 if (p
==gc_state
.collector
)
341 odxprint(safepoints
,"notifying thread %p csp %p",p
,*p
->csp_around_foreign_call
);
342 boolean was_in_lisp
= !set_thread_csp_access(p
,0);
344 /* Threads "in-lisp" block leaving GC_MESSAGE, as we
345 * need them to hit their CSP or the GSP, and we unmap
346 * the GSP when transitioning to GC_INVOKED. */
347 gc_state
.phase_wait
[GC_MESSAGE
]++;
348 SET_THREAD_STOP_PENDING(p
,T
);
349 } else if (thread_blocks_gc(p
)) {
350 /* Threads "in-alien" don't block leaving GC_MESSAGE,
351 * as the CSP trap is sufficient to catch them, but
352 * any thread that is WITHOUT-GCING prevents exit from
354 gc_state
.phase_wait
[GC_INVOKED
]++;
355 SET_THREAD_STOP_PENDING(p
,T
);
361 static inline void gc_notify_final()
364 odxprint(safepoints
,"%s","global notification");
365 gc_assert(gc_state
.phase
== GC_SETTLED
);
366 gc_state
.phase_wait
[GC_SETTLED
]=0;
367 /* All remaining lisp threads, except for the collector, now need
368 * to be stopped, so that the collector can run the GC. Any
369 * thread already stopped shows up as being "in-alien", so we
370 * don't bother with them here. */
371 WITH_ALL_THREADS_LOCK
{
373 if (p
== gc_state
.collector
)
375 odxprint(safepoints
,"notifying thread %p csp %p",p
,*p
->csp_around_foreign_call
);
376 boolean was_in_lisp
= !set_thread_csp_access(p
,0);
378 gc_state
.phase_wait
[GC_SETTLED
]++;
379 SET_THREAD_STOP_PENDING(p
,T
);
385 static inline void gc_done()
387 CURRENT_THREAD_VAR(self
);
389 boolean inhibit
= (read_TLS(GC_INHIBIT
,self
)==T
);
391 odxprint(safepoints
,"%s","global denotification");
392 WITH_ALL_THREADS_LOCK
{
394 if (inhibit
&& (read_TLS(GC_PENDING
,p
)==T
))
395 write_TLS(GC_PENDING
,NIL
,p
);
396 set_thread_csp_access(p
,1);
401 static inline void gc_handle_phase()
403 odxprint(safepoints
,"Entering phase %d (%s)",
404 gc_state
.phase
, gc_phase_names
[gc_state
.phase
]);
405 switch (gc_state
.phase
) {
431 /* become ready to leave the <old> phase, but unready to leave the <new> phase;
432 * `old' can be GC_NONE, it means this thread weren't blocking any state. `cur'
433 * can be GC_NONE, it means this thread wouldn't block GC_NONE, but still wait
435 static inline void gc_advance(gc_phase_t cur
, gc_phase_t old
) {
436 odxprint(safepoints
,"GC advance request %d (%s) -> %d (%s) in phase %d (%s)",
437 old
, gc_phase_names
[old
], cur
, gc_phase_names
[cur
],
438 gc_state
.phase
, gc_phase_names
[gc_state
.phase
]);
441 if (cur
== gc_state
.phase
)
443 if (old
< gc_state
.phase
)
445 if (old
!= GC_NONE
) {
446 gc_state
.phase_wait
[old
]--;
447 odxprint(safepoints
,"%d holders of phase %d (%s) without me",gc_state
.phase_wait
[old
],old
,gc_phase_names
[old
]);
449 if (cur
!= GC_NONE
) {
450 gc_state
.phase_wait
[cur
]++;
451 odxprint(safepoints
,"%d holders of phase %d (%s) with me",gc_state
.phase_wait
[cur
],cur
,gc_phase_names
[cur
]);
453 /* roll forth as long as there's no waiters */
454 while (gc_state
.phase_wait
[gc_state
.phase
]==0
455 && gc_state
.phase
!= cur
) {
456 gc_state
.phase
= gc_phase_next(gc_state
.phase
);
457 odxprint(safepoints
,"no blockers, direct advance to %d (%s)",gc_state
.phase
,gc_phase_names
[gc_state
.phase
]);
459 #ifdef LISP_FEATURE_SB_THREAD
460 pthread_cond_broadcast(&gc_state
.phase_cond
[gc_state
.phase
]);
463 odxprint(safepoints
,"going to wait for %d threads",gc_state
.phase_wait
[gc_state
.phase
]);
468 thread_register_gc_trigger()
470 odxprint(misc
, "/thread_register_gc_trigger");
471 struct thread
*self
= arch_os_get_current_thread();
473 if (gc_state
.phase
== GC_NONE
&&
474 read_TLS(IN_SAFEPOINT
,self
)!=T
&&
475 !thread_blocks_gc(self
)) {
476 /* A thread (this thread), while doing allocation, has
477 * determined that we need to run the garbage collector.
478 * But it's in the middle of initializing an object, so we
479 * advance to GC_FLIGHT, arming the GSP trap with the idea
480 * that there is a GSP trap check once the allocated
481 * object is initialized. Any thread that has GC_PENDING
482 * set and GC_INHIBIT clear can take over from here (see
483 * thread_in_lisp_raised()), but some thread must. */
484 gc_advance(GC_FLIGHT
,GC_NONE
);
492 /* Thread may gc if all of these are true:
493 * 1) GC_INHIBIT == NIL (outside of protected part of without-gcing)
494 * Note that we are in a safepoint here, which is always outside of PA. */
496 CURRENT_THREAD_VAR(self
);
497 return (read_TLS(GC_INHIBIT
, self
) == NIL
);
500 #ifdef LISP_FEATURE_SB_THRUPTION
502 thread_may_thrupt(os_context_t
*ctx
)
504 struct thread
* self
= arch_os_get_current_thread();
505 /* Thread may be interrupted if all of these are true:
506 * 1) Deferrables are unblocked in the context of the signal that
507 * went into the safepoint. -- Otherwise the surrounding code
508 * didn't want to be interrupted by a signal, so presumably it didn't
509 * want to be INTERRUPT-THREADed either.
510 * (See interrupt_handle_pending for an exception.)
511 * 2) On POSIX: There is no pending signal. This is important even
512 * after checking the sigmask, since we could be in the
513 * handle_pending trap following re-enabling of interrupts.
514 * Signals are unblocked in that case, but the signal is still
515 * pending; we want to run GC before handling the signal and
516 * therefore entered this safepoint. But the thruption would call
517 * ALLOW-WITH-INTERRUPTS, and could re-enter the handle_pending
518 * trap, leading to recursion.
519 * 3) INTERRUPTS_ENABLED is non-nil.
520 * 4) No GC pending; it takes precedence.
521 * Note that we are in a safepoint here, which is always outside of PA. */
523 if (read_TLS(INTERRUPTS_ENABLED
, self
) == NIL
)
526 if (read_TLS(GC_PENDING
, self
) != NIL
)
529 if (THREAD_STOP_PENDING(self
) != NIL
)
532 #ifdef LISP_FEATURE_WIN32
533 if (deferrables_blocked_p(&self
->os_thread
->blocked_signal_set
))
536 /* ctx is NULL if the caller wants to ignore the sigmask. */
537 if (ctx
&& deferrables_blocked_p(os_context_sigmask_addr(ctx
)))
539 if (read_TLS(INTERRUPT_PENDING
, self
) != NIL
)
543 if (read_TLS(RESTART_CLUSTERS
, self
) == NIL
)
544 /* This special case prevents TERMINATE-THREAD from hitting
545 * during INITIAL-THREAD-FUNCTION before it's ready. Curiously,
546 * deferrables are already unblocked there. Further
547 * investigation may be in order. */
553 // returns 0 if skipped, 1 otherwise
555 check_pending_thruptions(os_context_t
*ctx
)
557 struct thread
*p
= arch_os_get_current_thread();
559 #ifdef LISP_FEATURE_WIN32
560 pthread_t pself
= p
->os_thread
;
562 /* On Windows, wake_thread/kill_safely does not set THRUPTION_PENDING
563 * in the self-kill case; instead we do it here while also clearing the
565 if (pself
->pending_signal_set
)
566 if (__sync_fetch_and_and(&pself
->pending_signal_set
,0))
567 write_TLS(THRUPTION_PENDING
, T
, p
);
570 if (!thread_may_thrupt(ctx
))
572 if (read_TLS(THRUPTION_PENDING
, p
) == NIL
)
574 write_TLS(THRUPTION_PENDING
, NIL
, p
);
576 #ifdef LISP_FEATURE_WIN32
577 oldset
= pself
->blocked_signal_set
;
578 pself
->blocked_signal_set
= deferrable_sigset
;
581 block_deferrable_signals(&oldset
);
584 int was_in_lisp
= ctx
&& !foreign_function_call_active_p(p
);
587 fake_foreign_function_call(ctx
);
590 DX_ALLOC_SAP(context_sap
, ctx
);
591 WITH_GC_AT_SAFEPOINTS_ONLY() {
592 funcall1(StaticSymbolFunction(RUN_INTERRUPTION
), context_sap
);
596 undo_fake_foreign_function_call(ctx
);
598 #ifdef LISP_FEATURE_WIN32
599 pself
->blocked_signal_set
= oldset
;
600 if (ctx
) ctx
->sigmask
= oldset
;
602 thread_sigmask(SIG_SETMASK
, &oldset
, 0);
610 on_stack_p(struct thread
*th
, void *esp
)
612 return (void *)th
->control_stack_start
614 < (void *)th
->control_stack_end
;
617 #ifndef LISP_FEATURE_WIN32
618 /* (Technically, we still allocate an altstack even on Windows. Since
619 * Windows has a contiguous stack with an automatic guard page of
620 * user-configurable size instead of an alternative stack though, the
621 * SBCL-allocated altstack doesn't actually apply and won't be used.) */
623 on_altstack_p(struct thread
*th
, void *esp
)
625 void *start
= (char *)th
+dynamic_values_bytes
;
626 void *end
= (char *)start
+ 32*SIGSTKSZ
;
627 return start
<= esp
&& esp
< end
;
632 assert_on_stack(struct thread
*th
, void *esp
)
634 if (on_stack_p(th
, esp
))
636 #ifndef LISP_FEATURE_WIN32
637 if (on_altstack_p(th
, esp
))
638 lose("thread %p: esp on altstack: %p", th
, esp
);
640 lose("thread %p: bogus esp: %p", th
, esp
);
643 // returns 0 if skipped, 1 otherwise
645 check_pending_gc(os_context_t
*ctx
)
647 odxprint(misc
, "check_pending_gc");
648 struct thread
* self
= arch_os_get_current_thread();
652 if ((read_TLS(IN_SAFEPOINT
,self
) == T
) &&
653 ((read_TLS(GC_INHIBIT
,self
) == NIL
) &&
654 (read_TLS(GC_PENDING
,self
) == NIL
))) {
655 write_TLS(IN_SAFEPOINT
,NIL
,self
);
657 if (thread_may_gc() && (read_TLS(IN_SAFEPOINT
, self
) == NIL
)) {
658 if ((read_TLS(GC_PENDING
, self
) == T
)) {
659 lispobj gc_happened
= NIL
;
661 bind_variable(IN_SAFEPOINT
,T
,self
);
662 block_deferrable_signals(&sigset
);
663 if(read_TLS(GC_PENDING
,self
)==T
)
664 gc_happened
= funcall1(StaticSymbolFunction(SUB_GC
), 0);
666 thread_sigmask(SIG_SETMASK
,&sigset
,NULL
);
667 if (gc_happened
== T
) {
668 /* POST_GC wants to enable interrupts */
669 if (read_TLS(INTERRUPTS_ENABLED
,self
) == T
||
670 read_TLS(ALLOW_WITH_INTERRUPTS
,self
) == T
) {
671 odxprint(misc
, "going to call POST_GC");
672 funcall0(StaticSymbolFunction(POST_GC
));
682 void thread_in_lisp_raised(os_context_t
*ctxptr
)
684 struct thread
*self
= arch_os_get_current_thread();
685 boolean check_gc_and_thruptions
= 0;
686 odxprint(safepoints
,"%s","thread_in_lisp_raised");
688 /* Either we just hit the GSP trap, or we took a PIT stop and
689 * there is a stop-for-GC or thruption pending. */
691 if (gc_state
.phase
== GC_FLIGHT
&&
692 read_TLS(GC_PENDING
,self
)==T
&&
693 !thread_blocks_gc(self
) &&
694 thread_may_gc() && read_TLS(IN_SAFEPOINT
,self
)!=T
) {
695 /* Some thread (possibly even this one) that does not have
696 * GC_INHIBIT set has noticed that a GC is warranted and
697 * advanced the phase to GC_FLIGHT, arming the GSP trap,
698 * which this thread has hit. This thread doesn't have
699 * GC_INHIBIT set, and has also noticed that a GC is
700 * warranted. It doesn't matter which thread pushes
701 * things forwards at this point, just that it happens.
702 * This thread is now a candidate for running the GC, so
703 * we advance to GC_QUIET, where the only threads still
704 * running are competing to run the GC. */
705 set_csp_from_context(self
, ctxptr
);
706 gc_advance(GC_QUIET
,GC_FLIGHT
);
707 set_thread_csp_access(self
,1);
708 /* If a thread has already reached gc_stop_the_world(),
709 * just wait until the world starts again. */
710 if (gc_state
.collector
) {
711 gc_advance(GC_NONE
,GC_QUIET
);
713 /* ??? Isn't this already T? */
714 write_TLS(GC_PENDING
,T
,self
);
716 *self
->csp_around_foreign_call
= 0;
717 check_gc_and_thruptions
= 1;
719 /* This thread isn't a candidate for running the GC
720 * (yet?), so we can't advance past GC_FLIGHT, so wait for
721 * the next phase, GC_MESSAGE, before we do anything. */
722 if (gc_state
.phase
== GC_FLIGHT
) {
723 gc_state_wait(GC_MESSAGE
);
725 if (!thread_blocks_gc(self
)) {
726 /* This thread doesn't have GC_INHIBIT set, so sit
727 * tight and wait for the GC to be over. The current
728 * phase is GC_MESSAGE, GC_INVOKED, GC_QUIET, or
730 SET_THREAD_STOP_PENDING(self
,NIL
);
731 set_thread_csp_access(self
,1);
732 set_csp_from_context(self
, ctxptr
);
733 if (gc_state
.phase
<= GC_SETTLED
)
734 gc_advance(GC_NONE
,gc_state
.phase
);
736 gc_state_wait(GC_NONE
);
737 *self
->csp_around_foreign_call
= 0;
738 check_gc_and_thruptions
= 1;
740 /* This thread has GC_INHIBIT set, meaning that it's
741 * within a WITHOUT-GCING, so advance from wherever we
742 * are (GC_MESSAGE) to GC_INVOKED so that we can
743 * continue running. When we leave the WITHOUT-GCING
744 * we'll take a PIT stop and wind up in the case
745 * above... Or we'll call gc_stop_the_world(). */
746 gc_advance(GC_INVOKED
,gc_state
.phase
);
747 SET_THREAD_STOP_PENDING(self
,T
);
748 /* Why do we not want to run thruptions here? */
752 /* If we still need to GC, and it's not inhibited, call into
753 * SUB-GC. Phase is either GC_QUIET or GC_NONE. */
754 if (check_gc_and_thruptions
) {
755 check_pending_gc(ctxptr
);
756 #ifdef LISP_FEATURE_SB_THRUPTION
757 while(check_pending_thruptions(ctxptr
));
762 void thread_in_safety_transition(os_context_t
*ctxptr
)
764 struct thread
*self
= arch_os_get_current_thread();
765 boolean was_in_alien
;
767 odxprint(safepoints
,"%s","GC safety transition");
769 was_in_alien
= set_thread_csp_access(self
,1);
771 /* This is an alien->lisp or alien->alien transition. */
772 if (thread_blocks_gc(self
)) {
773 /* gc_notify_early() accounted for this thread as not
774 * being able to leave GC_INVOKED when it armed our
775 * CSP trap, but some other threads may still be
776 * holding things back at GC_MESSAGE, so wait for
777 * GC_INVOKED before continuing. Don't advance, the
778 * threads preventing exit from GC_MESSAGE have that
780 gc_state_wait(GC_INVOKED
);
782 /* This thread isn't within a WITHOUT-GCING, so just
783 * wait until the GC is done before continuing. */
784 gc_state_wait(GC_NONE
);
787 /* This is a lisp->alien or lisp->lisp transition. */
788 if (!thread_blocks_gc(self
)) {
789 /* This thread doesn't have GC_INHIBIT set, so sit
790 * tight and wait for the GC to be over. This is
791 * virtually the same logic as the similar case in
792 * thread_in_lisp_raised(). */
793 SET_THREAD_STOP_PENDING(self
,NIL
);
794 set_csp_from_context(self
, ctxptr
);
795 if (gc_state
.phase
<= GC_SETTLED
)
796 gc_advance(GC_NONE
,gc_state
.phase
);
798 gc_state_wait(GC_NONE
);
799 *self
->csp_around_foreign_call
= 0;
801 /* This thread has GC_INHIBIT set, meaning that it's
802 * within a WITHOUT-GCING, so advance from wherever we
803 * are (GC_MESSAGE) to GC_INVOKED so that we can
804 * continue running. When we leave the WITHOUT-GCING
805 * we'll take a PIT stop and wind up in the case
806 * above... Or we'll call gc_stop_the_world(). This
807 * logic is identical to the similar case in
808 * thread_in_lisp_raised(). */
809 gc_advance(GC_INVOKED
,gc_state
.phase
);
810 SET_THREAD_STOP_PENDING(self
,T
);
814 #ifdef LISP_FEATURE_SB_THRUPTION
816 while(check_pending_thruptions(ctxptr
));
821 #ifdef LISP_FEATURE_WIN32
822 void thread_interrupted(os_context_t
*ctxptr
)
824 struct thread
*self
= arch_os_get_current_thread();
825 boolean gc_active
, was_in_alien
;
827 odxprint(safepoints
,"%s","pending interrupt trap");
829 gc_active
= gc_cycle_active();
831 was_in_alien
= set_thread_csp_access(self
,1);
836 thread_in_safety_transition(ctxptr
);
838 thread_in_lisp_raised(ctxptr
);
841 check_pending_gc(ctxptr
);
842 #ifdef LISP_FEATURE_SB_THRUPTION
843 while(check_pending_thruptions(ctxptr
));
851 struct thread
* self
= arch_os_get_current_thread();
852 odxprint(safepoints
, "stop the world");
854 /* This thread is the collector, and needs special handling in
855 * gc_notify_early() and gc_notify_final() because of it. */
856 gc_state
.collector
= self
;
857 /* And we need to control advancement past GC_QUIET. */
858 gc_state
.phase_wait
[GC_QUIET
]++;
860 /* So, we won the race to get to gc_stop_the_world(). Now we
861 * need to get to GC_COLLECT, where we're the only thread
862 * running, so that we can run the collector. What we do
863 * depends on what's already been done. */
864 switch(gc_state
.phase
) {
866 gc_advance(GC_QUIET
,gc_state
.phase
);
870 if ((gc_state
.phase
== GC_MESSAGE
)
871 || (gc_state
.phase
== GC_INVOKED
)) {
872 /* If the phase was GC_MESSAGE or GC_INVOKED, we were
873 * accounted as "in alien", and are on the GC_INVOKED
874 * waitcount, or we were "in lisp" but in WITHOUT-GCING,
875 * which led to us putting OURSELVES on the GC_INVOKED
877 gc_advance(GC_QUIET
, GC_INVOKED
);
879 gc_state_wait(GC_QUIET
);
882 /* Some number of threads were trying to get to GC_QUIET.
883 * But this thread is sufficient to be able to leave
885 gc_state
.phase_wait
[GC_QUIET
]=1;
886 /* Advance through GC_SETTLED to GC_COLLECT, stopping the
887 * other threads that were racing to stop the world. */
888 gc_advance(GC_COLLECT
,GC_QUIET
);
893 lose("Stopping the world in unexpected state %d",gc_state
.phase
);
896 set_thread_csp_access(self
,1);
898 SET_THREAD_STOP_PENDING(self
,NIL
);
902 void gc_start_the_world()
904 odxprint(safepoints
,"%s","start the world");
906 gc_state
.collector
= NULL
;
907 write_TLS(IN_WITHOUT_GCING
,IN_WITHOUT_GCING
,
908 arch_os_get_current_thread());
909 gc_advance(GC_NONE
,GC_COLLECT
);
914 #ifdef LISP_FEATURE_SB_THRUPTION
915 /* wake_thread(thread) -- ensure a thruption delivery to
918 # ifdef LISP_FEATURE_WIN32
921 wake_thread_io(struct thread
* thread
)
923 SetEvent(thread
->private_events
.events
[1]);
924 win32_maybe_interrupt_io(thread
);
928 wake_thread_win32(struct thread
*thread
)
930 struct thread
*self
= arch_os_get_current_thread();
932 wake_thread_io(thread
);
934 if (read_TLS(THRUPTION_PENDING
,thread
)==T
)
937 write_TLS(THRUPTION_PENDING
,T
,thread
);
939 if ((read_TLS(GC_PENDING
,thread
)==T
)
940 ||(THREAD_STOP_PENDING(thread
)==T
)
944 wake_thread_io(thread
);
945 pthread_mutex_unlock(&all_threads_lock
);
948 if (gc_state
.phase
== GC_NONE
) {
949 gc_advance(GC_INVOKED
,GC_NONE
);
950 gc_advance(GC_NONE
,GC_INVOKED
);
954 pthread_mutex_lock(&all_threads_lock
);
959 wake_thread_posix(os_thread_t os_thread
)
962 struct thread
*thread
;
963 struct thread
*self
= arch_os_get_current_thread();
965 /* Must not and need not attempt to signal ourselves while we're the
967 if (self
->os_thread
== os_thread
) {
968 write_TLS(THRUPTION_PENDING
,T
,self
);
969 while (check_pending_thruptions(0 /* ignore the sigmask */))
974 /* We are not in a signal handler here, so need to block signals
977 block_deferrable_signals(&oldset
);
980 if (gc_state
.phase
== GC_NONE
) {
981 odxprint(safepoints
, "wake_thread_posix: invoking");
982 gc_advance(GC_INVOKED
,GC_NONE
);
984 /* only if in foreign code, notify using signal */
985 WITH_ALL_THREADS_LOCK
{
986 for_each_thread (thread
)
987 if (thread
->os_thread
== os_thread
) {
988 /* it's still alive... */
991 odxprint(safepoints
, "wake_thread_posix: found");
992 write_TLS(THRUPTION_PENDING
,T
,thread
);
993 if (read_TLS(GC_PENDING
,thread
) == T
994 || THREAD_STOP_PENDING(thread
) == T
)
997 if (os_get_csp(thread
)) {
998 odxprint(safepoints
, "wake_thread_posix: kill");
999 /* ... and in foreign code. Push it into a safety
1001 int status
= pthread_kill(os_thread
, SIGPIPE
);
1003 lose("wake_thread_posix: pthread_kill failed with %d\n",
1010 gc_advance(GC_NONE
,GC_INVOKED
);
1012 odxprint(safepoints
, "wake_thread_posix: passive");
1013 /* We are not able to wake the thread up actively, but maybe
1014 * some other thread will take care of it. Kludge: Unless it is
1015 * in foreign code. Let's at least try to get our return value
1017 WITH_ALL_THREADS_LOCK
{
1018 for_each_thread (thread
)
1019 if (thread
->os_thread
== os_thread
) {
1020 write_TLS(THRUPTION_PENDING
,T
,thread
);
1028 odxprint(safepoints
, "wake_thread_posix leaving, found=%d", found
);
1029 thread_sigmask(SIG_SETMASK
, &oldset
, 0);
1030 return found
? 0 : -1;
1032 #endif /* !LISP_FEATURE_WIN32 */
1033 #endif /* LISP_FEATURE_SB_THRUPTION */
1036 os_get_csp(struct thread
* th
)
1038 FSHOW_SIGNAL((stderr
, "Thread %p has CSP *(%p) == %p, stack [%p,%p]\n",
1040 th
->csp_around_foreign_call
,
1041 *(void***)th
->csp_around_foreign_call
,
1042 th
->control_stack_start
,
1043 th
->control_stack_end
));
1044 return *(void***)th
->csp_around_foreign_call
;
1048 #ifndef LISP_FEATURE_WIN32
1050 # ifdef LISP_FEATURE_SB_THRUPTION
1052 thruption_handler(int signal
, siginfo_t
*info
, os_context_t
*ctx
)
1054 struct thread
*self
= arch_os_get_current_thread();
1056 void *transition_sp
= os_get_csp(self
);
1058 /* In Lisp code. Do not run thruptions asynchronously. The
1059 * next safepoint will take care of it. */
1062 #ifndef LISP_FEATURE_C_STACK_IS_CONTROL_STACK
1063 if (!foreign_function_call_active_p(self
))
1064 lose("csp && !ffca");
1067 /* In C code. As a rule, we assume that running thruptions is OK. */
1068 *self
->csp_around_foreign_call
= 0;
1069 thread_in_lisp_raised(ctx
);
1070 *self
->csp_around_foreign_call
= (intptr_t) transition_sp
;
1074 #ifdef LISP_FEATURE_C_STACK_IS_CONTROL_STACK
1075 /* Trap trampolines are in target-assem.S so that they pick up the
1076 * trap instruction selection features automatically. */
1078 handle_global_safepoint_violation(lispobj fun
, lispobj
*args
, int nargs
);
1080 handle_csp_safepoint_violation(lispobj fun
, lispobj
*args
, int nargs
);
1084 handle_safepoint_violation(os_context_t
*ctx
, os_vm_address_t fault_address
)
1086 FSHOW_SIGNAL((stderr
, "fault_address = %p, sp = %p, &csp = %p\n",
1088 GC_SAFEPOINT_TRAP_ADDR
,
1089 arch_os_get_current_thread()->csp_around_foreign_call
));
1091 struct thread
*self
= arch_os_get_current_thread();
1093 if (fault_address
== (os_vm_address_t
) GC_SAFEPOINT_TRAP_ADDR
) {
1094 #ifdef LISP_FEATURE_C_STACK_IS_CONTROL_STACK
1095 /* We're on the altstack and don't want to run Lisp code. */
1096 arrange_return_to_c_function(ctx
, handle_global_safepoint_violation
, 0);
1098 if (foreign_function_call_active_p(self
)) lose("GSP trap in C?");
1099 fake_foreign_function_call(ctx
);
1100 thread_in_lisp_raised(ctx
);
1101 undo_fake_foreign_function_call(ctx
);
1106 if (fault_address
== (os_vm_address_t
) self
->csp_around_foreign_call
) {
1107 #ifdef LISP_FEATURE_C_STACK_IS_CONTROL_STACK
1108 arrange_return_to_c_function(ctx
, handle_csp_safepoint_violation
, 0);
1110 if (!foreign_function_call_active_p(self
)) lose("CSP trap in Lisp?");
1111 thread_in_safety_transition(ctx
);
1116 /* not a safepoint */
1119 #endif /* LISP_FEATURE_WIN32 */
1121 #if defined(LISP_FEATURE_SB_SAFEPOINT_STRICTLY) && !defined(LISP_FEATURE_WIN32)
1123 signal_handler_callback(lispobj run_handler
, int signo
, void *info
, void *ctx
)
1125 init_thread_data scribble
;
1127 DX_ALLOC_SAP(args_sap
, args
);
1132 attach_os_thread(&scribble
);
1134 odxprint(misc
, "callback from signal handler thread for: %d\n", signo
);
1135 WITH_GC_AT_SAFEPOINTS_ONLY() {
1136 funcall3(StaticSymbolFunction(SIGNAL_HANDLER_CALLBACK
),
1137 run_handler
, make_fixnum(signo
), args_sap
);
1140 detach_os_thread(&scribble
);
1145 #endif /* LISP_FEATURE_SB_SAFEPOINT -- entire file */