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

97 Коммитов

Автор SHA1 Сообщение Дата
Koichi Sasada 1c4fc0241d rename thread internal naming
Now GVL is not process *Global* so this patch try to use
another words.

* `rb_global_vm_lock_t` -> `struct rb_thread_sched`
  * `gvl->owner` -> `sched->running`
  * `gvl->waitq` -> `sched->readyq`
* `rb_gvl_init` -> `rb_thread_sched_init`
* `gvl_destroy` -> `rb_thread_sched_destroy`
* `gvl_acquire` -> `thread_sched_to_running` # waiting -> ready -> running
* `gvl_release` -> `thread_sched_to_waiting` # running -> waiting
* `gvl_yield`   -> `thread_sched_yield`
* `GVL_UNLOCK_BEGIN` -> `THREAD_BLOCKING_BEGIN`
* `GVL_UNLOCK_END` -> `THREAD_BLOCKING_END`

* removed
  * `rb_ractor_gvl`
  * `rb_vm_gvl_destroy` (not used)

There are GVL functions such as `rb_thread_call_without_gvl()` yet
but I don't have good name to replace them. Maybe GVL stands for
"Greate Valuable Lock" or something like that.
2022-04-22 07:54:09 +09:00
Nobuyoshi Nakada 7b1ece9b94
Get rid of type-punning pointer casts 2022-04-07 19:19:13 +09:00
Yusuke Endoh 23530d68cb ractor.c: Add a helper function to ensure the context is a main ractor 2022-03-30 16:50:46 +09:00
Nobuyoshi Nakada 42a0bed351
Prefix ccan headers (#4568)
* Prefixed ccan headers

* Remove unprefixed names in ccan/build_assert

* Remove unprefixed names in ccan/check_type

* Remove unprefixed names in ccan/container_of

* Remove unprefixed names in ccan/list

Co-authored-by: Samuel Williams <samuel.williams@oriontransfer.co.nz>
2022-03-30 20:36:31 +13:00
Alan Wu 51e98eab1f
Fix Ractor.receive_if + rb_vm_barrier() deadlock
I have this scripts that deadlocks after about
5 minutes if I repeatedly run it with a shell loop:

```ruby
$VERBOSE = nil
lamb = ->(main, gc) do
  gc.verify_internal_consistency
  gc.verify_internal_consistency
  main << 1
  gc.verify_internal_consistency
  gc.verify_internal_consistency
  main << 2
  gc.verify_internal_consistency
  gc.verify_internal_consistency
  main << 3
  gc.verify_internal_consistency
  gc.verify_internal_consistency
end

lamb[[], GC]
lamb[[], GC]

r = Ractor.new Ractor.current, GC, &lamb

a = []
a << Ractor.receive_if{|msg| msg == 2}
a << Ractor.receive_if{|msg| msg == 3}
a << Ractor.receive_if{|msg| msg == 1}
```

Shell loop:

```shell
while ./miniruby deadlock.rb; do date; done
```

Once it locks up, CTRL-C doesn't interrupt the process which
led me to infer `receive_if` is looping in `ractor_receive_if()`
without checking for interrupts. This can be confirmed by
attaching a debugger to the deadlocked miniruby.

The deadlock has one thread looping in `receive_if`
and another waiting in `rb_vm_barrier()`. The barrier relies
on interrupt checking to finish. Theoretically speaking the
`rb_vm_barrier()` could come from one thread naturally starting GC.
We found this while developing YJIT but it dead locks running
with YJIT disabled. YJIT currently relies on `rb_vm_barrier()`
to synchronize before changing memory protection.

This diff adds an interrupt check in the loop in `Ractor#receive_if`
which seems to fix the deadlock.

In addition, this commit allows interrupting the following single
ractor script with CTRL-C.

```shell
ruby -e 'Ractor.current.send(3); Ractor.receive_if { false }'
```
2022-03-28 17:00:45 -04:00
Koichi Sasada c9af8a32a0 `USE_RUBY_DEBUG_LOG` doesn't check `RUBY_DEVEL`
`USE_RUBY_DEBUG_LOG` was only defined when `RUBY_DEVEL` is defined.
This patch removes this dependency (`USE_RUBY_DEBUG_LOG` is defined
independently from `RUBY_DEVEL`).

Do not commit a patch which enables `USE_RUBY_DEBUG_LOG`.
2021-12-29 00:22:02 +09:00
Nobuyoshi Nakada 975a6efd7e Suppress undef warnings for USE_RUBY_DEBUG_LOG 2021-12-25 18:04:25 +09:00
Jose Narvaez 4e2eb7695e Yet Another Ruby JIT!
Renaming uJIT to YJIT. AKA s/ujit/yjit/g.
2021-10-20 18:19:31 -04:00
Alan Wu 57977ba30d uJIT: Implement opt_getinlinecache
* ujit: implement opt_getinlinecache

Aggressively bet that writes to constants don't happen and invalidate
all opt_getinlinecache blocks on any and all constant writes.

Use alignment padding on block_t to track this assumption. No change to
sizeof(block_t).

* Fix compile warnings when not RUBY_DEBUG
* Fix reversed condition
* Switch to st_table to keep track of assumptions

Co-authored-by: Aaron Patterson <aaron.patterson@gmail.com>
Co-authored-by: Maxime Chevalier-Boisvert <maximechevalierb@gmail.com>
2021-10-20 18:19:30 -04:00
Nobuyoshi Nakada 0c15752556
Use `RUBY_FUNCTION_NAME_STRING` for old Visual C++
Probably `__func__` is supported since Visual C++ 2015 (= 14.0,
`_MSC_VER` = 1900).
2021-10-20 11:22:33 +09:00
Nobuyoshi Nakada 768ceb4ead
Cast to void pointer for `%p` in commented out code [ci skip] 2021-10-20 11:22:33 +09:00
Kazuhiro NISHIYAMA 9b18f1bffe Supress `warning: data argument not used by format string [-Wformat-extra-args]` 2021-10-20 07:48:30 +09:00
Nobuyoshi Nakada ff480f2953
Cast to void pointer to suppress -Wformat-pedantic in RUBY_DEBUG_LOG 2021-10-03 13:59:48 +09:00
Peter Zhu bbedd29b6e [Bug #18117] Fix Ractor race condition with GC
rb_objspace_reachable_objects_from requires that the GC not be active.
Since the Ractor barrier is not executed for incremental sweeping,
Ractor may call rb_objspace_reachable_objects_from after sweeping
has started to share objects. This causes a crash that looks like
the following:

```
<internal:ractor>:627: [BUG] rb_objspace_reachable_objects_from() is not supported while during_gc == true
```

Co-authored-by: Vinicius Stock <vinicius.stock@shopify.com>
2021-08-24 09:47:42 -04:00
Peter Zhu 4a627dbdfd [Bug #18014] Fix memory leak in GC when using Ractors
When a Ractor is removed, the freelist in the Ractor cache is not
returned to the GC, leaving the freelist permanently lost. This commit
recycles the freelist when the Ractor is destroyed, preventing a memory
leak from occurring.
2021-07-15 11:48:52 -04:00
eileencodes 8209b73580 Evacuate transient heap when enabling ractors
If the GC has been disabled we need to re-enable it so we can evacuate
the transient heap.

Fixes https://bugs.ruby-lang.org/issues/17985

[Bug #17985] [ruby-core:104260]

Co-authored-by: Aaron Patterson <tenderlove@ruby-lang.org>
2021-06-23 10:03:09 -07:00
Takashi Kokubun e1b03b0c2b
Enable VM_ASSERT in --jit CIs (#4543) 2021-06-01 00:15:51 -07:00
Ryuta Kamizono 33f2ff3bab Fix some typos by spell checker 2021-04-26 10:07:41 +09:00
Nobuyoshi Nakada 983f6d0f2a
Moved locking VM to an atomic operation 2021-03-13 09:11:21 +09:00
Nobuyoshi Nakada b3c53a8a88
Make Ractor stdio belonging to the Ractor [Bug #17672]
Defer making ractor stdio until ractor started.
Before ractor started, created objects belong to the caller ractor
instead of the created ractor.
2021-03-07 00:58:28 +09:00
Koichi Sasada 7b9476fbfa Ractor.allocate should not be allowed
Ractor.allocate and Ractor#dup should not be allowed like Thread.
[Bug #17642]
2021-02-18 22:35:34 +09:00
Koichi Sasada fff1edf23b fix Ractor.yield(obj, move: true)
Ractor.yield(obj, move: true) and
Ractor.select(..., yield_value: obj, move: true) tried to yield a
value with move semantices, but if the trial is faild, the obj
should not become a moved object.

To keep this rule, `wait_moving` wait status is introduced.

New yield/take process:
(1) If a ractor tried to yield (move:true), make taking racotr's
    wait status `wait_moving` and make a moved object by
    `ractor_move(obj)` and wakeup taking ractor.
(2) If a ractor tried to take a message from a ractor waiting fo
    yielding (move:true), wakeup the ractor and wait for (1).
2021-01-22 12:16:37 +09:00
Koichi Sasada d0d6227a0d alen should be actions number on ractor_select()
alen was number of rs, but it should be actions number
(taking ractors + receiving + yielding).
2021-01-22 12:16:37 +09:00
Koichi Sasada 03d1850bfa use ractor_wakeup()
Use ractor_wakeup() for same code.
2021-01-22 02:48:31 +09:00
Koichi Sasada d968829afa expose some C-APIs for ractor
expose some C-APIs to try to make ractor utilities on external gems.

* add
  * rb_ractor_local_storage_value_lookup() to check availability
* expose
  * rb_ractor_make_shareable()
  * rb_ractor_make_shareable_copy()
  * rb_proc_isolate() (not public)
  * rb_proc_isolate_bang() (not public)
  * rb_proc_ractor_make_shareable() (not public)
2021-01-06 16:03:09 +09:00
Koichi Sasada 7340e7f827 introduce rb_ractor_atfork()
to reset main ractor at fork().
2020-12-24 04:30:50 +09:00
Koichi Sasada 7fcb6b3dbe fix ractor-locking around rb_ractor_thread_list()
With locking a ractor, rb_ary_push() can call RB_VM_LOCK_ENTER()
and it violates an assertion: should not acquire ractor-lock.
2020-12-24 04:30:49 +09:00
Nobuyoshi Nakada c0a2d95cf3 Update rb_ractor_ensure_shareable
* Fixed use of rb_ractor_shareable_p
* Raise Ractor::IsolationError
2020-12-23 13:50:42 +09:00
Nobuyoshi Nakada 7a094146e6 Changed shareable literal semantics [Feature #17397]
When `literal`, check if the literal about to be assigned to a
constant is ractor-shareable, otherwise raise `Ractor::Error` at
runtime instead of `SyntaxError`.
2020-12-23 13:50:42 +09:00
Koichi Sasada 7e44ade565 ruby_single_main_ractor should be clear before warn
rb_warn can produce T_HASA object and it should not use
transient heap.
2020-12-23 13:39:48 +09:00
Marc-Andre Lafortune 91773ddd26 Remove debugging code 2020-12-21 18:56:46 -05:00
Koichi Sasada c34c6a89cb fix ractor's doc. [ci skip] 2020-12-22 06:09:42 +09:00
Koichi Sasada 35471a9487 add Ractor#[]/#[]= for ractor local storage
This API is similar to plain old Thread#[]/Fiber#[] interface
with symbol key.
2020-12-22 05:26:32 +09:00
Koichi Sasada 02d9524cda separate rb_ractor_pub from rb_ractor_t
separate some fields from rb_ractor_t to rb_ractor_pub and put it
at the beggining of rb_ractor_t and declare it in vm_core.h so
vm_core.h can access rb_ractor_pub fields.

Now rb_ec_ractor_hooks() is a complete inline function and no
MJIT related issue.
2020-12-22 00:03:00 +09:00
Koichi Sasada a2950369bd TracePoint.new(&block) should be ractor-local
TracePoint should be ractor-local because the Proc can violate the
Ractor-safe.
2020-12-22 00:03:00 +09:00
Koichi Sasada dca6752fec Introduce Ractor::IsolationError
Ractor has several restrictions to keep each ractor being isolated
and some operation such as `CONST="foo"` in non-main ractor raises
an exception. This kind of operation raises an error but there is
confusion (some code raises RuntimeError and some code raises
NameError).

To make clear we introduce Ractor::IsolationError which is raised
when the isolation between ractors is violated.
2020-12-21 22:29:05 +09:00
Kazuhiro NISHIYAMA 74a7877836
[DOC] Remove about FrozenError from Ractor::MovedObject [ci skip]
Because unfreeze Ractor::MovedObject at
76e8848037
2020-12-21 13:25:03 +09:00
Koichi Sasada 6be61ab264 should use owned_p instead of locked_p
It should raise an error if the same thread tris to call
receive/receive_if.
2020-12-21 02:39:34 +09:00
Koichi Sasada 7600f69a8e rename to rb_ractor_make_shareable_copy()
from rb_ractor_make_copy_shareable().
2020-12-21 02:21:33 +09:00
Koichi Sasada 730f314171 fix Ractor.make_shareable() with Class/Module
To check shareable-ness, rb_ractor_shareable_p() is needed
for Class/Module objects isntead of checking flags.
2020-12-21 01:13:39 +09:00
Marc-Andre Lafortune a273171ca8 Tweak Ractor doc [doc] [ci skip] 2020-12-19 13:08:24 -05:00
Victor Shepelev 1f565ac6d9
Add documentation for Ractor (#3895) 2020-12-19 13:04:40 -05:00
Koichi Sasada 76e8848037 unfreeze Ractor::MovedObject
Matz prefers to unfreeze the class.
[Feature #17401]
2020-12-19 05:57:12 +09:00
Koichi Sasada 80cb9165fa add "copy: true" option for Ractor.make_shareable
Ractor.make_shareable(obj) tries to make obj a shareable object
by changing the attribute of obj and traversable objects from obj
(mainly freeze them).

"copy: true" option is more conservative approach by make deep
copied object and make it sharable. It doesn't affect any existing
objects.
2020-12-19 05:52:18 +09:00
Jeremy Evans 7e2dbbda35 Use category: :experimental in warnings that are related to experimental features
This adds rb_category_compile_warn in order to emit compiler warnings
with categories.  Note that Ripper currently ignores the category
for these warnings, but by default it ignores the warnings completely,
so this shouldn't matter.
2020-12-18 09:54:11 -08:00
Koichi Sasada 24f018972b fix timing bug
ractor_sleep() can remain wait.status by interrupt, so that this
patch handles more correctly.

This patch fixed this kind of assertion failures:

   Assertion Failed: ../src/ractor.c:1332:ractor_yield_atexit:cr->sync.wait.status == wait_none
2020-12-17 00:34:30 +09:00
Koichi Sasada a9a7f4d8b8 Ractor#receive_if to receive only matched messages
Instead of Ractor.receive, Ractor.receive_if can provide a pattern
by a block and you can choose the receiving message.

[Feature #17378]
2020-12-16 19:12:48 +09:00
Nobuyoshi Nakada 416e402cf3
Fixed a suspicious comparison 2020-12-13 13:12:18 +09:00
Koichi Sasada ee194af2aa re-layout rb_ractor_t
separate synchronization data and ractor local data.
2020-12-09 01:40:38 +09:00
Koichi Sasada c2fa024e02 fix Thread's interrupt and Ractor#take issue
Thread's interrupt set Ractor's wakeup_status as interrupted, but
the status remains next Ractor communication API. This patch makes
to ignore the previous interrupt state.
[Bug #17366]

Also this patch solves the Thread#kill and Ractor#take issues.
2020-12-07 16:01:35 +09:00