summaryrefslogtreecommitdiff
path: root/thread_pthread.c
Commit message (Collapse)AuthorAgeFilesLines
* Use language TLS specifier if it is possible.Koichi Sasada2020-10-201-0/+16
| | | | | | | To access TLS, it is faster to use language TLS specifier instead of using pthread_get/setspecific functions. Original proposal is: Use native thread locals. #3665
* Introduce Ractor mechanism for parallel executionKoichi Sasada2020-09-031-109/+117
| | | | | | | | | | | | | | | | This commit introduces Ractor mechanism to run Ruby program in parallel. See doc/ractor.md for more details about Ractor. See ticket [Feature #17100] to see the implementation details and discussions. [Feature #17100] This commit does not complete the implementation. You can find many bugs on using Ractor. Also the specification will be changed so that this feature is experimental. You will see a warning when you make the first Ractor with `Ractor.new`. I hope this feature can help programmers from thread-safety issues.
* Get rid of -Wgnu-folding-constant errorsNobuyoshi Nakada2020-05-011-5/+8
| | | | Also renamed as like as a constant.
* Fixed inverted current thread condition [Bug #16808]Nobuyoshi Nakada2020-04-231-1/+1
|
* Truncate too long thread name before setting [Bug #16808]Nobuyoshi Nakada2020-04-231-6/+30
|
* thread_pthread.c: allocate sigaltstack before pthread_createYusuke Endoh2020-03-061-1/+4
| | | | | | | | | | | | A new (not-initialized-yet) pthread attempts to allocate sigaltstack by using xmalloc. It may cause GC, but because the thread is not initialized yet, ruby_native_thread_p() returns false, which leads to "[FATAL] failed to allocate memory" and exit. In fact, we can observe the error message in the log of OpenBSD CI: https://rubyci.org/logs/rubyci.s3.amazonaws.com/openbsd-current/ruby-master/log/20200306T083005Z.log.html.gz This changeset allocates sigaltstack before pthread is created.
* more on NULL versus functions.卜部昌平2020-02-071-1/+1
| | | | | | Function pointers are not void*. See also ce4ea956d24eab5089a143bba38126f2b11b55b6 8427fca49bd85205f5a8766292dd893f003c0e48
* rb_thread_create now free from ANYARGS卜部昌平2019-08-271-1/+1
| | | | | | After 5e86b005c0f2ef30df2f9906c7e2f3abefe286a2, I now think ANYARGS is dangerous and should be extinct. This commit deletes ANYARGS from rb_thread_create, which seems very safe to do.
* * expand tabs.git2019-06-191-2/+2
|
* Remove IA64 support.Samuel Williams2019-06-191-70/+5
|
* * remove trailing spaces, expand tabs.git2019-06-191-1/+1
|
* Fix handling of vm_stack_size and avoid trying to deallocate it.Samuel Williams2019-06-191-1/+1
|
* * expand tabs.git2019-05-251-17/+17
|
* Fix process not waking up on signals on OpenBSDJeremy Evans2019-05-241-12/+20
| | | | | | | | | | | | | | | | | | | | | When using UBF_TIMER_PTHREAD (the UBF handler on OpenBSD), the timer_pthread_fn function will not signal the main thread with SIGVTALRM in cases where timer_pthread is armed before consume_communication_pipe is called. This is because consume_communication_pipe will unarm the timer. Fix this by checking the return value of consume_communication_pipe. If it returns TRUE and the timer_pthread is disarmed, then signal the main thread with SIGVTALRM. On OpenBSD, this fixes TestThread#test_thread_timer_and_interrupt, and fixes hangs in TestProcess#test_execopts_redirect_open_fifo_interrupt_raise and TestProcess#test_execopts_redirect_open_fifo_interrupt_print. It also fixes the use of Ctrl+C/SIGINT in irb on OpenBSD. It does not cause any test failures on Linux when UBF_TIMER_PTHREAD is forced as the UBF handler. Fixes [Bug #15798]
* introduce rb_nogvl C-API to mark ubf as async-signal-safenormal2019-01-041-0/+5
| | | | | | | | | | | | | | | | | | | | | | | | zlib and bignum both contain unblocking functions which are async-signal-safe and do not require spawning additional threads. We can execute those functions directly in signal handlers without incurring overhead of extra threads, so provide C-API users the ability to deal with that. Other C-API users may have similar need. This flexible API can supercede existing uses of rb_thread_call_without_gvl and rb_thread_call_without_gvl2 by introducing a flags argument to control behavior. Note: this API is NOT finalized. It needs approval from other committers. I prefer shorter name than previous rb_thread_call_without_gvl* functions because my eyes requires big fonts. [Bug #15499] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66712 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* thread.c (call_without_gvl): spawn thread for UBF iff single-threadednormal2019-01-041-0/+19
| | | | | | | | | | | We need another native thread to call some unblocking functions which aren't RUBY_UBF_IO or RUBY_UBF_PROCESS. Instead of a permanent thread in <= 2.5, we can now rely on the thread cache feature to perform interrupts. [ruby-core:90865] [Bug #15499] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66708 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* thread_pthread.c (ubf_timer_disarm): ignore EINVAL iff timer is deadnormal2018-12-201-2/+12
| | | | | | | | | | | | | | | | | | | | | The following race may happen if ubf_timer_destroy calls timer_delete before ubf_timer_disarm gets called from a different thread. Consider the following timelines: ubf_timer_destroy | ubf_timer_disarm -------------------------------------+----------------------------- | CAS(ARM => DISARM) CAS(DISARM => DEAD) | timer_delete | | timer_settime(disarm) Another option may be to add an intermediate "RTIMER_DISARMING" state to the transition, but I figure the EINVAL check is simpler and less intrusive code-wise. cf. http://ci.rvm.jp/results/trunk-iseq_binary@silicon-docker/1545794 git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66457 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* thread_pthread.c (ubf_timer_destroy): more careful state transitionnormal2018-12-181-4/+27
| | | | | | | | | We must not call timer_destroy while another thread is calling timer_settime to arm the timer. cf. http://ci.rvm.jp/results/trunk-iseq_binary@silicon-docker/1541578 git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66446 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* thread_pthread (ubf_timer_destroy): use VM_ASSERTnormal2018-12-161-3/+1
| | | | | | Don't need the overhead at runtime git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66417 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* * expand tabs.svn2018-12-161-3/+3
| | | | git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66414 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* thread_pthread.c: fix memory leak from fork loop leapfrog (v3)normal2018-12-161-27/+62
| | | | | | | | | | | | | | | | | | Constantly forking a single-threaded process in a loop leads to a memory leak when using POSIX timers. This fixes the leak for GNU/Linux systems running glibc. v2: disarm before timer_delete v3: ubf_timer_arm prevents double-arming This unreverts r66291 / commit ab73ef6b7037039a05edcbf2a0c1b1108197e036 Example Linux-only reproduction may be found in: r66290 / commit 043047a8fd5315d98eac38ddbd04ebe8db361817 Note: FreeBSD 11.2 still leaks, I'm not sure why, yet. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66413 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* thread_pthread.c (native_ppoll_sleep): drop ubf_select referencesnormal2018-12-131-2/+1
| | | | | | | | We don't use ubf_select after r65495 / 5de7b3b4f27df747899c243adbb10c9799ad1399 ("thread_pthread.c (native_ppoll_sleep): new eventfd (or pipe) for ubf"), so we don't need to unregister the thread from the ubf list. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66382 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* thread_pthread.c (native_sleep): sched_yield if GVL uncontendednormal2018-12-131-2/+24
| | | | | | | | | | | | | | | Uncontended GVL waitqueue could mean a single CPU setup where threads are starved and can't even insert themselves into our waitqueue. So we force other threads to run upon releasing the GVL in an uncontended state, in the hope that we can avoid entering the slow path of ppoll and similar syscalls. This should prevent test/ruby/test_thread.rb::test_signal_at_join timeout problems on our single CPU FreeBSD CI machine. [ruby-core:90417] [Bug #15398] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66381 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* thread_pthread.c (gvl_release_common): constify return valuenormal2018-12-131-2/+2
| | | | | | No need for it to be mutable git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66379 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* Revert "thread_pthread.c: fix memory leak from fork loop leapfrog (v2)"normal2018-12-081-9/+7
| | | | | | | | | This reverts r66290 / commit 043047a8fd5315d98eac38ddbd04ebe8db361817. Still fails on CI, and I'm not able to reproduce the failure, either :< http://ci.rvm.jp/results/trunk-test@ruby-sky1/1508228 git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66291 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* thread_pthread.c: fix memory leak from fork loop leapfrog (v2)normal2018-12-081-7/+9
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | Constantly forking a single-threaded process in a loop leads to a memory leak when using POSIX timers. v2: disarm before timer_delete ==> fork_leapfrog.rb <== require 'io/wait' Dir.chdir '/proc' prev = 0 loop do pid = fork exit!(0) if pid # show the number of 4K pages used (Linux-only) n = File.read("#$$/statm").split(-' ')[1].to_i if n > prev puts "#{prev} => #{n}" prev = n end # since Ctrl-C from a terminal can't stop this loop, # allow the user to just hit any key to stop break if STDIN.wait(0) end git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66290 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* Revert "thread_pthread.c: fix memory leak from fork loop leapfrog"normal2018-12-081-8/+7
| | | | | | | | Oops, CI failures... This reverts r66288 / commit 2b1dcc1dd1eb260fd20ff1e6e0dfb0e5624a3cc6. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66289 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* thread_pthread.c: fix memory leak from fork loop leapfrognormal2018-12-081-7/+8
| | | | | | | | | | | | | | | | | | | | | | | | | | | Constantly forking a single-threaded process in a loop leads to a memory leak when using POSIX timers. ==> fork_leapfrog.rb <== require 'io/wait' Dir.chdir '/proc' prev = 0 loop do pid = fork exit!(0) if pid # show the number of 4K pages used (Linux-only) n = File.read("#$$/statm").split(-' ')[1].to_i if n > prev puts "#{prev} => #{n}" prev = n end # since Ctrl-C from a terminal can't stop this loop, # allow the user to just hit any key to stop break if STDIN.wait(0) end git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66288 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* thread_pthread.c (rb_reserved_fd_p): false-positive on negative FDnormal2018-11-201-0/+4
| | | | | | | | | Negative-numbered FDs are never valid FDs on POSIX-like platforms, and we initialize our self-pipes/eventfd values to "-1", so stop treating -1 as a reserved FD if our system is too low on resources to allocate FDs at startup. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65832 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* thread_pthread.c (rb_sigwait_sleep): add note about spurious wakeupnormal2018-11-091-0/+3
| | | | | | | I already forgot why we needed to jump through such hoops :x [ruby-core:88102] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65648 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* separate Thread type (func or proc) explicitly.ko12018-11-081-26/+26
| | | | | | | | | | | | | | | | | | | | | | | | | * vm_core.h (rb_thread_struct): introduce new fields `invoke_type` and `invoke_arg`. There are two types threads: invoking proc (normal Ruby thread created by `Thread.new do ... end`) and invoking func, created by C-API. `invoke_type` shows the types. * thread.c (thread_do_start): copy `invoke_arg.proc.args` contents from Array to ALLOCA stack memory if args length is enough small (<8). We don't need to keep Array and don't need to cancel using transient heap. * vm.c (thread_mark): For func invoking threads, they can pass (void *) parameter (rb_thread_t::invoke_arg::func::arg). However, a rubyspec test (thread_spec.c) passes an Array object and it expect to mark it. Clealy it is out of scope (misuse of `rb_thread_create` C-API). However, I'm not sure someone else has such kind of misunderstanding. So now we mark conservatively this (void *) arg with rb_gc_mark_maybe. This misuse is found by this error log. http://ci.rvm.jp/results/trunk-theap-asserts@silicon-docker/1448164 git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65622 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* thread_pthread.c (native_ppoll_sleep): new eventfd (or pipe) for ubfnormal2018-11-011-10/+30
| | | | | | | | | | | | | | | | | | | | Relying on ubf_select + ubf_list for main thread is not guaranteed to wake a process up as it does not acquire sigwait_fd and all other threads may be sleeping. native_cond_sleep and the sigwait_fd path are immune to TOCTOU issues, but native_ppoll_sleep may have its wakeup stolen by sigwait_fd sleeper and the RUBY_VM_INTERRUPTED check is insufficient. Note: for pthreads platforms without POSIX timers, this becomes more expensive than Ruby 2.5, as six pipe FDs come into use. Linux is best off with only two descriptors for eventfd. [ruby-core:89655] cf. http://ci.rvm.jp/results/trunk-mjit@silicon-docker/1437559 http://ci.rvm.jp/results/trunk-mjit-wait@silicon-docker/1437673 git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65495 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* thread_pthread.c (ubf_select): avoid deadlock on contentionnormal2018-10-311-4/+10
| | | | | | | | | | | vm->gvl.lock can be held by another thread, we must not wait on it when called by the MJIT worker thread when it migrates work to another thread. ubf_select is designed to do retrying anyways, so it has no obligation to wake up a timer thread. cf. http://ci.rvm.jp/results/trunk-mjit-wait@silicon-docker/1437880 git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65465 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* * expand tabs.svn2018-10-301-2/+2
| | | | git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65439 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* use RARRAY_AREF() instead of RARRAY_CONST_PTR().ko12018-10-301-3/+2
| | | | git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65438 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* add disabling MJIT features option.ko12018-10-201-0/+2
| | | | | | | | | | | | | | | | | | | | * configure.ac: introduce new configure option `--enable-mjit` and `--disable-mjit`. Default is "enable". `--disable-mjit` disables all of MJIT features so that `ruby --jit` can't enable MJIT. This option affect a macro `USE_MJIT`. This change remove `--enable/disable-install-mjit-header` option. * Makefile.in: introduce the `ENABLE_MJIT` variable. * common.mk: use `ENABLE_MJIT` option. * internal.h: respect `USE_MJIT`. Same as other *.c, *.h. * test/ruby/test_jit.rb: check `ENABLE_MJIT` key of rbconfg.rb. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65204 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* rb_sigwait_sleep: change internal API to use rb_hrtime_tnormal2018-10-191-12/+11
| | | | | | | rb_hrtime_t is a more pleasant type to use and this can make future changes around sleeping/scheduling easier. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65182 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* define ubf_list_atfork() as empty on cygwinduerst2018-09-051-0/+1
| | | | git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64635 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* thread_pthread.h: rename `gvl.acquired' to `gvl.owner' and documentnormal2018-08-281-7/+7
| | | | | | | | | `acquired' was an old boolean variable, but nowadays it is a rb_thread_t pointer; "gvl.owner" seems like a more appropriate name. And document the contended path including waitq, timer, and timer_err. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64581 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* thread_pthread.c: document sigwait_th and sigwait_fd [ci skip]normal2018-08-271-1/+8
| | | | | | This is an important concept to document, I think. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64580 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* thread_pthread.c: fix deadlock on test_thread.rb::test_signal_at_joinnormal2018-08-271-2/+6
| | | | | | 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
* process.c: simplify SIGCHLD-based waitpidnormal2018-08-271-20/+0
| | | | | | | | | | | | | | 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
* thread_pthread.c: avoid lock ping-pong in do_gvl_timer & ubf_selectnormal2018-08-271-12/+10
| | | | | | | | | | | | | 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
* thread_pthread.c (ubf_wakeup_thread): `th' is never NULLnormal2018-08-251-2/+1
| | | | git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64539 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* thread_pthread.c: main thread always gets hit by signalsnormal2018-08-251-1/+41
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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
* thread.c: use rb_hrtime_t scalar for high-resolution time operationsnormal2018-08-251-56/+54
| | | | | | | | | | | | | | | | | | | | | 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
* thread_pthread.c: use eventfd instead of pipe on Linuxnormal2018-08-241-8/+42
| | | | | | | | | | | 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
* thread_pthread.c (ubf_timer_destroy): remove redundant getpid checknormal2018-08-231-10/+7
| | | | | | | 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
* thread_pthread.c: reinitialize ubf_list at forknormal2018-08-201-7/+8
| | | | | | | | | | | | | 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
* thread_pthread.c: reset timeslice delay when uncontendednormal2018-08-191-3/+6
| | | | | | | | | | | | | | | | 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