[#104481] [Ruby master Feature#18020] Introduce `IO::Buffer` for fiber scheduler. — samuel@...

Issue #18020 has been reported by ioquatix (Samuel Williams).

31 messages 2021/07/03

[#104492] [Ruby master Bug#18022] Spec errors for rbconfig/unicode_[emoji_]version_spec: Using Ruby 2.7 even when on Ruby 3.1 — duerst@...

Issue #18022 has been reported by duerst (Martin D=FCrst).

8 messages 2021/07/04

[#104552] [Ruby master Feature#18033] Time.new to parse a string — nobu@...

Issue #18033 has been reported by nobu (Nobuyoshi Nakada).

26 messages 2021/07/09

[#104560] [Ruby master Bug#18035] Introduce general module for immutable by default. — samuel@...

Issue #18035 has been reported by ioquatix (Samuel Williams).

41 messages 2021/07/09

[#104629] [Ruby master Misc#18039] DevelopersMeeting20210819Japan — mame@...

Issue #18039 has been reported by mame (Yusuke Endoh).

11 messages 2021/07/16

[#104643] [Ruby master Bug#18040] Why should `foo(1 if true)` be an error? — bughit.github@...

Issue #18040 has been reported by bughit (bug hit).

10 messages 2021/07/19

[#104665] [Ruby master Feature#18042] YARV code optimization — motoroller95@...

Issue #18042 has been reported by motoroller (Iskandar Gohar).

11 messages 2021/07/23

[#104692] [Ruby master Bug#18048] Thread#join can break with fiber scheduler unblock fails or blocks. — samuel@...

Issue #18048 has been reported by ioquatix (Samuel Williams).

10 messages 2021/07/27

[#104723] [Ruby master Bug#18054] No rule to make target 'thread_fd_close.c', needed by 'thread_fd_close.o' — duerst@...

Issue #18054 has been reported by duerst (Martin D=FCrst).

8 messages 2021/07/29

[ruby-core:104557] [Ruby master Feature#18020] Introduce `IO::Buffer` for fiber scheduler.

From: samuel@...
Date: 2021-07-09 07:01:58 UTC
List: ruby-core #104557
Issue #18020 has been updated by ioquatix (Samuel Williams).


Okay, the PR is ready for review: https://github.com/ruby/ruby/pull/4621

Here is how it's used:

- `uring.c`: https://github.com/socketry/event/blob/b40bb0b174aed4cc3fed0f0eaafdd73f2a6a6f4c/ext/event/backend/uring.c#L265-L365
- `epoll.c`: https://github.com/socketry/event/blob/b40bb0b174aed4cc3fed0f0eaafdd73f2a6a6f4c/ext/event/backend/epoll.c#L269-L414
- `kqueue.c` implementation largely the same as epoll.
- `select.rb`: https://github.com/socketry/event/blob/b40bb0b174aed4cc3fed0f0eaafdd73f2a6a6f4c/lib/event/backend/select.rb#L56-L101

In `io_uring` implementation, the data buffer is passed directly to the OS for zero-copy I/O.

A brief overview of the implementation:

- It provides a fast path from internal `IO` buffering to the fiber scheduler.
- It's primarily an object that represents a `(void*, size_t)` tuple.
- It can allocate it's own memory using `malloc`, `mmap` or `VirtualAlloc` (mainly for testing).
- It can also map `File` objects into memory (experimental).
- It provides some basic provisions for getting and setting data.
- It provides a locking mechanism to prevent incorrect usage while the buffer is being used by the OS/system.
- It provides mutable/immutable flag to validate correct usage when reading/writing.

Going forward, I would like to see a more elaborate model where we can read and write directly using these buffers. We want a fast path for binary protocols like DNS, HTTP/2 etc. This implementation of `get`/`set` is 4x faster than `String#unpack` in my limited testing.


----------------------------------------
Feature #18020: Introduce `IO::Buffer` for fiber scheduler.
https://bugs.ruby-lang.org/issues/18020#change-92836

* Author: ioquatix (Samuel Williams)
* Status: Open
* Priority: Normal
----------------------------------------
After continuing to build out the fiber scheduler interface and the specific hooks required for `io_uring`, I found some trouble within the implementation of `IO`.

I found that in some cases, we need to read into the `rb_io_buffer_t` struct directly. I tried creating a "fake string" in order to transit back into the Ruby fiber scheduler interface and this did work, but I was told we cannot expose fake string to Ruby code.

So, after this, and many other frustrations with using `String` as a IO buffer, I decided to implement a low level `IO::Buffer` based on my needs for high performance IO, and as part of the fiber scheduler interface. Going forward, this can form the basis of newer interfaces like `IO::Buffer#splice` and so on. We can also add support for `IO#read(n, buffer)` rather than string. This avoids many encoding and alignment issues.

While I'm less interested in the user facing interface at this time, I believe we can introduce it incrementally. Initially my focus is on the interface requirements for the fiber scheduler. Then, I'll look at how we can integrate it more into `IO` directly. The goal is to have this in place for Ruby 3.1.



-- 
https://bugs.ruby-lang.org/

Unsubscribe: <mailto:ruby-core-request@ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-core>

In This Thread