summaryrefslogtreecommitdiff
path: root/ext/-test-/memory_view
diff options
context:
space:
mode:
Diffstat (limited to 'ext/-test-/memory_view')
-rw-r--r--ext/-test-/memory_view/depend8
-rw-r--r--ext/-test-/memory_view/extconf.rb2
-rw-r--r--ext/-test-/memory_view/memory_view.c237
3 files changed, 150 insertions, 97 deletions
diff --git a/ext/-test-/memory_view/depend b/ext/-test-/memory_view/depend
index bcbd98d41f..a6ffd76f45 100644
--- a/ext/-test-/memory_view/depend
+++ b/ext/-test-/memory_view/depend
@@ -7,7 +7,6 @@ memory_view.o: $(hdrdir)/ruby/backward.h
memory_view.o: $(hdrdir)/ruby/backward/2/assume.h
memory_view.o: $(hdrdir)/ruby/backward/2/attributes.h
memory_view.o: $(hdrdir)/ruby/backward/2/bool.h
-memory_view.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
memory_view.o: $(hdrdir)/ruby/backward/2/inttypes.h
memory_view.o: $(hdrdir)/ruby/backward/2/limits.h
memory_view.o: $(hdrdir)/ruby/backward/2/long_long.h
@@ -15,6 +14,7 @@ memory_view.o: $(hdrdir)/ruby/backward/2/stdalign.h
memory_view.o: $(hdrdir)/ruby/backward/2/stdarg.h
memory_view.o: $(hdrdir)/ruby/defines.h
memory_view.o: $(hdrdir)/ruby/intern.h
+memory_view.o: $(hdrdir)/ruby/internal/abi.h
memory_view.o: $(hdrdir)/ruby/internal/anyargs.h
memory_view.o: $(hdrdir)/ruby/internal/arithmetic.h
memory_view.o: $(hdrdir)/ruby/internal/arithmetic/char.h
@@ -52,6 +52,7 @@ memory_view.o: $(hdrdir)/ruby/internal/attr/noexcept.h
memory_view.o: $(hdrdir)/ruby/internal/attr/noinline.h
memory_view.o: $(hdrdir)/ruby/internal/attr/nonnull.h
memory_view.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+memory_view.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
memory_view.o: $(hdrdir)/ruby/internal/attr/pure.h
memory_view.o: $(hdrdir)/ruby/internal/attr/restrict.h
memory_view.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -111,7 +112,6 @@ memory_view.o: $(hdrdir)/ruby/internal/intern/enumerator.h
memory_view.o: $(hdrdir)/ruby/internal/intern/error.h
memory_view.o: $(hdrdir)/ruby/internal/intern/eval.h
memory_view.o: $(hdrdir)/ruby/internal/intern/file.h
-memory_view.o: $(hdrdir)/ruby/internal/intern/gc.h
memory_view.o: $(hdrdir)/ruby/internal/intern/hash.h
memory_view.o: $(hdrdir)/ruby/internal/intern/io.h
memory_view.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -128,6 +128,7 @@ memory_view.o: $(hdrdir)/ruby/internal/intern/re.h
memory_view.o: $(hdrdir)/ruby/internal/intern/ruby.h
memory_view.o: $(hdrdir)/ruby/internal/intern/select.h
memory_view.o: $(hdrdir)/ruby/internal/intern/select/largesize.h
+memory_view.o: $(hdrdir)/ruby/internal/intern/set.h
memory_view.o: $(hdrdir)/ruby/internal/intern/signal.h
memory_view.o: $(hdrdir)/ruby/internal/intern/sprintf.h
memory_view.o: $(hdrdir)/ruby/internal/intern/string.h
@@ -142,14 +143,13 @@ memory_view.o: $(hdrdir)/ruby/internal/memory.h
memory_view.o: $(hdrdir)/ruby/internal/method.h
memory_view.o: $(hdrdir)/ruby/internal/module.h
memory_view.o: $(hdrdir)/ruby/internal/newobj.h
-memory_view.o: $(hdrdir)/ruby/internal/rgengc.h
memory_view.o: $(hdrdir)/ruby/internal/scan_args.h
memory_view.o: $(hdrdir)/ruby/internal/special_consts.h
memory_view.o: $(hdrdir)/ruby/internal/static_assert.h
memory_view.o: $(hdrdir)/ruby/internal/stdalign.h
memory_view.o: $(hdrdir)/ruby/internal/stdbool.h
+memory_view.o: $(hdrdir)/ruby/internal/stdckdint.h
memory_view.o: $(hdrdir)/ruby/internal/symbol.h
-memory_view.o: $(hdrdir)/ruby/internal/token_paste.h
memory_view.o: $(hdrdir)/ruby/internal/value.h
memory_view.o: $(hdrdir)/ruby/internal/value_type.h
memory_view.o: $(hdrdir)/ruby/internal/variable.h
diff --git a/ext/-test-/memory_view/extconf.rb b/ext/-test-/memory_view/extconf.rb
index d786b15db9..123b80b8d0 100644
--- a/ext/-test-/memory_view/extconf.rb
+++ b/ext/-test-/memory_view/extconf.rb
@@ -1,3 +1,5 @@
# frozen_string_literal: false
+require "mkmf"
+
require_relative "../auto_ext.rb"
auto_ext(inc: true)
diff --git a/ext/-test-/memory_view/memory_view.c b/ext/-test-/memory_view/memory_view.c
index a59e7b872b..63f0beb81e 100644
--- a/ext/-test-/memory_view/memory_view.c
+++ b/ext/-test-/memory_view/memory_view.c
@@ -1,4 +1,6 @@
#include "ruby.h"
+
+#ifdef HAVE_RUBY_MEMORY_VIEW_H
#include "ruby/memory_view.h"
#define STRUCT_ALIGNOF(T, result) do { \
@@ -12,7 +14,7 @@ static VALUE sym_offset;
static VALUE sym_size;
static VALUE sym_repeat;
static VALUE sym_obj;
-static VALUE sym_len;
+static VALUE sym_byte_size;
static VALUE sym_readonly;
static VALUE sym_format;
static VALUE sym_item_size;
@@ -24,48 +26,24 @@ static VALUE sym_endianness;
static VALUE sym_little_endian;
static VALUE sym_big_endian;
-static VALUE exported_objects;
-
-static int
+static bool
exportable_string_get_memory_view(VALUE obj, rb_memory_view_t *view, int flags)
{
VALUE str = rb_ivar_get(obj, id_str);
rb_memory_view_init_as_byte_array(view, obj, RSTRING_PTR(str), RSTRING_LEN(str), true);
-
- VALUE count = rb_hash_lookup2(exported_objects, obj, INT2FIX(0));
- count = rb_funcall(count, '+', 1, INT2FIX(1));
- rb_hash_aset(exported_objects, obj, count);
-
- return 1;
-}
-
-static int
-exportable_string_release_memory_view(VALUE obj, rb_memory_view_t *view)
-{
- VALUE count = rb_hash_lookup2(exported_objects, obj, INT2FIX(0));
- if (INT2FIX(1) == count) {
- rb_hash_delete(exported_objects, obj);
- }
- else if (INT2FIX(0) == count) {
- rb_raise(rb_eRuntimeError, "Duplicated releasing of a memory view has been occurred for %"PRIsVALUE, obj);
- }
- else {
- count = rb_funcall(count, '-', 1, INT2FIX(1));
- rb_hash_aset(exported_objects, obj, count);
- }
-
- return 1;
+ return true;
}
-static int
+static bool
exportable_string_memory_view_available_p(VALUE obj)
{
- return Qtrue;
+ VALUE str = rb_ivar_get(obj, id_str);
+ return !NIL_P(str);
}
static const rb_memory_view_entry_t exportable_string_memory_view_entry = {
exportable_string_get_memory_view,
- exportable_string_release_memory_view,
+ NULL,
exportable_string_memory_view_available_p
};
@@ -104,15 +82,15 @@ memory_view_parse_item_format(VALUE mod, VALUE format)
const char *err = NULL;
rb_memory_view_item_component_t *members;
- ssize_t n_members;
+ size_t n_members;
ssize_t item_size = rb_memory_view_parse_item_format(c_str, &members, &n_members, &err);
VALUE result = rb_ary_new_capa(3);
rb_ary_push(result, SSIZET2NUM(item_size));
if (!err) {
- VALUE ary = rb_ary_new_capa(n_members);
- ssize_t i;
+ VALUE ary = rb_ary_new_capa((long)n_members);
+ size_t i;
for (i = 0; i < n_members; ++i) {
VALUE member = rb_hash_new();
rb_hash_aset(member, sym_format, rb_str_new(&members[i].format, 1));
@@ -146,7 +124,7 @@ memory_view_get_memory_view_info(VALUE mod, VALUE obj)
VALUE hash = rb_hash_new();
rb_hash_aset(hash, sym_obj, view.obj);
- rb_hash_aset(hash, sym_len, SSIZET2NUM(view.len));
+ rb_hash_aset(hash, sym_byte_size, SSIZET2NUM(view.byte_size));
rb_hash_aset(hash, sym_readonly, view.readonly ? Qtrue : Qfalse);
rb_hash_aset(hash, sym_format, view.format ? rb_str_new_cstr(view.format) : Qnil);
rb_hash_aset(hash, sym_item_size, SSIZET2NUM(view.item_size));
@@ -207,28 +185,103 @@ memory_view_fill_contiguous_strides(VALUE mod, VALUE ndim_v, VALUE item_size_v,
}
static VALUE
+memory_view_get_ref_count(VALUE obj)
+{
+ if (rb_memory_view_exported_object_registry == Qundef) {
+ return Qnil;
+ }
+
+ st_table *table;
+ TypedData_Get_Struct(rb_memory_view_exported_object_registry, st_table,
+ &rb_memory_view_exported_object_registry_data_type,
+ table);
+
+ st_data_t count;
+ if (st_lookup(table, (st_data_t)obj, &count)) {
+ return ULL2NUM(count);
+ }
+
+ return Qnil;
+}
+
+static VALUE
+memory_view_ref_count_while_exporting_i(VALUE obj, long n)
+{
+ if (n == 0) {
+ return memory_view_get_ref_count(obj);
+ }
+
+ rb_memory_view_t view;
+ if (!rb_memory_view_get(obj, &view, 0)) {
+ return Qnil;
+ }
+
+ VALUE ref_count = memory_view_ref_count_while_exporting_i(obj, n-1);
+ rb_memory_view_release(&view);
+
+ return ref_count;
+}
+
+static VALUE
+memory_view_ref_count_while_exporting(VALUE mod, VALUE obj, VALUE n)
+{
+ Check_Type(n, T_FIXNUM);
+ return memory_view_ref_count_while_exporting_i(obj, FIX2LONG(n));
+}
+
+static VALUE
+memory_view_extract_item_members(VALUE mod, VALUE str, VALUE format)
+{
+ StringValue(str);
+ StringValue(format);
+
+ rb_memory_view_item_component_t *members;
+ size_t n_members;
+ const char *err = NULL;
+ (void)rb_memory_view_parse_item_format(RSTRING_PTR(format), &members, &n_members, &err);
+ if (err != NULL) {
+ rb_raise(rb_eArgError, "Unable to parse item format");
+ }
+
+ VALUE item = rb_memory_view_extract_item_members(RSTRING_PTR(str), members, n_members);
+ xfree(members);
+
+ return item;
+}
+
+static VALUE
expstr_initialize(VALUE obj, VALUE s)
{
+ if (!NIL_P(s)) {
+ Check_Type(s, T_STRING);
+ }
rb_ivar_set(obj, id_str, s);
return Qnil;
}
-static int
+static bool
mdview_get_memory_view(VALUE obj, rb_memory_view_t *view, int flags)
{
VALUE buf_v = rb_ivar_get(obj, id_str);
+ VALUE format_v = rb_ivar_get(obj, SYM2ID(sym_format));
VALUE shape_v = rb_ivar_get(obj, SYM2ID(sym_shape));
VALUE strides_v = rb_ivar_get(obj, SYM2ID(sym_strides));
- ssize_t i, ndim = RARRAY_LEN(shape_v);
+ const char *err;
+ const ssize_t item_size = rb_memory_view_item_size_from_format(RSTRING_PTR(format_v), &err);
+ if (item_size < 0) {
+ return false;
+ }
+
+ ssize_t ndim = RARRAY_LEN(shape_v);
+ if (!NIL_P(strides_v) && RARRAY_LEN(strides_v) != ndim) {
+ rb_raise(rb_eArgError, "strides has an invalid dimension");
+ }
+
ssize_t *shape = ALLOC_N(ssize_t, ndim);
- ssize_t *strides = NULL;
+ ssize_t *strides = ALLOC_N(ssize_t, ndim);
+ ssize_t i;
if (!NIL_P(strides_v)) {
- if (RARRAY_LEN(strides_v) != ndim) {
- rb_raise(rb_eArgError, "strides has an invalid dimension");
- }
-
- strides = ALLOC_N(ssize_t, ndim);
for (i = 0; i < ndim; ++i) {
shape[i] = NUM2SSIZET(RARRAY_AREF(shape_v, i));
strides[i] = NUM2SSIZET(RARRAY_AREF(strides_v, i));
@@ -238,41 +291,35 @@ mdview_get_memory_view(VALUE obj, rb_memory_view_t *view, int flags)
for (i = 0; i < ndim; ++i) {
shape[i] = NUM2SSIZET(RARRAY_AREF(shape_v, i));
}
+
+ i = ndim - 1;
+ strides[i] = item_size;
+ for (; i > 0; --i) {
+ strides[i-1] = strides[i] * shape[i];
+ }
}
rb_memory_view_init_as_byte_array(view, obj, RSTRING_PTR(buf_v), RSTRING_LEN(buf_v), true);
- view->format = "l";
- view->item_size = sizeof(long);
+ view->format = RSTRING_PTR(format_v);
+ view->item_size = item_size;
view->ndim = ndim;
view->shape = shape;
view->strides = strides;
+ view->sub_offsets = NULL;
- VALUE count = rb_hash_lookup2(exported_objects, obj, INT2FIX(0));
- count = rb_funcall(count, '+', 1, INT2FIX(1));
- rb_hash_aset(exported_objects, obj, count);
-
- return 1;
+ return true;
}
-static int
+static bool
mdview_release_memory_view(VALUE obj, rb_memory_view_t *view)
{
- VALUE count = rb_hash_lookup2(exported_objects, obj, INT2FIX(0));
- if (INT2FIX(1) == count) {
- rb_hash_delete(exported_objects, obj);
- }
- else if (INT2FIX(0) == count) {
- rb_raise(rb_eRuntimeError, "Duplicated releasing of a memory view has been occurred for %"PRIsVALUE, obj);
- }
- else {
- count = rb_funcall(count, '-', 1, INT2FIX(1));
- rb_hash_aset(exported_objects, obj, count);
- }
+ xfree((void *)view->shape);
+ xfree((void *)view->strides);
- return 1;
+ return true;
}
-static int
+static bool
mdview_memory_view_available_p(VALUE obj)
{
return true;
@@ -285,13 +332,15 @@ static const rb_memory_view_entry_t mdview_memory_view_entry = {
};
static VALUE
-mdview_initialize(VALUE obj, VALUE buf, VALUE shape, VALUE strides)
+mdview_initialize(VALUE obj, VALUE buf, VALUE format, VALUE shape, VALUE strides)
{
Check_Type(buf, T_STRING);
+ StringValue(format);
Check_Type(shape, T_ARRAY);
if (!NIL_P(strides)) Check_Type(strides, T_ARRAY);
rb_ivar_set(obj, id_str, buf);
+ rb_ivar_set(obj, SYM2ID(sym_format), format);
rb_ivar_set(obj, SYM2ID(sym_shape), shape);
rb_ivar_set(obj, SYM2ID(sym_strides), strides);
return Qnil;
@@ -319,19 +368,20 @@ mdview_aref(VALUE obj, VALUE indices_v)
indices[i] = NUM2SSIZET(RARRAY_AREF(indices_v, i));
}
- char *ptr = rb_memory_view_get_item_pointer(&view, indices);
+ VALUE result = rb_memory_view_get_item(&view, indices);
ALLOCV_END(buf_indices);
-
- long x = *(long *)ptr;
- VALUE result = LONG2FIX(x);
rb_memory_view_release(&view);
return result;
}
+#endif /* HAVE_RUBY_MEMORY_VIEW_H */
+
void
Init_memory_view(void)
{
+ rb_ext_ractor_safe(true);
+#ifdef HAVE_RUBY_MEMORY_VIEW_H
VALUE mMemoryViewTestUtils = rb_define_module("MemoryViewTestUtils");
rb_define_module_function(mMemoryViewTestUtils, "available?", memory_view_available_p, 1);
@@ -340,45 +390,47 @@ Init_memory_view(void)
rb_define_module_function(mMemoryViewTestUtils, "parse_item_format", memory_view_parse_item_format, 1);
rb_define_module_function(mMemoryViewTestUtils, "get_memory_view_info", memory_view_get_memory_view_info, 1);
rb_define_module_function(mMemoryViewTestUtils, "fill_contiguous_strides", memory_view_fill_contiguous_strides, 4);
+ rb_define_module_function(mMemoryViewTestUtils, "ref_count_while_exporting", memory_view_ref_count_while_exporting, 2);
+ rb_define_module_function(mMemoryViewTestUtils, "extract_item_members", memory_view_extract_item_members, 2);
VALUE cExportableString = rb_define_class_under(mMemoryViewTestUtils, "ExportableString", rb_cObject);
rb_define_method(cExportableString, "initialize", expstr_initialize, 1);
rb_memory_view_register(cExportableString, &exportable_string_memory_view_entry);
VALUE cMDView = rb_define_class_under(mMemoryViewTestUtils, "MultiDimensionalView", rb_cObject);
- rb_define_method(cMDView, "initialize", mdview_initialize, 3);
+ rb_define_method(cMDView, "initialize", mdview_initialize, 4);
rb_define_method(cMDView, "[]", mdview_aref, 1);
rb_memory_view_register(cMDView, &mdview_memory_view_entry);
- id_str = rb_intern("__str__");
- sym_format = ID2SYM(rb_intern("format"));
- sym_native_size_p = ID2SYM(rb_intern("native_size_p"));
- sym_offset = ID2SYM(rb_intern("offset"));
- sym_size = ID2SYM(rb_intern("size"));
- sym_repeat = ID2SYM(rb_intern("repeat"));
- sym_obj = ID2SYM(rb_intern("obj"));
- sym_len = ID2SYM(rb_intern("len"));
- sym_readonly = ID2SYM(rb_intern("readonly"));
- sym_format = ID2SYM(rb_intern("format"));
- sym_item_size = ID2SYM(rb_intern("item_size"));
- sym_ndim = ID2SYM(rb_intern("ndim"));
- sym_shape = ID2SYM(rb_intern("shape"));
- sym_strides = ID2SYM(rb_intern("strides"));
- sym_sub_offsets = ID2SYM(rb_intern("sub_offsets"));
- sym_endianness = ID2SYM(rb_intern("endianness"));
- sym_little_endian = ID2SYM(rb_intern("little_endian"));
- sym_big_endian = ID2SYM(rb_intern("big_endian"));
+ id_str = rb_intern_const("__str__");
+ sym_format = ID2SYM(rb_intern_const("format"));
+ sym_native_size_p = ID2SYM(rb_intern_const("native_size_p"));
+ sym_offset = ID2SYM(rb_intern_const("offset"));
+ sym_size = ID2SYM(rb_intern_const("size"));
+ sym_repeat = ID2SYM(rb_intern_const("repeat"));
+ sym_obj = ID2SYM(rb_intern_const("obj"));
+ sym_byte_size = ID2SYM(rb_intern_const("byte_size"));
+ sym_readonly = ID2SYM(rb_intern_const("readonly"));
+ sym_format = ID2SYM(rb_intern_const("format"));
+ sym_item_size = ID2SYM(rb_intern_const("item_size"));
+ sym_ndim = ID2SYM(rb_intern_const("ndim"));
+ sym_shape = ID2SYM(rb_intern_const("shape"));
+ sym_strides = ID2SYM(rb_intern_const("strides"));
+ sym_sub_offsets = ID2SYM(rb_intern_const("sub_offsets"));
+ sym_endianness = ID2SYM(rb_intern_const("endianness"));
+ sym_little_endian = ID2SYM(rb_intern_const("little_endian"));
+ sym_big_endian = ID2SYM(rb_intern_const("big_endian"));
#ifdef WORDS_BIGENDIAN
- rb_const_set(mMemoryViewTestUtils, rb_intern("NATIVE_ENDIAN"), sym_big_endian);
+ rb_const_set(mMemoryViewTestUtils, rb_intern_const("NATIVE_ENDIAN"), sym_big_endian);
#else
- rb_const_set(mMemoryViewTestUtils, rb_intern("NATIVE_ENDIAN"), sym_little_endian);
+ rb_const_set(mMemoryViewTestUtils, rb_intern_const("NATIVE_ENDIAN"), sym_little_endian);
#endif
#define DEF_ALIGNMENT_CONST(type, TYPE) do { \
int alignment; \
STRUCT_ALIGNOF(type, alignment); \
- rb_const_set(mMemoryViewTestUtils, rb_intern(#TYPE "_ALIGNMENT"), INT2FIX(alignment)); \
+ rb_const_set(mMemoryViewTestUtils, rb_intern_const(#TYPE "_ALIGNMENT"), INT2FIX(alignment)); \
} while(0)
DEF_ALIGNMENT_CONST(short, SHORT);
@@ -394,6 +446,5 @@ Init_memory_view(void)
#undef DEF_ALIGNMENT_CONST
- exported_objects = rb_hash_new();
- rb_gc_register_mark_object(exported_objects);
+#endif /* HAVE_RUBY_MEMORY_VIEW_H */
}