};
extern processor_t *processors;
+extern processor_t *smp_io_blocked;
extern __thread processor_t *self;
extern processor_t *gc_processor;
/* 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;
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;
}
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
}
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
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); \
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))
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