<feed xmlns='http://www.w3.org/2005/Atom'>
<title>ruby.git/thread_win32.c, branch v3_4_9</title>
<subtitle>The Ruby Programming Language</subtitle>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/'/>
<entry>
<title>Proof of Concept: Allow to prevent fork from happening in known fork unsafe API</title>
<updated>2024-09-05T09:43:46+00:00</updated>
<author>
<name>Jean Boussier</name>
<email>jean.boussier@gmail.com</email>
</author>
<published>2024-05-29T14:46:04+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=63cbe3f6ac9feb44a2e43b1f853e2ca7e049316c'/>
<id>63cbe3f6ac9feb44a2e43b1f853e2ca7e049316c</id>
<content type='text'>
[Feature #20590]

For better of for worse, fork(2) remain the primary provider of
parallelism in Ruby programs. Even though it's frowned uppon in
many circles, and a lot of literature will simply state that only
async-signal safe APIs are safe to use after `fork()`, in practice
most APIs work well as long as you are careful about not forking
while another thread is holding a pthread mutex.

One of the APIs that is known cause fork safety issues is `getaddrinfo`.
If you fork while another thread is inside `getaddrinfo`, a mutex
may be left locked in the child, with no way to unlock it.

I think we could reduce the impact of these problem by preventing
in for the most notorious and common cases, by locking around
`fork(2)` and known unsafe APIs with a read-write lock.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
[Feature #20590]

For better of for worse, fork(2) remain the primary provider of
parallelism in Ruby programs. Even though it's frowned uppon in
many circles, and a lot of literature will simply state that only
async-signal safe APIs are safe to use after `fork()`, in practice
most APIs work well as long as you are careful about not forking
while another thread is holding a pthread mutex.

One of the APIs that is known cause fork safety issues is `getaddrinfo`.
If you fork while another thread is inside `getaddrinfo`, a mutex
may be left locked in the child, with no way to unlock it.

I think we could reduce the impact of these problem by preventing
in for the most notorious and common cases, by locking around
`fork(2)` and known unsafe APIs with a read-write lock.
</pre>
</div>
</content>
</entry>
<entry>
<title>Fix some warnings</title>
<updated>2024-08-16T05:51:21+00:00</updated>
<author>
<name>Raed Rizqie</name>
<email>raed.rizqie@gmail.com</email>
</author>
<published>2024-08-16T05:51:21+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=018bd07f07e43a5be8ed94cfbcaac3c742b30b0a'/>
<id>018bd07f07e43a5be8ed94cfbcaac3c742b30b0a</id>
<content type='text'>
* Fix unused functions when no `mmap`.

  ```
  shape.c:285:1: warning: unused function 'redblack_insert' [-Wunused-function]
    285 | redblack_insert(redblack_node_t * tree, ID key, rb_shape_t * value)
        | ^~~~~~~~~~~~~~~
  ```

* Fix unknown warning group '-Wmaybe-uninitialized' with clang.

  ```
  thread_win32.c:596:1: warning: unknown warning group '-Wmaybe-uninitialized', ignored [-Wunknown-warning-option]
    596 | COMPILER_WARNING_IGNORED(-Wmaybe-uninitialized)
        | ^
  ```

Co-authored-by: Nobuyoshi Nakada &lt;nobu.nakada@gmail.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
* Fix unused functions when no `mmap`.

  ```
  shape.c:285:1: warning: unused function 'redblack_insert' [-Wunused-function]
    285 | redblack_insert(redblack_node_t * tree, ID key, rb_shape_t * value)
        | ^~~~~~~~~~~~~~~
  ```

* Fix unknown warning group '-Wmaybe-uninitialized' with clang.

  ```
  thread_win32.c:596:1: warning: unknown warning group '-Wmaybe-uninitialized', ignored [-Wunknown-warning-option]
    596 | COMPILER_WARNING_IGNORED(-Wmaybe-uninitialized)
        | ^
  ```

Co-authored-by: Nobuyoshi Nakada &lt;nobu.nakada@gmail.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>`rb_thread_sched_destroy` is not used now at all</title>
<updated>2024-03-22T09:53:44+00:00</updated>
<author>
<name>Nobuyoshi Nakada</name>
<email>nobu@ruby-lang.org</email>
</author>
<published>2024-03-22T09:53:44+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=e2a9b87126d59e4766479a7aa12cf7a648f46506'/>
<id>e2a9b87126d59e4766479a7aa12cf7a648f46506</id>
<content type='text'>
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
</pre>
</div>
</content>
</entry>
<entry>
<title>`rb_thread_lock_native_thread()`</title>
<updated>2024-02-21T06:38:29+00:00</updated>
<author>
<name>Koichi Sasada</name>
<email>ko1@atdot.net</email>
</author>
<published>2024-02-20T10:09:23+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=d578684989fd2d75f086a259719e3eb0fe57ccb2'/>
<id>d578684989fd2d75f086a259719e3eb0fe57ccb2</id>
<content type='text'>
Introduce `rb_thread_lock_native_thread()` to allocate dedicated
native thread to the current Ruby thread for M:N threads.
This C API is similar to Go's `runtime.LockOSThread()`.

Accepted at https://github.com/ruby/dev-meeting-log/blob/master/2023/DevMeeting-2023-08-24.md
(and missed to implement on Ruby 3.3.0)
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Introduce `rb_thread_lock_native_thread()` to allocate dedicated
native thread to the current Ruby thread for M:N threads.
This C API is similar to Go's `runtime.LockOSThread()`.

Accepted at https://github.com/ruby/dev-meeting-log/blob/master/2023/DevMeeting-2023-08-24.md
(and missed to implement on Ruby 3.3.0)
</pre>
</div>
</content>
</entry>
<entry>
<title>Make stack bounds detection work with ASAN</title>
<updated>2024-01-18T22:55:12+00:00</updated>
<author>
<name>KJ Tsanaktsidis</name>
<email>kj@kjtsanaktsidis.id.au</email>
</author>
<published>2023-11-12T02:34:43+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=cabdaebc701217049d8a6457c5100f23910f4423'/>
<id>cabdaebc701217049d8a6457c5100f23910f4423</id>
<content type='text'>
Where a local variable is used as part of the stack bounds detection, it
has to actually be on the stack. ASAN can put local variable on "fake
stacks", however, with addresses in different memory mappings. This
completely destroys the stack bounds calculation, and can lead to e.g.
things not getting GC marked on the machine stack or stackoverflow
checks that always fail.

The __asan_addr_is_in_fake_stack helper can be used to get the _real_
stack address of such variables, and thus perform the stack size
calculation properly

[Bug #20001]
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Where a local variable is used as part of the stack bounds detection, it
has to actually be on the stack. ASAN can put local variable on "fake
stacks", however, with addresses in different memory mappings. This
completely destroys the stack bounds calculation, and can lead to e.g.
things not getting GC marked on the machine stack or stackoverflow
checks that always fail.

The __asan_addr_is_in_fake_stack helper can be used to get the _real_
stack address of such variables, and thus perform the stack size
calculation properly

[Bug #20001]
</pre>
</div>
</content>
</entry>
<entry>
<title>Pass down "stack start" variables from closer to the top of the stack</title>
<updated>2024-01-18T22:55:12+00:00</updated>
<author>
<name>KJ Tsanaktsidis</name>
<email>kj@kjtsanaktsidis.id.au</email>
</author>
<published>2023-11-12T02:24:55+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=807714447ef02c77bb0e17fe27d96ee2692264f8'/>
<id>807714447ef02c77bb0e17fe27d96ee2692264f8</id>
<content type='text'>
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-&gt;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-&gt;ec-&gt;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-&gt;ec-&gt;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
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
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-&gt;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-&gt;ec-&gt;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-&gt;ec-&gt;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
</pre>
</div>
</content>
</entry>
<entry>
<title>Revert "Pass down "stack start" variables from closer to the top of the stack"</title>
<updated>2024-01-12T06:58:54+00:00</updated>
<author>
<name>KJ Tsanaktsidis</name>
<email>kj@kjtsanaktsidis.id.au</email>
</author>
<published>2024-01-12T06:32:16+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=396e94666ba1646cb0fd1459eeae3f2e7ddd2658'/>
<id>396e94666ba1646cb0fd1459eeae3f2e7ddd2658</id>
<content type='text'>
This reverts commit 4ba8f0dc993953d3ddda6328e3ef17a2fc2cbde5.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
This reverts commit 4ba8f0dc993953d3ddda6328e3ef17a2fc2cbde5.
</pre>
</div>
</content>
</entry>
<entry>
<title>Revert "Make stack bounds detection work with ASAN"</title>
<updated>2024-01-12T06:58:54+00:00</updated>
<author>
<name>KJ Tsanaktsidis</name>
<email>kj@kjtsanaktsidis.id.au</email>
</author>
<published>2024-01-12T06:32:16+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=6af0f442c7d16ab526c0e6859aa97ff217b73f99'/>
<id>6af0f442c7d16ab526c0e6859aa97ff217b73f99</id>
<content type='text'>
This reverts commit 6185cfdf38e26026c6d38220eeca48689e54cdcf.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
This reverts commit 6185cfdf38e26026c6d38220eeca48689e54cdcf.
</pre>
</div>
</content>
</entry>
<entry>
<title>Make stack bounds detection work with ASAN</title>
<updated>2024-01-12T06:29:48+00:00</updated>
<author>
<name>KJ Tsanaktsidis</name>
<email>kj@kjtsanaktsidis.id.au</email>
</author>
<published>2023-11-12T02:34:43+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=6185cfdf38e26026c6d38220eeca48689e54cdcf'/>
<id>6185cfdf38e26026c6d38220eeca48689e54cdcf</id>
<content type='text'>
Where a local variable is used as part of the stack bounds detection, it
has to actually be on the stack. ASAN can put local variable on "fake
stacks", however, with addresses in different memory mappings. This
completely destroys the stack bounds calculation, and can lead to e.g.
things not getting GC marked on the machine stack or stackoverflow
checks that always fail.

The __asan_addr_is_in_fake_stack helper can be used to get the _real_
stack address of such variables, and thus perform the stack size
calculation properly

[Bug #20001]
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Where a local variable is used as part of the stack bounds detection, it
has to actually be on the stack. ASAN can put local variable on "fake
stacks", however, with addresses in different memory mappings. This
completely destroys the stack bounds calculation, and can lead to e.g.
things not getting GC marked on the machine stack or stackoverflow
checks that always fail.

The __asan_addr_is_in_fake_stack helper can be used to get the _real_
stack address of such variables, and thus perform the stack size
calculation properly

[Bug #20001]
</pre>
</div>
</content>
</entry>
<entry>
<title>Pass down "stack start" variables from closer to the top of the stack</title>
<updated>2024-01-12T06:29:48+00:00</updated>
<author>
<name>KJ Tsanaktsidis</name>
<email>kj@kjtsanaktsidis.id.au</email>
</author>
<published>2023-11-12T02:24:55+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=4ba8f0dc993953d3ddda6328e3ef17a2fc2cbde5'/>
<id>4ba8f0dc993953d3ddda6328e3ef17a2fc2cbde5</id>
<content type='text'>
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]
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
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]
</pre>
</div>
</content>
</entry>
</feed>
