aboutsummaryrefslogtreecommitdiffstats
path: root/ractor_core.h
Commit message (Collapse)AuthorAgeFilesLines
* Revert "allow enabling Prism via flag or env var"HParker2023-12-061-1/+0
| | | | This reverts commit 9b76c7fc89460ed8e9be40e4037c1d68395c0f6d.
* allow enabling Prism via flag or env varHParker2023-12-051-0/+1
| | | | | | | | | | Enable Prism using either --prism ruby --prism test.rb or via env var RUBY_PRISM=1 ruby test.rb
* M:N thread scheduler for RactorsKoichi Sasada2023-10-121-1/+7
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This patch introduce M:N thread scheduler for Ractor system. In general, M:N thread scheduler employs N native threads (OS threads) to manage M user-level threads (Ruby threads in this case). On the Ruby interpreter, 1 native thread is provided for 1 Ractor and all Ruby threads are managed by the native thread. From Ruby 1.9, the interpreter uses 1:1 thread scheduler which means 1 Ruby thread has 1 native thread. M:N scheduler change this strategy. Because of compatibility issue (and stableness issue of the implementation) main Ractor doesn't use M:N scheduler on default. On the other words, threads on the main Ractor will be managed with 1:1 thread scheduler. There are additional settings by environment variables: `RUBY_MN_THREADS=1` enables M:N thread scheduler on the main ractor. Note that non-main ractors use the M:N scheduler without this configuration. With this configuration, single ractor applications run threads on M:1 thread scheduler (green threads, user-level threads). `RUBY_MAX_CPU=n` specifies maximum number of native threads for M:N scheduler (default: 8). This patch will be reverted soon if non-easy issues are found. [Bug #19842]
* macos: symbols for `rb_execution_context_t` should be internalNobuyoshi Nakada2023-07-081-3/+3
|
* Remove dependancy of vm_core.h on shape.hMatt Valentine-House2023-04-061-0/+1
| | | | so that now shape can happily include gc.h
* relax assertionKoichi Sasada2023-03-311-1/+1
| | | | `ec` can be NULL in future.
* add debug log to `rb_ractor_thread_switch`Koichi Sasada2023-03-311-0/+4
|
* `rb_ractor_thread_list()` only for current ractorKoichi Sasada2023-03-301-1/+1
| | | | so that no need to lock the ractor.
* Rewrite Ractor synchronization mechanismKoichi Sasada2023-03-021-16/+56
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | This patch rewrites Ractor synchronization mechanism, send/receive and take/yield. * API * Ractor::Selector is introduced for lightweight waiting for many ractors. * Data structure * remove `struct rb_ractor_waiting_list` and use `struct rb_ractor_queue takers_queue` to manage takers. * remove `rb_ractor_t::yield_atexit` and use `rb_ractor_t::sync::will_basket::type` to check the will. * add `rb_ractor_basket::p.take` to represent a taking ractor. * Synchronization protocol * For the Ractor local GC, `take` can not make a copy object directly so ask to generate the copy from the yielding ractor. * The following steps shows what `r1.take` does on `r0`. * step1: (r0) register `r0` into `r1`'s takers. * step2: (r0) check `r1`'s status and wakeup r0 if `r1` is waiting for yielding a value. * step3: (r0) sleep until `r1` wakes up `r0`. * The following steps shows what `Ractor.yield(v)` on `r1`. * step1: (r1) check first takers of `r1` and if there is (`r0`), make a copy object of `v` and pass it to `r0` and wakes up `r0`. * step2: (r1) if there is no taker ractors, sleep until another ractor try to take.
* Let SHAPE_BITS take 32 bits on debug buildsPeter Zhu2022-11-211-2/+0
| | | | | The ractor_belonging_id has been moved out of the headers, so object shapes can take the top 32 bits of the flags on debug builds.
* Add RVALUE_OVERHEAD and move ractor_belonging_idPeter Zhu2022-11-211-3/+4
| | | | | | | This commit adds RVALUE_OVERHEAD for storing metadata at the end of the slot. This commit moves the ractor_belonging_id in debug builds from the flags to RVALUE_OVERHEAD which frees the 16 bits in the headers for object shapes.
* rename SHAPE_BITS to SHAPE_ID_NUM_BITSAaron Patterson2022-11-181-1/+1
|
* Revert "Revert "This commit implements the Object Shapes technique in CRuby.""Jemma Issroff2022-10-111-2/+4
| | | | This reverts commit 9a6803c90b817f70389cae10d60b50ad752da48f.
* Revert "This commit implements the Object Shapes technique in CRuby."Aaron Patterson2022-09-301-4/+2
| | | | This reverts commit 68bc9e2e97d12f80df0d113e284864e225f771c2.
* This commit implements the Object Shapes technique in CRuby.Jemma Issroff2022-09-281-2/+4
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Object Shapes is used for accessing instance variables and representing the "frozenness" of objects. Object instances have a "shape" and the shape represents some attributes of the object (currently which instance variables are set and the "frozenness"). Shapes form a tree data structure, and when a new instance variable is set on an object, that object "transitions" to a new shape in the shape tree. Each shape has an ID that is used for caching. The shape structure is independent of class, so objects of different types can have the same shape. For example: ```ruby class Foo def initialize # Starts with shape id 0 @a = 1 # transitions to shape id 1 @b = 1 # transitions to shape id 2 end end class Bar def initialize # Starts with shape id 0 @a = 1 # transitions to shape id 1 @b = 1 # transitions to shape id 2 end end foo = Foo.new # `foo` has shape id 2 bar = Bar.new # `bar` has shape id 2 ``` Both `foo` and `bar` instances have the same shape because they both set instance variables of the same name in the same order. This technique can help to improve inline cache hits as well as generate more efficient machine code in JIT compilers. This commit also adds some methods for debugging shapes on objects. See `RubyVM::Shape` for more details. For more context on Object Shapes, see [Feature: #18776] Co-Authored-By: Aaron Patterson <tenderlove@ruby-lang.org> Co-Authored-By: Eileen M. Uchitelle <eileencodes@gmail.com> Co-Authored-By: John Hawthorn <john@hawthorn.email>
* Revert this until we can figure out WB issues or remove shapes from GCAaron Patterson2022-09-261-4/+2
| | | | | | | | | | Revert "* expand tabs. [ci skip]" This reverts commit 830b5b5c351c5c6efa5ad461ae4ec5085e5f0275. Revert "This commit implements the Object Shapes technique in CRuby." This reverts commit 9ddfd2ca004d1952be79cf1b84c52c79a55978f4.
* This commit implements the Object Shapes technique in CRuby.Jemma Issroff2022-09-261-2/+4
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Object Shapes is used for accessing instance variables and representing the "frozenness" of objects. Object instances have a "shape" and the shape represents some attributes of the object (currently which instance variables are set and the "frozenness"). Shapes form a tree data structure, and when a new instance variable is set on an object, that object "transitions" to a new shape in the shape tree. Each shape has an ID that is used for caching. The shape structure is independent of class, so objects of different types can have the same shape. For example: ```ruby class Foo def initialize # Starts with shape id 0 @a = 1 # transitions to shape id 1 @b = 1 # transitions to shape id 2 end end class Bar def initialize # Starts with shape id 0 @a = 1 # transitions to shape id 1 @b = 1 # transitions to shape id 2 end end foo = Foo.new # `foo` has shape id 2 bar = Bar.new # `bar` has shape id 2 ``` Both `foo` and `bar` instances have the same shape because they both set instance variables of the same name in the same order. This technique can help to improve inline cache hits as well as generate more efficient machine code in JIT compilers. This commit also adds some methods for debugging shapes on objects. See `RubyVM::Shape` for more details. For more context on Object Shapes, see [Feature: #18776] Co-Authored-By: Aaron Patterson <tenderlove@ruby-lang.org> Co-Authored-By: Eileen M. Uchitelle <eileencodes@gmail.com> Co-Authored-By: John Hawthorn <john@hawthorn.email>
* Disable Ractor check on 32bit architecturesAaron Patterson2022-08-241-1/+1
| | | | | | | | | | | | | Ractor verification requires storing the ractor id in the top 32 bits of the object header. Unfortunately 32 bit machines only have 32 bits in the object header. The verification code has a 32 bit left shift which doesn't work on i686 and will clobber existing flags. This commit disables the verification code on i686 since i686 will crash if it's enabled. Co-Authored-By: John Hawthorn <john@hawthorn.email> Co-Authored-By: Jemma Issroff <jemmaissroff@gmail.com>
* Fix format-pedantic warningsNobuyoshi Nakada2022-07-281-1/+1
|
* Add "rb_" prefixes to toplevel enum definitionsYusuke Endoh2022-07-221-4/+4
| | | | ... as per ko1's request.
* Move enum definitions out of struct definitionYusuke Endoh2022-07-221-39/+42
|
* cleanup by `RUBY_DEBUG_LOG2` and `VM_ASSERT`Koichi Sasada2022-05-241-12/+5
|
* rename thread internal namingKoichi Sasada2022-04-221-2/+1
| | | | | | | | | | | | | | | | | | | | | | | | 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.
* internal/ractor.h: AddedYusuke Endoh2022-03-301-2/+0
| | | | Currently it has only one function prototype.
* ractor.c: Add a helper function to ensure the context is a main ractorYusuke Endoh2022-03-301-0/+2
|
* Prefix ccan headers (#4568)Nobuyoshi Nakada2022-03-301-2/+2
| | | | | | | | | | | | | * 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>
* Move rb_ractor_p definitionS.H2021-10-041-0/+1
|
* Remove printf family from the mjit headerNobuyoshi Nakada2021-09-111-5/+9
| | | | | Linking printf family functions makes mjit objects to link unnecessary code.
* [Bug #18014] Fix memory leak in GC when using RactorsPeter Zhu2021-07-151-4/+1
| | | | | | | 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.
* Fix trivial -Wundef warningsBenoit Daloze2021-05-041-1/+1
| | | | | | * See [Feature #17752] Co-authored-by: xtkoba (Tee KOBAYASHI) <xtkoba+ruby@gmail.com>
* fix Ractor.yield(obj, move: true)Koichi Sasada2021-01-221-0/+1
| | | | | | | | | | | | | | | | 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).
* shareable_constant_value: experimental_copyKoichi Sasada2020-12-241-0/+2
| | | | | | | "experimental_everything" makes the assigned value, it means the assignment change the state of assigned value. "experimental_copy" tries to make a deep copy and make copyied object sharable.
* introduce rb_ractor_atfork()Koichi Sasada2020-12-241-0/+1
| | | | to reset main ractor at fork().
* add Ractor#[]/#[]= for ractor local storageKoichi Sasada2020-12-221-0/+1
| | | | | This API is similar to plain old Thread#[]/Fiber#[] interface with symbol key.
* separate rb_ractor_pub from rb_ractor_tKoichi Sasada2020-12-221-7/+14
| | | | | | | | | 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.
* TracePoint.new(&block) should be ractor-localKoichi Sasada2020-12-221-0/+2
| | | | | TracePoint should be ractor-local because the Proc can violate the Ractor-safe.
* Ractor#receive_if to receive only matched messagesKoichi Sasada2020-12-161-2/+6
| | | | | | | Instead of Ractor.receive, Ractor.receive_if can provide a pattern by a block and you can choose the receiving message. [Feature #17378]
* revert da3bca513f437b05b3953c3712ff48621fc5e008Koichi Sasada2020-12-111-1/+0
| | | | | | | It seems introduce critical problems. Now I could not find out the issue. http://ci.rvm.jp/results/trunk-test@ruby-sky1/3286048
* cache free pages per ractorKoichi Sasada2020-12-101-0/+1
| | | | | | | Per ractor method cache (GH-#3842) only cached 1 page and this patch caches several pages to keep at least 512 free slots if available. If you increase the number of cached free slots, all cached slots will be collected when the GC is invoked.
* re-layout rb_ractor_tKoichi Sasada2020-12-091-9/+10
| | | | separate synchronization data and ractor local data.
* per-ractor object allocationKoichi Sasada2020-12-071-0/+5
| | | | | | | | Now object allocation requires VM global lock to synchronize objspace. However, of course, it introduces huge overhead. This patch caches some slots (in a page) by each ractor and use cached slots for object allocation. If there is no cached slots, acquire the global lock and get new cached slots, or start GC (marking or lazy sweeping).
* ruby_single_main_ractor for single ractor modeKoichi Sasada2020-12-071-3/+1
| | | | | | | | ruby_multi_ractor was a flag that indicates the interpreter doesn't make any additional ractors (single ractor mode). Instead of boolean flag, ruby_single_main_ractor pointer is introduced which keeps main ractor's pointer if single ractor mode. If additional ractors are created, ruby_single_main_ractor becomes NULL.
* ractor local storage C-APIKoichi Sasada2020-12-011-2/+10
| | | | | | | | | | | | | | | | | | | | | | To manage ractor-local data for C extension, the following APIs are defined. * rb_ractor_local_storage_value_newkey * rb_ractor_local_storage_value * rb_ractor_local_storage_value_set * rb_ractor_local_storage_ptr_newkey * rb_ractor_local_storage_ptr * rb_ractor_local_storage_ptr_set At first, you need to create a key of storage by rb_ractor_local_(value|ptr)_newkey(). For ptr storage, it accepts the type of storage, how to mark and how to free with ractor's lifetime. rb_ractor_local_storage_value/set are used to access a VALUE and rb_ractor_local_storage_ptr/set are used to access a pointer. random.c uses this API.
* Use opaque struct pointer than voidNobuyoshi Nakada2020-11-271-1/+3
|
* per-ractor Random::DEFAULTKoichi Sasada2020-11-271-0/+2
| | | | | | | | | | Random generators are not Ractor-safe, so we need to prepare per-ractor default random genearators. This patch set `Random::DEFAULT = Randm` (not a Random instance, but the Random class) and singleton methods like `Random.rand()` use a per-ractor random generator. [Feature #17322]
* Move the declaration into the functionKazuhiro NISHIYAMA2020-11-181-0/+4
| | | | instead of 'do not call it directly.' comment.
* fix public interfaceKoichi Sasada2020-11-181-0/+306
To make some kind of Ractor related extensions, some functions should be exposed. * include/ruby/thread_native.h * rb_native_mutex_* * rb_native_cond_* * include/ruby/ractor.h * RB_OBJ_SHAREABLE_P(obj) * rb_ractor_shareable_p(obj) * rb_ractor_std*() * rb_cRactor and rm ractor_pub.h and rename srcdir/ractor.h to srcdir/ractor_core.h (to avoid conflict with include/ruby/ractor.h)