aboutsummaryrefslogtreecommitdiffstats
path: root/memory_view.c
diff options
context:
space:
mode:
authorKenta Murata <mrkn@users.noreply.github.com>2020-12-16 13:43:56 +0900
committerGitHub <noreply@github.com>2020-12-16 13:43:56 +0900
commit1bafb3cb47649037cc93fec97503c18a864e3983 (patch)
tree8ba0b9c561ec84a0eff76c816b9f6cf8a038e1a8 /memory_view.c
parent1e11c12a066036e85177104a9f8f5469063858a7 (diff)
downloadruby-1bafb3cb47649037cc93fec97503c18a864e3983.tar.gz
[memory_view] Make MemoryView API Ractor-safe (#3911)
* memory_view.c: make Ractor-safe * test/ruby/test_memory_view.rb: Add test_ractor * memory_view: fix typo * memory_view.c: Use st_update in unregster_exported_object * memory_view: update dependency
Diffstat (limited to 'memory_view.c')
-rw-r--r--memory_view.c97
1 files changed, 42 insertions, 55 deletions
diff --git a/memory_view.c b/memory_view.c
index 5d6ef14b3a..7a2a518647 100644
--- a/memory_view.c
+++ b/memory_view.c
@@ -11,6 +11,7 @@
#include "internal/variable.h"
#include "internal/util.h"
#include "ruby/memory_view.h"
+#include "vm_sync.h"
#if SIZEOF_INTPTR_T == SIZEOF_LONG_LONG
# define INTPTR2NUM LL2NUM
@@ -30,6 +31,7 @@
// Exported Object Registry
+static st_table *exported_object_table = NULL;
VALUE rb_memory_view_exported_object_registry = Qundef;
static int
@@ -42,16 +44,18 @@ exported_object_registry_mark_key_i(st_data_t key, st_data_t value, st_data_t da
static void
exported_object_registry_mark(void *ptr)
{
- st_table *table = ptr;
- st_foreach(table, exported_object_registry_mark_key_i, 0);
+ // Don't use RB_VM_LOCK_ENTER here. It is unnecessary during GC.
+ st_foreach(exported_object_table, exported_object_registry_mark_key_i, 0);
}
static void
exported_object_registry_free(void *ptr)
{
- st_table *table = ptr;
- st_clear(table);
- st_free_table(table);
+ // Note that calling RB_VM_LOCK_ENTER here is unnecessary now.
+ // But it may be changed in the future.
+ st_clear(exported_object_table);
+ st_free_table(exported_object_table);
+ exported_object_table = NULL;
}
const rb_data_type_t rb_memory_view_exported_object_registry_data_type = {
@@ -64,33 +68,11 @@ const rb_data_type_t rb_memory_view_exported_object_registry_data_type = {
0, 0, RUBY_TYPED_FREE_IMMEDIATELY
};
-static void
-init_exported_object_registry(void)
-{
- if (rb_memory_view_exported_object_registry != Qundef) {
- return;
- }
-
- st_table *table = rb_init_identtable();
- VALUE obj = TypedData_Wrap_Struct(
- 0, &rb_memory_view_exported_object_registry_data_type, table);
- rb_gc_register_mark_object(obj);
- rb_memory_view_exported_object_registry = obj;
-}
-
-static inline st_table *
-get_exported_object_table(void)
-{
- st_table *table;
- TypedData_Get_Struct(rb_memory_view_exported_object_registry, st_table,
- &rb_memory_view_exported_object_registry_data_type,
- table);
- return table;
-}
-
static int
-update_exported_object_ref_count(st_data_t *key, st_data_t *val, st_data_t arg, int existing)
+exported_object_add_ref(st_data_t *key, st_data_t *val, st_data_t arg, int existing)
{
+ ASSERT_vm_locking();
+
if (existing) {
*val += 1;
}
@@ -100,39 +82,34 @@ update_exported_object_ref_count(st_data_t *key, st_data_t *val, st_data_t arg,
return ST_CONTINUE;
}
-static void
-register_exported_object(VALUE obj)
+static int
+exported_object_dec_ref(st_data_t *key, st_data_t *val, st_data_t arg, int existing)
{
- if (rb_memory_view_exported_object_registry == Qundef) {
- init_exported_object_registry();
- }
+ ASSERT_vm_locking();
- st_table *table = get_exported_object_table();
+ if (existing) {
+ *val -= 1;
+ if (*val == 0) {
+ return ST_DELETE;
+ }
+ }
+ return ST_CONTINUE;
+}
- st_update(table, (st_data_t)obj, update_exported_object_ref_count, 0);
+static void
+register_exported_object(VALUE obj)
+{
+ RB_VM_LOCK_ENTER();
+ st_update(exported_object_table, (st_data_t)obj, exported_object_add_ref, 0);
+ RB_VM_LOCK_LEAVE();
}
static void
unregister_exported_object(VALUE obj)
{
- if (rb_memory_view_exported_object_registry == Qundef) {
- return;
- }
-
- st_table *table = get_exported_object_table();
-
- st_data_t count;
- if (!st_lookup(table, (st_data_t)obj, &count)) {
- return;
- }
-
- if (--count == 0) {
- st_data_t key = (st_data_t)obj;
- st_delete(table, &key, &count);
- }
- else {
- st_insert(table, (st_data_t)obj, count);
- }
+ RB_VM_LOCK_ENTER();
+ st_update(exported_object_table, (st_data_t)obj, exported_object_dec_ref, 0);
+ RB_VM_LOCK_LEAVE();
}
// MemoryView
@@ -876,5 +853,15 @@ rb_memory_view_release(rb_memory_view_t* view)
void
Init_MemoryView(void)
{
+ exported_object_table = rb_init_identtable();
+
+ // exported_object_table is referred through rb_memory_view_exported_object_registry
+ // in -test-/memory_view extension.
+ VALUE obj = TypedData_Wrap_Struct(
+ 0, &rb_memory_view_exported_object_registry_data_type,
+ exported_object_table);
+ rb_gc_register_mark_object(obj);
+ rb_memory_view_exported_object_registry = obj;
+
id_memory_view = rb_intern_const("__memory_view__");
}