From: Matt Birkholz Date: Sun, 19 Jul 2015 17:31:14 +0000 (-0700) Subject: Forward SIGCHLD to the io-waiter. X-Git-Url: https://birchwood-abbey.net/git?a=commitdiff_plain;h=511ed0874d1fb16e926216783f86a9c8cec043c4;p=mit-scheme.git Forward SIGCHLD to the io-waiter. Set/clear the new variable smp_io_blocked around calls to poll/select so that subprocess_death (SIGCHLD) can wake a blocked processor without having to ask Scheme which (if any) is running the io-waiter. Wake the processor with a timer interrupt withOUT fiddling next_timer. --- diff --git a/src/microcode/ossmp.h b/src/microcode/ossmp.h index da4b85a02..4eafb5094 100644 --- a/src/microcode/ossmp.h +++ b/src/microcode/ossmp.h @@ -58,6 +58,7 @@ struct processor { }; extern processor_t *processors; +extern processor_t *smp_io_blocked; extern __thread processor_t *self; extern processor_t *gc_processor; diff --git a/src/microcode/prossmp.c b/src/microcode/prossmp.c index eba3173ec..162fc8356 100644 --- a/src/microcode/prossmp.c +++ b/src/microcode/prossmp.c @@ -60,6 +60,9 @@ static processor_t *threads_processor = NULL; /* The current pthread's processor. */ __thread processor_t *self; +/* The io-waiter's processor when it is blocked in test-select-registry. */ +processor_t *smp_io_blocked = NULL; + extern int saved_processor_count; extern int saved_processor_heap_size; extern int saved_stack_size; diff --git a/src/microcode/uxio.c b/src/microcode/uxio.c index 027f7c7e5..5736e4eb1 100644 --- a/src/microcode/uxio.c +++ b/src/microcode/uxio.c @@ -33,6 +33,14 @@ USA. Tchannel OS_channel_table_size; struct channel * channel_table; +#ifdef ENABLE_SMP +# define SMP_IO_BLOCKED smp_io_blocked = self +# define SMP_IO_UNBLOCKED smp_io_blocked = NULL +#else +# define SMP_IO_BLOCKED do {} while (false) +# define SMP_IO_UNBLOCKED do {} while (false) +#endif + #ifndef HAVE_POLL #ifdef HAVE_SELECT static struct timeval zero_timeout; @@ -600,17 +608,21 @@ safe_poll (struct pollfd *fds, nfds_t nfds, int blockp) } else { + SMP_IO_BLOCKED; n = (UX_ppoll (fds, nfds, NULL, &old)); + SMP_IO_UNBLOCKED; } UX_sigprocmask (SIG_SETMASK, &old, NULL); } #else /* not HAVE_PPOLL */ { + SMP_IO_BLOCKED; INTERRUPTABLE_EXTENT (n, (((OS_process_any_status_change ()) || ((GET_INT_CODE) != 0)) ? ((errno = EINTR), (-1)) : (UX_poll (fds, nfds, (blockp ? INFTIM : 0))))); + SMP_IO_UNBLOCKED; } #endif @@ -814,18 +826,22 @@ safe_select (int nfds, SELECT_TYPE *readfds, SELECT_TYPE *writefds, int blockp) } else { + SMP_IO_BLOCKED; n = (UX_pselect (nfds, readfds, writefds, NULL, NULL, &old)); + SMP_IO_UNBLOCKED; } UX_sigprocmask (SIG_SETMASK, &old, NULL); } #else /* not HAVE_PSELECT */ { + SMP_IO_BLOCKED; INTERRUPTABLE_EXTENT (n, (((OS_process_any_status_change ()) || ((GET_INT_CODE) != 0)) ? ((errno = EINTR), (-1)) : (UX_select (nfds, readfds, writefds, NULL, (blockp ? NULL : &zero_timeout))))); + SMP_IO_UNBLOCKED; } #endif diff --git a/src/microcode/uxproc.c b/src/microcode/uxproc.c index 9ae288029..9dc32b367 100644 --- a/src/microcode/uxproc.c +++ b/src/microcode/uxproc.c @@ -58,6 +58,12 @@ static Tprocess foreground_child_process; static long process_tick; static long sync_tick; +#ifdef ENABLE_SMP +# ifdef ENABLE_DEBUGGING_TOOLS +# define ENABLE_SMP_DEBUGGING 1 +# endif +#endif + #define NEW_RAW_STATUS(process, status, reason) do \ { \ (PROCESS_RAW_STATUS (process)) = (status); \ @@ -719,7 +725,14 @@ find_process (pid_t pid) static void subprocess_death (pid_t pid, int * status) { - Tprocess process = (find_process (pid)); + Tprocess process; + +#ifdef ENABLE_SMP_DEBUGGING + if (smp_trace_p) + outf_error_line (";%d subprocess_death: %d blocked", self->id, + (smp_io_blocked != NULL ? smp_io_blocked->id : -1)); +#endif + process = (find_process (pid)); if (process != NO_PROCESS) { if (WIFEXITED (*status)) @@ -732,6 +745,22 @@ subprocess_death (pid_t pid, int * status) NEW_RAW_STATUS (process, process_status_signalled, (WTERMSIG (*status))); } +#ifdef ENABLE_SMP + if (smp_io_blocked != NULL && smp_io_blocked != self) + { +# ifdef ENABLE_SMP_DEBUGGING + if (smp_trace_p) + outf_error_line (";%d subprocess_death: interrupting %d", + self->id, smp_io_blocked->id); +# endif + pthread_kill (smp_io_blocked->pthread, SIGALRM); +# ifdef ENABLE_SMP_DEBUGGING + if (smp_trace_p) + outf_error_line (";%d subprocess_death: interrupted %d", + self->id, smp_io_blocked->id); +# endif + } +#endif } static void