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

135 Коммитов

Автор SHA1 Сообщение Дата
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
tenderlove 3b60f4a590 [Doc] Recover example about Queue
`trunk@42862` dropped example's last line.

e334bb2ce5 (diff-8783a9b452e430bcf0d7b0c6e34f1db0L144)
e334bb2ce5 (diff-38e7b9d781319cfbc49445f8f6625b8aR195)

This brings no output.

```queue_example1.rb
queue = Queue.new

producer = Thread.new do
  5.times do |i|
    sleep rand(i) # simulate expense
    queue << i
    puts "#{i} produced"
  end
end

consumer = Thread.new do
  5.times do |i|
    value = queue.pop
    sleep rand(i/2) # simulate expense
    puts "consumed #{value}"
  end
end
```

```queue_example2.rb
queue = Queue.new

producer = Thread.new do
  5.times do |i|
    sleep rand(i) # simulate expense
    queue << i
    puts "#{i} produced"
  end
end

consumer = Thread.new do
  5.times do |i|
    value = queue.pop
    sleep rand(i/2) # simulate expense
    puts "consumed #{value}"
  end
end

consumer.join
```

$ ruby queue_example1.rb
$

$ ruby queue_example2.rb
0 produced
1 produced
consumed 0
consumed 1
2 produced
consumed 2
3 produced
consumed 3
4 produced
consumed 4
$

Co-Authored-By: Sanemat <o.gata.ken@gmail.com>

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64058 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-07-25 18:09:02 +00:00
nobu 97e05dad7f UNREACHABLE_RETURN
* include/ruby/ruby.h (UNREACHABLE_RETURN): UNREACHABLE at the end
  of non-void functions.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64025 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-07-24 05:38:07 +00:00
normal 501069b8a4 thread_sync.c (rb_mutex_lock): fix deadlock
* thread_sync.c (rb_mutex_lock): fix deadlock
  [ruby-core:87467] [Bug #14841]

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63711 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-06-22 02:32:30 +00:00
normal d2f52a5fb7 thread_sync.c (condvar_ptr): reset fork_gen after forking
Otherwise the condition variable waiter list will always
be empty, which is wrong :x

[Bug #14725] [Bug #14634]

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63309 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-04-30 23:47:21 +00:00
normal b6e2851431 thread_sync.c: remove "volatile" qualifiers
I may store ->ec in rb_mutex_t instead of ->th to support green
thread.  For now, "volatile" is useless for thread-safety
anyways and we're not dealing with *jmp or signals with mutex.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63282 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-04-28 06:23:43 +00:00
normal 0d77b73db7 thread_sync.c: remove unused list_heads
I forgot to clean these up in r63215

* thread_sync.c (szqueue_list, queue_list, condvar_list): remove

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63281 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-04-28 06:00:39 +00:00
normal af72dcd91b thread_sync: redo r62934 to use fork_gen
Instead of maintaining linked-lists to store all
rb_queue/rb_szqueue/rb_condvar structs; store only a fork_gen
serial number to simplify management of these items.

This reduces initialization costs and avoids the up-front cost
of resetting all Queue/SizedQueue/ConditionVariable objects at
fork while saving 8 bytes per-structure on 64-bit.  There are no
savings on 32-bit.

* thread.c (rb_thread_atfork_internal): remove rb_thread_sync_reset_all call
* thread_sync.c (rb_thread_sync_reset_all): remove
* thread_sync.c (queue_live): remove
* thread_sync.c (queue_free): remove
* thread_sync.c (struct rb_queue): s/live/fork_gen/
* thread_sync.c (queue_data_type): use default free
* thread_sync.c (queue_alloc): remove list_add
* thread_sync.c (queue_fork_check): new function
* thread_sync.c (queue_ptr): call queue_fork_check
* thread_sync.c (szqueue_free): remove
* thread_sync.c (szqueue_data_type): use default free
* thread_sync.c (szqueue_alloc): remove list_add
* thread_sync.c (szqueue_ptr):  check fork_gen via queue_fork_check
* thread_sync.c (struct rb_condvar): s/live/fork_gen/
* thread_sync.c (condvar_free): remove
* thread_sync.c (cv_data_type): use default free
* thread_sync.c (condvar_ptr): check fork_gen
* thread_sync.c (condvar_alloc): remove list_add
  [ruby-core:86316] [Bug #14634]

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63215 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-04-20 22:53:37 +00:00
stomar 5bae48bd56 thread_sync.c: [DOC] fix typo
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63161 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-04-14 16:51:34 +00:00
shyouhei 85e9f28793 offsetof(type, foo.bar) is (arguably) a GCCism
clang -Wextended-offsetof warns this line.
CF: http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2031.htm


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63124 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-04-09 03:24:21 +00:00
normal a2d63ea2fb thread_sync.c: avoid reaching across stacks of dead threads
rb_ensure is insufficient cleanup for fork and we must
reinitialize all waitqueues in the child process.

Unfortunately this increases the footprint of ConditionVariable,
Queue and SizedQueue by 8 bytes on 32-bit (16 bytes on 64-bit).

[ruby-core:86316] [Bug #14634]

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62934 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-03-27 09:28:37 +00:00
normal 1b455428d3 thread.c: reset waitq of keeping mutexes in child
We must not maintain references to threads in the parent process
in any mutexes held by the child process.

* thread_sync.c (rb_mutex_cleanup_keeping_mutexes): new function
* thread.c (rb_thread_atfork): cleanup keeping mutexes
  [ruby-core:85940] [Bug #14578]

Fixes: r58604 (commit 3586c9e087)
       ("reduce rb_mutex_t size from 160 to 80 bytes on 64-bit")

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62668 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-03-05 22:58:13 +00:00
nobu 96db72ce38 [DOC] missing docs at toplevel
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62544 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-02-23 02:18:52 +00:00
nobu c8094ff154 no ID cache in Init functions
Init functions are called only once, cache is useless.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62429 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-02-16 08:39:48 +00:00
normal 0abd9b7f25 thread.c: favor timespec internally
This results in fewer conversion on common modern systems with
support for clock_gettime, pthread_cond_timedwait and ppoll.
gettimeofday is declared obsolete by POSIX.1-2008, so it is yet
another reason to move away from it.  This also appears to result
in the reduction of compatibility code required for dealing
with inconsistent implementations of "struct timeval".tv_sec

In the future, this will also result in fewer conversions for
kqueue and pselect if we elect to use them.

[ruby-core:85416] [Feature #14452]

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62272 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-02-07 01:57:14 +00:00
shyouhei 0c932244fe raise_closed_queue_error marked as NORETURN
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@61926 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-01-18 09:44:47 +00:00
nobu 602fda25ab thread_sync.c: fix rdoc
* thread_sync.c (define_thread_class): hide rb_define_class_under
  from rdoc, so that fake code to teach rdoc takes effect.

* thread_sync.c (Init_thread_sync): teach rdoc Mutex.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@61337 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2017-12-19 10:46:51 +00:00
ko1 5dfdaa9299 move rb_thread_t::interrupt_flag and mask
to rb_execution_context_t.

* vm_core.h (rb_thread_t): move
  `rb_thread_t::interrupt_flag` and
  `rb_thread_t::interrupt_mask` to rb_execution_context_t.

  RUBY_VM_CHECK_INTS() accepts `ec` instead of `th`.

* cont.c (rb_fiber_terminate): to propagate interrupt information,
  add new parameter `need_interrupt`.


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@60672 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2017-11-06 07:44:28 +00:00
kazu 6064132c42 Remove unnecessary `require 'thread'`
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@60139 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2017-10-08 07:00:01 +00:00
nobu 2b582b7ca6 UNALIGNED_MEMBER_ACCESS
* eval_intern.h (UNALIGNED_MEMBER_ACCESS): suppress
  address-of-packed-member warnings by clang 4.0.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@59450 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2017-07-30 14:48:45 +00:00
normal b11350d609 thread_sync.c: fix documentation for Queue#close
When Queue#closed? is true, using push/enq/<< will raise an
exception, and not return nil.

* thread_sync.c: fix documentation for Queue#close
  Thanks to John Anderson.  [ruby-core:81749] [Misc #13673]

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@59165 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2017-06-23 20:59:00 +00:00
normal ea1ce47fd7 thread_sync.c: rewrite the rest using using ccan/list
The performance improvement increases as the number of waiters
increases, due to avoiding the O(n) behavior of rb_ary_delete on
the waiting thread.  Uncontended queues and condition variables
performance is not altered significantly.

Function entry cost is slightly increased for ConditionVariable,
since the data pointer is separately allocated and not embedded
into the RVALUE slot.

[ruby-core:81235] [Feature #13552]

name                  |trunk  |built
----------------------|------:|------:
vm_thread_condvar1    |  0.858|  0.858
vm_thread_condvar2    |  1.003|  0.804
vm_thread_queue       |  0.131|  0.129
vm_thread_sized_queue |  0.265|  0.251
vm_thread_sized_queue2|  0.892|  0.859
vm_thread_sized_queue3|  0.879|  0.845
vm_thread_sized_queue4|  0.599|  0.486

Speedup ratio: compare with the result of `trunk' (greater is better)

name                  |built
----------------------|------:
vm_thread_condvar1    |  0.999
vm_thread_condvar2    |  1.246
vm_thread_queue       |  1.020
vm_thread_sized_queue |  1.057
vm_thread_sized_queue2|  1.039
vm_thread_sized_queue3|  1.041
vm_thread_sized_queue4|  1.233

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@58805 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2017-05-19 18:53:11 +00:00
normal 44e48eca5f thread_sync.c: rename mutex_waiter struct to sync_waiter
We will reuse this struct for ConditionVariable, Queue, and SizedQueue,
so it is no longer Mutex-specific.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@58804 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2017-05-19 18:34:38 +00:00
nobu e3d4de3512 suppress a warning [ci skip]
* thread_sync.c (rb_mutex_num_waiting): suppress warning C4700 by
  VC, uninitialized local variable.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@58715 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2017-05-14 13:01:46 +00:00
nobu 6924066a65 adjust styles [ci skip]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@58646 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2017-05-10 00:39:26 +00:00
normal 774420eba0 reduce rb_mutex_t size from 80 bytes to 72 bytes on 64-bit
We can use existing RVALUE flags to avoid adding a 4-byte
integer to store a boolean flag.  This integer cost us 8 bytes
due to default (lack of) struct packing on x86-64

* thread_sync.c (MUTEX_ALLOW_TRAP): define as FL_USER1
  (struct rb_mutex_struct): remove allow_trap
  (rb_mutex_lock): adjust for flag check
  (rb_mutex_allow_trap): adjust for flag set/unset

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@58608 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2017-05-08 01:59:17 +00:00
normal 3586c9e087 reduce rb_mutex_t size from 160 to 80 bytes on 64-bit
Instead of relying on a native condition variable and mutex for
every Ruby Mutex object, use a doubly linked-list to implement a
waiter queue in the Mutex.  The immediate benefit of this is
reducing the size of every Mutex object, as some projects have
many objects requiring synchronization.

In the future, this technique using a linked-list and on-stack
list node (struct mutex_waiter) should allow us to easily
transition to M:N threading model, as we can avoid the native
thread dependency to implement Mutex.

We already do something similar for autoload in variable.c,
and this was inspired by the Linux kernel wait queue (as
ccan/list is inspired by the Linux kernel linked-list).

Finaly, there are big performance improvements for Mutex
benchmarks, especially in contended cases:

measure target: real

name            |trunk  |built
----------------|------:|------:
loop_whileloop2 |  0.149|  0.148
vm2_mutex*      |  0.893|  0.651
vm_thread_mutex1|  0.809|  0.624
vm_thread_mutex2|  2.608|  0.628
vm_thread_mutex3| 28.227|  0.881

Speedup ratio: compare with the result of `trunk' (greater is better)

name            |built
----------------|------:
loop_whileloop2 |  1.002
vm2_mutex*      |  1.372
vm_thread_mutex1|  1.297
vm_thread_mutex2|  4.149
vm_thread_mutex3| 32.044

Tested on AMD FX-8320 8-core at 3.5GHz

* thread_sync.c (struct mutex_waiter): new on-stack struct
  (struct rb_mutex_struct): remove native lock/cond, use ccan/list
  (rb_mutex_num_waiting): new function for debug_deadlock_check
  (mutex_free): remove native_*_destroy
  (mutex_alloc): initialize waitq, remove native_*_initialize
  (rb_mutex_trylock): remove native_mutex_{lock,unlock}
  (lock_func): remove
  (lock_interrupt): remove
  (rb_mutex_lock): rewrite waiting path to use native_sleep + ccan/list
  (rb_mutex_unlock_th): rewrite to wake up from native_sleep
  using rb_threadptr_interrupt
  (rb_mutex_abandon_all): empty waitq
* thread.c (debug_deadlock_check): update for new struct
  (rb_check_deadlock): ditto
  [ruby-core:80913] [Feature #13517]

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@58604 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2017-05-08 00:18:53 +00:00
normal c4378e0fb8 thread_sync.c: document SizedQueue#clear correctly [ci skip]
* thread_sync.c (rb_szqueue_clear): fix class name in RDoc

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@58511 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2017-04-30 09:06:39 +00:00
normal 6e5e1b3728 thread_sync.c (rb_mutex_lock): spelling fix [ci skip]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@58485 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2017-04-25 20:20:08 +00:00
normal cad4591086 remove branches in dmark and dfree GC callbacks
dmark and dfree callbacks are never called in gc.c for NULL
DATA_PTR values, not even for zombie objects.

* compile.c (ibf_loader_mark): remove branch for pointer validity
* compile.c (ibf_loader_free): ditto
* cont.c (cont_free): ditto
* cont.c (fiber_free): ditto
* dir.c (dir_free): ditto
* ext/stringio/stringio.c (strio_mark): ditto
* proc.c (binding_free): ditto
* thread_sync.c (mutex_free): ditto
* vm.c (thread_free): ditto

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@58006 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2017-03-17 19:59:56 +00:00
ko1 bfdfc99cc2 allow Queue operation in trap.
* thread_sync.c: allow spurious wakeup to check Queue status just after trap.
  [Bug #12405]

* test/thread/test_queue.rb: add a test for it.


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@57479 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2017-01-31 07:00:38 +00:00
ko1 6897b3b985 define rb_thread_sleep_deadly_allow_spurious_wakeup().
* thread.c, thread_sync.c: define new function
  rb_thread_sleep_deadly_allow_spurious_wakeup() and use it instead of
  using sleep_forever() directly.


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@57478 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2017-01-31 06:39:01 +00:00
ko1 919a9d9e02 use TRUE/FALSE.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@57477 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2017-01-31 06:31:06 +00:00
nobu 325587ee7f thread_sync.c: Document exception types
* thread_sync.c (rb_queue_pop, rb_szqueue_push, rb_szqueue_pop):
  Document exception types, ThreadError, raised by Queue and
  SizedQueue.  [Fix GH-1451]

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@56287 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2016-09-29 10:34:25 +00:00
nobu 084487a372 thread_sync.c: Remove confusing comments
* thread_sync.c (Init_thread_sync): Remove confusing doc comments,
  which are picked up by rdoc unexpectedly, from Queue and
  SizedQueue.  [Fix GH-1450]

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@56285 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2016-09-29 10:21:04 +00:00
nobu 56695b35de thread_sync.c: alias_global_const
* thread_sync.c (alias_global_const): extract from a macro.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@56023 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2016-08-28 08:53:22 +00:00
nobu c463366dfd rb_funcallv
* *.c: rename rb_funcall2 to rb_funcallv, except for extensions
  which are/will be/may be gems.  [Fix GH-1406]

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@55773 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2016-07-29 11:57:14 +00:00
nobu a46df859cc thread.c: clear atfork functions
* thread.c (rb_thread_atfork, rb_thread_atfork_before_exec): do
  nothing unless working fork is available.
* thread_sync.c (rb_mutex_abandon_all): define only if working
  fork is available.
* thread_sync.c (rb_mutex_abandon_keeping_mutexes): ditto.
* thread_sync.c (rb_mutex_abandon_locking_mutex): ditto.
* thread_win32.c (gvl_init): never used.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@54960 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2016-05-09 01:46:37 +00:00
nobu 13d62659ce thread_sync.c: define global constants always
* thread_sync.c (ALIAS_GLOBAL_CONST): define global constant
  aliases unconditionally.  same constants are not defined at this
  time.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@54826 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2016-04-30 02:55:18 +00:00
nobu fe9817618d thread_sync.c: Update rdoc for Queue [skip ci]
* thread_sync.c: [DOC] Update documentation for Queue class
  description.  [Fix GH-1292]

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@54146 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2016-03-17 08:20:29 +00:00
sho-h 571fb5b687 thread_sync.c: [DOC] remove SizedQueue#close argument. [ci skip]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@53428 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2016-01-04 06:38:26 +00:00
normal 004bb16ccc thread_sync.c: remove unnecessary casts for queue_sleep
"Qfalse" and "(VALUE)0" are equivalent, and do not matter
for an ignored argument, either.

Additionally, there's no reason to cast the pointer to
rb_thread_sleep_deadly when we already have a queue_sleep
wrapper.

* thread_sync.c (queue_do_pop): avoid cast with Qfalse
  (rb_szqueue_push): ditto, use queue_sleep wrapper

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@53413 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2016-01-02 12:08:34 +00:00
normal 5ad289b133 thread_sync.c: static classes
We do not want to waste space by exposing globals to other
objects.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@53364 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2015-12-28 21:52:15 +00:00
ko1 2f5b8f0529 * *.c (*_memsize): do not check ptr.
NULL checking is finished Before call of memsize functions.
  See r52979.




git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@52986 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2015-12-09 00:38:32 +00:00
ko1 e2609033ab * thread_sync.c: reduce the specification of Queue#close.
* Queue#close accepts no arguments.
  * deq'ing on closed queue returns nil, always.
  [Feature #10600]

* test/thread/test_queue.rb: catch up this fix.




git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@52691 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2015-11-21 00:32:09 +00:00
nobu aabd765f0b thread_sync.c: fix typos
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@51750 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2015-09-03 15:17:25 +00:00
ko1 c37c67cef8 * thread_sync.c (queue_do_close): ignore multiple close to allow
multiple producers.
  https://bugs.ruby-lang.org/issues/10600#note-14



git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@51732 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2015-09-01 09:17:28 +00:00
ko1 dcf6ac4975 * thread_tools.c: rename thread_tools.c to thread_sync.c.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@51730 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2015-09-01 09:08:42 +00:00