1173 Commits

Author SHA1 Message Date
Nobuyoshi Nakada
aad9fa2853
Use RB_VM_LOCKING 2025-05-25 15:22:43 +09:00
Daisuke Fujimura (fd0)
70f8f7c4b1 Fix warning on cygwin 2025-05-23 20:49:19 +09:00
Samuel Williams
73c9d6ccaa
Allow IO#close to interrupt IO operations on fibers using fiber_interrupt hook. (#12839) 2025-05-23 14:55:05 +09:00
John Hawthorn
05e0e7223a Use atomic load to read interrupt mask 2025-05-20 09:56:31 -07:00
John Hawthorn
d67d169aea Use atomics for system_working global
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).
2025-05-15 15:18:10 -07:00
John Hawthorn
d845da05e8 Force reset running time in timer interrupt
Co-authored-by: Ivo Anjo <ivo.anjo@datadoghq.com>
Co-authored-by: Luke Gruber <luke.gru@gmail.com>
2025-05-15 14:44:26 -07:00
Nobuyoshi Nakada
2e3f81838c
Align styles [ci skip] 2025-05-15 17:48:40 +09:00
Samuel Williams
87261c2d95
Ensure that forked process do not see invalid blocking operations. (#13343) 2025-05-15 15:50:15 +09:00
Luke Gruber
1d4822a175 Get ractor message passing working with > 1 thread sending/receiving values 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]
2025-05-13 13:23:57 -07:00
Samuel Williams
425fa0aeb5
Make waiting_fd behaviour per-IO. (#13127)
- `rb_thread_fd_close` is deprecated and now a no-op.
- IO operations (including close) no longer take a vm-wide lock.
2025-05-13 19:02:03 +09:00
Aaron Patterson
f7ff380998 Clean up Ractor cache after fork
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 <john@hawthorn.email>
2025-05-08 10:53:28 -07:00
Nobuyoshi Nakada
c218862d3c
Fix style [ci skip] 2025-04-19 22:02:10 +09:00
Samuel Williams
20a1c1dc6b
Ensure struct rb_io is passed through to thread.c. (#13134) 2025-04-19 09:55:16 +09:00
Samuel Williams
4e970c5d5a Expose ruby_thread_has_gvl_p. 2025-04-14 18:28:09 +09:00
Yusuke Endoh
0d6263bd41 Fix coverage measurement for negative line numbers
Fixes [Bug #21220]

Co-Authored-By: Mike Bourgeous <mike@mikebourgeous.com>
Co-Authored-By: Jean Boussier <jean.boussier@gmail.com>
2025-04-09 23:45:54 +09:00
Jean Boussier
532b9246d3 Initialize ractor thgroup in thread_do_start_proc
Followup: https://github.com/ruby/ruby/pull/13013
2025-03-31 11:14:34 +02:00
Jean Boussier
5e421ce8d9 ractor: don't inherit the default thread group
[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.
2025-03-31 10:25:52 +02:00
John Hawthorn
310c00a137 Reset thread interrupt lock on fork
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 <tenderlove@ruby-lang.org>
2025-03-25 19:14:26 -07:00
Masataka Pocke Kuwabara
0cab608d3a
[Bug #21127] Thread deadlock does not display backtraces (#12721)
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 <code@jeremyevans.net>
2025-02-14 16:31:58 +09:00
Nobuyoshi Nakada
4a67ef09cc
[Feature #21116] Extract RJIT as a third-party gem 2025-02-13 18:01:03 +09:00
Nobuyoshi Nakada
aca0b92c2f prev_mn_schedulable might be clobbered by longjmp 2025-01-30 18:19:53 +09:00
tomoya ishida
2d3d7a74e9
[DOC] Fix wrong call-seq format (#12662) 2025-01-29 21:53:00 +09:00
Nobuyoshi Nakada
9a5ad1b558
Fix -Wsign-compare warning on mingw 2024-12-26 18:21:05 +09:00
Nobuyoshi Nakada
57f6329ba7 Check RUBY_THREAD_TIMESLICE value 2024-12-18 11:12:34 +09:00
Aaron Patterson
fffef9aa5d Add an environment variable for controlling the default Thread quantum
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 <john@hawthorn.email>
2024-12-12 16:04:49 -08:00
Samuel Williams
9c268302bf
Introduce Fiber::Scheduler#blocking_operation_wait. (#12016)
Redirect `rb_nogvl` blocking operations to the fiber scheduler if possible
to prevent stalling the event loop.

[Feature #20876]
2024-11-20 19:40:17 +13:00
Koichi Sasada
97aaf6f760 introduce rb_ec_check_ints()
to avoid TLS issue with N:M threads.
2024-11-08 18:02:46 +09:00
Koichi Sasada
c8297c3eed interrupt_exec
introduce
- rb_threadptr_interrupt_exec
- rb_ractor_interrupt_exec

to intercept the thread/ractor execution.
2024-11-08 18:02:46 +09:00
Samuel Williams
048bb1e176
ubf_th appears to be unused. (#11994) 2024-11-07 02:28:47 +00:00
Samuel Williams
3b9896acfc
Revert "Introduce Fiber Scheduler blocking_region hook. (#11963)" (#12013)
This reverts some of commit 87fb44dff6409a19d12052cf0fc07ba80a4c45ac.

We will rename and propose a slightly different interface.
2024-11-06 22:19:40 +13:00
Nobuyoshi Nakada
24f7829abf
Fix the conditional macro name [ci skip]
`RUBY_VM_CRITICAL_SECTION` is not used anywhere.
2024-11-02 12:04:52 +09:00
Samuel Williams
87fb44dff6
Introduce Fiber Scheduler blocking_region hook. (#11963) 2024-10-31 17:26:37 +13:00
KJ Tsanaktsidis
e08d5239b6 Ensure fiber scheduler is woken up when close interrupts read
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 patch ensures that if the close happened in a fiber scheduled
thread, that the scheduler is notified that the fiber is unblocked.

[Bug #20723]
2024-09-17 10:11:44 +10:00
Peter Zhu
c996f4091f Ignore -Wdangling-pointer in rb_gc_set_stack_end
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-13 10:06:57 -04:00
JP Camara
b5f1291015 The Timeout::Error example no longer works consistently
* This PR from the timeout gem (https://github.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://github.com/ruby/timeout/issues/41
2024-09-09 09:10:06 +09:00
Jeremy Evans
7f1fe5f091 Raise a TypeError for Thread#thread_variable{?,_get} for non-symbol
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-06 12:07:32 +02:00
Aaron Patterson
d9487dd011
Speed up chunkypng benchmark (#11087)
* Speed up chunkypng benchmark

Since d037c5196a14c03e72746ccdf0437b5dd4f80a69 we're seeing a slowdown
in ChunkyPNG benchmarks in YJIT bench. This patch 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 <XrXr@users.noreply.github.com>

---------

Co-authored-by: Maxime Chevalier-Boisvert <maximechevalierb@gmail.com>
Co-authored-by: Alan Wu <XrXr@users.noreply.github.com>
2024-07-02 22:20:01 +00:00
Nobuyoshi Nakada
c05f60a600
Suppress -Wclobbered warning for BLOCKING_REGION 2024-06-01 16:25:12 +09:00
Nobuyoshi Nakada
da69c9235f
Fix -Wclobbered warnings 2024-05-29 17:38:26 +09:00
Nobuyoshi Nakada
d037c5196a
Suppress -Wclobbered warnings
At 7afc16aa48beb093b06eb978bc430f90dd771690, now `BLOCKING_REGION`
contains `setjmp` call in `RB_VM_SAVE_MACHINE_CONTEXT`.  By this
change, variables in blocks for this macro may be clobbered.
2024-05-20 01:30:49 +09:00
KJ Tsanaktsidis
7afc16aa48 Inline RB_VM_SAVE_MACHINE_CONTEXT into BLOCKING_REGION
There's an exhaustive explanation of this in the linked redmine bug, but
the short version is as follows:

blocking_region_begin can spill callee-saved registers to the stack for
its own use. That means they're not saved to ec->machine by the call to
setjmp, since by that point they're already on the stack and new,
different values are in the real registers. ec->machine's end-of-stack
pointer is also bumped to accomodate this, BUT, after
blocking_region_begin returns, that points past the end of the stack!

As far as C is concerned, that's fine; the callee-saved registers are
restored when blocking_region_begin returns. But, if another thread
triggers GC, it is relying on finding references to Ruby objects by
walking the stack region pointed to by ec->machine.

If the C code in exec; subsequently does things that use that stack
memory, then the value will be overwritten and the GC might prematurely
collect something it shouldn't.

[Bug #20493]
2024-05-19 12:08:35 +09:00
Jean Boussier
f06670c5a2 Eliminate usage of OBJ_FREEZE_RAW
Previously it would bypass the `FL_ABLE` check, but
since shapes introduction, it started having a different
behavior than `OBJ_FREEZE`, as it would onyl set the `FL_FREEZE`
flag, but not update the shape.

I have no indication of this causing a bug yet, but it seems
like a trap waiting to happen.
2024-04-16 17:20:35 +02:00
Samuel Williams
a7ff264477
Don't clear pending interrupts in the parent process. (#10365) 2024-03-27 10:10:07 +13:00
Takashi Kokubun
696b2716e0 Return stdbool from recursive_check()
The return value is used as a boolean value in C. Since it's not used as
a Ruby object, it just seems confusing that it returns a VALUE.
2024-03-26 11:33:02 -07:00
Takashi Kokubun
16cf9047c6 [DOC] Fix a couple other descriptions
similarly to 332f4938cf3adbff8f15b647767dc660583a5bef
2024-03-26 11:24:44 -07:00
Takashi Kokubun
332f4938cf [DOC] Fix a description about rb_exec_recursive_outer
It gives true/TRUE (int) instead of Qtrue (VALUE).
2024-03-26 11:21:32 -07:00
KJ Tsanaktsidis
48d3bdddba Move asan_fake_stack_handle to EC, not thread
It's really a property of the EC; each fiber (which has its own EC) also
has its own asan_fake_stack_handle.

[Bug #20310]
2024-03-25 14:57:04 +11:00
Nobuyoshi Nakada
e2a9b87126
rb_thread_sched_destroy is not used now at all 2024-03-22 18:53:44 +09:00
Nobuyoshi Nakada
127d7a35df
Some functions are not used when THREAD_MODEL=none 2024-03-22 18:20:13 +09:00
Nobuyoshi Nakada
28a2105a55
Prefer enum ruby_tag_type over int 2024-03-17 15:57:19 +09:00