When a scheduler is present, it's entirely possible for
`th->keeping_mutexes` to be updated while enumerating the waitq. Therefore
it must be fetched only during the removal operation.
* When there is a scheduler, the Fiber that would be blocked has already
been rescheduled and there is no point to interrupt something else.
That blocked Fiber will be rescheduled as the next call to the scheduler
(e.g., IO, sleep, other blocking sync).
* See discussion on https://github.com/ruby/ruby/commit/d01954632d
* scheduler.unblock was already already called before but with no corresponding scheduler.block
* add test that Queue#pop makes the scheduler wait until it gets an element.
* Enables Mutex to be used as synchronization between multiple Fibers
of the same Thread.
* With a Fiber scheduler we can yield to another Fiber on contended
Mutex#lock instead of blocking the entire thread.
* This also makes the behavior of Mutex consistent across CRuby, JRuby and TruffleRuby.
* [Feature #16792]
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.
After 5e86b005c0, I now think ANYARGS is
dangerous and should be extinct. This commit deletes ANYARGS from
rb_ensure, which also revealed many arity / type mismatches.
* internal.h (UNALIGNED_MEMBER_ACCESS, UNALIGNED_MEMBER_PTR):
moved from eval_intern.h.
* compile.c iseq.c, vm.c: use UNALIGNED_MEMBER_PTR for `entries`
in `struct iseq_catch_table`.
* vm_eval.c, vm_insnhelper.c: use UNALIGNED_MEMBER_PTR for `body`
in `rb_method_definition_t`.
The true bug fork_gen was hiding was rb_mutex_abandon_locking_mutex
failing to unconditionally clear the waitq of mutexes it was
waiting on. So we fix rb_mutex_abandon_locking_mutex, instead,
and eliminate rb_mutex_cleanup_keeping_mutexes.
This commit was tested heavily on a single-core Pentium-M which
was my most reliable reproducer of the "crash.rb" script from
[Bug #15383]
[Bug #14578] [Bug #15383]
Note: [Bug #15430] turned out to be an entirely different
problem: RLIMIT_NPROC limit was hit on the CI VMs.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66489 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
... when clearing waitq. Otherwise, we risk redundantly clearing
valid waiters in future calls to `mutex_ptr`.
Note: I am not sure if this fixes [Bug #15430], and even if it
did, fork_gen is a belt-and-suspenders redundancy for [Bug #15383]
which wastes one word for every Mutex object.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66477 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
rb_mutex_abandon_all functions fine when passed a NULL value,
so let the compiler deal with the complexity of the branch
instead of the person reading the code.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66476 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Mutexes need to remain locked after forking.
This fixes "[BUG] invalid keeping_mutexes: Attempt to unlock a
mutex which is locked by another thread" and should
fix test_fork_while_parent_locked failures in CI
[ruby-core:90581] [Bug #15424]
[ruby-core:90595] [Bug #15430]
Fixes: r66230 ("handle mutexes held by parent threads in children")
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66438 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Especially over checking argc then calling rb_scan_args just to
raise an ArgumentError.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66238 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Mutexes may be held by threads which only exist in the parent
process, so their waitqueues may be populated with references
to other dead threads. We must reset them at fork.
I am a moron for introducing this bug :<
[ruby-core:90312] [Bug #15383]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66230 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Patch by Lars Kanis. [Fix GH-1949]
* Describe the impact of Queue#close to Queue#deq .
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64756 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This let us avoid looping in rb_szqueue_max_set, saves us
some lines of code and reduces binary size slightly
(numbers from 32-bit x86):
text data bss dec hex filename
before: 91272 392 156 91820 166ac thread.o
after: 91200 392 156 91748 16664 thread.o
Inspiration from this taken from the FUTEX_WAKE op
of the Linux futex(2) syscall.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64542 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
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
Following ko1's lead in r59192, this gets rid of non-obvious
assignments which happen inside macros.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64490 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
According to r52446, it is only necessary for the current item (@i),
not the `@nxt` parameter for list_for_each_safe.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64486 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This is needed to reliably fix ConditionVariable#wait on Thread#kill
[Bug #14999] because there is still a chance an interrupt could fire
and prevent lock acquisition after an ensure statement.
Arguably, rb_mutex_lock itself should be uninterruptible, but that
already prevents bootstraptest/test_thread.rb from completing and
probably breaks existing use cases.
For reference, POSIX expressly forbids EINTR from pthread_mutex_lock.
[ruby-core:88556] [Bug #14999]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64476 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
GCC is smart enough to optimize these away, but my attention
span is too short :{
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64474 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
We do not want to risk switching threads before going to sleep
because it can cause unexpected wakeups and put us in an
unexpected state when used with ConditionVariable.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64464 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* This reverts commit 647fc1227a4146ecbfeb0d59358abc8d99cd8ae6:
"thread_sync.c (rb_mutex_synchronize): only unlock if we own the mutex"
* Let's try to preserve the semantics of always being locked inside
Mutex#synchronize, even if an exception interrupts ConditionVariable#wait.
* As discussed on [Bug #14999].
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64448 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
If an exception is raised inside Mutex#sleep (via ConditionVariable#wait),
we cannot guarantee we can own the mutex in the ensure callback.
However, who owns the mutex at that point does not matter. What
matters is the Mutex is usable after an exception occurs.
* thread_sync.c (rb_mutex_synchronize): only unlock if we own the mutex
* spec/ruby/library/conditionvariable/wait_spec.rb: only test lock
usability after thread kill. Who owns the lock at any
particular moment is an implementation detail which we cannot
easily guarantee.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64441 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This reverts commit d7ddbff295 (r64436)
Seems worthless at preventing CI failures
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64440 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Calling rb_mutex_sleep directly should avoid
thread-switching/interrupt checking which can lead to occasional
failures.
Unfortunately, this means overriding Mutex#sleep is no longer
supported. Will let this commit run for a bit see if CI failures
from ConditionVariable specs continue...
cf. https://rubyci.org/logs/rubyci.s3.amazonaws.com/ubuntu/ruby-trunk/log/20180817T213003Z.fail.html.gz
[ruby-core:88524] [Bug #14999]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64436 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
We (the thread acquiring the mutex) need to acquire the mutex
before being killed to work with ConditionVariable#wait.
Thus we reinstate the acquire-immediately-after-sleeping logic
from pre-r63711 while still retaining the
acquire-after-checking-for-interrupts logic from r63711.
This regression was introduced in
commit 501069b8a4 (r63711)
("thread_sync.c (rb_mutex_lock): fix deadlock") for
[Bug #14841]
[ruby-core:88503] [Bug #14999] [Bug #14841]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64398 b2dd03c8-39d4-4d8f-98ff-823fe69b080e