Age | Commit message (Collapse) | Author |
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
* 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
|
|
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
|
|
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64123 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
|
|
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64116 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
|
|
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
|
|
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
|
|
[ruby-core:88088] [Misc #14937] [Bug #5343]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64113 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
mwrap <https://80x24.org/mwrap/> interposes malloc functions and
checks for GVL existence to determine Ruby source locations of
malloc calls. pthread_getattr_np (from get_stack) may call
realloc to get the CPU set size; so when using the thread-cache,
ruby_thread_has_gvl_p() may hit a false positive on reused
threads with lingering rb_thread_t in thread-specific data.
This was causing mwrap to call rb_source_location_cstr() and
crash because it was pointed to a zero ec->cfp->iseq.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63836 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
|
|
Some systems lack SIGCHLD or have incomplete SIGCHLD
implementations. So enable polling mode for them.
[ruby-core:87705] [Bug #14867]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63795 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
|
|
Use a global SIGCHLD handler to guard all callers of rb_waitpid.
To work safely with multi-threaded programs, we introduce a
VM-wide waitpid_lock to be acquired BEFORE fork/vfork spawns the
process. This is to be combined with the new ruby_waitpid_locked
function used by mjit.c in a non-Ruby thread.
Ruby-level SIGCHLD handlers registered with Signal.trap(:CHLD)
continues to work as before and there should be no regressions
in any existing use cases.
Splitting the wait queues for PID > 0 and groups (PID <= 0)
ensures we favor PID > 0 callers.
The disabling of SIGCHLD in rb_f_system is longer necessary,
as we use deferred signal handling and no longer make ANY
blocking waitpid syscalls in other threads which could "beat"
the waitpid call made by rb_f_system.
We prevent SIGCHLD from firing in normal Ruby Threads and only
enable it in the timer-thread, to prevent spurious wakeups
from in test/-ext-/gvl/test_last_thread.rb with MJIT enabled.
I've tried to guard as much of the code for RUBY_SIGCHLD==0
using C "if" statements rather than CPP "#if" so to reduce
the likelyhood of portability problems as the compiler will
see more code.
We also work to suppress false-positives from
Process.wait(-1, Process::WNOHANG) to quiets warnings from
spec/ruby/core/process/wait2_spec.rb with MJIT enabled.
Lastly, we must implement rb_grantpt for ext/pty. We need a
MJIT-compatible way of supporting grantpt(3) which may spawn
the `pt_chown' binary and call waitpid(2) on it.
[ruby-core:87605] [Ruby trunk Bug#14867]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63758 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
|
|
thread_pthread.c: Drop pthread_attr_setscope usage. It seems that,
at least on Linux and macOS, PTHREAD_SCOPE_PROCESS is not supported
and thus PTHREAD_SCOPE_SYSTEM should be used by default.
Let's just stop calling this until we find some platform that needs
`pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM)`.
[Misc #14854]
From: fd0 (Daisuke Fujimura)
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63730 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
|
|
It is unnecessary to clear unblock.arg once unblock.func is
cleared, and unblock_function_clear in thread.c doesn't
touch it, either.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63724 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
|
|
This fixes bootstraptest/test_fork.rb for systems with
sleepy timer thread disabled.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63709 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
|
|
"gvl.waiting" is volatile, so the compiler won't perform
these optimizations for us.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63683 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
|
|
I guess everybody has poll() and fcntl() nowadays, as
the non-sleepy timer thread build has been broken for
years, now.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63682 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
|
|
Some operating systems will work without calling
pthread_condattr_init, but some won't (such as OpenBSD). Prior
to r63238, pthread_condattr_init was always called before
calling pthread_condattr_setclock.
From: Jeremy Evans <code@jeremyevans.net>
[ruby-core:87345] [Ruby trunk Bug#14807]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63548 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
|
|
I suspect GC may free the rb_thread_t (th) pointer by the time
we call register_cached_thread_and_wait.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63499 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
|
|
Since r62466 ("thread_pthread.c: shorten and fix thread cache implementation"),
our thread cache is no longer buggy with programs using fork.
This makes significant improvements in vm_thread_alive_check1
and vm_thread_create_join benchmarks and does not introduce
regressions.
Unlike old thread cache, I've changed the cache to only last 3
seconds since per-thread setup in most programs rarely takes
more than a few milliseconds to re-establish things like network
connections. This is configurable by changing the THREAD_CACHE_TIME
variable.
I hope this allows users to simplify their code by removing the
need for thread pools in many cases.
vm_thread_alive_check1 10.872 0.150
vm_thread_close 1.988 2.027
vm_thread_condvar1 0.751 0.767
vm_thread_condvar2 0.744 0.752
vm_thread_create_join 5.296 2.343
vm_thread_mutex1 1.911 1.892
vm_thread_mutex2 1.902 1.896
vm_thread_mutex3 2.389 2.313
vm_thread_pass 0.271 0.272
vm_thread_pass_flood 0.175 0.179
vm_thread_pipe 0.460 0.436
vm_thread_queue 0.453 0.446
vm_thread_sized_queue 0.547 0.547
vm_thread_sized_queue2 1.417 1.413
vm_thread_sized_queue3 1.410 1.426
vm_thread_sized_queue4 0.787 0.791
Speedup ratio: compare with the result of `trunk' (greater is better)
name built
vm_thread_alive_check1 72.456
vm_thread_close 0.981
vm_thread_condvar1 0.979
vm_thread_condvar2 0.990
vm_thread_create_join 2.260
vm_thread_mutex1 1.010
vm_thread_mutex2 1.003
vm_thread_mutex3 1.033
vm_thread_pass 0.994
vm_thread_pass_flood 0.980
vm_thread_pipe 1.055
vm_thread_queue 1.016
vm_thread_sized_queue 0.999
vm_thread_sized_queue2 1.003
vm_thread_sized_queue3 0.989
vm_thread_sized_queue4 0.995
[ruby-core:87030] [Feature #14757]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63498 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
|
|
This allows native_sleep to use less stack (80 -> 64 bytes on
x86-64) for GVL_UNLOCK_BEGIN/END. For future APIs, we will pass
`ec` or `th` around anyways, so the BLOCKING_REGION change
should be beneficial in the future.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63448 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
|
|
* thread_pthread.c (Init_native_thread): fallback to the default
CLOCK_REALTIME when failed to set to CLOCK_MONOTONIC, e.g. on
Solaris. [Misc #14497]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63244 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
|
|
There's no reason to use CLOCK_REALTIME for any condvars in Ruby.
Indeed, we initialized all condvars with RB_CONDATTR_CLOCK_MONOTONIC
anyway; so simplify our code and reduce ifdefs.
[ruby-core:85639] [Misc #14497]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63238 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
|
|
Instead of allocating and registering the altstack in different
places, do it together to reduce code and improve readability.
When thread cache is enabled, storing altstack in rb_thread_t
is wasteful and we may reuse altstack in the same pthread.
This also lets us clearly allow use of xmalloc to allow GC to
recover from ENOMEM.
[ruby-core:85621] [Feature #14487]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63213 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
|
|
The previous logic would overwrite the error message, replacing the message with the `fd` number.
This tiny update will print the message in full.
(I'm trying to debug an issue with the timer thread on my machine and the lack of error messages makes it really hard).
[Fix GH-1829]
From: Bo <bo@bowild.com>
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62661 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
|
|
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62485 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
|
|
I noticed this because of https://bugs.ruby-lang.org/issues/14494
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62484 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
|
|
Followup-to: r61719 (commit e8f40bd8f83e1b22ef9c22f0e5d7a1fc0b07f94c)
("thread_pthread: remove HAVE_PTHREAD_ATTR_INIT ifdefs")
[ruby-core:84758] [Misc #14342]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62478 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
|
|
This is required on some platforms to avoid leaks.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62477 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
|
|
No need to hold a lock while destroying a condition variable.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62476 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
|
|
This should be slightly cheaper on NPTL as it does not rely on
atomics to set pd->joinid. We already use pthread_attr_setdetachstate,
so it won't introduce new problems by using a function we did not
use before.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62475 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
|
|
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62468 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
|
|
Update to use ccan/list for constant-time delete on expiry and
avoid malloc. We must also initialize th->thread_id upon thread
reuse so Thread#name= works immediately upon thread creation.
We must also reinitialize the cache mutex and list_head on
fork like we do with GVL and timer thread mutexes.
While we're at it, use monotonic clock for timeout to avoid
system time changes.
"make exam TESTS='-x test_time_tz'" passes with USE_THREAD_CACHE
enabled (but remains off, here).
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62466 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
|
|
Rely on getclockofday for CLOCK_MONOTONIC, avoid needless
variables, and rely on overflow protection from timespec_add
instead of coding our own.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62459 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
|
|
unavailable
This is also for emscripten.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62409 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
|