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

69 Коммитов

Автор SHA1 Сообщение Дата
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