<feed xmlns='http://www.w3.org/2005/Atom'>
<title>ruby.git/internal/thread.h, branch v3_3_11</title>
<subtitle>The Ruby Programming Language</subtitle>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/'/>
<entry>
<title>Ensure fiber scheduler is woken up when close interrupts read</title>
<updated>2024-09-23T16:25:10+00:00</updated>
<author>
<name>KJ Tsanaktsidis</name>
<email>ktsanaktsidis@zendesk.com</email>
</author>
<published>2024-09-13T07:40:30+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=5b6009870dff883a8e71a05e60f175cea1d00d55'/>
<id>5b6009870dff883a8e71a05e60f175cea1d00d55</id>
<content type='text'>
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]
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
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]
</pre>
</div>
</content>
</entry>
<entry>
<title>declare `rb_thread_io_blocking_call`</title>
<updated>2023-12-19T22:00:41+00:00</updated>
<author>
<name>Koichi Sasada</name>
<email>ko1@atdot.net</email>
</author>
<published>2023-12-19T20:25:38+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=ec51a3c8183d555b6ccaa37834fac855ded3af88'/>
<id>ec51a3c8183d555b6ccaa37834fac855ded3af88</id>
<content type='text'>
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
</pre>
</div>
</content>
</entry>
<entry>
<title>M:N thread scheduler for Ractors</title>
<updated>2023-10-12T05:47:01+00:00</updated>
<author>
<name>Koichi Sasada</name>
<email>ko1@atdot.net</email>
</author>
<published>2023-04-10T01:53:13+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=be1bbd5b7d40ad863ab35097765d3754726bbd54'/>
<id>be1bbd5b7d40ad863ab35097765d3754726bbd54</id>
<content type='text'>
This patch introduce M:N thread scheduler for Ractor system.

In general, M:N thread scheduler employs N native threads (OS threads)
to manage M user-level threads (Ruby threads in this case).
On the Ruby interpreter, 1 native thread is provided for 1 Ractor
and all Ruby threads are managed by the native thread.

From Ruby 1.9, the interpreter uses 1:1 thread scheduler which means
1 Ruby thread has 1 native thread. M:N scheduler change this strategy.

Because of compatibility issue (and stableness issue of the implementation)
main Ractor doesn't use M:N scheduler on default. On the other words,
threads on the main Ractor will be managed with 1:1 thread scheduler.

There are additional settings by environment variables:

`RUBY_MN_THREADS=1` enables M:N thread scheduler on the main ractor.
Note that non-main ractors use the M:N scheduler without this
configuration. With this configuration, single ractor applications
run threads on M:1 thread scheduler (green threads, user-level threads).

`RUBY_MAX_CPU=n` specifies maximum number of native threads for
M:N scheduler (default: 8).

This patch will be reverted soon if non-easy issues are found.

[Bug #19842]
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
This patch introduce M:N thread scheduler for Ractor system.

In general, M:N thread scheduler employs N native threads (OS threads)
to manage M user-level threads (Ruby threads in this case).
On the Ruby interpreter, 1 native thread is provided for 1 Ractor
and all Ruby threads are managed by the native thread.

From Ruby 1.9, the interpreter uses 1:1 thread scheduler which means
1 Ruby thread has 1 native thread. M:N scheduler change this strategy.

Because of compatibility issue (and stableness issue of the implementation)
main Ractor doesn't use M:N scheduler on default. On the other words,
threads on the main Ractor will be managed with 1:1 thread scheduler.

There are additional settings by environment variables:

`RUBY_MN_THREADS=1` enables M:N thread scheduler on the main ractor.
Note that non-main ractors use the M:N scheduler without this
configuration. With this configuration, single ractor applications
run threads on M:1 thread scheduler (green threads, user-level threads).

`RUBY_MAX_CPU=n` specifies maximum number of native threads for
M:N scheduler (default: 8).

This patch will be reverted soon if non-easy issues are found.

[Bug #19842]
</pre>
</div>
</content>
</entry>
<entry>
<title>Use a real Ruby mutex in rb_io_close_wait_list (#7884)</title>
<updated>2023-06-01T08:37:18+00:00</updated>
<author>
<name>KJ Tsanaktsidis</name>
<email>ktsanaktsidis@zendesk.com</email>
</author>
<published>2023-06-01T08:37:18+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=edee9b6a12ac846d7b3de2d704e170bf28178cb3'/>
<id>edee9b6a12ac846d7b3de2d704e170bf28178cb3</id>
<content type='text'>
Because a thread calling IO#close now blocks in a native condvar wait,
it's possible for there to be _no_ threads left to actually handle
incoming signals/ubf calls/etc.

This manifested as failing tests on Solaris 10 (SPARC), because:

* One thread called IO#close, which sent a SIGVTALRM to the other
  thread to interrupt it, and then waited on the condvar to be notified
  that the reading thread was done.
* One thread was calling IO#read, but it hadn't yet reached the actual
  call to select(2) when the SIGVTALRM arrived, so it never unblocked
  itself.

This results in a deadlock.

The fix is to use a real Ruby mutex for the close lock; that way, the
closing thread goes into sigwait-sleep and can keep trying to interrupt
the select(2) thread.

See the discussion in: https://github.com/ruby/ruby/pull/7865/</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Because a thread calling IO#close now blocks in a native condvar wait,
it's possible for there to be _no_ threads left to actually handle
incoming signals/ubf calls/etc.

This manifested as failing tests on Solaris 10 (SPARC), because:

* One thread called IO#close, which sent a SIGVTALRM to the other
  thread to interrupt it, and then waited on the condvar to be notified
  that the reading thread was done.
* One thread was calling IO#read, but it hadn't yet reached the actual
  call to select(2) when the SIGVTALRM arrived, so it never unblocked
  itself.

This results in a deadlock.

The fix is to use a real Ruby mutex for the close lock; that way, the
closing thread goes into sigwait-sleep and can keep trying to interrupt
the select(2) thread.

See the discussion in: https://github.com/ruby/ruby/pull/7865/</pre>
</div>
</content>
</entry>
<entry>
<title>Fix busy-loop when waiting for file descriptors to close</title>
<updated>2023-05-26T05:51:23+00:00</updated>
<author>
<name>KJ Tsanaktsidis</name>
<email>kj@kjtsanaktsidis.id.au</email>
</author>
<published>2023-05-21T12:29:16+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=66871c5a06d723f8350935ced1e88d8cc929d809'/>
<id>66871c5a06d723f8350935ced1e88d8cc929d809</id>
<content type='text'>
When one thread is closing a file descriptor whilst another thread is
concurrently reading it, we need to wait for the reading thread to be
done with it to prevent a potential EBADF (or, worse, file descriptor
reuse).

At the moment, that is done by keeping a list of threads still using the
file descriptor in io_close_fptr. It then continually calls
rb_thread_schedule() in fptr_finalize_flush until said list is empty.

That busy-looping seems to behave rather poorly on some OS's,
particulary FreeBSD. It can cause the TestIO#test_race_gets_and_close
test to fail (even with its very long 200 second timeout) because the
closing thread starves out the using thread.

To fix that, I introduce the concept of struct rb_io_close_wait_list; a
list of threads still using a file descriptor that we want to close. We
call `rb_notify_fd_close` to let the thread scheduler know we're closing
a FD, which fills the list with threads. Then, we call
rb_notify_fd_close_wait which will block the thread until all of the
still-using threads are done.

This is implemented with a condition variable sleep, so no busy-looping
is required.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
When one thread is closing a file descriptor whilst another thread is
concurrently reading it, we need to wait for the reading thread to be
done with it to prevent a potential EBADF (or, worse, file descriptor
reuse).

At the moment, that is done by keeping a list of threads still using the
file descriptor in io_close_fptr. It then continually calls
rb_thread_schedule() in fptr_finalize_flush until said list is empty.

That busy-looping seems to behave rather poorly on some OS's,
particulary FreeBSD. It can cause the TestIO#test_race_gets_and_close
test to fail (even with its very long 200 second timeout) because the
closing thread starves out the using thread.

To fix that, I introduce the concept of struct rb_io_close_wait_list; a
list of threads still using a file descriptor that we want to close. We
call `rb_notify_fd_close` to let the thread scheduler know we're closing
a FD, which fills the list with threads. Then, we call
rb_notify_fd_close_wait which will block the thread until all of the
still-using threads are done.

This is implemented with a condition variable sleep, so no busy-looping
is required.
</pre>
</div>
</content>
</entry>
<entry>
<title>Add Fiber#kill, similar to Thread#kill. (#7823)</title>
<updated>2023-05-18T14:33:42+00:00</updated>
<author>
<name>Samuel Williams</name>
<email>samuel.williams@oriontransfer.co.nz</email>
</author>
<published>2023-05-18T14:33:42+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=2df5a697e2726a11f0441b13fb5c73dd549837c8'/>
<id>2df5a697e2726a11f0441b13fb5c73dd549837c8</id>
<content type='text'>
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
</pre>
</div>
</content>
</entry>
<entry>
<title>Move RB_VM_SAVE_MACHINE_CONTEXT to internal/thread.h</title>
<updated>2023-03-15T21:26:26+00:00</updated>
<author>
<name>Matt Valentine-House</name>
<email>matt@eightbitraptor.com</email>
</author>
<published>2023-03-08T10:45:59+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=4ae9c34a4e00d148f206affb3a65926bf3fe230f'/>
<id>4ae9c34a4e00d148f206affb3a65926bf3fe230f</id>
<content type='text'>
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
</pre>
</div>
</content>
</entry>
<entry>
<title>Stop exporting symbols for MJIT</title>
<updated>2023-03-07T05:59:23+00:00</updated>
<author>
<name>Takashi Kokubun</name>
<email>takashikkbn@gmail.com</email>
</author>
<published>2023-03-07T05:34:31+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=233ddfac541749a0da80ea27913dc1ef4ea700bb'/>
<id>233ddfac541749a0da80ea27913dc1ef4ea700bb</id>
<content type='text'>
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
</pre>
</div>
</content>
</entry>
<entry>
<title>Only emit circular dependency warning for owned thread shields</title>
<updated>2023-02-08T08:50:00+00:00</updated>
<author>
<name>Jean byroot Boussier</name>
<email>jean.boussier+github@shopify.com</email>
</author>
<published>2023-02-06T22:30:42+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=8ce2fb9bbbaea14737c84385b1573f743a30f773'/>
<id>8ce2fb9bbbaea14737c84385b1573f743a30f773</id>
<content type='text'>
[Bug #19415]

If multiple threads attemps to load the same file concurrently
it's not a circular dependency issue.

So we check that the existing ThreadShield is owner by the current
fiber before warning about circular dependencies.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
[Bug #19415]

If multiple threads attemps to load the same file concurrently
it's not a circular dependency issue.

So we check that the existing ThreadShield is owner by the current
fiber before warning about circular dependencies.
</pre>
</div>
</content>
</entry>
<entry>
<title>Revert "Only emit circular dependency warning for owned thread shields"</title>
<updated>2023-02-06T22:30:35+00:00</updated>
<author>
<name>Jean byroot Boussier</name>
<email>jean.boussier+github@shopify.com</email>
</author>
<published>2023-02-06T22:30:00+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=c19defd02665492de7147572714ebe692260c849'/>
<id>c19defd02665492de7147572714ebe692260c849</id>
<content type='text'>
This reverts commit fa49651e05a06512e18ccb2f54a7198c9ff579de.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
This reverts commit fa49651e05a06512e18ccb2f54a7198c9ff579de.
</pre>
</div>
</content>
</entry>
</feed>
