Age | Commit message (Collapse) | Author |
---|
| Notes: Merged: https://.com/ruby/ruby/pull/13634 |
| Expose `rb_thread_resolve_unblock_function` internally. Notes: Merged-By: ioquatix <[email protected]> |
| Previously rb_ractor_interrupt_exec would use an intermediate function to create a new thread with the actual target function, replacing the data being passed in with a piece of malloc memory holding the "next" function and the original data. Because of this, passing rb_interrupt_exec_flag_value_data to rb_ractor_interrupt_exec didn't have the intended effect of allowing data to be passed in and marked. This commit adds a rb_interrupt_exec_flag_new_thread flag, which both simplifies the implementation and allows the original data to be marked. Notes: Merged: https://.com/ruby/ruby/pull/13531 |
| We never freed any resources of rb_native_thread at fork because it would cause it to hang. This is because it called rb_native_cond_destroy for condition variables. We can't call rb_native_cond_destroy here because according to the specs of pthread_cond_destroy: Attempting to destroy a condition variable upon which other threads are currently blocked results in undefined behavior. Specifically, glibc's pthread_cond_destroy waits on all the other listeners. Since after forking all the threads are dead, the condition variable's listeners will never wake up, so it will hang forever. This commit changes it to only free the memory and none of the condition variables. Notes: Merged: https://.com/ruby/ruby/pull/13591 |
| Notes: Merged: https://.com/ruby/ruby/pull/13437 |
| Notes: Merged: https://.com/ruby/ruby/pull/13437 |
| Notes: Merged-By: ioquatix <[email protected]> |
| (#13526) Fixes the following: ```ruby Thread.new { Fiber.current.kill }.join ``` Notes: Merged-By: ioquatix <[email protected]> |
| `__has_warning` is clang, not gcc. Notes: Merged: https://.com/ruby/ruby/pull/13509 |
| `#fiber_interrupt`. (#13492) Notes: Merged-By: ioquatix <[email protected]> |
| * Added `Ractor::Port` * `Ractor::Port#receive` (support multi-threads) * `Rcator::Port#close` * `Ractor::Port#closed?` * Added some methods * `Ractor#join` * `Ractor#value` * `Ractor#monitor` * `Ractor#unmonitor` * Removed some methods * `Ractor#take` * `Ractor.yield` * Change the spec * `Racotr.select` You can wait for multiple sequences of messages with `Ractor::Port`. ```ruby ports = 3.times.map{ Ractor::Port.new } ports.map.with_index do |port, ri| Ractor.new port,ri do |port, ri| 3.times{|i| port << "r#{ri}-#{i}"} end end p ports.each{|port| pp 3.times.map{port.receive}} ``` In this example, we use 3 ports, and 3 Ractors send messages to them respectively. We can receive a series of messages from each port. You can use `Ractor#value` to get the last value of a Ractor's block: ```ruby result = Ractor.new do heavy_task() end.value ``` You can wait for the termination of a Ractor with `Ractor#join` like this: ```ruby Ractor.new do some_task() end.join ``` `#value` and `#join` are similar to `Thread#value` and `Thread#join`. To implement `#join`, `Ractor#monitor` (and `Ractor#unmonitor`) is introduced. This commit changes `Ractor.select()` method. It now only accepts ports or Ractors, and returns when a port receives a message or a Ractor terminates. We removes `Ractor.yield` and `Ractor#take` because: * `Ractor::Port` supports most of similar use cases in a simpler manner. * Removing them significantly simplifies the code. We also change the internal thread scheduler code (thread_pthread.c): * During barrier synchronization, we keep the `ractor_sched` lock to avoid deadlocks. This lock is released by `rb_ractor_sched_barrier_end()` which is called at the end of operations that require the barrier. * fix potential deadlock issues by checking interrupts just before setting UBF. https://bugs.ruby-lang.org/issues/21262 Notes: Merged: https://.com/ruby/ruby/pull/13445 |
| Notes: Merged: https://.com/ruby/ruby/pull/13439 |
| Notes: Merged: https://.com/ruby/ruby/pull/13425 |
| `fiber_interrupt` hook. (#12839) Notes: Merged-By: ioquatix <[email protected]> |
| Notes: Merged: https://.com/ruby/ruby/pull/13357 |
| Although it almost certainly works in this case, volatile is best not used for multi-threaded code. Using atomics instead avoids warnings from TSan. This also simplifies some logic, as system_working was previously only ever assigned to 1, so --system_working <= 0 should always return true (unless it underflowed). Notes: Merged: https://.com/ruby/ruby/pull/13333 |
| Co-authored-by: Ivo Anjo <[email protected]> Co-authored-by: Luke Gruber <[email protected]> Notes: Merged: https://.com/ruby/ruby/pull/12094 |
| |
| Notes: Merged-By: ioquatix <[email protected]> |
| in same ractor Rework ractors so that any ractor action (Ractor.receive, Ractor#send, Ractor.yield, Ractor#take, Ractor.select) will operate on the thread that called the action. It will put that thread to sleep if it's a blocking function and it needs to put it to sleep, and the awakening action (Ractor.yield, Ractor#send) will wake up the blocked thread. Before this change every blocking ractor action was associated with the ractor struct and its fields. If a ractor called Ractor.receive, its wait status was wait_receiving, and when another ractor calls r.send on it, it will look for that status in the ractor struct fields and wake it up. The problem was that what if 2 threads call blocking ractor actions in the same ractor. Imagine if 1 thread has called Ractor.receive and another r.take. Then, when a different ractor calls r.send on it, it doesn't know which ruby thread is associated to which ractor action, so what ruby thread should it schedule? This change moves some fields onto the ruby thread itself so that ruby threads are the ones that have ractor blocking statuses, and threads are then specifically scheduled when unblocked. Fixes [#17624] Fixes [#21037] Notes: Merged: https://.com/ruby/ruby/pull/12633 |
| - `rb_thread_fd_close` is deprecated and now a no-op. - IO operations (including close) no longer take a vm-wide lock. Notes: Merged-By: ioquatix <[email protected]> |
| Ractors created in a parent process should be properly shut down in the child process. They need their cache cleared and status set to "terminated" Co-authored-by: John Hawthorn <[email protected]> Notes: Merged: https://.com/ruby/ruby/pull/12982 |
| |
| Notes: Merged-By: ioquatix <[email protected]> |
| Notes: Merged: https://.com/ruby/ruby/pull/11975 |
| Fixes [Bug #21220] Co-Authored-By: Mike Bourgeous <[email protected]> Co-Authored-By: Jean Boussier <[email protected]> Notes: Merged: https://.com/ruby/ruby/pull/13089 |
| Followup: https://.com/ruby/ruby/pull/13013 Notes: Merged: https://.com/ruby/ruby/pull/13016 |
| [Bug #17506] `Thread.current.group` isn't shareable so it shouldn't be inherited by the main thread of a new Ractor. This cause an extra allocation when spawning a ractor, which could be elided with a bit of extra work, but not sure if it's worth the effort. Notes: Merged: https://.com/ruby/ruby/pull/13013 |
| If a thread was holding this lock before fork, it will not exist in the child process. We should re-initialize these locks as we do with the VM locks when forking. Co-authored-by: Aaron Patterson <[email protected]> Notes: Merged: https://.com/ruby/ruby/pull/12981 |
| Previously, Ruby displayed backtraces for each thread on deadlock. However, it has not been shown since Ruby 3.0. It should display the backtrace for debugging. Co-authored-by: Jeremy Evans <[email protected]> Notes: Merged-By: pocke <[email protected]> |
| Notes: Merged: https://.com/ruby/ruby/pull/12740 |
| Notes: Merged: https://.com/ruby/ruby/pull/12676 |
| Notes: Merged-By: tompng <[email protected]> |
| |
| Notes: Merged: https://.com/ruby/ruby/pull/12328 |
| This commit adds an environment variable `RUBY_THREAD_TIMESLICE` for specifying the default thread quantum in milliseconds. You can adjust this variable to tune throughput, which is especially useful on multithreaded systems that are mixing CPU bound work and IO bound work. The default quantum remains 100ms. [Feature #20861] Co-Authored-By: John Hawthorn <[email protected]> Notes: Merged: https://.com/ruby/ruby/pull/11981 |
| Redirect `rb_nogvl` blocking operations to the fiber scheduler if possible to prevent stalling the event loop. [Feature #20876] Notes: Merged-By: ioquatix <[email protected]> |
| to avoid TLS issue with N:M threads. Notes: Merged: https://.com/ruby/ruby/pull/11142 |
| introduce - rb_threadptr_interrupt_exec - rb_ractor_interrupt_exec to intercept the thread/ractor execution. Notes: Merged: https://.com/ruby/ruby/pull/11142 |
| Notes: Merged-By: ioquatix <[email protected]> |
| This reverts some of commit 87fb44dff6409a19d12052cf0fc07ba80a4c45ac. We will rename and propose a slightly different interface. Notes: Merged-By: ioquatix <[email protected]> |
| `RUBY_VM_CRITICAL_SECTION` is not used anywhere. |
| Notes: Merged-By: ioquatix <[email protected]> |
| If one thread is reading and another closes that socket, the close blocks waiting for the read to abort cleanly. This ensures that Ruby is totally done with the file descriptor _BEFORE_ we tell the OS to close and potentially re-use it. When the read is correctly terminated, the close should be unblocked. That currently works if closing is happening on a thread, but if it's happening on a fiber with a fiber scheduler, it does NOT work. This ensures that if the close happened in a fiber scheduled thread, that the scheduler is notified that the fiber is unblocked. [Bug #20723] Notes: Merged: https://.com/ruby/ruby/pull/11614 |
| Fixes this compiler warning: thread.c:4530:18: warning: storing the address of local variable ‘stack_end’ in ‘*stack_end_p’ [-Wdangling-pointer=] 4530 | *stack_end_p = &stack_end; | ~~~~~~~~~~~~~^~~~~~~~~~~~ |
| * This PR from the timeout gem (https://.com/ruby/timeout/pull/30) made it so you have to handle_interrupt on Timeout::ExitException instead of Timeout::Error * Efficiency changes to the gem (one shared thread) mean you can't consistently handle timeout errors using handle_timeout: https://.com/ruby/timeout/issues/41 Notes: Merged: https://.com/ruby/ruby/pull/11474 |
| Previously, a TypeError was not raised if there were no thread variables, because the conversion to symbol was done after that check. Convert to symbol before checking for whether thread variables are set to make the behavior consistent. Fixes [Bug #20606] |
| * Speed up chunkypng benchmark Since d037c5196a14c03e72746ccdf0437b5dd4f80a69 we're seeing a slowdown in ChunkyPNG benchmarks in YJIT bench. This addresses the slowdown. Making the thread volatile speeds up the benchmark by 2 or 3% on my machine. ``` before: ruby 3.4.0dev (2024-07-02T18:48:43Z master b2b8306b46) [x86_64-linux] after: ruby 3.4.0dev (2024-07-02T20:07:44Z speed-chunkypng 418334dba9) [x86_64-linux] ---------- ----------- ---------- ---------- ---------- ------------- ------------ bench before (ms) stddev (%) after (ms) stddev (%) after 1st itr before/after chunky-png 1000.2 0.1 980.6 0.1 1.02 1.02 ---------- ----------- ---------- ---------- ---------- ------------- ------------ Legend: - after 1st itr: ratio of before/after time for the first benchmarking iteration. - before/after: ratio of before/after time. Higher is better for after. Above 1 represents a speedup. Output: ./data/output_015.csv ``` * Update thread.c Co-authored-by: Alan Wu <[email protected]> --------- Co-authored-by: Maxime Chevalier-Boisvert <[email protected]> Co-authored-by: Alan Wu <[email protected]> |
| |
| |