Граф коммитов

97 Коммитов

Автор SHA1 Сообщение Дата
Samuel Williams 3b5b309b7b Proposed method for dealing with stack locals which have non-local lifetime. 2020-12-05 11:38:56 +13:00
Nobuyoshi Nakada 0d52dce3a3
strip trailing spaces and adjusted indents [ci skip] 2020-11-12 19:27:20 +09:00
Samuel Williams c39984ec5c Tidy up book keeping for `thread->keeping_mutexes`.
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.
2020-11-08 20:40:52 +13:00
Samuel Williams f73135233b Don't try to resume blocked fiber on dead thread. 2020-11-08 20:40:52 +13:00
Samuel Williams a08ee8330d Rename to `Fiber#set_scheduler`. 2020-11-07 23:39:50 +13:00
Samuel Williams 70f08f1eed Make `Thread#join` non-blocking. 2020-09-21 11:48:44 +12:00
Benoit Daloze 6987c8997e Remove from waiter in Mutex#lock with ensure when calling rb_scheduler_block()
* Previously this could lead to an invalid waiter entry and then trying
  to wake up that waiter would result in various issues in rb_mutex_unlock_th().
2020-09-20 13:35:39 +02:00
Benoit Daloze af1926e859 Fix copy/paste error from 5bb5e706f1 2020-09-18 11:11:47 +02:00
Benoit Daloze 5bb5e706f1 Only interrupt when there is no scheduler in sync_wakeup()
* 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
2020-09-18 10:39:27 +02:00
Benoit Daloze d9b943b8e5 Cleanup commented code
* Mutex operations no longer disable the Fiber scheduler.
2020-09-17 17:29:43 +02:00
Benoit Daloze d01954632d Add missing goto found;
* To still remove the lock from the Thread's list of acquired locks.
* Also to not wake up other waiters and preserve blocking behavior.
2020-09-17 17:26:52 +02:00
Benoit Daloze 264889ec3d Fix Mutex#unlock with a scheduler and thread contention
* It would hit "[BUG] unexpected THREAD_STOPPED" before.
2020-09-17 15:15:43 +02:00
Benoit Daloze 9472d16061 Call scheduler.block instead of scheduler.kernel_sleep for blocking Queue/SizedQueue operations
* 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.
2020-09-17 14:59:38 +02:00
Benoit Daloze 738a089b3a Rename scheduler.{mutex_lock,mutex_unlock} to {block,unblock}
* Move #kernel_sleep next to #block as it is similar
2020-09-17 14:30:40 +02:00
Samuel Williams 8eea66a0ca Add support for Queue & SizedQueue. 2020-09-14 16:44:09 +12:00
Samuel Williams 0f613cc5f1 Add support for ConditionVariable. 2020-09-14 16:44:09 +12:00
Samuel Williams 1a0cfe2839 Improve handling of urgent notification pipe. 2020-09-14 16:44:09 +12:00
Benoit Daloze 178c1b0922 Make Mutex per-Fiber instead of per-Thread
* 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]
2020-09-14 16:44:09 +12:00
Koichi Sasada 79df14c04b Introduce Ractor mechanism for parallel execution
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.
2020-09-03 21:11:06 +09:00
卜部昌平 f402dc3557 rb_szqueue_push: do not goto into a branch
I'm not necessarily against every goto in general, but jumping into a
branch is definitely a bad idea.  Better refactor.
2020-06-29 11:05:41 +09:00
Samuel Williams 0e3b0fcdba
Thread scheduler for light weight concurrency. 2020-05-14 22:10:55 +12:00
Nobuyoshi Nakada 5d430c1b34
Added more NORETURN declarations 2020-05-11 00:40:14 +09:00
卜部昌平 115fec062c more on NULL versus functions.
Function pointers are not void*.  See also
ce4ea956d2
8427fca49b
2020-02-07 14:24:19 +09:00
Koichi Sasada d8d581bfc4 add assertion for mutex_lock.
After do_mutex_lock(mutex), the mutex should be owned by the current
thread. Adding an assertion for this assumption.
2019-10-28 12:19:18 +09:00
Nobuyoshi Nakada 0c6f36668a
Adjusted spaces [ci skip] 2019-09-27 10:20:56 +09:00
卜部昌平 69683968a9 fix arity of rb_mutex_synchronize_m
This is just a trivial mistake introduced in
6c56dae4b2.
2019-08-29 18:34:09 +09:00
卜部昌平 703783324c rb_ensure now free from ANYARGS
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.
2019-08-27 15:52:26 +09:00
Neeraj Bhunwal c1d78a7f0e do_mutex_lock: release mutex before checking for interrupts (fixes issue 15360) 2019-06-11 15:44:11 -07:00
Nobuyoshi Nakada b1aecef873
Use UNALIGNED_MEMBER_PTR
* 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`.
2019-05-31 16:04:16 +09:00
normal 0fd53f519f thread_sync.c (rb_mutex_t): eliminate fork_gen
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
2018-12-22 01:41:18 +00:00
normal fa5601e7b9 thread_sync.c (rb_mutex_cleanup_keeping_mutexes): update fork_gen
... 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
2018-12-21 12:32:52 +00:00
normal 2a742d5f9b thread_sync.c (rb_mutex_abandon_keeping_mutexes): remove unnecessary check
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
2018-12-21 12:32:48 +00:00
normal 1df9c2bc1c thread_sync.c (mutex_ptr): only reinitalize waitqueue at fork
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
2018-12-18 09:21:05 +00:00
nobu 98e65d9d92 Prefer rb_check_arity when 0 or 1 arguments
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
2018-12-06 07:49:24 +00:00
normal 818f1c65ab thread_sync.c (mutex_ptr): handle mutexes held by parent threads in children
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
2018-12-05 18:58:45 +00:00
marcandre 18fe495902 Add some missing documentation to Queue#{close|deq} [ci skip]
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
2018-09-16 02:45:16 +00:00
normal 70d6c1a102 thread_sync.c: common wakeup_{one,all} implementation
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
2018-08-26 12:41:16 +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 79bdb6f9c8 thread*.c: replace GetMutexPtr with mutex_ptr
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
2018-08-21 01:01:42 +00:00
normal 39c64117f6 thread*.c: avoid unnecessary initialization for list_for_each_safe
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
2018-08-20 21:34:44 +00:00
normal 25d274b35a thread_sync.c (rb_condvar_initialize): remove extra semicolon
Oops :x

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64477 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-08-19 23:36:23 +00:00
normal d9cb901779 thread_sync.c (rb_mutex_sleep): disable interrupt checking in ensure
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
2018-08-19 22:20:22 +00:00
normal 883422b191 thread_sync.rb (rb_condvar_wait): golf out unnecessary variables
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
2018-08-19 20:16:15 +00:00
normal 77038f9f82 Revert "thread_sync.c (rb_mutex_sleep): skip interrupt check before sleep"
This reverts commit 2e420b8b99 (r64464)

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64466 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-08-19 00:01:03 +00:00
normal 2e420b8b99 thread_sync.c (rb_mutex_sleep): skip interrupt check before sleep
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
2018-08-18 20:04:07 +00:00
eregon c742050ea5 Revert r64441
* 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
2018-08-18 13:52:53 +00:00
normal 647fc1227a thread_sync.c (rb_mutex_synchronize): only unlock if we own the mutex
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
2018-08-18 06:33:49 +00:00
normal 6e0d69e4a7 Revert "thread_sync.c (do_sleep): avoid thread-switch/interrupt check"
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
2018-08-18 06:05:17 +00:00
normal d7ddbff295 thread_sync.c (do_sleep): avoid thread-switch/interrupt check
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
2018-08-18 04:24:31 +00:00
normal 2cf3bd5bb2 thread_sync.c (rb_mutex_lock): acquire lock before being killed
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
2018-08-16 19:59:21 +00:00