summaryrefslogtreecommitdiff
path: root/thread.c
AgeCommit message (Collapse)Author
6 days* adjust indentNobuyoshi Nakada
Notes: Merged: https://.com/ruby/ruby/pull/13634
9 daysFix blocking operation cancellation. (#13614)Samuel Williams
Expose `rb_thread_resolve_unblock_function` internally. Notes: Merged-By: ioquatix <[email protected]>
10 daysAdd a new_thread flag to rb_interrupt_execJohn Hawthorn
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
10 daysFree rb_native_thread memory at forkPeter Zhu
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
2025-06-06Fix `blocking_operation_wait` use-after-free bug.Samuel Williams
Notes: Merged: https://.com/ruby/ruby/pull/13437
2025-06-06`rb_io_blocking_operation_exit` should not execute with pending interrupts.Samuel Williams
Notes: Merged: https://.com/ruby/ruby/pull/13437
2025-06-06Handle spurious wakeups in `Thread#join`. (#13532)Samuel Williams
Notes: Merged-By: ioquatix <[email protected]>
2025-06-06[Bug #21400] Fix rb_bug() when killing current root fiber in non-main thread ↵Luke Gruber
(#13526) Fixes the following: ```ruby Thread.new { Fiber.current.kill }.join ``` Notes: Merged-By: ioquatix <[email protected]>
2025-06-04Suppress dangling pointer warning by gccNobuyoshi Nakada
`__has_warning` is clang, not gcc. Notes: Merged: https://.com/ruby/ruby/pull/13509
2025-06-02Fix compatibility with fiber schedulers that don't implement ↵Samuel Williams
`#fiber_interrupt`. (#13492) Notes: Merged-By: ioquatix <[email protected]>
2025-05-31`Ractor::Port`Koichi Sasada
* 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
2025-05-25Use RB_VM_LOCKINGNobuyoshi Nakada
Notes: Merged: https://.com/ruby/ruby/pull/13439
2025-05-23Fix warning on cygwinDaisuke Fujimura (fd0)
Notes: Merged: https://.com/ruby/ruby/pull/13425
2025-05-23Allow `IO#close` to interrupt IO operations on fibers using ↵Samuel Williams
`fiber_interrupt` hook. (#12839) Notes: Merged-By: ioquatix <[email protected]>
2025-05-20Use atomic load to read interrupt maskJohn Hawthorn
Notes: Merged: https://.com/ruby/ruby/pull/13357
2025-05-15Use atomics for system_working globalJohn Hawthorn
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
2025-05-15Force reset running time in timer interruptJohn Hawthorn
Co-authored-by: Ivo Anjo <[email protected]> Co-authored-by: Luke Gruber <[email protected]> Notes: Merged: https://.com/ruby/ruby/pull/12094
2025-05-15Align styles [ci skip]Nobuyoshi Nakada
2025-05-15Ensure that forked process do not see invalid blocking operations. (#13343)Samuel Williams
Notes: Merged-By: ioquatix <[email protected]>
2025-05-13Get ractor message passing working with > 1 thread sending/receiving values ↵Luke Gruber
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
2025-05-13Make `waiting_fd` behaviour per-IO. (#13127)Samuel Williams
- `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]>
2025-05-08Clean up Ractor cache after forkAaron Patterson
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
2025-04-19Fix style [ci skip]Nobuyoshi Nakada
2025-04-19Ensure `struct rb_io` is passed through to `thread.c`. (#13134)Samuel Williams
Notes: Merged-By: ioquatix <[email protected]>
2025-04-14Expose `ruby_thread_has_gvl_p`.Samuel Williams
Notes: Merged: https://.com/ruby/ruby/pull/11975
2025-04-09Fix coverage measurement for negative line numbersYusuke Endoh
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
2025-03-31Initialize ractor thgroup in `thread_do_start_proc`Jean Boussier
Followup: https://.com/ruby/ruby/pull/13013 Notes: Merged: https://.com/ruby/ruby/pull/13016
2025-03-31ractor: don't inherit the default thread groupJean Boussier
[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
2025-03-25Reset thread interrupt lock on forkJohn Hawthorn
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
2025-02-14[Bug #21127] Thread deadlock does not display backtraces (#12721)Masataka Pocke Kuwabara
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]>
2025-02-13[Feature #21116] Extract RJIT as a third-party gemNobuyoshi Nakada
Notes: Merged: https://.com/ruby/ruby/pull/12740
2025-01-30`prev_mn_schedulable` might be clobbered by `longjmp`Nobuyoshi Nakada
Notes: Merged: https://.com/ruby/ruby/pull/12676
2025-01-29[DOC] Fix wrong call-seq format (#12662)tomoya ishida
Notes: Merged-By: tompng <[email protected]>
2024-12-26Fix -Wsign-compare warning on mingwNobuyoshi Nakada
2024-12-18Check RUBY_THREAD_TIMESLICE valueNobuyoshi Nakada
Notes: Merged: https://.com/ruby/ruby/pull/12328
2024-12-12Add an environment variable for controlling the default Thread quantumAaron Patterson
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
2024-11-20Introduce `Fiber::Scheduler#blocking_operation_wait`. (#12016)Samuel Williams
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]>
2024-11-08introduce `rb_ec_check_ints()`Koichi Sasada
to avoid TLS issue with N:M threads. Notes: Merged: https://.com/ruby/ruby/pull/11142
2024-11-08`interrupt_exec`Koichi Sasada
introduce - rb_threadptr_interrupt_exec - rb_ractor_interrupt_exec to intercept the thread/ractor execution. Notes: Merged: https://.com/ruby/ruby/pull/11142
2024-11-07`ubf_th` appears to be unused. (#11994)Samuel Williams
Notes: Merged-By: ioquatix <[email protected]>
2024-11-06Revert "Introduce Fiber Scheduler `blocking_region` hook. (#11963)" (#12013)Samuel Williams
This reverts some of commit 87fb44dff6409a19d12052cf0fc07ba80a4c45ac. We will rename and propose a slightly different interface. Notes: Merged-By: ioquatix <[email protected]>
2024-11-02Fix the conditional macro name [ci skip]Nobuyoshi Nakada
`RUBY_VM_CRITICAL_SECTION` is not used anywhere.
2024-10-31Introduce Fiber Scheduler `blocking_region` hook. (#11963)Samuel Williams
Notes: Merged-By: ioquatix <[email protected]>
2024-09-17Ensure fiber scheduler is woken up when close interrupts readKJ Tsanaktsidis
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
2024-09-13Ignore -Wdangling-pointer in rb_gc_set_stack_endPeter Zhu
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; | ~~~~~~~~~~~~~^~~~~~~~~~~~
2024-09-09The Timeout::Error example no longer works consistentlyJP Camara
* 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
2024-07-06Raise a TypeError for Thread#thread_variable{?,_get} for non-symbolJeremy Evans
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]
2024-07-02Speed up chunkypng benchmark (#11087)Aaron Patterson
* 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]>
2024-06-01Suppress -Wclobbered warning for BLOCKING_REGIONNobuyoshi Nakada
2024-05-29Fix -Wclobbered warningsNobuyoshi Nakada