[#100689] [Ruby master Feature#17303] Make webrick to bundled gems or remove from stdlib — hsbt@...

Issue #17303 has been reported by hsbt (Hiroshi SHIBATA).

11 messages 2020/11/02

[#100715] [Ruby master Bug#17306] TestGCCompact#test_ast_compacts test failures — v.ondruch@...

Issue #17306 has been reported by vo.x (Vit Ondruch).

11 messages 2020/11/05

[#100720] [Ruby master Feature#17307] A way to mark C extensions as thread-safe, Ractor-safe, or unsafe — eregontp@...

Issue #17307 has been reported by Eregon (Benoit Daloze).

22 messages 2020/11/05

[#100744] [Ruby master Bug#17310] Closed ractors should die — marcandre-ruby-core@...

Issue #17310 has been reported by marcandre (Marc-Andre Lafortune).

12 messages 2020/11/08

[#100753] [Ruby master Feature#17312] New methods in Enumerable and Enumerator::Lazy: flatten, product, compact — zverok.offline@...

Issue #17312 has been reported by zverok (Victor Shepelev).

11 messages 2020/11/09

[#100763] [Ruby master Feature#17314] Provide a way to declare visibility of attributes defined by attr* methods in a single expression — radek.bulat@...

SXNzdWUgIzE3MzE0IGhhcyBiZWVuIHJlcG9ydGVkIGJ5IHJhZGFyZWsgKFJhZG9zxYJhdyBCdcWC

17 messages 2020/11/10

[#100777] [Ruby master Feature#17316] On memoization — sawadatsuyoshi@...

Issue #17316 has been reported by sawa (Tsuyoshi Sawada).

18 messages 2020/11/11

[#100788] [Ruby master Misc#17319] Rename Random::urandom to os_random and document random data sources — zofrex@...

Issue #17319 has been reported by zofrex (James Sanderson).

11 messages 2020/11/11

[#100807] [Ruby master Feature#17322] Deprecate `Random::DEFAULT` and introduce `Random.default()` method to provide Ractor-supported default random generator — ko1@...

Issue #17322 has been reported by ko1 (Koichi Sasada).

14 messages 2020/11/12

[#100816] [Ruby master Feature#17323] Ractor::LVar to provide ractor-local storage — ko1@...

Issue #17323 has been reported by ko1 (Koichi Sasada).

19 messages 2020/11/12

[#100849] [Ruby master Feature#17325] Adds Fiber#cancel, which forces a Fiber to break/return — nicholas.evans@...

Issue #17325 has been reported by nevans (Nicholas Evans).

17 messages 2020/11/14

[#100852] [Ruby master Feature#17326] Add Kernel#must! to the standard library — zimmerman.jake@...

SXNzdWUgIzE3MzI2IGhhcyBiZWVuIHJlcG9ydGVkIGJ5IGpleiAoSmFrZSBaaW1tZXJtYW4pLg0K

24 messages 2020/11/14

[#100858] [Ruby master Feature#17327] The Queue constructor should take an initial set of items — chris@...

Issue #17327 has been reported by chrisseaton (Chris Seaton).

10 messages 2020/11/15

[#100897] [Ruby master Feature#17330] Object#non — zverok.offline@...

Issue #17330 has been reported by zverok (Victor Shepelev).

21 messages 2020/11/17

[#100925] [Ruby master Feature#17331] Let Fiber#raise work with transferring fibers — nicholas.evans@...

Issue #17331 has been reported by nevans (Nicholas Evans).

12 messages 2020/11/18

[#100930] [Ruby master Feature#17333] Enumerable#many? — masafumi.o1988@...

Issue #17333 has been reported by okuramasafumi (Masafumi OKURA).

10 messages 2020/11/18

[#100971] [Ruby master Bug#17337] Don't embed Ruby build time configuration into Ruby — v.ondruch@...

Issue #17337 has been reported by vo.x (Vit Ondruch).

16 messages 2020/11/20

[#100999] [Ruby master Feature#17339] Semantic grouping on BigDecimal#to_s — co.chuma@...

Issue #17339 has been reported by chumaltd (Takahiro Chuma).

9 messages 2020/11/21

[#101071] [Ruby master Feature#17342] Hash#fetch_set — hunter_spawn@...

Issue #17342 has been reported by MaxLap (Maxime Lapointe).

26 messages 2020/11/25

[#101093] [Ruby master Misc#17346] DevelopersMeeting20201210Japan — mame@...

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

17 messages 2020/11/26

[#101141] [Ruby master Bug#17354] Module#const_source_location is misleading for constants awaiting autoload — tom@...

SXNzdWUgIzE3MzU0IGhhcyBiZWVuIHJlcG9ydGVkIGJ5IHRvbXN0dWFydCAoVG9tIFN0dWFydCku

21 messages 2020/11/29

[#101143] [Ruby master Feature#17355] Or-patterns (pattern matching like Foo(x) | Bar(x)) — fg@...

Issue #17355 has been reported by decuplet (Nikita Shilnikov).

8 messages 2020/11/29

[#101153] [Ruby master Feature#17356] Alignment of memory allocated through Fiddle struct's malloc — andrea.ribuoli@...

Issue #17356 has been reported by AndreaRibuoli (Andrea Ribuoli).

8 messages 2020/11/30

[ruby-core:100727] [Ruby master Feature#17307] A way to mark C extensions as thread-safe, Ractor-safe, or unsafe

From: eregontp@...
Date: 2020-11-06 12:34:57 UTC
List: ruby-core #100727
Issue #17307 has been updated by Eregon (Benoit Daloze).


@ko1 discussed with @matz and they concluded with this interface:
```c
Init_foo()
{
  RB_EXT_CONFIG({
    .ractor_safe = true,
    .thread_safe = true,
  });
  rb_define_method(mod, "foo", func, arity);
}
```

Sounds good to me.
Here is a sketch of an implementation, also with a "3rd variant" to check it's extensible if we need it in the future:

```c
#include <stdbool.h>
#include <stdio.h>
struct rb_ext_config {
  bool ractor_safe;
  bool thread_safe;
  bool third_variant_safe;
};
#define RB_EXT_CONFIG(...) \
  struct rb_ext_config config = __VA_ARGS__; \
  rb_ext_config(&config);
void rb_ext_config(struct rb_ext_config *config) {
  printf("ractor_safe: %d\n", config->ractor_safe);
  printf("thread_safe: %d\n", config->thread_safe);
  printf("third_variant_safe: %d\n", config->third_variant_safe);
}
int main(int argc, char const *argv[]) {
  RB_EXT_CONFIG({
    .ractor_safe = true,
    .thread_safe = true,
  });
  return 0;
}
```
outputs:
```
ractor_safe: 1
thread_safe: 1
third_variant_safe: 0
```

For backward compatibility, it will also be needed to wrap if in `#ifdef RB_EXT_CONFIG`, which seems fine.

However, this struct design means all implementations will have to define both the `ractor_safe` and `thread_safe` members,
otherwise it will fail to compile.

And if/when we would add a third member, then we would need some way to check if that member is declared, otherwise it wouldn't be backward compatible.
This seems to work, although I'm not sure if such usages of the preprocessor are well defined:
```c
  RB_EXT_CONFIG({
    .ractor_safe = true,
    .thread_safe = true,
#ifdef RB_EXT_CONFIG_VARIANT3
    .third_variant_safe = true,
#endif
  });
```

----------------------------------------
Feature #17307: A way to mark C extensions as thread-safe, Ractor-safe, or unsafe
https://bugs.ruby-lang.org/issues/17307#change-88370

* Author: Eregon (Benoit Daloze)
* Status: Open
* Priority: Normal
----------------------------------------
I would like to design a way to mark C extensions as thread-safe, Ractor-safe, or unsafe (= needs process-global lock).
By default, if not marked, C extensions would be treated as unsafe for compatibility.

Specifically, TruffleRuby supports C extensions, but for scalability it is important to run at least some of them in parallel (e.g., HTTP parsing in Puma).
This was notably mentioned in my [RubyKaigi talk](https://speakerdeck.com/eregon/running-rack-and-rails-faster-with-truffleruby?slide=17).
TruffleRuby defaults to acquire a global lock when executing C extension code for maximum compatibility (Ruby code OTOH can always run in parallel).
There is a command-line option for that lock and it can be disabled, but then it is disabled for all C extensions.
The important property for TruffleRuby is that the C extension does not need a global lock, i.e., that it synchronizes any mutable state in C that could be accessed by multiple threads, such as global C variables.
I believe many C extensions are already thread-safe, or can easily become thread-safe, because they do not rely on global state and do not share the RData objects between threads.

Ractor also needs a way to mark C extensions, to know if it's OK to use the C extension in multiple Ractors in parallel, and that the C extension will not leak non-shareable objects from one Ractor to another, which would lead to bugs & segfaults.
Otherwise, C extensions could only be used on the main/initial Ractor (or need to acquire a process-global lock whenever executing C extension code and ensure no non-shareable objects leak between Ractors), which would be a very big limitation (almost every non-trivial application depends on a C extension transitively).

In both cases, global state in the C extension needs synchronization.
In the thread-safe case, mutable state in C that could be accessed by multiple Ruby threads needs to be synchronized too (there might be no such state, e.g., if C extension objects are created per Thread).
In the Ractor case, the C extension must never pass an object from a Ractor to another, unless it is a shareable object.

What do you think would be a good way to "mark" C extensions?
Maybe defining a symbol in the C extension, similar to the `Init_foo` we have, like say `foo_is_thread_safe`/`foo_is_ractor_safe`?
A symbol including the C extension name seems best, to avoid any possible confusion when looking it up.

Maybe there are other ways to mark C extensions than defining symbols, that could still be read by the Ruby implementation reliably?

I used the term `C extensions` but of course it would apply to native extensions too (including C++/Rust/...).

cc @ko1



-- 
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