Commit graph

511 commits

Author SHA1 Message Date
normal
1b1274f728 thread_pthread.c: fix deadlock on test_thread.rb::test_signal_at_join
Fixes: r64575 ("avoid lock ping-pong in do_gvl_timer & ubf_select")

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64579 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-08-27 23:29:44 +00:00
normal
9d4027b503 process.c: simplify SIGCHLD-based waitpid
Introduce a new rb_thread_sleep_interruptible that does not
execute interrupts before sleeping.  Skipping the interrupt
check before sleep is required for out-of-GVL ruby_waitpid_all
to function properly when setting waitpid_state.ret

Now that ubf_select can be called by the gvl.timer thread
without recursive locking gvl.lock, we can safely use
rb_threadptr_interrupt to deal with waking up sleeping
processes,

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64576 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-08-27 17:17:13 +00:00
normal
943bf37b10 thread_pthread.c: avoid lock ping-pong in do_gvl_timer & ubf_select
This simplifies the locking logic somewhat.

While we're at it, designate_timer_thread is worthless in
ubf_select because gvl_acquire_common already guarantees there
is a gvl.timer if gvl->waitq is populated.

In the future (for auto-fiber), this will allow using
th->unblock.func for rb_waitpid callers (via rb_sigchld_handler).

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64575 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-08-27 17:17:08 +00:00
normal
894847a5de thread_pthread.c (ubf_wakeup_thread): `th' is never NULL
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64539 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-08-25 22:14:14 +00:00
normal
70a8a6d3eb thread_pthread.c: main thread always gets hit by signals
We need to ensure Signal.trap handlers can function if the main
thread is sleeping after a subthread has grabbed sigwait_fd,
but later exited.

Consider the following timeline:

main_thread             sub-thread
-----------------------------------------
Signal.trap() { ... }
                        get sigwait_fd
                        ppoll on sigwait_fd
native_cond_sleep
(via pthread_cond_wait)
                        ppoll times-out
			put sigwait_fd
                        sub-thread exits

only thread alive
SIGNAL HITS

The problem is pthread_cond_wait cannot return EINTR,
so we can never run the Signal.trap handler.  So we
will avoid using native_cond_sleep in the main thread
and always use ppoll to sleep when in the main thread.
This can guarantee the main thread remains aware of
signals; even if it cannot safely read off sigwait_fd

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64538 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-08-25 21:59:30 +00:00
normal
b0253a7569 thread.c: use rb_hrtime_t scalar for high-resolution time operations
Relying on "struct timespec" was too annoying API-wise and
used more stack space.  "double" was a bit wacky w.r.t rounding
in the past, so now we'll switch to using a 64-bit type.

Unsigned 64-bit integer is able to give us over nearly 585
years of range with nanoseconds.  This range is good enough
for the Linux kernel internal time representation, so it
ought to be good enough for us.

This reduces the stack usage of functions while GVL is held
(and thus subject to marking) on x86-64 Linux (with ppoll):

	rb_wait_for_single_fd    120 => 104
	do_select                120 => 88

[ruby-core:88582] [Misc #15014]

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64533 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-08-25 06:58:35 +00:00
normal
0a77fd04b7 thread_pthread.c: use eventfd instead of pipe on Linux
Based on r64478, any regular user creating more than 1024 pipes
on Linux will end up with tiny pipes with only a single page
capacity.  So avoid wasting user resources and use lighter
eventfd on Linux.

[ruby-core:88563] [Misc #15011]

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64527 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-08-24 19:19:01 +00:00
normal
7bde63fad6 thread_pthread.c (ubf_timer_destroy): remove redundant getpid check
TIMER_THREAD_CREATED_P already checks that pid, and glibc 2.25+
no longer caches getpid(2).

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64524 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-08-23 19:49:35 +00:00
normal
17e4aff277 thread_pthread.c: reinitialize ubf_list at fork
It's possible for the ubf_list_head to be populated with dead
threads at fork or the ubf_list_lock to be held, so reinitialize
both at startup.

And while we're at it, use a static initializer at startup
to save a library call and kill some ifdef.

[ruby-core:88578] [Bug #15013]

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64485 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-08-20 21:34:39 +00:00
normal
d2afeb9445 thread_pthread.c: reset timeslice delay when uncontended
This matches the behavior of old timer thread more closely
and seems to fix [Bug #14999] when limited to a single CPU.
I cannot reproduce the error on a multi-core system unless
I use schedtool to force affinity to a single CPU:

schedtool -a 0x01 -e make test-spec \
	MSPECOPT='-R1000 spec/ruby/library/conditionvariable/wait_spec.rb'

While it may be good enough to pass the spec, I don't have
huge degree of confidence in the interrupt handling robustness
under extremely heavy load (these may be ancient bugs, though).

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64467 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-08-19 00:01:08 +00:00
normal
8b6297e56d thread_pthread.c (rb_sigwait_fd_get): skip getpid check
This is not called in signal handlers, so there's no reason for
it.  glibc 2.25+ no longer caches getpid(), so it will cost a
syscall for those users.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64403 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-08-17 02:06:54 +00:00
normal
3872ea814c thread_pthread.c: reduce ubf_timer arming for non-signal wakeups
We do not need to rely on SIGVTALRM for non-sighandler wakeups.
This will reduce spurious wakeups in cases where sigwait_fd
is not grabbed again, soon.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64389 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-08-16 08:26:56 +00:00
normal
960ef493a4 thread_pthread.c: check signals from gvl.timer
For (rare) blocking functions which are not affected by signals,
we need to call the appropriate unblocking function via
`threadptr_trap_interrupt'

While we're at it, handling waitpid/SIGCHLD from gvl.timer isn't
harmful, here.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64388 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-08-16 08:26:51 +00:00
normal
4610d36c4c thread_pthread.c: hoist out do_gvl_timer and improve documentation
This hopefully clarifies the roles of UBF_TIMER and vm->gvl.timer

[ruby-core:88475] [Misc #14937]

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64377 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-08-15 07:16:55 +00:00
normal
906ad1670a thread_pthread.h (native_thread_data): split list_node between ubf and gvl
Do not waste extra memory for each thread, but make
thread_pthread.c easier-to-follow as a result.

[ruby-core:88475] [Misc #14937]

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64375 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-08-15 05:31:31 +00:00
normal
3dcf85e08e thread_pthread.c: rename rb_timer_* to ubf_timer_*
These functions will not be exported outside of thread_pthread.c
and we need to clarify the timer here is used for ubf and not
timeslice.

[ruby-core:88475] [Misc #14937]

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64373 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-08-15 04:32:46 +00:00
normal
e4fd71d64d thread_pthread.c: rename timer_thread_pipe to signal_self_pipe
This data structure has nothing to do with timers or threads.

[ruby-core:88475] [Misc #14937]

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64372 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-08-15 04:32:41 +00:00
normal
5dca7d86b9 thread_pthread.c: additional UBF_TIMER == UBF_TIMER_PTHREAD guards
Hopefully this makes the code easier-to-follow

[ruby-core:88475] [Misc #14937]

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64371 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-08-15 04:32:36 +00:00
normal
635294038b Revert "thread_pthread.c: use UBF_TIMER_PTHREAD on Solaris"
This reverts commit 31bfe0fe86 (r64357)

commit 17ed23bb6d (r64359,
"fix fragile spec from unpredictable errno") is the correct fix

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64361 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-08-14 22:06:40 +00:00
normal
31bfe0fe86 thread_pthread.c: use UBF_TIMER_PTHREAD on Solaris
I'm not sure what's causing this failure in Solaris and only
on rubyspec, since rb_io_wait_readable is a well-exercised
code path in other places.  But maybe using a pthread for
timing (similar to old timer-thread) can solve the issue.

cf. 20180814T042506Z.fail.html.gz

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64357 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-08-14 06:49:25 +00:00
normal
291afc96bd thread_pthread.c: use CLOCK_REALTIME on SunOS (Solaris)
timer_create does not seem to support CLOCK_MONOTONIC on Solaris,
and CLOCK_HIRES seems like it could fail with insufficient permissions:

https://docs.oracle.com/cd/E86824_01/html/E54766/timer-create-3c.html

(Only tested on Linux and FreeBSD)

[ruby-core:88360] [Misc #14937]

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64356 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-08-14 02:24:37 +00:00
normal
8da12db13d thread_pthread (rb_timer_arm): ignore UBF_TIMER_POSIX state 2
It looks like I forgot to account for a situation involving 3
threads.

[ruby-core:88360] [Misc #14937]

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64354 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-08-13 22:19:54 +00:00
normal
3dd6288d73 thread_pthread: use POSIX timer or thread to get rid of races
This closes race condition where GVL is uncontended and a thread
receives a signal immediately before calling the blocking
function when releasing GVL:

	1) check interrupts
	2) release GVL
	3) blocking function

If signal fires after 1) but before 3), that thread may never
wake up if GVL is uncontended

We also need to wakeup the ubf_list unconditionally on
gvl_yield; because two threads can be yielding to each other
while waiting on IO#close while waiting on threads in IO#read or
IO#gets.

[ruby-core:88360] [Misc #14937]

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64353 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-08-13 21:34:24 +00:00
normal
48b6bd74e2 thread_pthread.c: eliminate timer thread by restructuring GVL
This reverts commit 194a6a2c68 (r64203).

Race conditions which caused the original reversion will be fixed
in the subsequent commit.

[ruby-core:88360] [Misc #14937]

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64352 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-08-13 21:34:20 +00:00
normal
194a6a2c68 thread_pthread.c: restore timer-thread for now :<
[ruby-core:88306]

Revert "process.c: ensure th->interrupt lock is held when migrating"

This reverts commit 5ca416bdf6 (r64201)

Revert "process.c (rb_waitpid): reduce sigwait_fd bouncing"

This reverts commit 217bdd776f (r64200).

Revert "test/ruby/test_thread.rb (test_thread_timer_and_interrupt): add timeouts"

This reverts commit 9f395f1120 (r64199).

Revert "thread_pthread.c (native_sleep): reduce ppoll sleeps"

This reverts commit b3aa256c4d (r64193).

Revert "thread.c (consume_communication_pipe): do not retry after short read"

This reverts commit 291a82f748 (r64185).

Revert "test/ruby/test_io.rb (test_race_gets_and_close): timeout each thread"

This reverts commit 3dbd8d1f66 (r64184).

Revert "thread_pthread.c (gvl_acquire_common): persist timeout across calls"

This reverts commit 8c2ae6e3ed (r64165).

Revert "test/ruby/test_io.rb (test_race_gets_and_close): use SIGABRT on timeout"

This reverts commit 931cda4db8 (r64135).

Revert "thread_pthread.c (gvl_yield): do ubf wakeups when uncontended"

This reverts commit 508f00314f (r64133).

Revert "thread_pthread.h (native_thread_data): split condvars on some platforms"

This reverts commit a038bf238b (r64124).

Revert "process.c (waitpid_nogvl): prevent conflicting use of sleep_cond"

This reverts commit 7018acc946 (r64117).

Revert "thread_pthread.c (rb_sigwait_sleep): th may be 0 from MJIT"

This reverts commit 56491afc79 (r64116).

Revert "thread*.c: waiting on sigwait_fd performs periodic ubf wakeups"

This reverts commit ab47a57a46 (r64115).

Revert "thread_pthread.c (gvl_destroy): make no-op on GVL bits"

This reverts commit 95cae74817 (r64114).

Revert "thread_pthread.c (rb_sigwait_sleep): fix uninitialized poll set in UBF case"

This reverts commit 4514362948 (r64113).

Revert "thread_pthread.c (rb_sigwait_sleep): re-fix [Bug #5343] harder"

This reverts commit 26b8a70bb3 (r64111).

Revert "thread.c: move ppoll wrapper into thread_pthread.c"

This reverts commit 3dc7727d22 (r64110).

Revert "thread.c: move ppoll wrapper before thread_pthread.c"

This reverts commit 2fa1e2e3c3 (r64109).

Revert "thread_pthread.c (ubf_select): refix [Bug #5343]"

This reverts commit 4c1ab82f06 (r64108).

Revert "thread_win32.c: suppress warnings by -Wsuggest-attribute"

This reverts commit 6a9b63e390 (r64159).

Revert "thread_pthread: remove timer-thread by restructuring GVL"

This reverts commit 708bfd2115 (r64107).

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64203 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-08-06 05:22:00 +00:00
normal
2ba640f359 thread_pthread: stop trying to deal with cancellation
We don't use pthreads cancellation ourselves and it's painful to
use correctly.  Any cancelled threads would break
vm->living_threads, GVL, thread_sync.c, autoload, etc...

So don't bother caring; because we can't stop rogue extensions
from completely breaking the VM in other ways, either.

[ruby-core:88282] [Misc #14962]

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64197 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-08-05 20:06:49 +00:00
normal
b3aa256c4d thread_pthread.c (native_sleep): reduce ppoll sleeps
By holding into sigwait_fd until after we acquire GVL, we can
hit the faster native_cond_sleep path instead of ppoll when
another thread wants to start sleeping.  ppoll-ing on sigwait_fd
isn't really useful in program where GVL is contended

This also allows reducing vm->gvl.lock mutex contention on
waitpid sleep migrations.

                         r64170        this patch
vm_thread_condvar1        0.921        1.356

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64193 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-08-05 08:56:52 +00:00
mame
4cef2c8d6b thread_pthread.c: add a macro guard for PTHREAD_CANCEL_ENABLE
It seems to be unavailable on some platforms including my Android phone.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64166 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-08-03 05:11:20 +00:00
normal
8c2ae6e3ed thread_pthread.c (gvl_acquire_common): persist timeout across calls
Reuse old expiration time if the previous native_cond_timedwait
did not return ETIMEDOUT.  This should improve timeslice
accuracy for Timeout.timeout rubyspec without causing excessive
wakeups on uncontended GVL acquisition.

cf. http://ci.rvm.jp/results/trunk-gc-asserts@silicon-docker/1180486
    http://ci.rvm.jp/results/trunk-gc-asserts@silicon-docker/1184623

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64165 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-08-02 21:13:50 +00:00
normal
86d35a6b1a thread_pthread.c (unregister_ubf_list): assert unblock.func is unset
We must not allow reentry into ubf_list_head once we delete
ourselves, otherwise we could hang in there forever.

[ruby-core:88218] [Bug #14945]

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64134 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-07-30 21:48:32 +00:00
normal
508f00314f thread_pthread.c (gvl_yield): do ubf wakeups when uncontended
Not having contention for GVL could mean everybody else is stuck
in blocking region without GVL, so we kick the ubf list in that
case.

I expect this to fix test_thread_fd_close timeout:
http://ci.rvm.jp/results/trunk-test@ruby-sky3/1173398

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64133 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-07-30 18:53:46 +00:00
nobu
09df9972dc thread_pthread.c: revert r64123
* thread_pthread.c (USE_NATIVE_SLEEP_COND): revised wrongly removed
  line with the ifndef guard.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64131 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-07-30 15:21:01 +00:00
normal
a038bf238b thread_pthread.h (native_thread_data): split condvars on some platforms
Maybe some platforms have strange condition variable implementations
which have a "memory" of which mutexes they're associated with.

In any case, it makes documentation easier even on GNU/Linux and
FreeBSD.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64124 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-07-30 09:54:41 +00:00
nobu
c307ffe64f thread_pthread.c: remove duplicate define
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64123 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-07-30 08:45:19 +00:00
normal
56491afc79 thread_pthread.c (rb_sigwait_sleep): th may be 0 from MJIT
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64116 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-07-30 06:02:22 +00:00
normal
ab47a57a46 thread*.c: waiting on sigwait_fd performs periodic ubf wakeups
We need to be able to perform periodic ubf_list wakeups when a
thread is sleeping and waiting on signals.

[ruby-core:88088] [Misc #14937] [Bug #5343]

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64115 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-07-30 05:51:06 +00:00
normal
95cae74817 thread_pthread.c (gvl_destroy): make no-op on GVL bits
It's possible for another thread to take vm->gvl.lock
during gvl_release at the end of thread_start_func_2
during VM shutdown, at least.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64114 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-07-30 05:51:01 +00:00
normal
4514362948 thread_pthread.c (rb_sigwait_sleep): fix uninitialized poll set in UBF case
[ruby-core:88088] [Misc #14937] [Bug #5343]

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64113 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-07-30 04:28:28 +00:00
normal
26b8a70bb3 thread_pthread.c (rb_sigwait_sleep): re-fix [Bug #5343] harder
We can't always designate a timer thread, so any sleepers must
also perform ubf wakeups.  Note: a similar change needs to be
made for rb_thread_fd_select and rb_wait_for_single_fd.

[ruby-core:88088] [Misc #14937] [Bug #5343]

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64111 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-07-30 02:28:00 +00:00
normal
3dc7727d22 thread.c: move ppoll wrapper into thread_pthread.c
thread_pthread.c relies on ppoll for rb_sigwait_sleep, so ensure
the compatibility wrapper is available for it.

[Bug #14950]

Reported-by: SHIBATA Hiroshi <hsbt@ruby-lang.org>
Reported-by: Greg L <Greg.mpls@gmail.com>

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64110 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-07-30 00:31:08 +00:00
normal
4c1ab82f06 thread_pthread.c (ubf_select): refix [Bug #5343]
We still need to to designate a timer thread after registering target
thread for the ubf list.

Oops :x

Note: I was never able to reproduce
test/thread/test_queue.rb::test_thr_kill failures on my on
Debian machines.

[ruby-core:88088] [Misc #14937] [Bug #5343]

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64108 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-07-29 22:19:15 +00:00
normal
708bfd2115 thread_pthread: remove timer-thread by restructuring GVL
To reduce resource use and reduce CI failure; remove
timer-thread.  Single-threaded Ruby processes (including forked
children) will never see extra thread overhead.  This prevents
glibc and jemalloc from going into multi-threaded mode and
initializing locks or causing fragmentation via arena explosion.

The GVL is implements its own wait-queue as a ccan/list to
permit controlling wakeup order.  Timeslice under contention is
handled by a designated timer thread (similar to choosing a
"patrol_thread" for current deadlock checking).

There is only one self-pipe, now, as wakeups for timeslice are
done independently using condition variables.  This reduces FD
pressure slightly.

Signal handling is handled directly by a Ruby Thread (instead
of timer-thread) by exposing signal self-pipe to callers of
rb_thread_fd_select, native_sleep, rb_wait_for_single_fd, etc...
Acquiring, using, and releasing the self-pipe is exposed via 4
new internal functions:

1) rb_sigwait_fd_get - exclusively acquire timer_thread_pipe.normal[0]

2) rb_sigwait_fd_sleep - sleep and wait for signal (and no other FDs)

3) rb_sigwait_fd_put - release acquired result from rb_sigwait_fd_get

4) rb_sigwait_fd_migrate - migrate signal handling to another thread
                           after calling rb_sigwait_fd_put.

rb_sigwait_fd_migrate is necessary for waitpid callers because
only one thread can wait on self-pipe at a time, otherwise a
deadlock will occur if threads fight over the self-pipe.

TRAP_INTERRUPT_MASK is now set for the main thread directly in
signal handler via rb_thread_wakeup_timer_thread.

Originally, I wanted to use POSIX timers
(timer_create/timer_settime) for this.  Unfortunately, this
proved unfeasible as Mutex#sleep resumes on spurious wakeups and
test/thread/test_cv.rb::test_condvar_timed_wait failed.  Using
pthread_sigmask to mask out SIGVTALRM fixed that test,  but
test/fiddle/test_function.rb::test_nogvl_poll proved there'd be
some unavoidable (and frequent) incompatibilities from that
approach.

Finally, this allows us to drop thread_destruct_lock and
interrupt current ec directly.

We don't need to rely on vm->thread_destruct_lock or a coherent
vm->running_thread on any platform.  Separate timer-thread for
time slice and signal handling is relegated to thread_win32.c,
now.

[ruby-core:88088] [Misc #14937]

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64107 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-07-29 20:47:33 +00:00
normal
c95467e597 thread_pthread.c: clear altstacks in thread cache at GVL destruction
Otherwise, an altstack may live past ObjectSpace destruction
and xfree-ing the altstack will segfault.

[ruby-core:85621] [Feature #14487]

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64102 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-07-29 10:15:11 +00:00
normal
c6b85fcd01 timer_thread: do not close pipes around fork
There's actually no need to close the pipes used by the
sleepy timer thread before forking, only to stop the timer
thread itself.

Instead, we only close the parent pipes in the child process,
either via close-on-exec flag or when reinitializing the timer
thread.

This change will be necessary when we allow
rb_wait_for_single_fd and rb_thread_fd_select to wait on the
timer_thread_pipe.normal[0] directly and eliminate timer thread.

I don't anticipate compatibility problems with this change
alone.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63960 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-07-12 23:23:25 +00:00
normal
b205642518 thread_pthread: avoid redundant error message on pipe2() fail
Seeing one error for pipe creation is enough.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63949 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-07-11 08:49:23 +00:00
normal
23f4ba46de thread_pthread.c: use mask for timer implementation
timer-thread will continue to be supported, but future
"timer" implementation may not be a thread.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63948 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-07-11 08:49:18 +00:00
normal
c93adfc170 mjit: get rid of memory leak in pause+resume loop
pthread_atfork is not idempotent and repeatedly calling it
causes it to register the same hook repeatedly; leading to
unbound memory growth.

Ruby already has a (confusing-named) internal API for to call
in the forked child process: rb_thread_atfork
Call the MJIT child_after_fork hook inside that to prevent
unbound growth with the following loop:

    loop do
      RubyVM::MJIT.pause
      RubyVM::MJIT.resume
    end

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63884 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-07-08 07:27:24 +00:00
normal
44fc3d08eb unrevert r63852 but keep SIGCHLD path disabled for win32
Reading win32/win32.c waitpid implementation, maybe waitpid(-1, ...)
on that platform will never conflict with mjit use of waitpid.

In any case, I've added WAITPID_USE_SIGCHLD macro to vm_core.h
so it can be easy for Linux/BSD users to test (hopefully!)
win32-compatible code.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63855 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-07-05 03:02:33 +00:00
naruse
df4a126d65 Revert r63758 and related commits
The change is unstable on Windows. Please re-commit it when it correctly
supports Windows.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63852 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-07-04 15:08:56 +00:00
normal
d9dac20bb3 thread_pthread.c: pass rb_vm_t to timer_thread_sleep
I love `container_of' for generic data structures, but
in this case it's unnecessary and slightly harder-to-read.

This will make "Timeout in VM" slightly easier-to-read:
https://bugs.ruby-lang.org/issues/14859

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63846 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-07-04 01:26:31 +00:00