diff options
Diffstat (limited to 'ext/-test-/memory_view')
| -rw-r--r-- | ext/-test-/memory_view/depend | 8 | ||||
| -rw-r--r-- | ext/-test-/memory_view/extconf.rb | 2 | ||||
| -rw-r--r-- | ext/-test-/memory_view/memory_view.c | 237 |
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 */ } |
