Age | Commit message (Collapse) | Author |
---|
| |
| Notes: Merged-By: ioquatix <samuel@codeotaku.com> |
| Notes: Merged: https://github.com/ruby/ruby/pull/11975 |
| Fixes [Bug #21220] Co-Authored-By: Mike Bourgeous <mike@mikebourgeous.com> Co-Authored-By: Jean Boussier <jean.boussier@gmail.com> Notes: Merged: https://github.com/ruby/ruby/pull/13089 |
| Followup: https://github.com/ruby/ruby/pull/13013 Notes: Merged: https://github.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://github.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 <tenderlove@ruby-lang.org> Notes: Merged: https://github.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 <code@jeremyevans.net> Notes: Merged-By: pocke <p.ck.t22@gmail.com> |
| Notes: Merged: https://github.com/ruby/ruby/pull/12740 |
| Notes: Merged: https://github.com/ruby/ruby/pull/12676 |
| Notes: Merged-By: tompng <tomoyapenguin@gmail.com> |
| |
| Notes: Merged: https://github.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 <john@hawthorn.email> Notes: Merged: https://github.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 <samuel@codeotaku.com> |
| to avoid TLS issue with N:M threads. Notes: Merged: https://github.com/ruby/ruby/pull/11142 |
| introduce - rb_threadptr_interrupt_exec - rb_ractor_interrupt_exec to intercept the thread/ractor execution. Notes: Merged: https://github.com/ruby/ruby/pull/11142 |
| Notes: Merged-By: ioquatix <samuel@codeotaku.com> |
| This reverts some of commit 87fb44dff6409a19d12052cf0fc07ba80a4c45ac. We will rename and propose a slightly different interface. Notes: Merged-By: ioquatix <samuel@codeotaku.com> |
| `RUBY_VM_CRITICAL_SECTION` is not used anywhere. |
| Notes: Merged-By: ioquatix <samuel@codeotaku.com> |
| 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] Notes: Merged: https://github.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://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 Notes: Merged: https://github.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 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> |
| |
| |
| 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. |
| 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] |
| 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. |
| |
| 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. |
| similarly to 332f4938cf3adbff8f15b647767dc660583a5bef |
| It gives true/TRUE (int) instead of Qtrue (VALUE). |
| 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] |
| |
| |
| |
| |
| |
| [Feature #16495] |
| |
| ASAN leaves a pointer to the fake frame on the stack; we can use the __asan_addr_is_in_fake_stack API to work out the extent of the fake stack and thus mark any VALUEs contained therein. [Bug #20001] |
| This commit changes how stack extents are calculated for both the main thread and other threads. Ruby uses the address of a local variable as part of the calculation for machine stack extents: * pthreads uses it as a lower-bound on the start of the stack, because glibc (and maybe other libcs) can store its own data on the stack before calling into user code on thread creation. * win32 uses it as an argument to VirtualQuery, which gets the extent of the memory mapping which contains the variable However, the local being used for this is actually too low (too close to the leaf function call) in both the main thread case and the new thread case. In the main thread case, we have the `INIT_STACK` macro, which is used for pthreads to set the `native_main_thread->stack_start` value. This value is correctly captured at the very top level of the program (in main.c). However, this is _not_ what's used to set the execution context machine stack (`th->ec->machine_stack.stack_start`); that gets set as part of a call to `ruby_thread_init_stack` in `Init_BareVM`, using the address of a local variable allocated _inside_ `Init_BareVM`. This is too low; we need to use a local allocated closer to the top of the program. In the new thread case, the lolcal is allocated inside `native_thread_init_stack`, which is, again, too low. In both cases, this means that we might have VALUEs lying outside the bounds of `th->ec->machine.stack_{start,end}`, which won't be marked correctly by the GC machinery. To fix this, * In the main thread case: We already have `INIT_STACK` at the right level, so just pass that local var to `ruby_thread_init_stack`. * In the new thread case: Allocate the local one level above the call to `native_thread_init_stack` in `call_thread_start_func2`. [Bug #20001] fix |
| This reverts commit 4ba8f0dc993953d3ddda6328e3ef17a2fc2cbde5. |
| This reverts commit d10bc3a2b8300cffc383e10c3730871e851be24c. |
| ASAN leaves a pointer to the fake frame on the stack; we can use the __asan_addr_is_in_fake_stack API to work out the extent of the fake stack and thus mark any VALUEs contained therein. [Bug #20001] |
| The implementation of `native_thread_init_stack` for the various threading models can use the address of a local variable as part of the calculation of the machine stack extents: * pthreads uses it as a lower-bound on the start of the stack, because glibc (and maybe other libcs) can store its own data on the stack before calling into user code on thread creation. * win32 uses it as an argument to VirtualQuery, which gets the extent of the memory mapping which contains the variable However, the local being used for this is actually allocated _inside_ the `native_thread_init_stack` frame; that means the caller might allocate a VALUE on the stack that actually lies outside the bounds stored in machine.stack_{start,end}. A local variable from one level above the topmost frame that stores VALUEs on the stack must be drilled down into the call to `native_thread_init_stack` to be used in the calculation. This probably doesn't _really_ matter for the win32 case (they'll be in the same memory mapping so VirtualQuery should return the same thing), but definitely could matter for the pthreads case. [Bug #20001] |
| `rb_thread_wait_for_single_fd(fd)` waits until `fd` is ready. Without MN it shouldn't use `thread_io_wait_events()` for the retry checking (alwasy false if MN is not active). |