enclave 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/README.md +182 -0
- data/Rakefile +30 -0
- data/ext/enclave/enclave.c +390 -0
- data/ext/enclave/extconf.rb +33 -0
- data/ext/enclave/mruby/Makefile +63 -0
- data/ext/enclave/mruby/Rakefile +102 -0
- data/ext/enclave/mruby/benchmark/bm_ao_render.rb +309 -0
- data/ext/enclave/mruby/benchmark/bm_app_lc_fizzbuzz.rb +51 -0
- data/ext/enclave/mruby/benchmark/bm_fib.rb +6 -0
- data/ext/enclave/mruby/benchmark/bm_mandel_term.rb +34 -0
- data/ext/enclave/mruby/benchmark/bm_so_lists.rb +49 -0
- data/ext/enclave/mruby/benchmark/bm_so_mandelbrot.rb +65 -0
- data/ext/enclave/mruby/benchmark/vm_dispatch_bench.c +197 -0
- data/ext/enclave/mruby/benchmark/vm_optimization_bench.rb +513 -0
- data/ext/enclave/mruby/build/host/include/mrbconf.h +230 -0
- data/ext/enclave/mruby/build/host/include/mruby/array.h +303 -0
- data/ext/enclave/mruby/build/host/include/mruby/boxing_nan.h +169 -0
- data/ext/enclave/mruby/build/host/include/mruby/boxing_no.h +59 -0
- data/ext/enclave/mruby/build/host/include/mruby/boxing_word.h +248 -0
- data/ext/enclave/mruby/build/host/include/mruby/class.h +157 -0
- data/ext/enclave/mruby/build/host/include/mruby/common.h +127 -0
- data/ext/enclave/mruby/build/host/include/mruby/compile.h +187 -0
- data/ext/enclave/mruby/build/host/include/mruby/data.h +76 -0
- data/ext/enclave/mruby/build/host/include/mruby/debug.h +75 -0
- data/ext/enclave/mruby/build/host/include/mruby/dump.h +159 -0
- data/ext/enclave/mruby/build/host/include/mruby/endian.h +44 -0
- data/ext/enclave/mruby/build/host/include/mruby/error.h +168 -0
- data/ext/enclave/mruby/build/host/include/mruby/gc.h +77 -0
- data/ext/enclave/mruby/build/host/include/mruby/hash.h +234 -0
- data/ext/enclave/mruby/build/host/include/mruby/internal.h +278 -0
- data/ext/enclave/mruby/build/host/include/mruby/irep.h +142 -0
- data/ext/enclave/mruby/build/host/include/mruby/istruct.h +50 -0
- data/ext/enclave/mruby/build/host/include/mruby/khash.h +455 -0
- data/ext/enclave/mruby/build/host/include/mruby/mempool.h +19 -0
- data/ext/enclave/mruby/build/host/include/mruby/numeric.h +174 -0
- data/ext/enclave/mruby/build/host/include/mruby/object.h +44 -0
- data/ext/enclave/mruby/build/host/include/mruby/opcode.h +73 -0
- data/ext/enclave/mruby/build/host/include/mruby/ops.h +133 -0
- data/ext/enclave/mruby/build/host/include/mruby/presym/id.h +895 -0
- data/ext/enclave/mruby/build/host/include/mruby/presym/scanning.h +82 -0
- data/ext/enclave/mruby/build/host/include/mruby/presym/table.h +1787 -0
- data/ext/enclave/mruby/build/host/include/mruby/presym.h +65 -0
- data/ext/enclave/mruby/build/host/include/mruby/proc.h +184 -0
- data/ext/enclave/mruby/build/host/include/mruby/range.h +77 -0
- data/ext/enclave/mruby/build/host/include/mruby/re.h +16 -0
- data/ext/enclave/mruby/build/host/include/mruby/string.h +428 -0
- data/ext/enclave/mruby/build/host/include/mruby/throw.h +81 -0
- data/ext/enclave/mruby/build/host/include/mruby/value.h +471 -0
- data/ext/enclave/mruby/build/host/include/mruby/variable.h +108 -0
- data/ext/enclave/mruby/build/host/include/mruby/version.h +143 -0
- data/ext/enclave/mruby/build/host/include/mruby.h +1632 -0
- data/ext/enclave/mruby/build/host/mrbc/include/mruby/presym/id.h +281 -0
- data/ext/enclave/mruby/build/host/mrbc/include/mruby/presym/table.h +559 -0
- data/ext/enclave/mruby/build/host/mrbgems/gem_init.c +164 -0
- data/ext/enclave/mruby/build/host/mrbgems/mruby-array-ext/gem_init.c +650 -0
- data/ext/enclave/mruby/build/host/mrbgems/mruby-binding/gem_init.c +21 -0
- data/ext/enclave/mruby/build/host/mrbgems/mruby-catch/gem_init.c +86 -0
- data/ext/enclave/mruby/build/host/mrbgems/mruby-class-ext/gem_init.c +21 -0
- data/ext/enclave/mruby/build/host/mrbgems/mruby-compar-ext/gem_init.c +99 -0
- data/ext/enclave/mruby/build/host/mrbgems/mruby-complex/gem_init.c +362 -0
- data/ext/enclave/mruby/build/host/mrbgems/mruby-data/gem_init.c +21 -0
- data/ext/enclave/mruby/build/host/mrbgems/mruby-enum-chain/gem_init.c +229 -0
- data/ext/enclave/mruby/build/host/mrbgems/mruby-enum-ext/gem_init.c +1420 -0
- data/ext/enclave/mruby/build/host/mrbgems/mruby-enum-lazy/gem_init.c +602 -0
- data/ext/enclave/mruby/build/host/mrbgems/mruby-enumerator/gem_init.c +822 -0
- data/ext/enclave/mruby/build/host/mrbgems/mruby-eval/gem_init.c +21 -0
- data/ext/enclave/mruby/build/host/mrbgems/mruby-fiber/gem_init.c +21 -0
- data/ext/enclave/mruby/build/host/mrbgems/mruby-hash-ext/gem_init.c +591 -0
- data/ext/enclave/mruby/build/host/mrbgems/mruby-kernel-ext/gem_init.c +21 -0
- data/ext/enclave/mruby/build/host/mrbgems/mruby-math/gem_init.c +21 -0
- data/ext/enclave/mruby/build/host/mrbgems/mruby-metaprog/gem_init.c +21 -0
- data/ext/enclave/mruby/build/host/mrbgems/mruby-method/gem_init.c +153 -0
- data/ext/enclave/mruby/build/host/mrbgems/mruby-numeric-ext/gem_init.c +211 -0
- data/ext/enclave/mruby/build/host/mrbgems/mruby-object-ext/gem_init.c +94 -0
- data/ext/enclave/mruby/build/host/mrbgems/mruby-objectspace/gem_init.c +21 -0
- data/ext/enclave/mruby/build/host/mrbgems/mruby-pack/gem_init.c +21 -0
- data/ext/enclave/mruby/build/host/mrbgems/mruby-proc-binding/gem_init.c +21 -0
- data/ext/enclave/mruby/build/host/mrbgems/mruby-proc-ext/gem_init.c +237 -0
- data/ext/enclave/mruby/build/host/mrbgems/mruby-random/gem_init.c +21 -0
- data/ext/enclave/mruby/build/host/mrbgems/mruby-range-ext/gem_init.c +205 -0
- data/ext/enclave/mruby/build/host/mrbgems/mruby-rational/gem_init.c +147 -0
- data/ext/enclave/mruby/build/host/mrbgems/mruby-set/gem_init.c +487 -0
- data/ext/enclave/mruby/build/host/mrbgems/mruby-sprintf/gem_init.c +83 -0
- data/ext/enclave/mruby/build/host/mrbgems/mruby-string-ext/gem_init.c +220 -0
- data/ext/enclave/mruby/build/host/mrbgems/mruby-struct/gem_init.c +175 -0
- data/ext/enclave/mruby/build/host/mrbgems/mruby-symbol-ext/gem_init.c +153 -0
- data/ext/enclave/mruby/build/host/mrbgems/mruby-time/gem_init.c +21 -0
- data/ext/enclave/mruby/build/host/mrbgems/mruby-toplevel-ext/gem_init.c +78 -0
- data/ext/enclave/mruby/build/host/mrblib/mrblib.c +1758 -0
- data/ext/enclave/mruby/build_config/ArduinoDue.rb +72 -0
- data/ext/enclave/mruby/build_config/IntelEdison.rb +69 -0
- data/ext/enclave/mruby/build_config/IntelGalileo.rb +88 -0
- data/ext/enclave/mruby/build_config/RX630.rb +63 -0
- data/ext/enclave/mruby/build_config/android_arm64_v8a.rb +11 -0
- data/ext/enclave/mruby/build_config/android_armeabi_v7a_neon_hard.rb +13 -0
- data/ext/enclave/mruby/build_config/bench.rb +11 -0
- data/ext/enclave/mruby/build_config/boxing.rb +19 -0
- data/ext/enclave/mruby/build_config/chipKITMax32.rb +68 -0
- data/ext/enclave/mruby/build_config/ci/gcc-clang.rb +40 -0
- data/ext/enclave/mruby/build_config/ci/msvc.rb +20 -0
- data/ext/enclave/mruby/build_config/clang-asan.rb +11 -0
- data/ext/enclave/mruby/build_config/cosmopolitan.rb +86 -0
- data/ext/enclave/mruby/build_config/cross-32bit.rb +14 -0
- data/ext/enclave/mruby/build_config/cross-mingw-winetest.rb +90 -0
- data/ext/enclave/mruby/build_config/cross-mingw.rb +14 -0
- data/ext/enclave/mruby/build_config/default.rb +83 -0
- data/ext/enclave/mruby/build_config/dreamcast_shelf.rb +81 -0
- data/ext/enclave/mruby/build_config/emscripten-cxx.rb +12 -0
- data/ext/enclave/mruby/build_config/emscripten.rb +10 -0
- data/ext/enclave/mruby/build_config/gameboyadvance.rb +72 -0
- data/ext/enclave/mruby/build_config/helpers/wine_runner.rb +71 -0
- data/ext/enclave/mruby/build_config/host-cxx.rb +12 -0
- data/ext/enclave/mruby/build_config/host-debug.rb +20 -0
- data/ext/enclave/mruby/build_config/host-f32.rb +14 -0
- data/ext/enclave/mruby/build_config/host-gprof.rb +14 -0
- data/ext/enclave/mruby/build_config/host-m32.rb +15 -0
- data/ext/enclave/mruby/build_config/host-nofloat.rb +22 -0
- data/ext/enclave/mruby/build_config/host-shared.rb +36 -0
- data/ext/enclave/mruby/build_config/i586-pc-msdosdjgpp.rb +76 -0
- data/ext/enclave/mruby/build_config/luckfox_pico.rb +106 -0
- data/ext/enclave/mruby/build_config/milkv_duo.rb +106 -0
- data/ext/enclave/mruby/build_config/minimal.rb +4 -0
- data/ext/enclave/mruby/build_config/mrbc.rb +10 -0
- data/ext/enclave/mruby/build_config/nintendo_switch.rb +73 -0
- data/ext/enclave/mruby/build_config/nintendo_wii.rb +95 -0
- data/ext/enclave/mruby/build_config/no-float.rb +17 -0
- data/ext/enclave/mruby/build_config/playstationportable.rb +78 -0
- data/ext/enclave/mruby/build_config/serenity.rb +26 -0
- data/ext/enclave/mruby/build_config.rb +9 -0
- data/ext/enclave/mruby/examples/mrbgems/c_and_ruby_extension_example/mrblib/example.rb +5 -0
- data/ext/enclave/mruby/examples/mrbgems/c_and_ruby_extension_example/src/example.c +23 -0
- data/ext/enclave/mruby/examples/mrbgems/c_and_ruby_extension_example/test/example.rb +7 -0
- data/ext/enclave/mruby/examples/mrbgems/c_extension_example/src/example.c +23 -0
- data/ext/enclave/mruby/examples/mrbgems/c_extension_example/test/example.c +7 -0
- data/ext/enclave/mruby/examples/mrbgems/c_extension_example/test/example.rb +3 -0
- data/ext/enclave/mruby/examples/mrbgems/cdata_extension_example/src/example.c +77 -0
- data/ext/enclave/mruby/examples/mrbgems/cdata_extension_example/test/example.c +7 -0
- data/ext/enclave/mruby/examples/mrbgems/mruby-YOUR-bigint/core/bigint.c +70 -0
- data/ext/enclave/mruby/examples/mrbgems/ruby_extension_example/mrblib/example.rb +5 -0
- data/ext/enclave/mruby/examples/mrbgems/ruby_extension_example/test/example.rb +3 -0
- data/ext/enclave/mruby/include/mrbconf.h +230 -0
- data/ext/enclave/mruby/include/mruby/array.h +303 -0
- data/ext/enclave/mruby/include/mruby/boxing_nan.h +169 -0
- data/ext/enclave/mruby/include/mruby/boxing_no.h +59 -0
- data/ext/enclave/mruby/include/mruby/boxing_word.h +248 -0
- data/ext/enclave/mruby/include/mruby/class.h +157 -0
- data/ext/enclave/mruby/include/mruby/common.h +127 -0
- data/ext/enclave/mruby/include/mruby/compile.h +187 -0
- data/ext/enclave/mruby/include/mruby/data.h +76 -0
- data/ext/enclave/mruby/include/mruby/debug.h +75 -0
- data/ext/enclave/mruby/include/mruby/dump.h +159 -0
- data/ext/enclave/mruby/include/mruby/endian.h +44 -0
- data/ext/enclave/mruby/include/mruby/error.h +168 -0
- data/ext/enclave/mruby/include/mruby/gc.h +77 -0
- data/ext/enclave/mruby/include/mruby/hash.h +234 -0
- data/ext/enclave/mruby/include/mruby/internal.h +278 -0
- data/ext/enclave/mruby/include/mruby/irep.h +142 -0
- data/ext/enclave/mruby/include/mruby/istruct.h +50 -0
- data/ext/enclave/mruby/include/mruby/khash.h +455 -0
- data/ext/enclave/mruby/include/mruby/mempool.h +19 -0
- data/ext/enclave/mruby/include/mruby/numeric.h +174 -0
- data/ext/enclave/mruby/include/mruby/object.h +44 -0
- data/ext/enclave/mruby/include/mruby/opcode.h +73 -0
- data/ext/enclave/mruby/include/mruby/ops.h +133 -0
- data/ext/enclave/mruby/include/mruby/presym/scanning.h +82 -0
- data/ext/enclave/mruby/include/mruby/presym.h +65 -0
- data/ext/enclave/mruby/include/mruby/proc.h +184 -0
- data/ext/enclave/mruby/include/mruby/range.h +77 -0
- data/ext/enclave/mruby/include/mruby/re.h +16 -0
- data/ext/enclave/mruby/include/mruby/string.h +428 -0
- data/ext/enclave/mruby/include/mruby/throw.h +81 -0
- data/ext/enclave/mruby/include/mruby/value.h +471 -0
- data/ext/enclave/mruby/include/mruby/variable.h +108 -0
- data/ext/enclave/mruby/include/mruby/version.h +143 -0
- data/ext/enclave/mruby/include/mruby.h +1632 -0
- data/ext/enclave/mruby/lib/mruby/amalgam.rb +568 -0
- data/ext/enclave/mruby/lib/mruby/build/command.rb +383 -0
- data/ext/enclave/mruby/lib/mruby/build/load_gems.rb +383 -0
- data/ext/enclave/mruby/lib/mruby/build.rb +616 -0
- data/ext/enclave/mruby/lib/mruby/core_ext.rb +61 -0
- data/ext/enclave/mruby/lib/mruby/doc.rb +51 -0
- data/ext/enclave/mruby/lib/mruby/gem.rb +585 -0
- data/ext/enclave/mruby/lib/mruby/lockfile.rb +81 -0
- data/ext/enclave/mruby/lib/mruby/presym.rb +167 -0
- data/ext/enclave/mruby/lib/mruby/source.rb +32 -0
- data/ext/enclave/mruby/mrbgems/default-no-fpu.gembox +3 -0
- data/ext/enclave/mruby/mrbgems/default-no-stdio.gembox +4 -0
- data/ext/enclave/mruby/mrbgems/default.gembox +25 -0
- data/ext/enclave/mruby/mrbgems/full-core.gembox +6 -0
- data/ext/enclave/mruby/mrbgems/hal-posix-dir/mrbgem.rake +7 -0
- data/ext/enclave/mruby/mrbgems/hal-posix-dir/src/dir_hal.c +193 -0
- data/ext/enclave/mruby/mrbgems/hal-posix-io/mrbgem.rake +8 -0
- data/ext/enclave/mruby/mrbgems/hal-posix-io/src/io_hal.c +602 -0
- data/ext/enclave/mruby/mrbgems/hal-posix-socket/mrbgem.rake +8 -0
- data/ext/enclave/mruby/mrbgems/hal-posix-socket/src/socket_hal.c +158 -0
- data/ext/enclave/mruby/mrbgems/hal-posix-task/README.md +102 -0
- data/ext/enclave/mruby/mrbgems/hal-posix-task/mrbgem.rake +8 -0
- data/ext/enclave/mruby/mrbgems/hal-posix-task/src/task_hal.c +252 -0
- data/ext/enclave/mruby/mrbgems/hal-win-dir/mrbgem.rake +7 -0
- data/ext/enclave/mruby/mrbgems/hal-win-dir/src/dir_hal.c +249 -0
- data/ext/enclave/mruby/mrbgems/hal-win-io/mrbgem.rake +11 -0
- data/ext/enclave/mruby/mrbgems/hal-win-io/src/io_hal.c +646 -0
- data/ext/enclave/mruby/mrbgems/hal-win-socket/mrbgem.rake +12 -0
- data/ext/enclave/mruby/mrbgems/hal-win-socket/src/socket_hal.c +177 -0
- data/ext/enclave/mruby/mrbgems/hal-win-task/README.md +109 -0
- data/ext/enclave/mruby/mrbgems/hal-win-task/mrbgem.rake +11 -0
- data/ext/enclave/mruby/mrbgems/hal-win-task/src/task_hal.c +187 -0
- data/ext/enclave/mruby/mrbgems/math.gembox +12 -0
- data/ext/enclave/mruby/mrbgems/metaprog.gembox +21 -0
- data/ext/enclave/mruby/mrbgems/mruby-array-ext/README.md +87 -0
- data/ext/enclave/mruby/mrbgems/mruby-array-ext/mrbgem.rake +5 -0
- data/ext/enclave/mruby/mrbgems/mruby-array-ext/mrblib/array.rb +784 -0
- data/ext/enclave/mruby/mrbgems/mruby-array-ext/src/array.c +1583 -0
- data/ext/enclave/mruby/mrbgems/mruby-array-ext/test/array.rb +849 -0
- data/ext/enclave/mruby/mrbgems/mruby-benchmark/README.md +257 -0
- data/ext/enclave/mruby/mrbgems/mruby-benchmark/mrbgem.rake +10 -0
- data/ext/enclave/mruby/mrbgems/mruby-benchmark/mrblib/benchmark.rb +131 -0
- data/ext/enclave/mruby/mrbgems/mruby-benchmark/test/benchmark.rb +244 -0
- data/ext/enclave/mruby/mrbgems/mruby-bigint/README-fgmp.md +154 -0
- data/ext/enclave/mruby/mrbgems/mruby-bigint/README.md +44 -0
- data/ext/enclave/mruby/mrbgems/mruby-bigint/core/bigint.c +6335 -0
- data/ext/enclave/mruby/mrbgems/mruby-bigint/core/bigint.h +117 -0
- data/ext/enclave/mruby/mrbgems/mruby-bigint/mrbgem.rake +10 -0
- data/ext/enclave/mruby/mrbgems/mruby-bigint/test/bigint.rb +157 -0
- data/ext/enclave/mruby/mrbgems/mruby-bin-config/README.md +46 -0
- data/ext/enclave/mruby/mrbgems/mruby-bin-config/mrbgem.rake +49 -0
- data/ext/enclave/mruby/mrbgems/mruby-bin-config/mruby-config +46 -0
- data/ext/enclave/mruby/mrbgems/mruby-bin-config/mruby-config.bat +92 -0
- data/ext/enclave/mruby/mrbgems/mruby-bin-debugger/README.md +63 -0
- data/ext/enclave/mruby/mrbgems/mruby-bin-debugger/bintest/mrdb.rb +283 -0
- data/ext/enclave/mruby/mrbgems/mruby-bin-debugger/bintest/print.rb +703 -0
- data/ext/enclave/mruby/mrbgems/mruby-bin-debugger/mrbgem.rake +10 -0
- data/ext/enclave/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/apibreak.c +523 -0
- data/ext/enclave/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/apibreak.h +26 -0
- data/ext/enclave/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/apilist.c +238 -0
- data/ext/enclave/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/apilist.h +14 -0
- data/ext/enclave/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/apiprint.c +88 -0
- data/ext/enclave/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/apiprint.h +13 -0
- data/ext/enclave/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/apistring.c +34 -0
- data/ext/enclave/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/apistring.h +14 -0
- data/ext/enclave/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/cmdbreak.c +436 -0
- data/ext/enclave/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/cmdmisc.c +509 -0
- data/ext/enclave/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/cmdprint.c +71 -0
- data/ext/enclave/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/cmdrun.c +64 -0
- data/ext/enclave/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/mrdb.c +768 -0
- data/ext/enclave/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/mrdb.h +159 -0
- data/ext/enclave/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/mrdbconf.h +24 -0
- data/ext/enclave/mruby/mrbgems/mruby-bin-debugger/tools/mrdb/mrdberror.h +19 -0
- data/ext/enclave/mruby/mrbgems/mruby-bin-mirb/README.md +94 -0
- data/ext/enclave/mruby/mrbgems/mruby-bin-mirb/bintest/mirb.rb +58 -0
- data/ext/enclave/mruby/mrbgems/mruby-bin-mirb/mrbgem.rake +7 -0
- data/ext/enclave/mruby/mrbgems/mruby-bin-mirb/tools/mirb/mirb.c +808 -0
- data/ext/enclave/mruby/mrbgems/mruby-bin-mirb/tools/mirb/mirb_buffer.c +1035 -0
- data/ext/enclave/mruby/mrbgems/mruby-bin-mirb/tools/mirb/mirb_buffer.h +185 -0
- data/ext/enclave/mruby/mrbgems/mruby-bin-mirb/tools/mirb/mirb_completion.c +797 -0
- data/ext/enclave/mruby/mrbgems/mruby-bin-mirb/tools/mirb/mirb_completion.h +132 -0
- data/ext/enclave/mruby/mrbgems/mruby-bin-mirb/tools/mirb/mirb_editor.c +1118 -0
- data/ext/enclave/mruby/mrbgems/mruby-bin-mirb/tools/mirb/mirb_editor.h +153 -0
- data/ext/enclave/mruby/mrbgems/mruby-bin-mirb/tools/mirb/mirb_highlight.c +516 -0
- data/ext/enclave/mruby/mrbgems/mruby-bin-mirb/tools/mirb/mirb_highlight.h +95 -0
- data/ext/enclave/mruby/mrbgems/mruby-bin-mirb/tools/mirb/mirb_history.c +185 -0
- data/ext/enclave/mruby/mrbgems/mruby-bin-mirb/tools/mirb/mirb_history.h +76 -0
- data/ext/enclave/mruby/mrbgems/mruby-bin-mirb/tools/mirb/mirb_term.c +491 -0
- data/ext/enclave/mruby/mrbgems/mruby-bin-mirb/tools/mirb/mirb_term.h +137 -0
- data/ext/enclave/mruby/mrbgems/mruby-bin-mrbc/README.md +58 -0
- data/ext/enclave/mruby/mrbgems/mruby-bin-mrbc/bintest/mrbc.rb +30 -0
- data/ext/enclave/mruby/mrbgems/mruby-bin-mrbc/mrbgem.rake +15 -0
- data/ext/enclave/mruby/mrbgems/mruby-bin-mrbc/tools/mrbc/mrbc.c +362 -0
- data/ext/enclave/mruby/mrbgems/mruby-bin-mrbc/tools/mrbc/stub.c +104 -0
- data/ext/enclave/mruby/mrbgems/mruby-bin-mruby/README.md +47 -0
- data/ext/enclave/mruby/mrbgems/mruby-bin-mruby/bintest/mruby.rb +178 -0
- data/ext/enclave/mruby/mrbgems/mruby-bin-mruby/mrbgem.rake +7 -0
- data/ext/enclave/mruby/mrbgems/mruby-bin-mruby/tools/mruby/mruby.c +380 -0
- data/ext/enclave/mruby/mrbgems/mruby-bin-strip/README.md +38 -0
- data/ext/enclave/mruby/mrbgems/mruby-bin-strip/bintest/mruby_strip.rb +73 -0
- data/ext/enclave/mruby/mrbgems/mruby-bin-strip/mrbgem.rake +7 -0
- data/ext/enclave/mruby/mrbgems/mruby-bin-strip/tools/mruby-strip/mruby_strip.c +139 -0
- data/ext/enclave/mruby/mrbgems/mruby-binding/README.md +256 -0
- data/ext/enclave/mruby/mrbgems/mruby-binding/mrbgem.rake +7 -0
- data/ext/enclave/mruby/mrbgems/mruby-binding/src/binding.c +518 -0
- data/ext/enclave/mruby/mrbgems/mruby-binding/test/binding.c +14 -0
- data/ext/enclave/mruby/mrbgems/mruby-binding/test/binding.rb +64 -0
- data/ext/enclave/mruby/mrbgems/mruby-catch/README.md +94 -0
- data/ext/enclave/mruby/mrbgems/mruby-catch/mrbgem.rake +5 -0
- data/ext/enclave/mruby/mrbgems/mruby-catch/mrblib/catch.rb +29 -0
- data/ext/enclave/mruby/mrbgems/mruby-catch/src/catch.c +149 -0
- data/ext/enclave/mruby/mrbgems/mruby-catch/test/catch.rb +86 -0
- data/ext/enclave/mruby/mrbgems/mruby-class-ext/README.md +81 -0
- data/ext/enclave/mruby/mrbgems/mruby-class-ext/mrbgem.rake +5 -0
- data/ext/enclave/mruby/mrbgems/mruby-class-ext/src/class.c +377 -0
- data/ext/enclave/mruby/mrbgems/mruby-class-ext/test/class.rb +46 -0
- data/ext/enclave/mruby/mrbgems/mruby-class-ext/test/module.rb +109 -0
- data/ext/enclave/mruby/mrbgems/mruby-cmath/README.md +45 -0
- data/ext/enclave/mruby/mrbgems/mruby-cmath/mrbgem.rake +8 -0
- data/ext/enclave/mruby/mrbgems/mruby-cmath/src/cmath.c +426 -0
- data/ext/enclave/mruby/mrbgems/mruby-cmath/test/cmath.rb +41 -0
- data/ext/enclave/mruby/mrbgems/mruby-compar-ext/README.md +65 -0
- data/ext/enclave/mruby/mrbgems/mruby-compar-ext/mrbgem.rake +5 -0
- data/ext/enclave/mruby/mrbgems/mruby-compar-ext/mrblib/compar.rb +75 -0
- data/ext/enclave/mruby/mrbgems/mruby-compar-ext/test/compar.rb +21 -0
- data/ext/enclave/mruby/mrbgems/mruby-compiler/README.md +28 -0
- data/ext/enclave/mruby/mrbgems/mruby-compiler/core/codegen.c +7316 -0
- data/ext/enclave/mruby/mrbgems/mruby-compiler/core/keywords +52 -0
- data/ext/enclave/mruby/mrbgems/mruby-compiler/core/lex.def +207 -0
- data/ext/enclave/mruby/mrbgems/mruby-compiler/core/node.h +784 -0
- data/ext/enclave/mruby/mrbgems/mruby-compiler/core/parse.y +8977 -0
- data/ext/enclave/mruby/mrbgems/mruby-compiler/core/y.tab.c +16136 -0
- data/ext/enclave/mruby/mrbgems/mruby-compiler/mrbgem.rake +42 -0
- data/ext/enclave/mruby/mrbgems/mruby-complex/README.md +55 -0
- data/ext/enclave/mruby/mrbgems/mruby-complex/mrbgem.rake +7 -0
- data/ext/enclave/mruby/mrbgems/mruby-complex/mrblib/complex.rb +259 -0
- data/ext/enclave/mruby/mrbgems/mruby-complex/src/complex.c +597 -0
- data/ext/enclave/mruby/mrbgems/mruby-complex/test/complex.rb +174 -0
- data/ext/enclave/mruby/mrbgems/mruby-data/README.md +126 -0
- data/ext/enclave/mruby/mrbgems/mruby-data/mrbgem.rake +5 -0
- data/ext/enclave/mruby/mrbgems/mruby-data/src/data.c +550 -0
- data/ext/enclave/mruby/mrbgems/mruby-data/test/data.rb +76 -0
- data/ext/enclave/mruby/mrbgems/mruby-dir/README.md +53 -0
- data/ext/enclave/mruby/mrbgems/mruby-dir/include/dir_hal.h +79 -0
- data/ext/enclave/mruby/mrbgems/mruby-dir/mrbgem.rake +35 -0
- data/ext/enclave/mruby/mrbgems/mruby-dir/mrblib/dir.rb +124 -0
- data/ext/enclave/mruby/mrbgems/mruby-dir/src/dir.c +493 -0
- data/ext/enclave/mruby/mrbgems/mruby-dir/test/dir.rb +138 -0
- data/ext/enclave/mruby/mrbgems/mruby-dir/test/dirtest.c +125 -0
- data/ext/enclave/mruby/mrbgems/mruby-encoding/README.md +96 -0
- data/ext/enclave/mruby/mrbgems/mruby-encoding/mrbgem.rake +8 -0
- data/ext/enclave/mruby/mrbgems/mruby-encoding/src/encoding.c +128 -0
- data/ext/enclave/mruby/mrbgems/mruby-encoding/test/numeric.rb +27 -0
- data/ext/enclave/mruby/mrbgems/mruby-encoding/test/string.rb +30 -0
- data/ext/enclave/mruby/mrbgems/mruby-enum-chain/README.md +80 -0
- data/ext/enclave/mruby/mrbgems/mruby-enum-chain/mrbgem.rake +6 -0
- data/ext/enclave/mruby/mrbgems/mruby-enum-chain/mrblib/chain.rb +149 -0
- data/ext/enclave/mruby/mrbgems/mruby-enum-chain/test/enum_chain.rb +108 -0
- data/ext/enclave/mruby/mrbgems/mruby-enum-ext/README.md +487 -0
- data/ext/enclave/mruby/mrbgems/mruby-enum-ext/mrbgem.rake +5 -0
- data/ext/enclave/mruby/mrbgems/mruby-enum-ext/mrblib/enum.rb +938 -0
- data/ext/enclave/mruby/mrbgems/mruby-enum-ext/test/enum.rb +223 -0
- data/ext/enclave/mruby/mrbgems/mruby-enum-lazy/README.md +91 -0
- data/ext/enclave/mruby/mrbgems/mruby-enum-lazy/mrbgem.rake +7 -0
- data/ext/enclave/mruby/mrbgems/mruby-enum-lazy/mrblib/lazy.rb +363 -0
- data/ext/enclave/mruby/mrbgems/mruby-enum-lazy/test/lazy.rb +59 -0
- data/ext/enclave/mruby/mrbgems/mruby-enumerator/README.md +89 -0
- data/ext/enclave/mruby/mrbgems/mruby-enumerator/mrbgem.rake +6 -0
- data/ext/enclave/mruby/mrbgems/mruby-enumerator/mrblib/enumerator.rb +861 -0
- data/ext/enclave/mruby/mrbgems/mruby-enumerator/test/enumerator.rb +664 -0
- data/ext/enclave/mruby/mrbgems/mruby-errno/README.md +83 -0
- data/ext/enclave/mruby/mrbgems/mruby-errno/mrbgem.rake +5 -0
- data/ext/enclave/mruby/mrbgems/mruby-errno/mrblib/errno.rb +50 -0
- data/ext/enclave/mruby/mrbgems/mruby-errno/src/errno.c +335 -0
- data/ext/enclave/mruby/mrbgems/mruby-errno/src/gen.rb +18 -0
- data/ext/enclave/mruby/mrbgems/mruby-errno/src/known_errors.def +156 -0
- data/ext/enclave/mruby/mrbgems/mruby-errno/src/known_errors_def.cstub +780 -0
- data/ext/enclave/mruby/mrbgems/mruby-errno/test/errno.rb +57 -0
- data/ext/enclave/mruby/mrbgems/mruby-error/README.md +103 -0
- data/ext/enclave/mruby/mrbgems/mruby-error/mrbgem.rake +5 -0
- data/ext/enclave/mruby/mrbgems/mruby-error/src/exception.c +143 -0
- data/ext/enclave/mruby/mrbgems/mruby-error/test/exception.c +60 -0
- data/ext/enclave/mruby/mrbgems/mruby-error/test/exception.rb +55 -0
- data/ext/enclave/mruby/mrbgems/mruby-eval/README.md +26 -0
- data/ext/enclave/mruby/mrbgems/mruby-eval/mrbgem.rake +10 -0
- data/ext/enclave/mruby/mrbgems/mruby-eval/src/eval.c +437 -0
- data/ext/enclave/mruby/mrbgems/mruby-eval/test/binding.rb +81 -0
- data/ext/enclave/mruby/mrbgems/mruby-eval/test/eval.rb +185 -0
- data/ext/enclave/mruby/mrbgems/mruby-exit/mrbgem.rake +5 -0
- data/ext/enclave/mruby/mrbgems/mruby-exit/src/mruby_exit.c +83 -0
- data/ext/enclave/mruby/mrbgems/mruby-fiber/mrbgem.rake +5 -0
- data/ext/enclave/mruby/mrbgems/mruby-fiber/src/fiber.c +575 -0
- data/ext/enclave/mruby/mrbgems/mruby-fiber/test/fiber.rb +210 -0
- data/ext/enclave/mruby/mrbgems/mruby-fiber/test/fiber2.rb +155 -0
- data/ext/enclave/mruby/mrbgems/mruby-fiber/test/fibertest.c +87 -0
- data/ext/enclave/mruby/mrbgems/mruby-hash-ext/README.md +392 -0
- data/ext/enclave/mruby/mrbgems/mruby-hash-ext/mrbgem.rake +6 -0
- data/ext/enclave/mruby/mrbgems/mruby-hash-ext/mrblib/hash.rb +408 -0
- data/ext/enclave/mruby/mrbgems/mruby-hash-ext/src/hash_ext.c +392 -0
- data/ext/enclave/mruby/mrbgems/mruby-hash-ext/test/hash.rb +317 -0
- data/ext/enclave/mruby/mrbgems/mruby-io/README.md +198 -0
- data/ext/enclave/mruby/mrbgems/mruby-io/include/io_hal.h +451 -0
- data/ext/enclave/mruby/mrbgems/mruby-io/include/mruby/io.h +76 -0
- data/ext/enclave/mruby/mrbgems/mruby-io/mrbgem.rake +34 -0
- data/ext/enclave/mruby/mrbgems/mruby-io/mrblib/file.rb +109 -0
- data/ext/enclave/mruby/mrbgems/mruby-io/mrblib/file_constants.rb +24 -0
- data/ext/enclave/mruby/mrbgems/mruby-io/mrblib/io.rb +303 -0
- data/ext/enclave/mruby/mrbgems/mruby-io/mrblib/kernel.rb +175 -0
- data/ext/enclave/mruby/mrbgems/mruby-io/src/file.c +1192 -0
- data/ext/enclave/mruby/mrbgems/mruby-io/src/file_test.c +403 -0
- data/ext/enclave/mruby/mrbgems/mruby-io/src/io.c +2260 -0
- data/ext/enclave/mruby/mrbgems/mruby-io/src/mruby_io_gem.c +21 -0
- data/ext/enclave/mruby/mrbgems/mruby-io/test/file.rb +415 -0
- data/ext/enclave/mruby/mrbgems/mruby-io/test/file_test.rb +112 -0
- data/ext/enclave/mruby/mrbgems/mruby-io/test/io.rb +668 -0
- data/ext/enclave/mruby/mrbgems/mruby-io/test/mruby_io_test.c +293 -0
- data/ext/enclave/mruby/mrbgems/mruby-kernel-ext/README.md +165 -0
- data/ext/enclave/mruby/mrbgems/mruby-kernel-ext/mrbgem.rake +5 -0
- data/ext/enclave/mruby/mrbgems/mruby-kernel-ext/src/kernel.c +316 -0
- data/ext/enclave/mruby/mrbgems/mruby-kernel-ext/test/kernel.rb +134 -0
- data/ext/enclave/mruby/mrbgems/mruby-math/README.md +77 -0
- data/ext/enclave/mruby/mrbgems/mruby-math/mrbgem.rake +5 -0
- data/ext/enclave/mruby/mrbgems/mruby-math/src/math.c +753 -0
- data/ext/enclave/mruby/mrbgems/mruby-math/test/math.rb +201 -0
- data/ext/enclave/mruby/mrbgems/mruby-metaprog/README.md +123 -0
- data/ext/enclave/mruby/mrbgems/mruby-metaprog/mrbgem.rake +5 -0
- data/ext/enclave/mruby/mrbgems/mruby-metaprog/src/metaprog.c +739 -0
- data/ext/enclave/mruby/mrbgems/mruby-metaprog/test/metaprog.rb +465 -0
- data/ext/enclave/mruby/mrbgems/mruby-method/README.md +66 -0
- data/ext/enclave/mruby/mrbgems/mruby-method/mrbgem.rake +7 -0
- data/ext/enclave/mruby/mrbgems/mruby-method/mrblib/method.rb +73 -0
- data/ext/enclave/mruby/mrbgems/mruby-method/src/method.c +890 -0
- data/ext/enclave/mruby/mrbgems/mruby-method/test/method.rb +514 -0
- data/ext/enclave/mruby/mrbgems/mruby-numeric-ext/README.md +78 -0
- data/ext/enclave/mruby/mrbgems/mruby-numeric-ext/mrbgem.rake +5 -0
- data/ext/enclave/mruby/mrbgems/mruby-numeric-ext/mrblib/numeric_ext.rb +125 -0
- data/ext/enclave/mruby/mrbgems/mruby-numeric-ext/src/numeric_ext.c +527 -0
- data/ext/enclave/mruby/mrbgems/mruby-numeric-ext/test/numeric.rb +137 -0
- data/ext/enclave/mruby/mrbgems/mruby-object-ext/README.md +144 -0
- data/ext/enclave/mruby/mrbgems/mruby-object-ext/mrbgem.rake +5 -0
- data/ext/enclave/mruby/mrbgems/mruby-object-ext/mrblib/object.rb +33 -0
- data/ext/enclave/mruby/mrbgems/mruby-object-ext/src/object.c +128 -0
- data/ext/enclave/mruby/mrbgems/mruby-object-ext/test/nil.rb +16 -0
- data/ext/enclave/mruby/mrbgems/mruby-object-ext/test/object.rb +67 -0
- data/ext/enclave/mruby/mrbgems/mruby-object-ext/test/object_ext.c +17 -0
- data/ext/enclave/mruby/mrbgems/mruby-objectspace/README.md +59 -0
- data/ext/enclave/mruby/mrbgems/mruby-objectspace/mrbgem.rake +5 -0
- data/ext/enclave/mruby/mrbgems/mruby-objectspace/src/mruby_objectspace.c +188 -0
- data/ext/enclave/mruby/mrbgems/mruby-objectspace/test/objectspace.rb +60 -0
- data/ext/enclave/mruby/mrbgems/mruby-os-memsize/README.md +75 -0
- data/ext/enclave/mruby/mrbgems/mruby-os-memsize/mrbgem.rake +10 -0
- data/ext/enclave/mruby/mrbgems/mruby-os-memsize/src/memsize.c +271 -0
- data/ext/enclave/mruby/mrbgems/mruby-os-memsize/test/memsize.rb +63 -0
- data/ext/enclave/mruby/mrbgems/mruby-pack/README.md +140 -0
- data/ext/enclave/mruby/mrbgems/mruby-pack/mrbgem.rake +5 -0
- data/ext/enclave/mruby/mrbgems/mruby-pack/src/pack.c +2129 -0
- data/ext/enclave/mruby/mrbgems/mruby-pack/test/pack.rb +202 -0
- data/ext/enclave/mruby/mrbgems/mruby-proc-binding/README.md +140 -0
- data/ext/enclave/mruby/mrbgems/mruby-proc-binding/mrbgem.rake +10 -0
- data/ext/enclave/mruby/mrbgems/mruby-proc-binding/src/proc_binding.c +76 -0
- data/ext/enclave/mruby/mrbgems/mruby-proc-binding/test/proc_binding.c +14 -0
- data/ext/enclave/mruby/mrbgems/mruby-proc-binding/test/proc_binding.rb +22 -0
- data/ext/enclave/mruby/mrbgems/mruby-proc-ext/README.md +107 -0
- data/ext/enclave/mruby/mrbgems/mruby-proc-ext/mrbgem.rake +5 -0
- data/ext/enclave/mruby/mrbgems/mruby-proc-ext/mrblib/proc.rb +130 -0
- data/ext/enclave/mruby/mrbgems/mruby-proc-ext/src/proc.c +267 -0
- data/ext/enclave/mruby/mrbgems/mruby-proc-ext/test/proc.c +62 -0
- data/ext/enclave/mruby/mrbgems/mruby-proc-ext/test/proc.rb +130 -0
- data/ext/enclave/mruby/mrbgems/mruby-random/README.md +272 -0
- data/ext/enclave/mruby/mrbgems/mruby-random/mrbgem.rake +5 -0
- data/ext/enclave/mruby/mrbgems/mruby-random/src/random.c +608 -0
- data/ext/enclave/mruby/mrbgems/mruby-random/test/random.rb +151 -0
- data/ext/enclave/mruby/mrbgems/mruby-range-ext/README.md +93 -0
- data/ext/enclave/mruby/mrbgems/mruby-range-ext/mrbgem.rake +5 -0
- data/ext/enclave/mruby/mrbgems/mruby-range-ext/mrblib/range.rb +155 -0
- data/ext/enclave/mruby/mrbgems/mruby-range-ext/src/range.c +236 -0
- data/ext/enclave/mruby/mrbgems/mruby-range-ext/test/range.rb +211 -0
- data/ext/enclave/mruby/mrbgems/mruby-rational/README.md +61 -0
- data/ext/enclave/mruby/mrbgems/mruby-rational/mrbgem.rake +7 -0
- data/ext/enclave/mruby/mrbgems/mruby-rational/mrblib/rational.rb +66 -0
- data/ext/enclave/mruby/mrbgems/mruby-rational/src/rational.c +1269 -0
- data/ext/enclave/mruby/mrbgems/mruby-rational/test/rational.rb +316 -0
- data/ext/enclave/mruby/mrbgems/mruby-set/LICENSE +24 -0
- data/ext/enclave/mruby/mrbgems/mruby-set/README.md +260 -0
- data/ext/enclave/mruby/mrbgems/mruby-set/mrbgem.rake +9 -0
- data/ext/enclave/mruby/mrbgems/mruby-set/mrblib/set.rb +325 -0
- data/ext/enclave/mruby/mrbgems/mruby-set/mruby-set.gem +6 -0
- data/ext/enclave/mruby/mrbgems/mruby-set/src/set.c +1535 -0
- data/ext/enclave/mruby/mrbgems/mruby-set/test/set.rb +764 -0
- data/ext/enclave/mruby/mrbgems/mruby-sleep/README.md +29 -0
- data/ext/enclave/mruby/mrbgems/mruby-sleep/example/sleep.rb +2 -0
- data/ext/enclave/mruby/mrbgems/mruby-sleep/mrbgem.rake +5 -0
- data/ext/enclave/mruby/mrbgems/mruby-sleep/src/sleep.c +187 -0
- data/ext/enclave/mruby/mrbgems/mruby-sleep/test/sleep_test.rb +29 -0
- data/ext/enclave/mruby/mrbgems/mruby-socket/README.md +56 -0
- data/ext/enclave/mruby/mrbgems/mruby-socket/include/socket_hal.h +83 -0
- data/ext/enclave/mruby/mrbgems/mruby-socket/mrbgem.rake +37 -0
- data/ext/enclave/mruby/mrbgems/mruby-socket/mrblib/socket.rb +1131 -0
- data/ext/enclave/mruby/mrbgems/mruby-socket/src/const.cstub +480 -0
- data/ext/enclave/mruby/mrbgems/mruby-socket/src/const.def +172 -0
- data/ext/enclave/mruby/mrbgems/mruby-socket/src/gen.rb +17 -0
- data/ext/enclave/mruby/mrbgems/mruby-socket/src/socket.c +1374 -0
- data/ext/enclave/mruby/mrbgems/mruby-socket/test/addrinfo.rb +91 -0
- data/ext/enclave/mruby/mrbgems/mruby-socket/test/basicsocket.rb +17 -0
- data/ext/enclave/mruby/mrbgems/mruby-socket/test/ipsocket.rb +44 -0
- data/ext/enclave/mruby/mrbgems/mruby-socket/test/socket.rb +38 -0
- data/ext/enclave/mruby/mrbgems/mruby-socket/test/sockettest.c +84 -0
- data/ext/enclave/mruby/mrbgems/mruby-socket/test/tcpsocket.rb +4 -0
- data/ext/enclave/mruby/mrbgems/mruby-socket/test/udpsocket.rb +16 -0
- data/ext/enclave/mruby/mrbgems/mruby-socket/test/unix.rb +130 -0
- data/ext/enclave/mruby/mrbgems/mruby-sprintf/README.md +235 -0
- data/ext/enclave/mruby/mrbgems/mruby-sprintf/mrbgem.rake +5 -0
- data/ext/enclave/mruby/mrbgems/mruby-sprintf/mrblib/string.rb +24 -0
- data/ext/enclave/mruby/mrbgems/mruby-sprintf/src/sprintf.c +1195 -0
- data/ext/enclave/mruby/mrbgems/mruby-sprintf/test/sprintf.rb +92 -0
- data/ext/enclave/mruby/mrbgems/mruby-strftime/README.md +140 -0
- data/ext/enclave/mruby/mrbgems/mruby-strftime/mrbgem.rake +7 -0
- data/ext/enclave/mruby/mrbgems/mruby-strftime/src/strftime.c +119 -0
- data/ext/enclave/mruby/mrbgems/mruby-strftime/test/strftime.rb +152 -0
- data/ext/enclave/mruby/mrbgems/mruby-string-ext/README.md +886 -0
- data/ext/enclave/mruby/mrbgems/mruby-string-ext/mrbgem.rake +5 -0
- data/ext/enclave/mruby/mrbgems/mruby-string-ext/mrblib/string.rb +166 -0
- data/ext/enclave/mruby/mrbgems/mruby-string-ext/src/string.c +2290 -0
- data/ext/enclave/mruby/mrbgems/mruby-string-ext/test/numeric.rb +27 -0
- data/ext/enclave/mruby/mrbgems/mruby-string-ext/test/range.rb +26 -0
- data/ext/enclave/mruby/mrbgems/mruby-string-ext/test/string.rb +765 -0
- data/ext/enclave/mruby/mrbgems/mruby-struct/README.md +105 -0
- data/ext/enclave/mruby/mrbgems/mruby-struct/mrbgem.rake +5 -0
- data/ext/enclave/mruby/mrbgems/mruby-struct/mrblib/struct.rb +69 -0
- data/ext/enclave/mruby/mrbgems/mruby-struct/src/struct.c +812 -0
- data/ext/enclave/mruby/mrbgems/mruby-struct/test/struct.rb +303 -0
- data/ext/enclave/mruby/mrbgems/mruby-symbol-ext/README.md +50 -0
- data/ext/enclave/mruby/mrbgems/mruby-symbol-ext/mrbgem.rake +5 -0
- data/ext/enclave/mruby/mrbgems/mruby-symbol-ext/mrblib/symbol.rb +72 -0
- data/ext/enclave/mruby/mrbgems/mruby-symbol-ext/src/symbol.c +79 -0
- data/ext/enclave/mruby/mrbgems/mruby-symbol-ext/test/symbol.rb +55 -0
- data/ext/enclave/mruby/mrbgems/mruby-task/README.md +770 -0
- data/ext/enclave/mruby/mrbgems/mruby-task/examples/inspection.rb +65 -0
- data/ext/enclave/mruby/mrbgems/mruby-task/examples/priority.rb +41 -0
- data/ext/enclave/mruby/mrbgems/mruby-task/examples/producer_consumer.rb +58 -0
- data/ext/enclave/mruby/mrbgems/mruby-task/examples/simple.rb +27 -0
- data/ext/enclave/mruby/mrbgems/mruby-task/examples/statistics.rb +59 -0
- data/ext/enclave/mruby/mrbgems/mruby-task/examples/suspend_resume.rb +47 -0
- data/ext/enclave/mruby/mrbgems/mruby-task/examples/task_pass.rb +21 -0
- data/ext/enclave/mruby/mrbgems/mruby-task/include/task.h +143 -0
- data/ext/enclave/mruby/mrbgems/mruby-task/include/task_hal.h +162 -0
- data/ext/enclave/mruby/mrbgems/mruby-task/mrbgem.rake +36 -0
- data/ext/enclave/mruby/mrbgems/mruby-task/src/task.c +1573 -0
- data/ext/enclave/mruby/mrbgems/mruby-task/test/task.rb +185 -0
- data/ext/enclave/mruby/mrbgems/mruby-test/README.md +7 -0
- data/ext/enclave/mruby/mrbgems/mruby-test/driver.c +315 -0
- data/ext/enclave/mruby/mrbgems/mruby-test/mrbgem.rake +173 -0
- data/ext/enclave/mruby/mrbgems/mruby-test/vformat.c +151 -0
- data/ext/enclave/mruby/mrbgems/mruby-test-inline-struct/mrbgem.rake +5 -0
- data/ext/enclave/mruby/mrbgems/mruby-test-inline-struct/test/inline.c +92 -0
- data/ext/enclave/mruby/mrbgems/mruby-test-inline-struct/test/inline.rb +118 -0
- data/ext/enclave/mruby/mrbgems/mruby-time/README.md +102 -0
- data/ext/enclave/mruby/mrbgems/mruby-time/include/mruby/time.h +27 -0
- data/ext/enclave/mruby/mrbgems/mruby-time/mrbgem.rake +5 -0
- data/ext/enclave/mruby/mrbgems/mruby-time/src/time.c +1739 -0
- data/ext/enclave/mruby/mrbgems/mruby-time/test/time.rb +313 -0
- data/ext/enclave/mruby/mrbgems/mruby-toplevel-ext/README.md +32 -0
- data/ext/enclave/mruby/mrbgems/mruby-toplevel-ext/mrbgem.rake +5 -0
- data/ext/enclave/mruby/mrbgems/mruby-toplevel-ext/mrblib/toplevel.rb +24 -0
- data/ext/enclave/mruby/mrbgems/mruby-toplevel-ext/test/toplevel.rb +23 -0
- data/ext/enclave/mruby/mrbgems/stdlib-ext.gembox +21 -0
- data/ext/enclave/mruby/mrbgems/stdlib-io.gembox +15 -0
- data/ext/enclave/mruby/mrbgems/stdlib.gembox +63 -0
- data/ext/enclave/mruby/mrblib/10error.rb +23 -0
- data/ext/enclave/mruby/mrblib/array.rb +102 -0
- data/ext/enclave/mruby/mrblib/compar.rb +102 -0
- data/ext/enclave/mruby/mrblib/enum.rb +358 -0
- data/ext/enclave/mruby/mrblib/hash.rb +276 -0
- data/ext/enclave/mruby/mrblib/kernel.rb +45 -0
- data/ext/enclave/mruby/mrblib/numeric.rb +160 -0
- data/ext/enclave/mruby/mrblib/range.rb +98 -0
- data/ext/enclave/mruby/mrblib/string.rb +173 -0
- data/ext/enclave/mruby/mrblib/symbol.rb +8 -0
- data/ext/enclave/mruby/oss-fuzz/mruby_fuzzer.c +18 -0
- data/ext/enclave/mruby/oss-fuzz/proto_to_ruby.h +55 -0
- data/ext/enclave/mruby/src/allocf.c +37 -0
- data/ext/enclave/mruby/src/array.c +2302 -0
- data/ext/enclave/mruby/src/backtrace.c +294 -0
- data/ext/enclave/mruby/src/cdump.c +498 -0
- data/ext/enclave/mruby/src/class.c +4394 -0
- data/ext/enclave/mruby/src/codedump.c +693 -0
- data/ext/enclave/mruby/src/debug.c +290 -0
- data/ext/enclave/mruby/src/dump.c +998 -0
- data/ext/enclave/mruby/src/enum.c +30 -0
- data/ext/enclave/mruby/src/error.c +937 -0
- data/ext/enclave/mruby/src/etc.c +421 -0
- data/ext/enclave/mruby/src/fmt_fp.c +372 -0
- data/ext/enclave/mruby/src/gc.c +1610 -0
- data/ext/enclave/mruby/src/hash.c +2355 -0
- data/ext/enclave/mruby/src/init.c +50 -0
- data/ext/enclave/mruby/src/kernel.c +718 -0
- data/ext/enclave/mruby/src/load.c +760 -0
- data/ext/enclave/mruby/src/mempool.c +225 -0
- data/ext/enclave/mruby/src/numeric.c +2420 -0
- data/ext/enclave/mruby/src/numops.c +112 -0
- data/ext/enclave/mruby/src/object.c +883 -0
- data/ext/enclave/mruby/src/print.c +136 -0
- data/ext/enclave/mruby/src/proc.c +572 -0
- data/ext/enclave/mruby/src/range.c +597 -0
- data/ext/enclave/mruby/src/readfloat.c +228 -0
- data/ext/enclave/mruby/src/readint.c +27 -0
- data/ext/enclave/mruby/src/readnum.c +43 -0
- data/ext/enclave/mruby/src/state.c +247 -0
- data/ext/enclave/mruby/src/string.c +3577 -0
- data/ext/enclave/mruby/src/symbol.c +1023 -0
- data/ext/enclave/mruby/src/value_array.h +28 -0
- data/ext/enclave/mruby/src/variable.c +1475 -0
- data/ext/enclave/mruby/src/version.c +17 -0
- data/ext/enclave/mruby/src/vm.c +3696 -0
- data/ext/enclave/mruby/tasks/amalgam.rake +34 -0
- data/ext/enclave/mruby/tasks/benchmark.rake +93 -0
- data/ext/enclave/mruby/tasks/bin.rake +23 -0
- data/ext/enclave/mruby/tasks/core.rake +12 -0
- data/ext/enclave/mruby/tasks/doc.rake +118 -0
- data/ext/enclave/mruby/tasks/install.rake +40 -0
- data/ext/enclave/mruby/tasks/libmruby.rake +90 -0
- data/ext/enclave/mruby/tasks/mrbgems.rake +152 -0
- data/ext/enclave/mruby/tasks/mrblib.rake +29 -0
- data/ext/enclave/mruby/tasks/presym.rake +57 -0
- data/ext/enclave/mruby/tasks/test.rake +84 -0
- data/ext/enclave/mruby/tasks/toolchains/android.rake +228 -0
- data/ext/enclave/mruby/tasks/toolchains/clang.rake +8 -0
- data/ext/enclave/mruby/tasks/toolchains/emscripten.rake +57 -0
- data/ext/enclave/mruby/tasks/toolchains/gcc.rake +74 -0
- data/ext/enclave/mruby/tasks/toolchains/openwrt.rake +32 -0
- data/ext/enclave/mruby/tasks/toolchains/visualcpp.rake +48 -0
- data/ext/enclave/mruby/test/assert.rb +404 -0
- data/ext/enclave/mruby/test/bintest.rb +55 -0
- data/ext/enclave/mruby/test/t/argumenterror.rb +37 -0
- data/ext/enclave/mruby/test/t/array.rb +478 -0
- data/ext/enclave/mruby/test/t/basicobject.rb +10 -0
- data/ext/enclave/mruby/test/t/bs_block.rb +621 -0
- data/ext/enclave/mruby/test/t/bs_literal.rb +38 -0
- data/ext/enclave/mruby/test/t/class.rb +505 -0
- data/ext/enclave/mruby/test/t/codegen.rb +196 -0
- data/ext/enclave/mruby/test/t/comparable.rb +79 -0
- data/ext/enclave/mruby/test/t/ensure.rb +36 -0
- data/ext/enclave/mruby/test/t/enumerable.rb +134 -0
- data/ext/enclave/mruby/test/t/exception.rb +425 -0
- data/ext/enclave/mruby/test/t/false.rb +31 -0
- data/ext/enclave/mruby/test/t/float.rb +296 -0
- data/ext/enclave/mruby/test/t/gc.rb +45 -0
- data/ext/enclave/mruby/test/t/hash.rb +976 -0
- data/ext/enclave/mruby/test/t/indexerror.rb +6 -0
- data/ext/enclave/mruby/test/t/integer.rb +247 -0
- data/ext/enclave/mruby/test/t/iterations.rb +61 -0
- data/ext/enclave/mruby/test/t/kernel.rb +462 -0
- data/ext/enclave/mruby/test/t/lang.rb +74 -0
- data/ext/enclave/mruby/test/t/literals.rb +386 -0
- data/ext/enclave/mruby/test/t/localjumperror.rb +13 -0
- data/ext/enclave/mruby/test/t/methods.rb +138 -0
- data/ext/enclave/mruby/test/t/module.rb +931 -0
- data/ext/enclave/mruby/test/t/nameerror.rb +28 -0
- data/ext/enclave/mruby/test/t/nil.rb +39 -0
- data/ext/enclave/mruby/test/t/nomethoderror.rb +22 -0
- data/ext/enclave/mruby/test/t/numeric.rb +114 -0
- data/ext/enclave/mruby/test/t/object.rb +10 -0
- data/ext/enclave/mruby/test/t/proc.rb +198 -0
- data/ext/enclave/mruby/test/t/range.rb +194 -0
- data/ext/enclave/mruby/test/t/rangeerror.rb +6 -0
- data/ext/enclave/mruby/test/t/regexperror.rb +4 -0
- data/ext/enclave/mruby/test/t/runtimeerror.rb +6 -0
- data/ext/enclave/mruby/test/t/standarderror.rb +6 -0
- data/ext/enclave/mruby/test/t/string.rb +981 -0
- data/ext/enclave/mruby/test/t/superclass.rb +46 -0
- data/ext/enclave/mruby/test/t/symbol.rb +30 -0
- data/ext/enclave/mruby/test/t/syntax.rb +1296 -0
- data/ext/enclave/mruby/test/t/true.rb +31 -0
- data/ext/enclave/mruby/test/t/typeerror.rb +6 -0
- data/ext/enclave/mruby/test/t/unicode.rb +39 -0
- data/ext/enclave/mruby/test/t/vformat.rb +57 -0
- data/ext/enclave/mruby/tools/lrama/LEGAL.md +12 -0
- data/ext/enclave/mruby/tools/lrama/MIT +21 -0
- data/ext/enclave/mruby/tools/lrama/NEWS.md +696 -0
- data/ext/enclave/mruby/tools/lrama/exe/lrama +7 -0
- data/ext/enclave/mruby/tools/lrama/lib/lrama/bitmap.rb +34 -0
- data/ext/enclave/mruby/tools/lrama/lib/lrama/command.rb +68 -0
- data/ext/enclave/mruby/tools/lrama/lib/lrama/context.rb +499 -0
- data/ext/enclave/mruby/tools/lrama/lib/lrama/counterexamples/derivation.rb +66 -0
- data/ext/enclave/mruby/tools/lrama/lib/lrama/counterexamples/example.rb +129 -0
- data/ext/enclave/mruby/tools/lrama/lib/lrama/counterexamples/path.rb +29 -0
- data/ext/enclave/mruby/tools/lrama/lib/lrama/counterexamples/production_path.rb +19 -0
- data/ext/enclave/mruby/tools/lrama/lib/lrama/counterexamples/start_path.rb +23 -0
- data/ext/enclave/mruby/tools/lrama/lib/lrama/counterexamples/state_item.rb +8 -0
- data/ext/enclave/mruby/tools/lrama/lib/lrama/counterexamples/transition_path.rb +19 -0
- data/ext/enclave/mruby/tools/lrama/lib/lrama/counterexamples/triple.rb +23 -0
- data/ext/enclave/mruby/tools/lrama/lib/lrama/counterexamples.rb +298 -0
- data/ext/enclave/mruby/tools/lrama/lib/lrama/diagnostics.rb +36 -0
- data/ext/enclave/mruby/tools/lrama/lib/lrama/digraph.rb +83 -0
- data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar/auxiliary.rb +9 -0
- data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar/binding.rb +67 -0
- data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar/code/destructor_code.rb +42 -0
- data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar/code/initial_action_code.rb +36 -0
- data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar/code/no_reference_code.rb +30 -0
- data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar/code/printer_code.rb +42 -0
- data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar/code/rule_action.rb +92 -0
- data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar/code.rb +53 -0
- data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar/counter.rb +17 -0
- data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar/destructor.rb +11 -0
- data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar/error_token.rb +11 -0
- data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar/parameterizing_rule/resolver.rb +62 -0
- data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar/parameterizing_rule/rhs.rb +40 -0
- data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar/parameterizing_rule/rule.rb +24 -0
- data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar/parameterizing_rule.rb +5 -0
- data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar/percent_code.rb +14 -0
- data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar/precedence.rb +13 -0
- data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar/printer.rb +11 -0
- data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar/reference.rb +16 -0
- data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar/rule.rb +75 -0
- data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar/rule_builder.rb +255 -0
- data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar/stdlib.y +122 -0
- data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar/symbol.rb +105 -0
- data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar/symbols/resolver.rb +301 -0
- data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar/symbols.rb +3 -0
- data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar/type.rb +20 -0
- data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar/union.rb +12 -0
- data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar.rb +407 -0
- data/ext/enclave/mruby/tools/lrama/lib/lrama/grammar_validator.rb +37 -0
- data/ext/enclave/mruby/tools/lrama/lib/lrama/lexer/grammar_file.rb +40 -0
- data/ext/enclave/mruby/tools/lrama/lib/lrama/lexer/location.rb +115 -0
- data/ext/enclave/mruby/tools/lrama/lib/lrama/lexer/token/char.rb +11 -0
- data/ext/enclave/mruby/tools/lrama/lib/lrama/lexer/token/ident.rb +11 -0
- data/ext/enclave/mruby/tools/lrama/lib/lrama/lexer/token/instantiate_rule.rb +30 -0
- data/ext/enclave/mruby/tools/lrama/lib/lrama/lexer/token/tag.rb +16 -0
- data/ext/enclave/mruby/tools/lrama/lib/lrama/lexer/token/user_code.rb +83 -0
- data/ext/enclave/mruby/tools/lrama/lib/lrama/lexer/token.rb +70 -0
- data/ext/enclave/mruby/tools/lrama/lib/lrama/lexer.rb +191 -0
- data/ext/enclave/mruby/tools/lrama/lib/lrama/logger.rb +21 -0
- data/ext/enclave/mruby/tools/lrama/lib/lrama/option_parser.rb +169 -0
- data/ext/enclave/mruby/tools/lrama/lib/lrama/options.rb +28 -0
- data/ext/enclave/mruby/tools/lrama/lib/lrama/output.rb +459 -0
- data/ext/enclave/mruby/tools/lrama/lib/lrama/parser.rb +2144 -0
- data/ext/enclave/mruby/tools/lrama/lib/lrama/report/duration.rb +27 -0
- data/ext/enclave/mruby/tools/lrama/lib/lrama/report/profile.rb +16 -0
- data/ext/enclave/mruby/tools/lrama/lib/lrama/report.rb +4 -0
- data/ext/enclave/mruby/tools/lrama/lib/lrama/state/reduce.rb +37 -0
- data/ext/enclave/mruby/tools/lrama/lib/lrama/state/reduce_reduce_conflict.rb +11 -0
- data/ext/enclave/mruby/tools/lrama/lib/lrama/state/resolved_conflict.rb +31 -0
- data/ext/enclave/mruby/tools/lrama/lib/lrama/state/shift.rb +15 -0
- data/ext/enclave/mruby/tools/lrama/lib/lrama/state/shift_reduce_conflict.rb +11 -0
- data/ext/enclave/mruby/tools/lrama/lib/lrama/state.rb +433 -0
- data/ext/enclave/mruby/tools/lrama/lib/lrama/states/item.rb +91 -0
- data/ext/enclave/mruby/tools/lrama/lib/lrama/states.rb +595 -0
- data/ext/enclave/mruby/tools/lrama/lib/lrama/states_reporter.rb +362 -0
- data/ext/enclave/mruby/tools/lrama/lib/lrama/trace_reporter.rb +45 -0
- data/ext/enclave/mruby/tools/lrama/lib/lrama/version.rb +5 -0
- data/ext/enclave/mruby/tools/lrama/lib/lrama.rb +22 -0
- data/ext/enclave/mruby/tools/lrama/template/bison/_yacc.h +71 -0
- data/ext/enclave/mruby/tools/lrama/template/bison/yacc.c +2068 -0
- data/ext/enclave/mruby/tools/lrama/template/bison/yacc.h +40 -0
- data/ext/enclave/sandbox_build_config.rb +15 -0
- data/ext/enclave/sandbox_core.c +722 -0
- data/ext/enclave/sandbox_core.h +87 -0
- data/lib/enclave/result.rb +29 -0
- data/lib/enclave/tool.rb +38 -0
- data/lib/enclave/version.rb +3 -0
- data/lib/enclave.rb +73 -0
- metadata +819 -0
|
@@ -0,0 +1,1573 @@
|
|
|
1
|
+
/*
|
|
2
|
+
** task.c - Task scheduler
|
|
3
|
+
**
|
|
4
|
+
** See Copyright Notice in mruby.h
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
#include <mruby.h>
|
|
8
|
+
#include <mruby/array.h>
|
|
9
|
+
#include <mruby/class.h>
|
|
10
|
+
#include <mruby/data.h>
|
|
11
|
+
#include <mruby/error.h>
|
|
12
|
+
#include <mruby/gc.h>
|
|
13
|
+
#include <mruby/hash.h>
|
|
14
|
+
#include <mruby/internal.h>
|
|
15
|
+
#include <mruby/presym.h>
|
|
16
|
+
#include <mruby/proc.h>
|
|
17
|
+
#include <mruby/string.h>
|
|
18
|
+
#include <mruby/variable.h>
|
|
19
|
+
#include <string.h>
|
|
20
|
+
#include <stdint.h>
|
|
21
|
+
#include <stdlib.h>
|
|
22
|
+
#include "task.h"
|
|
23
|
+
#include "task_hal.h"
|
|
24
|
+
|
|
25
|
+
/*
|
|
26
|
+
* Queue helper macros
|
|
27
|
+
*/
|
|
28
|
+
#define q_dormant_ (mrb->task.queues[MRB_TASK_QUEUE_DORMANT])
|
|
29
|
+
#define q_ready_ (mrb->task.queues[MRB_TASK_QUEUE_READY])
|
|
30
|
+
#define q_waiting_ (mrb->task.queues[MRB_TASK_QUEUE_WAITING])
|
|
31
|
+
#define q_suspended_ (mrb->task.queues[MRB_TASK_QUEUE_SUSPENDED])
|
|
32
|
+
#define tick_ (mrb->task.tick)
|
|
33
|
+
#define wakeup_tick_ (mrb->task.wakeup_tick)
|
|
34
|
+
#define switching_ (mrb->task.switching)
|
|
35
|
+
|
|
36
|
+
/* Get task from current context using pointer arithmetic */
|
|
37
|
+
#define MRB2TASK(mrb) ((mrb_task *)((uint8_t *)mrb->c - offsetof(mrb_task, c)))
|
|
38
|
+
|
|
39
|
+
/* Get task pointer from self with validation */
|
|
40
|
+
#define TASK_GET_PTR_OR_RAISE(var, self) \
|
|
41
|
+
do { \
|
|
42
|
+
(var) = (mrb_task*)mrb_data_get_ptr(mrb, (self), &mrb_task_type); \
|
|
43
|
+
if (!(var)) { \
|
|
44
|
+
mrb_raise(mrb, E_ARGUMENT_ERROR, "invalid task"); \
|
|
45
|
+
} \
|
|
46
|
+
} while (0)
|
|
47
|
+
|
|
48
|
+
/* Convert microseconds to tick count */
|
|
49
|
+
#define USEC_TO_TICKS(usec) (((usec) / 1000) / MRB_TICK_UNIT)
|
|
50
|
+
|
|
51
|
+
/* Maximum value for scheduler_lock (uint8_t max) */
|
|
52
|
+
#define MRB_TASK_SCHEDULER_LOCK_MAX 255
|
|
53
|
+
|
|
54
|
+
/* Check scheduler lock and raise error if locked */
|
|
55
|
+
static inline void
|
|
56
|
+
task_check_scheduler_lock(mrb_state *mrb)
|
|
57
|
+
{
|
|
58
|
+
if (mrb->task.scheduler_lock > 0) {
|
|
59
|
+
mrb_raise(mrb, E_RUNTIME_ERROR, "Cannot use asynchronous Task API during synchronous execution");
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/*
|
|
64
|
+
* Task data type for GC
|
|
65
|
+
*/
|
|
66
|
+
static void
|
|
67
|
+
mrb_task_free(mrb_state *mrb, void *ptr)
|
|
68
|
+
{
|
|
69
|
+
mrb_task *t = (mrb_task*)ptr;
|
|
70
|
+
if (t) {
|
|
71
|
+
/* Unregister from GC protection (unless it's the main task during shutdown) */
|
|
72
|
+
if (t != mrb->task.main_task) {
|
|
73
|
+
mrb_gc_unregister(mrb, t->self);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/* Free context resources - always free if allocated */
|
|
77
|
+
/* Main task never has allocated context (stbase/cibase are NULL) */
|
|
78
|
+
if (t->c.stbase) {
|
|
79
|
+
mrb_free(mrb, t->c.stbase);
|
|
80
|
+
}
|
|
81
|
+
if (t->c.cibase) {
|
|
82
|
+
mrb_free(mrb, t->c.cibase);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/* Free the task structure itself */
|
|
86
|
+
mrb_free(mrb, t);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
static const struct mrb_data_type mrb_task_type = {
|
|
91
|
+
"Task", mrb_task_free,
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
/*
|
|
95
|
+
* GC marking function for all tasks
|
|
96
|
+
* Called from gc.c during root_scan_phase
|
|
97
|
+
*/
|
|
98
|
+
void
|
|
99
|
+
mrb_task_mark_all(mrb_state *mrb)
|
|
100
|
+
{
|
|
101
|
+
int qi;
|
|
102
|
+
for (qi = 0; qi < 4; qi++) {
|
|
103
|
+
mrb_task *t = mrb->task.queues[qi];
|
|
104
|
+
while (t) {
|
|
105
|
+
struct mrb_context *c = &t->c;
|
|
106
|
+
mrb_callinfo *ci;
|
|
107
|
+
size_t i, e;
|
|
108
|
+
|
|
109
|
+
/* Mark task's stack */
|
|
110
|
+
if (c->stbase) {
|
|
111
|
+
if (c->ci) {
|
|
112
|
+
e = (c->ci->stack ? c->ci->stack - c->stbase : 0);
|
|
113
|
+
e += mrb_ci_nregs(c->ci);
|
|
114
|
+
}
|
|
115
|
+
else {
|
|
116
|
+
e = 0;
|
|
117
|
+
}
|
|
118
|
+
if (c->stbase + e > c->stend) e = c->stend - c->stbase;
|
|
119
|
+
for (i = 0; i < e; i++) {
|
|
120
|
+
mrb_gc_mark_value(mrb, c->stbase[i]);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/* Mark call stack */
|
|
125
|
+
if (c->cibase && c->ci) {
|
|
126
|
+
for (ci = c->cibase; ci <= c->ci; ci++) {
|
|
127
|
+
if (ci->proc) {
|
|
128
|
+
mrb_gc_mark(mrb, (struct RBasic*)ci->proc);
|
|
129
|
+
}
|
|
130
|
+
if (ci->u.target_class) {
|
|
131
|
+
mrb_gc_mark(mrb, (struct RBasic*)ci->u.target_class);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/* Mark fiber */
|
|
137
|
+
mrb_gc_mark(mrb, (struct RBasic*)c->fib);
|
|
138
|
+
|
|
139
|
+
/* Mark task-specific values */
|
|
140
|
+
mrb_gc_mark_value(mrb, t->self);
|
|
141
|
+
if (t->status == MRB_TASK_STATUS_DORMANT) {
|
|
142
|
+
mrb_gc_mark_value(mrb, t->state.result);
|
|
143
|
+
}
|
|
144
|
+
mrb_gc_mark_value(mrb, t->name);
|
|
145
|
+
|
|
146
|
+
t = t->next;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/*
|
|
152
|
+
* Queue operations
|
|
153
|
+
*/
|
|
154
|
+
|
|
155
|
+
/* Get queue head pointer based on task status */
|
|
156
|
+
static mrb_task**
|
|
157
|
+
q_get_queue(mrb_state *mrb, mrb_task *t)
|
|
158
|
+
{
|
|
159
|
+
switch (t->status) {
|
|
160
|
+
case MRB_TASK_STATUS_DORMANT:
|
|
161
|
+
return &q_dormant_;
|
|
162
|
+
case MRB_TASK_STATUS_READY:
|
|
163
|
+
case MRB_TASK_STATUS_RUNNING:
|
|
164
|
+
return &q_ready_;
|
|
165
|
+
case MRB_TASK_STATUS_WAITING:
|
|
166
|
+
return &q_waiting_;
|
|
167
|
+
case MRB_TASK_STATUS_SUSPENDED:
|
|
168
|
+
return &q_suspended_;
|
|
169
|
+
default:
|
|
170
|
+
return &q_dormant_;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/* Insert task into queue based on priority (higher priority = lower number = earlier in queue) */
|
|
175
|
+
static void
|
|
176
|
+
q_insert_task(mrb_state *mrb, mrb_task *t)
|
|
177
|
+
{
|
|
178
|
+
mrb_task **q = q_get_queue(mrb, t);
|
|
179
|
+
mrb_task *curr = *q;
|
|
180
|
+
mrb_task *prev = NULL;
|
|
181
|
+
|
|
182
|
+
/* Find insertion point - insert before first task with lower priority */
|
|
183
|
+
while (curr != NULL && curr->priority <= t->priority) {
|
|
184
|
+
prev = curr;
|
|
185
|
+
curr = curr->next;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/* Insert task */
|
|
189
|
+
t->next = curr;
|
|
190
|
+
if (prev == NULL) {
|
|
191
|
+
*q = t; /* Insert at head */
|
|
192
|
+
}
|
|
193
|
+
else {
|
|
194
|
+
prev->next = t; /* Insert after prev */
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
/* Delete task from its current queue */
|
|
199
|
+
static void
|
|
200
|
+
q_delete_task(mrb_state *mrb, mrb_task *t)
|
|
201
|
+
{
|
|
202
|
+
mrb_task **q = q_get_queue(mrb, t);
|
|
203
|
+
mrb_task *curr = *q;
|
|
204
|
+
mrb_task *prev = NULL;
|
|
205
|
+
|
|
206
|
+
/* Find and remove task */
|
|
207
|
+
while (curr != NULL) {
|
|
208
|
+
if (curr == t) {
|
|
209
|
+
if (prev == NULL) {
|
|
210
|
+
*q = curr->next; /* Remove from head */
|
|
211
|
+
}
|
|
212
|
+
else {
|
|
213
|
+
prev->next = curr->next; /* Remove from middle/end */
|
|
214
|
+
}
|
|
215
|
+
t->next = NULL;
|
|
216
|
+
return;
|
|
217
|
+
}
|
|
218
|
+
prev = curr;
|
|
219
|
+
curr = curr->next;
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
/* Cleanup terminated task and move to dormant queue if needed */
|
|
224
|
+
static inline mrb_bool
|
|
225
|
+
task_cleanup_if_stopped(mrb_state *mrb, mrb_task *t)
|
|
226
|
+
{
|
|
227
|
+
if (t->status == MRB_TASK_STATUS_DORMANT || t->c.status == MRB_TASK_STOPPED) {
|
|
228
|
+
/* Task is terminated but still in queue - remove it */
|
|
229
|
+
mrb_task_disable_irq();
|
|
230
|
+
q_delete_task(mrb, t);
|
|
231
|
+
if (t->status != MRB_TASK_STATUS_DORMANT) {
|
|
232
|
+
t->status = MRB_TASK_STATUS_DORMANT;
|
|
233
|
+
q_insert_task(mrb, t);
|
|
234
|
+
}
|
|
235
|
+
mrb_task_enable_irq();
|
|
236
|
+
return TRUE;
|
|
237
|
+
}
|
|
238
|
+
return FALSE;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
/*
|
|
242
|
+
* Task lifecycle
|
|
243
|
+
*/
|
|
244
|
+
|
|
245
|
+
/* Allocate new task */
|
|
246
|
+
static mrb_task*
|
|
247
|
+
task_alloc(mrb_state *mrb)
|
|
248
|
+
{
|
|
249
|
+
mrb_task *t = (mrb_task*)mrb_malloc(mrb, sizeof(mrb_task));
|
|
250
|
+
memset(t, 0, sizeof(mrb_task));
|
|
251
|
+
return t;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
/* Initialize task context (stack and callinfo) - similar to Fiber */
|
|
255
|
+
static void
|
|
256
|
+
task_init_context(mrb_state *mrb, mrb_task *t, const struct RProc *proc)
|
|
257
|
+
{
|
|
258
|
+
static const struct mrb_context mrb_context_zero = { 0 };
|
|
259
|
+
struct mrb_context *c = &t->c;
|
|
260
|
+
|
|
261
|
+
*c = mrb_context_zero;
|
|
262
|
+
|
|
263
|
+
/* Initialize VM stack */
|
|
264
|
+
size_t slen = TASK_STACK_INIT_SIZE;
|
|
265
|
+
if (proc->body.irep->nregs > slen) {
|
|
266
|
+
slen += proc->body.irep->nregs;
|
|
267
|
+
}
|
|
268
|
+
c->stbase = (mrb_value*)mrb_malloc(mrb, slen * sizeof(mrb_value));
|
|
269
|
+
c->stend = c->stbase + slen;
|
|
270
|
+
|
|
271
|
+
/* Initialize stack values to nil */
|
|
272
|
+
{
|
|
273
|
+
mrb_value *s = c->stbase + 1;
|
|
274
|
+
mrb_value *send = c->stend;
|
|
275
|
+
while (s < send) {
|
|
276
|
+
SET_NIL_VALUE(*s);
|
|
277
|
+
s++;
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
/* Set receiver to top self */
|
|
282
|
+
c->stbase[0] = mrb_top_self(mrb);
|
|
283
|
+
|
|
284
|
+
/* Initialize callinfo stack */
|
|
285
|
+
static const mrb_callinfo ci_zero = { 0 };
|
|
286
|
+
c->cibase = (mrb_callinfo*)mrb_malloc(mrb, TASK_CI_INIT_SIZE * sizeof(mrb_callinfo));
|
|
287
|
+
c->ciend = c->cibase + TASK_CI_INIT_SIZE;
|
|
288
|
+
c->ci = c->cibase;
|
|
289
|
+
c->cibase[0] = ci_zero;
|
|
290
|
+
|
|
291
|
+
/* Setup callinfo */
|
|
292
|
+
mrb_callinfo *ci = c->ci;
|
|
293
|
+
mrb_vm_ci_target_class_set(ci, MRB_PROC_TARGET_CLASS(proc));
|
|
294
|
+
mrb_vm_ci_proc_set(ci, proc);
|
|
295
|
+
ci->stack = c->stbase;
|
|
296
|
+
ci->pc = proc->body.irep->iseq; /* Initialize PC to start of bytecode */
|
|
297
|
+
|
|
298
|
+
c->status = MRB_TASK_CREATED;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
/*
|
|
302
|
+
* Scheduler core
|
|
303
|
+
*/
|
|
304
|
+
|
|
305
|
+
/* Wake up tasks waiting on join for a completed task */
|
|
306
|
+
static void
|
|
307
|
+
wake_up_join_waiters(mrb_state *mrb, mrb_task *completed_task)
|
|
308
|
+
{
|
|
309
|
+
mrb_task *curr = q_waiting_;
|
|
310
|
+
while (curr != NULL) {
|
|
311
|
+
mrb_task *next = curr->next;
|
|
312
|
+
if (curr->reason == MRB_TASK_REASON_JOIN && curr->wait.join == completed_task) {
|
|
313
|
+
mrb_task_disable_irq();
|
|
314
|
+
q_delete_task(mrb, curr);
|
|
315
|
+
curr->status = MRB_TASK_STATUS_READY;
|
|
316
|
+
curr->reason = MRB_TASK_REASON_NONE;
|
|
317
|
+
curr->wait.join = NULL;
|
|
318
|
+
q_insert_task(mrb, curr);
|
|
319
|
+
mrb_task_enable_irq();
|
|
320
|
+
}
|
|
321
|
+
curr = next;
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
/* Change task state with IRQ protection and queue management */
|
|
326
|
+
static void
|
|
327
|
+
task_change_state(mrb_state *mrb, mrb_task *t, uint8_t new_status)
|
|
328
|
+
{
|
|
329
|
+
mrb_task_disable_irq();
|
|
330
|
+
q_delete_task(mrb, t);
|
|
331
|
+
t->status = new_status;
|
|
332
|
+
q_insert_task(mrb, t);
|
|
333
|
+
mrb_task_enable_irq();
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
/* Execute a single task - core task execution logic */
|
|
337
|
+
static void
|
|
338
|
+
execute_task(mrb_state *mrb, mrb_task *t)
|
|
339
|
+
{
|
|
340
|
+
struct mrb_context *prev_c;
|
|
341
|
+
mrb_callinfo *prev_ci;
|
|
342
|
+
uint8_t prev_cci;
|
|
343
|
+
|
|
344
|
+
/* Set task as running */
|
|
345
|
+
t->status = MRB_TASK_STATUS_RUNNING;
|
|
346
|
+
t->state.timeslice = MRB_TIMESLICE_TICK_COUNT;
|
|
347
|
+
|
|
348
|
+
/* Switch to task context */
|
|
349
|
+
prev_c = mrb->c;
|
|
350
|
+
prev_ci = prev_c->ci;
|
|
351
|
+
prev_cci = prev_c->ci->cci;
|
|
352
|
+
t->c.prev = mrb->c;
|
|
353
|
+
mrb->c = &t->c;
|
|
354
|
+
|
|
355
|
+
/* Clear switching flag */
|
|
356
|
+
switching_ = FALSE;
|
|
357
|
+
|
|
358
|
+
/* Save proc and PC to locals before calling mrb_vm_exec */
|
|
359
|
+
const struct RProc *proc = t->c.ci->proc;
|
|
360
|
+
const mrb_code *pc = t->c.ci->pc;
|
|
361
|
+
|
|
362
|
+
/* With C function boundary checks, proc should never be NULL on resume */
|
|
363
|
+
if (!proc) {
|
|
364
|
+
mrb_raise(mrb, E_RUNTIME_ERROR, "task context corrupted: no proc on resume");
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
/* Set vmexec flag to prevent fiber_terminate from being called */
|
|
368
|
+
t->c.vmexec = TRUE;
|
|
369
|
+
|
|
370
|
+
/* Execute task - PC is saved in ci->pc from previous run */
|
|
371
|
+
t->state.result = mrb_vm_exec(mrb, proc, pc);
|
|
372
|
+
|
|
373
|
+
/* Clear vmexec flag */
|
|
374
|
+
t->c.vmexec = FALSE;
|
|
375
|
+
|
|
376
|
+
/* Clear switching flag */
|
|
377
|
+
switching_ = FALSE;
|
|
378
|
+
|
|
379
|
+
/* Restore context */
|
|
380
|
+
mrb->c = prev_c;
|
|
381
|
+
t->c.prev = NULL;
|
|
382
|
+
prev_c->ci = prev_ci;
|
|
383
|
+
prev_ci->cci = prev_cci;
|
|
384
|
+
|
|
385
|
+
/* Handle task termination */
|
|
386
|
+
if (t->c.status == MRB_TASK_STOPPED) {
|
|
387
|
+
switching_ = FALSE;
|
|
388
|
+
mrb_task_disable_irq();
|
|
389
|
+
q_delete_task(mrb, t);
|
|
390
|
+
t->status = MRB_TASK_STATUS_DORMANT;
|
|
391
|
+
q_insert_task(mrb, t);
|
|
392
|
+
mrb_task_enable_irq();
|
|
393
|
+
|
|
394
|
+
/* Wake up tasks waiting on join */
|
|
395
|
+
wake_up_join_waiters(mrb, t);
|
|
396
|
+
}
|
|
397
|
+
else if (t->status == MRB_TASK_STATUS_RUNNING) {
|
|
398
|
+
/* Task yielded but still running - move to ready queue */
|
|
399
|
+
t->status = MRB_TASK_STATUS_READY;
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
/* Tick handler - called by timer interrupt */
|
|
404
|
+
MRB_API void
|
|
405
|
+
mrb_tick(mrb_state *mrb)
|
|
406
|
+
{
|
|
407
|
+
mrb_task *t;
|
|
408
|
+
|
|
409
|
+
/* Increment global tick counter */
|
|
410
|
+
tick_++;
|
|
411
|
+
|
|
412
|
+
/* Decrease timeslice for running task */
|
|
413
|
+
t = q_ready_;
|
|
414
|
+
if (t && t->status == MRB_TASK_STATUS_RUNNING && t->state.timeslice > 0) {
|
|
415
|
+
t->state.timeslice--;
|
|
416
|
+
if (t->state.timeslice == 0) {
|
|
417
|
+
switching_ = TRUE; /* Trigger context switch */
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
/* Wake up sleeping tasks whose wakeup time has passed */
|
|
422
|
+
if ((int32_t)(wakeup_tick_ - tick_) <= 0) {
|
|
423
|
+
mrb_task *curr = q_waiting_;
|
|
424
|
+
mrb_task *next;
|
|
425
|
+
uint32_t next_wakeup = UINT32_MAX;
|
|
426
|
+
|
|
427
|
+
while (curr != NULL) {
|
|
428
|
+
next = curr->next;
|
|
429
|
+
|
|
430
|
+
if (curr->reason == MRB_TASK_REASON_SLEEP) {
|
|
431
|
+
if ((int32_t)(curr->wait.wakeup_tick - tick_) <= 0) {
|
|
432
|
+
/* Time to wake up */
|
|
433
|
+
q_delete_task(mrb, curr);
|
|
434
|
+
curr->status = MRB_TASK_STATUS_READY;
|
|
435
|
+
curr->reason = MRB_TASK_REASON_NONE;
|
|
436
|
+
q_insert_task(mrb, curr);
|
|
437
|
+
switching_ = TRUE;
|
|
438
|
+
}
|
|
439
|
+
else if (curr->wait.wakeup_tick < next_wakeup) {
|
|
440
|
+
next_wakeup = curr->wait.wakeup_tick;
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
curr = next;
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
wakeup_tick_ = next_wakeup;
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
/* Main scheduler loop */
|
|
452
|
+
MRB_API mrb_value
|
|
453
|
+
mrb_task_run(mrb_state *mrb)
|
|
454
|
+
{
|
|
455
|
+
mrb_task *t;
|
|
456
|
+
|
|
457
|
+
while (1) {
|
|
458
|
+
t = q_ready_;
|
|
459
|
+
|
|
460
|
+
/* No task ready - check if all tasks are done */
|
|
461
|
+
if (!t) {
|
|
462
|
+
mrb_task_disable_irq();
|
|
463
|
+
mrb_bool exiting = !q_ready_ && !q_waiting_ && !q_suspended_;
|
|
464
|
+
mrb_task_enable_irq();
|
|
465
|
+
if (exiting) {
|
|
466
|
+
/* All tasks are dormant - scheduler done */
|
|
467
|
+
break;
|
|
468
|
+
}
|
|
469
|
+
/* If there are tasks waiting or suspended, idle */
|
|
470
|
+
mrb_hal_task_idle_cpu(mrb);
|
|
471
|
+
continue;
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
/* Safety check - don't execute terminated tasks */
|
|
475
|
+
if (task_cleanup_if_stopped(mrb, t)) {
|
|
476
|
+
continue;
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
/* Execute task using core logic */
|
|
480
|
+
execute_task(mrb, t);
|
|
481
|
+
|
|
482
|
+
/* Move to end of ready queue if still running (round-robin) */
|
|
483
|
+
if (t->status == MRB_TASK_STATUS_READY) {
|
|
484
|
+
task_change_state(mrb, t, MRB_TASK_STATUS_READY);
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
/* Run incremental GC if active */
|
|
488
|
+
if (mrb->gc.state != MRB_GC_STATE_ROOT) {
|
|
489
|
+
mrb_incremental_gc(mrb);
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
return mrb_nil_value();
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
/* Single-step task execution for WASM event loop integration */
|
|
497
|
+
MRB_API mrb_value
|
|
498
|
+
mrb_task_run_once(mrb_state *mrb)
|
|
499
|
+
{
|
|
500
|
+
mrb_task *t = q_ready_;
|
|
501
|
+
|
|
502
|
+
/* No task ready */
|
|
503
|
+
if (!t) {
|
|
504
|
+
return mrb_nil_value();
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
/* Safety check - don't execute terminated tasks */
|
|
508
|
+
if (task_cleanup_if_stopped(mrb, t)) {
|
|
509
|
+
return mrb_true_value();
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
/* Execute task using core logic */
|
|
513
|
+
execute_task(mrb, t);
|
|
514
|
+
|
|
515
|
+
/* Move to end of ready queue if still ready (round-robin) */
|
|
516
|
+
if (t->status == MRB_TASK_STATUS_READY) {
|
|
517
|
+
task_change_state(mrb, t, MRB_TASK_STATUS_READY);
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
/* Run incremental GC if active */
|
|
521
|
+
if (mrb->gc.state != MRB_GC_STATE_ROOT) {
|
|
522
|
+
mrb_incremental_gc(mrb);
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
return mrb_true_value();
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
/*
|
|
529
|
+
* Sleep operations
|
|
530
|
+
*/
|
|
531
|
+
|
|
532
|
+
static void
|
|
533
|
+
sleep_us_impl(mrb_state *mrb, uint32_t usec)
|
|
534
|
+
{
|
|
535
|
+
mrb_task *t;
|
|
536
|
+
|
|
537
|
+
/* Check if we're in a task context */
|
|
538
|
+
if (mrb->c == mrb->root_c) {
|
|
539
|
+
/* Not in task context - sleep in real wall-clock time using HAL */
|
|
540
|
+
mrb_hal_task_sleep_us(mrb, usec);
|
|
541
|
+
/* Clear switching flag - we're in root context, not switching to a task */
|
|
542
|
+
switching_ = FALSE;
|
|
543
|
+
return;
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
/* Check for C function boundary - cannot do cooperative context switch */
|
|
547
|
+
mrb_callinfo *ci;
|
|
548
|
+
for (ci = mrb->c->ci; ci >= mrb->c->cibase; ci--) {
|
|
549
|
+
if (ci->cci > 0) {
|
|
550
|
+
/* Inside C function - fall back to blocking sleep without context switch */
|
|
551
|
+
mrb_hal_task_sleep_us(mrb, usec);
|
|
552
|
+
switching_ = FALSE;
|
|
553
|
+
return;
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
/* In task context - get current running task */
|
|
558
|
+
t = MRB2TASK(mrb);
|
|
559
|
+
|
|
560
|
+
mrb_task_disable_irq();
|
|
561
|
+
|
|
562
|
+
/* Remove from ready queue */
|
|
563
|
+
q_delete_task(mrb, t);
|
|
564
|
+
|
|
565
|
+
/* Move to waiting queue */
|
|
566
|
+
t->status = MRB_TASK_STATUS_WAITING;
|
|
567
|
+
t->reason = MRB_TASK_REASON_SLEEP;
|
|
568
|
+
/* Convert microseconds to ticks (tick unit is in milliseconds) */
|
|
569
|
+
t->wait.wakeup_tick = tick_ + USEC_TO_TICKS(usec);
|
|
570
|
+
|
|
571
|
+
/* Update next wakeup time if this task wakes earlier */
|
|
572
|
+
if ((int32_t)(t->wait.wakeup_tick - wakeup_tick_) < 0) {
|
|
573
|
+
wakeup_tick_ = t->wait.wakeup_tick;
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
q_insert_task(mrb, t);
|
|
577
|
+
|
|
578
|
+
mrb_task_enable_irq();
|
|
579
|
+
|
|
580
|
+
/* Trigger context switch */
|
|
581
|
+
switching_ = TRUE;
|
|
582
|
+
}
|
|
583
|
+
|
|
584
|
+
static void
|
|
585
|
+
sleep_ms_impl(mrb_state *mrb, uint32_t ms)
|
|
586
|
+
{
|
|
587
|
+
sleep_us_impl(mrb, ms * 1000);
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
static mrb_value
|
|
591
|
+
mrb_f_sleep(mrb_state *mrb, mrb_value self)
|
|
592
|
+
{
|
|
593
|
+
mrb_float sec = 0;
|
|
594
|
+
mrb_int n = mrb_get_args(mrb, "|f", &sec);
|
|
595
|
+
|
|
596
|
+
if (n == 0) {
|
|
597
|
+
/* No argument - suspend indefinitely */
|
|
598
|
+
mrb_task *t = q_ready_;
|
|
599
|
+
if (t) {
|
|
600
|
+
mrb_task_disable_irq();
|
|
601
|
+
q_delete_task(mrb, t);
|
|
602
|
+
t->status = MRB_TASK_STATUS_SUSPENDED;
|
|
603
|
+
q_insert_task(mrb, t);
|
|
604
|
+
mrb_task_enable_irq();
|
|
605
|
+
switching_ = TRUE;
|
|
606
|
+
}
|
|
607
|
+
return mrb_nil_value();
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
if (sec < 0) {
|
|
611
|
+
mrb_raise(mrb, E_ARGUMENT_ERROR, "time interval must be positive");
|
|
612
|
+
}
|
|
613
|
+
|
|
614
|
+
mrb_int ms = (mrb_int)(sec * 1000);
|
|
615
|
+
sleep_ms_impl(mrb, (uint32_t)ms);
|
|
616
|
+
|
|
617
|
+
return mrb_fixnum_value((mrb_int)sec);
|
|
618
|
+
}
|
|
619
|
+
|
|
620
|
+
static mrb_value
|
|
621
|
+
mrb_f_sleep_ms(mrb_state *mrb, mrb_value self)
|
|
622
|
+
{
|
|
623
|
+
mrb_int ms;
|
|
624
|
+
|
|
625
|
+
mrb_get_args(mrb, "i", &ms);
|
|
626
|
+
|
|
627
|
+
if (ms < 0) {
|
|
628
|
+
mrb_raise(mrb, E_ARGUMENT_ERROR, "time interval must be positive");
|
|
629
|
+
}
|
|
630
|
+
|
|
631
|
+
sleep_ms_impl(mrb, (uint32_t)ms);
|
|
632
|
+
|
|
633
|
+
return mrb_nil_value();
|
|
634
|
+
}
|
|
635
|
+
|
|
636
|
+
static mrb_value
|
|
637
|
+
mrb_f_usleep(mrb_state *mrb, mrb_value self)
|
|
638
|
+
{
|
|
639
|
+
mrb_int usec;
|
|
640
|
+
|
|
641
|
+
mrb_get_args(mrb, "i", &usec);
|
|
642
|
+
|
|
643
|
+
if (usec < 0) {
|
|
644
|
+
mrb_raise(mrb, E_ARGUMENT_ERROR, "time interval must be positive");
|
|
645
|
+
}
|
|
646
|
+
|
|
647
|
+
sleep_us_impl(mrb, (uint32_t)usec);
|
|
648
|
+
|
|
649
|
+
return mrb_fixnum_value(usec);
|
|
650
|
+
}
|
|
651
|
+
|
|
652
|
+
/*
|
|
653
|
+
* Task class methods
|
|
654
|
+
*/
|
|
655
|
+
|
|
656
|
+
static mrb_value
|
|
657
|
+
mrb_task_s_new(mrb_state *mrb, mrb_value self)
|
|
658
|
+
{
|
|
659
|
+
mrb_value blk;
|
|
660
|
+
mrb_value name_val = mrb_nil_value();
|
|
661
|
+
mrb_int priority = 128; /* Default middle priority */
|
|
662
|
+
mrb_value kw_values[2] = {mrb_undef_value(), mrb_undef_value()};
|
|
663
|
+
mrb_sym kw_names[2] = {MRB_SYM(name), MRB_SYM(priority)};
|
|
664
|
+
const mrb_kwargs kwargs = {
|
|
665
|
+
2, 0, kw_names, kw_values, NULL
|
|
666
|
+
};
|
|
667
|
+
|
|
668
|
+
/* Get block and optional keyword arguments */
|
|
669
|
+
mrb_get_args(mrb, "&:", &blk, &kwargs);
|
|
670
|
+
|
|
671
|
+
if (mrb_nil_p(blk)) {
|
|
672
|
+
mrb_raise(mrb, E_ARGUMENT_ERROR, "tried to create task without a block");
|
|
673
|
+
}
|
|
674
|
+
|
|
675
|
+
const struct RProc *proc = mrb_proc_ptr(blk);
|
|
676
|
+
|
|
677
|
+
/* Parse keyword arguments */
|
|
678
|
+
if (!mrb_undef_p(kw_values[0])) {
|
|
679
|
+
/* Validate name type - must be String */
|
|
680
|
+
if (!mrb_string_p(kw_values[0])) {
|
|
681
|
+
mrb_raise(mrb, E_TYPE_ERROR, "name must be a String");
|
|
682
|
+
}
|
|
683
|
+
name_val = kw_values[0];
|
|
684
|
+
}
|
|
685
|
+
if (!mrb_undef_p(kw_values[1])) {
|
|
686
|
+
/* Validate priority type - must be Integer */
|
|
687
|
+
if (!mrb_integer_p(kw_values[1])) {
|
|
688
|
+
mrb_raise(mrb, E_TYPE_ERROR, "priority must be an Integer");
|
|
689
|
+
}
|
|
690
|
+
priority = mrb_integer(kw_values[1]);
|
|
691
|
+
if (priority < 0 || priority > 255) {
|
|
692
|
+
mrb_raise(mrb, E_ARGUMENT_ERROR, "priority must be 0-255");
|
|
693
|
+
}
|
|
694
|
+
}
|
|
695
|
+
|
|
696
|
+
/* Allocate and initialize task */
|
|
697
|
+
mrb_task *t = task_alloc(mrb);
|
|
698
|
+
t->priority = (uint8_t)priority;
|
|
699
|
+
t->status = MRB_TASK_STATUS_READY;
|
|
700
|
+
t->reason = MRB_TASK_REASON_NONE;
|
|
701
|
+
t->name = name_val;
|
|
702
|
+
/* Note: proc is stored in t->c.ci->proc and marked via callinfo GC */
|
|
703
|
+
|
|
704
|
+
/* Create Ruby object to hold task */
|
|
705
|
+
mrb_value task_obj = mrb_obj_value(mrb_data_object_alloc(mrb, mrb_class_get_id(mrb, MRB_SYM(Task)),
|
|
706
|
+
t, &mrb_task_type));
|
|
707
|
+
t->self = task_obj;
|
|
708
|
+
|
|
709
|
+
/* Register with GC to protect task object from collection */
|
|
710
|
+
mrb_gc_register(mrb, task_obj);
|
|
711
|
+
|
|
712
|
+
/* Initialize task context */
|
|
713
|
+
task_init_context(mrb, t, proc);
|
|
714
|
+
|
|
715
|
+
/* Insert into ready queue */
|
|
716
|
+
mrb_task_disable_irq();
|
|
717
|
+
q_insert_task(mrb, t);
|
|
718
|
+
mrb_task_enable_irq();
|
|
719
|
+
|
|
720
|
+
/* Trigger context switch if this task has higher priority than current */
|
|
721
|
+
if (q_ready_ && q_ready_->status == MRB_TASK_STATUS_RUNNING) {
|
|
722
|
+
if (t->priority < q_ready_->priority) {
|
|
723
|
+
switching_ = TRUE;
|
|
724
|
+
}
|
|
725
|
+
}
|
|
726
|
+
|
|
727
|
+
return task_obj;
|
|
728
|
+
}
|
|
729
|
+
|
|
730
|
+
static mrb_value
|
|
731
|
+
mrb_task_s_current(mrb_state *mrb, mrb_value self)
|
|
732
|
+
{
|
|
733
|
+
/* Check if we're in root context */
|
|
734
|
+
if (mrb->c == mrb->root_c) {
|
|
735
|
+
/* Return main task wrapper (lazy-allocate if needed) */
|
|
736
|
+
if (!mrb->task.main_task) {
|
|
737
|
+
struct RClass *task_class = mrb_class_ptr(self);
|
|
738
|
+
struct RData *data = mrb_data_object_alloc(mrb, task_class, NULL, &mrb_task_type);
|
|
739
|
+
mrb_task *t = (mrb_task*)mrb_calloc(mrb, 1, sizeof(mrb_task));
|
|
740
|
+
|
|
741
|
+
/* Initialize as main task - special status that's never scheduled */
|
|
742
|
+
t->priority = 0;
|
|
743
|
+
t->status = MRB_TASK_STATUS_RUNNING; /* Always running */
|
|
744
|
+
t->name = mrb_str_new_cstr(mrb, "main");
|
|
745
|
+
t->self = mrb_obj_value(data);
|
|
746
|
+
data->data = t;
|
|
747
|
+
data->type = &mrb_task_type;
|
|
748
|
+
|
|
749
|
+
/* Register for GC protection */
|
|
750
|
+
mrb_gc_register(mrb, t->self);
|
|
751
|
+
|
|
752
|
+
/* Note: t->c is not used - root context is in mrb->root_c */
|
|
753
|
+
mrb->task.main_task = t;
|
|
754
|
+
}
|
|
755
|
+
return mrb->task.main_task->self;
|
|
756
|
+
}
|
|
757
|
+
|
|
758
|
+
/* Use pointer arithmetic to get task from context - O(1) */
|
|
759
|
+
mrb_task *t = MRB2TASK(mrb);
|
|
760
|
+
return t->self;
|
|
761
|
+
}
|
|
762
|
+
|
|
763
|
+
static mrb_value
|
|
764
|
+
mrb_task_s_list(mrb_state *mrb, mrb_value self)
|
|
765
|
+
{
|
|
766
|
+
mrb_value ary = mrb_ary_new(mrb);
|
|
767
|
+
|
|
768
|
+
/* Iterate all queues and collect tasks */
|
|
769
|
+
for (int i = 0; i < MRB_NUM_TASK_QUEUE; i++) {
|
|
770
|
+
mrb_task *t = mrb->task.queues[i];
|
|
771
|
+
while (t != NULL) {
|
|
772
|
+
mrb_ary_push(mrb, ary, t->self);
|
|
773
|
+
t = t->next;
|
|
774
|
+
}
|
|
775
|
+
}
|
|
776
|
+
|
|
777
|
+
return ary;
|
|
778
|
+
}
|
|
779
|
+
|
|
780
|
+
/*
|
|
781
|
+
* Run one task iteration - helper for Task.pass from root context
|
|
782
|
+
* Waits for ready tasks if needed (cooperative yielding)
|
|
783
|
+
*/
|
|
784
|
+
static void
|
|
785
|
+
task_run_one_iteration(mrb_state *mrb)
|
|
786
|
+
{
|
|
787
|
+
mrb_task *t = q_ready_;
|
|
788
|
+
|
|
789
|
+
/* No ready task - just return (sleep from root provides delays) */
|
|
790
|
+
if (!t) {
|
|
791
|
+
return;
|
|
792
|
+
}
|
|
793
|
+
|
|
794
|
+
/* Skip terminated tasks */
|
|
795
|
+
if (task_cleanup_if_stopped(mrb, t)) {
|
|
796
|
+
return;
|
|
797
|
+
}
|
|
798
|
+
|
|
799
|
+
/* Execute ready task */
|
|
800
|
+
execute_task(mrb, t);
|
|
801
|
+
}
|
|
802
|
+
|
|
803
|
+
static mrb_value
|
|
804
|
+
mrb_task_s_pass(mrb_state *mrb, mrb_value self)
|
|
805
|
+
{
|
|
806
|
+
if (mrb->c == mrb->root_c) {
|
|
807
|
+
/* Called from root context - run one task iteration */
|
|
808
|
+
task_run_one_iteration(mrb);
|
|
809
|
+
}
|
|
810
|
+
else {
|
|
811
|
+
/* Check for C function boundary - cannot yield from C function */
|
|
812
|
+
mrb_callinfo *ci;
|
|
813
|
+
for (ci = mrb->c->ci; ci >= mrb->c->cibase; ci--) {
|
|
814
|
+
if (ci->cci > 0) {
|
|
815
|
+
mrb_raise(mrb, E_RUNTIME_ERROR, "can't pass across C function boundary");
|
|
816
|
+
}
|
|
817
|
+
}
|
|
818
|
+
|
|
819
|
+
/* In task context - trigger context switch */
|
|
820
|
+
switching_ = TRUE;
|
|
821
|
+
}
|
|
822
|
+
|
|
823
|
+
return mrb_nil_value();
|
|
824
|
+
}
|
|
825
|
+
|
|
826
|
+
/* Helper to build statistics for a task queue */
|
|
827
|
+
static mrb_value
|
|
828
|
+
mrb_stat_sub(mrb_state *mrb, mrb_task *queue)
|
|
829
|
+
{
|
|
830
|
+
mrb_value stat = mrb_hash_new(mrb);
|
|
831
|
+
mrb_value tasks = mrb_ary_new(mrb);
|
|
832
|
+
mrb_task *curr = queue;
|
|
833
|
+
int count = 0;
|
|
834
|
+
|
|
835
|
+
/* Walk the queue and collect task objects */
|
|
836
|
+
while (curr) {
|
|
837
|
+
count++;
|
|
838
|
+
mrb_ary_push(mrb, tasks, curr->self);
|
|
839
|
+
curr = curr->next;
|
|
840
|
+
}
|
|
841
|
+
|
|
842
|
+
/* Build statistics hash */
|
|
843
|
+
mrb_hash_set(mrb, stat, mrb_symbol_value(MRB_SYM(count)), mrb_fixnum_value(count));
|
|
844
|
+
mrb_hash_set(mrb, stat, mrb_symbol_value(MRB_SYM(tasks)), tasks);
|
|
845
|
+
|
|
846
|
+
return stat;
|
|
847
|
+
}
|
|
848
|
+
|
|
849
|
+
static mrb_value
|
|
850
|
+
mrb_task_s_stat(mrb_state *mrb, mrb_value self)
|
|
851
|
+
{
|
|
852
|
+
mrb_value data = mrb_hash_new(mrb);
|
|
853
|
+
|
|
854
|
+
mrb_task_disable_irq();
|
|
855
|
+
|
|
856
|
+
/* Add global scheduler state */
|
|
857
|
+
mrb_hash_set(mrb, data, mrb_symbol_value(MRB_SYM(tick)), mrb_fixnum_value(tick_));
|
|
858
|
+
mrb_hash_set(mrb, data, mrb_symbol_value(MRB_SYM(wakeup_tick)), mrb_fixnum_value(wakeup_tick_));
|
|
859
|
+
|
|
860
|
+
/* Add statistics for each queue */
|
|
861
|
+
mrb_hash_set(mrb, data, mrb_symbol_value(MRB_SYM(dormant)), mrb_stat_sub(mrb, q_dormant_));
|
|
862
|
+
mrb_hash_set(mrb, data, mrb_symbol_value(MRB_SYM(ready)), mrb_stat_sub(mrb, q_ready_));
|
|
863
|
+
mrb_hash_set(mrb, data, mrb_symbol_value(MRB_SYM(waiting)), mrb_stat_sub(mrb, q_waiting_));
|
|
864
|
+
mrb_hash_set(mrb, data, mrb_symbol_value(MRB_SYM(suspended)), mrb_stat_sub(mrb, q_suspended_));
|
|
865
|
+
|
|
866
|
+
mrb_task_enable_irq();
|
|
867
|
+
|
|
868
|
+
return data;
|
|
869
|
+
}
|
|
870
|
+
|
|
871
|
+
static mrb_value
|
|
872
|
+
mrb_task_s_run(mrb_state *mrb, mrb_value self)
|
|
873
|
+
{
|
|
874
|
+
return mrb_task_run(mrb);
|
|
875
|
+
}
|
|
876
|
+
|
|
877
|
+
static mrb_value
|
|
878
|
+
mrb_task_s_get(mrb_state *mrb, mrb_value self)
|
|
879
|
+
{
|
|
880
|
+
mrb_value name;
|
|
881
|
+
|
|
882
|
+
mrb_get_args(mrb, "S", &name);
|
|
883
|
+
|
|
884
|
+
/* Search all queues for task with matching name */
|
|
885
|
+
for (int i = 0; i < MRB_NUM_TASK_QUEUE; i++) {
|
|
886
|
+
mrb_task *t = mrb->task.queues[i];
|
|
887
|
+
while (t != NULL) {
|
|
888
|
+
if (mrb_equal(mrb, t->name, name)) {
|
|
889
|
+
return t->self;
|
|
890
|
+
}
|
|
891
|
+
t = t->next;
|
|
892
|
+
}
|
|
893
|
+
}
|
|
894
|
+
|
|
895
|
+
return mrb_nil_value();
|
|
896
|
+
}
|
|
897
|
+
|
|
898
|
+
/*
|
|
899
|
+
* Task instance methods
|
|
900
|
+
*/
|
|
901
|
+
|
|
902
|
+
MRB_API mrb_value
|
|
903
|
+
mrb_task_status(mrb_state *mrb, mrb_value self)
|
|
904
|
+
{
|
|
905
|
+
mrb_task *t;
|
|
906
|
+
|
|
907
|
+
TASK_GET_PTR_OR_RAISE(t, self);
|
|
908
|
+
|
|
909
|
+
/* Return status as symbol matching original implementation */
|
|
910
|
+
return mrb_symbol_value(
|
|
911
|
+
(t->status == MRB_TASK_STATUS_RUNNING) ? MRB_SYM(RUNNING) :
|
|
912
|
+
(t->status == MRB_TASK_STATUS_READY) ? MRB_SYM(READY) :
|
|
913
|
+
(t->status == MRB_TASK_STATUS_WAITING) ? MRB_SYM(WAITING) :
|
|
914
|
+
(t->status == MRB_TASK_STATUS_SUSPENDED) ? MRB_SYM(SUSPENDED) :
|
|
915
|
+
(t->status == MRB_TASK_STATUS_DORMANT) ? MRB_SYM(DORMANT) :
|
|
916
|
+
MRB_SYM(UNKNOWN));
|
|
917
|
+
}
|
|
918
|
+
|
|
919
|
+
static mrb_value
|
|
920
|
+
mrb_task_inspect(mrb_state *mrb, mrb_value self)
|
|
921
|
+
{
|
|
922
|
+
mrb_task *t;
|
|
923
|
+
char buf[256];
|
|
924
|
+
const char *name_str;
|
|
925
|
+
const char *status_str;
|
|
926
|
+
|
|
927
|
+
TASK_GET_PTR_OR_RAISE(t, self);
|
|
928
|
+
|
|
929
|
+
/* Get status string directly from task status field */
|
|
930
|
+
switch (t->status) {
|
|
931
|
+
case MRB_TASK_STATUS_RUNNING:
|
|
932
|
+
status_str = "RUNNING";
|
|
933
|
+
break;
|
|
934
|
+
case MRB_TASK_STATUS_READY:
|
|
935
|
+
status_str = "READY";
|
|
936
|
+
break;
|
|
937
|
+
case MRB_TASK_STATUS_WAITING:
|
|
938
|
+
status_str = "WAITING";
|
|
939
|
+
break;
|
|
940
|
+
case MRB_TASK_STATUS_SUSPENDED:
|
|
941
|
+
status_str = "SUSPENDED";
|
|
942
|
+
break;
|
|
943
|
+
case MRB_TASK_STATUS_DORMANT:
|
|
944
|
+
status_str = "DORMANT";
|
|
945
|
+
break;
|
|
946
|
+
default:
|
|
947
|
+
status_str = "UNKNOWN";
|
|
948
|
+
break;
|
|
949
|
+
}
|
|
950
|
+
|
|
951
|
+
/* Get name as C string - avoid mrb_funcall to prevent VM state issues */
|
|
952
|
+
if (mrb_string_p(t->name)) {
|
|
953
|
+
name_str = RSTRING_PTR(t->name);
|
|
954
|
+
}
|
|
955
|
+
else if (mrb_symbol_p(t->name)) {
|
|
956
|
+
name_str = mrb_sym_name(mrb, mrb_symbol(t->name));
|
|
957
|
+
}
|
|
958
|
+
else {
|
|
959
|
+
/* Treat nil, undef, or any other type as unnamed */
|
|
960
|
+
name_str = "(unnamed)";
|
|
961
|
+
}
|
|
962
|
+
|
|
963
|
+
/* Format: #<Task:0x12345678 name:STATUS> */
|
|
964
|
+
snprintf(buf, sizeof(buf), "#<Task:%p %s:%s>",
|
|
965
|
+
(void *)t,
|
|
966
|
+
name_str,
|
|
967
|
+
status_str);
|
|
968
|
+
|
|
969
|
+
return mrb_str_new_cstr(mrb, buf);
|
|
970
|
+
}
|
|
971
|
+
|
|
972
|
+
static mrb_value
|
|
973
|
+
mrb_task_name(mrb_state *mrb, mrb_value self)
|
|
974
|
+
{
|
|
975
|
+
mrb_task *t;
|
|
976
|
+
|
|
977
|
+
TASK_GET_PTR_OR_RAISE(t, self);
|
|
978
|
+
|
|
979
|
+
/* Return "(noname)" if name is not set */
|
|
980
|
+
if (mrb_nil_p(t->name)) {
|
|
981
|
+
return mrb_str_new_lit(mrb, "(noname)");
|
|
982
|
+
}
|
|
983
|
+
|
|
984
|
+
return t->name;
|
|
985
|
+
}
|
|
986
|
+
|
|
987
|
+
static mrb_value
|
|
988
|
+
mrb_task_set_name(mrb_state *mrb, mrb_value self)
|
|
989
|
+
{
|
|
990
|
+
mrb_task *t;
|
|
991
|
+
mrb_value name;
|
|
992
|
+
|
|
993
|
+
TASK_GET_PTR_OR_RAISE(t, self);
|
|
994
|
+
|
|
995
|
+
mrb_get_args(mrb, "o", &name);
|
|
996
|
+
t->name = name;
|
|
997
|
+
|
|
998
|
+
return name;
|
|
999
|
+
}
|
|
1000
|
+
|
|
1001
|
+
static mrb_value
|
|
1002
|
+
mrb_task_priority(mrb_state *mrb, mrb_value self)
|
|
1003
|
+
{
|
|
1004
|
+
mrb_task *t;
|
|
1005
|
+
|
|
1006
|
+
TASK_GET_PTR_OR_RAISE(t, self);
|
|
1007
|
+
|
|
1008
|
+
return mrb_fixnum_value(t->priority);
|
|
1009
|
+
}
|
|
1010
|
+
|
|
1011
|
+
static mrb_value
|
|
1012
|
+
mrb_task_set_priority(mrb_state *mrb, mrb_value self)
|
|
1013
|
+
{
|
|
1014
|
+
mrb_task *t;
|
|
1015
|
+
mrb_int priority;
|
|
1016
|
+
|
|
1017
|
+
TASK_GET_PTR_OR_RAISE(t, self);
|
|
1018
|
+
|
|
1019
|
+
mrb_get_args(mrb, "i", &priority);
|
|
1020
|
+
|
|
1021
|
+
if (priority < 0 || priority > 255) {
|
|
1022
|
+
mrb_raise(mrb, E_ARGUMENT_ERROR, "priority must be 0-255");
|
|
1023
|
+
}
|
|
1024
|
+
|
|
1025
|
+
mrb_task_disable_irq();
|
|
1026
|
+
t->priority = (uint8_t)priority;
|
|
1027
|
+
|
|
1028
|
+
/* Re-sort in queue if task is ready */
|
|
1029
|
+
if (t->status == MRB_TASK_STATUS_READY || t->status == MRB_TASK_STATUS_RUNNING) {
|
|
1030
|
+
q_delete_task(mrb, t);
|
|
1031
|
+
q_insert_task(mrb, t);
|
|
1032
|
+
}
|
|
1033
|
+
mrb_task_enable_irq();
|
|
1034
|
+
|
|
1035
|
+
return mrb_fixnum_value(priority);
|
|
1036
|
+
}
|
|
1037
|
+
|
|
1038
|
+
/*
|
|
1039
|
+
* Forward declarations for internal functions
|
|
1040
|
+
*/
|
|
1041
|
+
static void suspend_task_internal(mrb_state *mrb, mrb_task *t);
|
|
1042
|
+
static void resume_task_internal(mrb_state *mrb, mrb_task *t);
|
|
1043
|
+
static void terminate_task_internal(mrb_state *mrb, mrb_task *t);
|
|
1044
|
+
|
|
1045
|
+
static mrb_value
|
|
1046
|
+
mrb_task_suspend(mrb_state *mrb, mrb_value self)
|
|
1047
|
+
{
|
|
1048
|
+
mrb_task *t;
|
|
1049
|
+
|
|
1050
|
+
TASK_GET_PTR_OR_RAISE(t, self);
|
|
1051
|
+
task_check_scheduler_lock(mrb);
|
|
1052
|
+
|
|
1053
|
+
suspend_task_internal(mrb, t);
|
|
1054
|
+
return self;
|
|
1055
|
+
}
|
|
1056
|
+
|
|
1057
|
+
static mrb_value
|
|
1058
|
+
mrb_task_resume(mrb_state *mrb, mrb_value self)
|
|
1059
|
+
{
|
|
1060
|
+
mrb_task *t;
|
|
1061
|
+
|
|
1062
|
+
TASK_GET_PTR_OR_RAISE(t, self);
|
|
1063
|
+
task_check_scheduler_lock(mrb);
|
|
1064
|
+
|
|
1065
|
+
resume_task_internal(mrb, t);
|
|
1066
|
+
return self;
|
|
1067
|
+
}
|
|
1068
|
+
|
|
1069
|
+
static mrb_value
|
|
1070
|
+
mrb_task_terminate(mrb_state *mrb, mrb_value self)
|
|
1071
|
+
{
|
|
1072
|
+
mrb_task *t;
|
|
1073
|
+
|
|
1074
|
+
TASK_GET_PTR_OR_RAISE(t, self);
|
|
1075
|
+
task_check_scheduler_lock(mrb);
|
|
1076
|
+
|
|
1077
|
+
terminate_task_internal(mrb, t);
|
|
1078
|
+
return self;
|
|
1079
|
+
}
|
|
1080
|
+
|
|
1081
|
+
static mrb_value
|
|
1082
|
+
mrb_task_join(mrb_state *mrb, mrb_value self)
|
|
1083
|
+
{
|
|
1084
|
+
mrb_task *t, *current;
|
|
1085
|
+
|
|
1086
|
+
TASK_GET_PTR_OR_RAISE(t, self);
|
|
1087
|
+
|
|
1088
|
+
/* Get current task using pointer arithmetic */
|
|
1089
|
+
if (mrb->c == mrb->root_c) {
|
|
1090
|
+
mrb_raise(mrb, E_RUNTIME_ERROR, "join can only be called from running task");
|
|
1091
|
+
}
|
|
1092
|
+
current = MRB2TASK(mrb);
|
|
1093
|
+
|
|
1094
|
+
/* Can't join self */
|
|
1095
|
+
if (t == current) {
|
|
1096
|
+
mrb_raise(mrb, E_ARGUMENT_ERROR, "can't join self");
|
|
1097
|
+
}
|
|
1098
|
+
|
|
1099
|
+
/* If task is already dormant, return immediately */
|
|
1100
|
+
if (t->status == MRB_TASK_STATUS_DORMANT) {
|
|
1101
|
+
return t->state.result;
|
|
1102
|
+
}
|
|
1103
|
+
|
|
1104
|
+
/* Wait for task to complete */
|
|
1105
|
+
mrb_task_disable_irq();
|
|
1106
|
+
q_delete_task(mrb, current);
|
|
1107
|
+
current->status = MRB_TASK_STATUS_WAITING;
|
|
1108
|
+
current->reason = MRB_TASK_REASON_JOIN;
|
|
1109
|
+
current->wait.join = t;
|
|
1110
|
+
q_insert_task(mrb, current);
|
|
1111
|
+
mrb_task_enable_irq();
|
|
1112
|
+
|
|
1113
|
+
/* Trigger context switch */
|
|
1114
|
+
switching_ = TRUE;
|
|
1115
|
+
|
|
1116
|
+
return t->state.result;
|
|
1117
|
+
}
|
|
1118
|
+
|
|
1119
|
+
/*
|
|
1120
|
+
* Synchronous execution
|
|
1121
|
+
*/
|
|
1122
|
+
|
|
1123
|
+
/* Execute a proc synchronously without context switching
|
|
1124
|
+
*
|
|
1125
|
+
* This function creates a temporary task, executes it to completion,
|
|
1126
|
+
* and returns the result. The scheduler_lock prevents any asynchronous
|
|
1127
|
+
* task operations during execution.
|
|
1128
|
+
*/
|
|
1129
|
+
MRB_API mrb_value
|
|
1130
|
+
mrb_execute_proc_synchronously(mrb_state *mrb, mrb_value proc_val, mrb_int argc, const mrb_value *argv)
|
|
1131
|
+
{
|
|
1132
|
+
struct RProc *proc = mrb_proc_ptr(proc_val);
|
|
1133
|
+
int ai = mrb_gc_arena_save(mrb);
|
|
1134
|
+
|
|
1135
|
+
/*
|
|
1136
|
+
* argc/argv are reserved for future use (e.g., passing arguments to
|
|
1137
|
+
* event handlers or callback functions). Currently all callers pass
|
|
1138
|
+
* 0 and NULL.
|
|
1139
|
+
*/
|
|
1140
|
+
(void)argc;
|
|
1141
|
+
(void)argv;
|
|
1142
|
+
|
|
1143
|
+
/* 1. Lock scheduler and save context */
|
|
1144
|
+
if (mrb->task.scheduler_lock >= MRB_TASK_SCHEDULER_LOCK_MAX) {
|
|
1145
|
+
mrb_raise(mrb, E_RUNTIME_ERROR, "scheduler lock overflow");
|
|
1146
|
+
}
|
|
1147
|
+
mrb->task.scheduler_lock++;
|
|
1148
|
+
struct mrb_context *original_c = mrb->c;
|
|
1149
|
+
|
|
1150
|
+
/* 2. Create a temporary task */
|
|
1151
|
+
mrb_task *t = task_alloc(mrb);
|
|
1152
|
+
t->priority = 0; /* Highest priority */
|
|
1153
|
+
t->status = MRB_TASK_STATUS_DORMANT;
|
|
1154
|
+
t->reason = MRB_TASK_REASON_NONE;
|
|
1155
|
+
t->name = mrb_str_new_lit(mrb, "(sync)");
|
|
1156
|
+
|
|
1157
|
+
/* Initialize task context */
|
|
1158
|
+
task_init_context(mrb, t, proc);
|
|
1159
|
+
|
|
1160
|
+
/* Create wrapper object (not registered with GC as we'll free it manually) */
|
|
1161
|
+
struct RClass *task_class = mrb_class_get(mrb, "Task");
|
|
1162
|
+
mrb_value task_obj = mrb_obj_value(mrb_data_object_alloc(mrb, task_class, t, &mrb_task_type));
|
|
1163
|
+
t->self = task_obj;
|
|
1164
|
+
|
|
1165
|
+
/* 3. Move task from DORMANT to READY */
|
|
1166
|
+
mrb_task_disable_irq();
|
|
1167
|
+
t->status = MRB_TASK_STATUS_READY;
|
|
1168
|
+
q_insert_task(mrb, t);
|
|
1169
|
+
mrb_task_enable_irq();
|
|
1170
|
+
|
|
1171
|
+
/* 4. Execute the task in a dedicated loop (no context switching) */
|
|
1172
|
+
t->status = MRB_TASK_STATUS_RUNNING;
|
|
1173
|
+
mrb->c = &t->c;
|
|
1174
|
+
|
|
1175
|
+
while (t->c.status != MRB_TASK_STOPPED) {
|
|
1176
|
+
t->state.result = mrb_vm_exec(mrb, mrb->c->ci->proc, mrb->c->ci->pc);
|
|
1177
|
+
}
|
|
1178
|
+
|
|
1179
|
+
/* If there's an unhandled exception after VM stops, save it as result */
|
|
1180
|
+
if (mrb->exc) {
|
|
1181
|
+
t->state.result = mrb_obj_value(mrb->exc);
|
|
1182
|
+
}
|
|
1183
|
+
|
|
1184
|
+
/* 5. Get result and clean up */
|
|
1185
|
+
mrb_value result = t->state.result;
|
|
1186
|
+
if (mrb_obj_ptr(result) == mrb->exc) {
|
|
1187
|
+
mrb->exc = NULL; /* Clear exception */
|
|
1188
|
+
}
|
|
1189
|
+
|
|
1190
|
+
/* 6. Free the temporary task's resources */
|
|
1191
|
+
mrb_task_disable_irq();
|
|
1192
|
+
q_delete_task(mrb, t);
|
|
1193
|
+
mrb_task_enable_irq();
|
|
1194
|
+
|
|
1195
|
+
/* Prevent double-free: clear Data object's type before freeing task */
|
|
1196
|
+
DATA_TYPE(task_obj) = NULL;
|
|
1197
|
+
|
|
1198
|
+
/* Free context resources directly (bypass GC since we own this task) */
|
|
1199
|
+
if (t->c.stbase) {
|
|
1200
|
+
mrb_free(mrb, t->c.stbase);
|
|
1201
|
+
t->c.stbase = NULL;
|
|
1202
|
+
}
|
|
1203
|
+
if (t->c.cibase) {
|
|
1204
|
+
mrb_free(mrb, t->c.cibase);
|
|
1205
|
+
t->c.cibase = NULL;
|
|
1206
|
+
}
|
|
1207
|
+
mrb_free(mrb, t);
|
|
1208
|
+
|
|
1209
|
+
/* 7. Restore context and unlock */
|
|
1210
|
+
mrb->c = original_c;
|
|
1211
|
+
mrb->task.scheduler_lock--;
|
|
1212
|
+
|
|
1213
|
+
mrb_gc_arena_restore(mrb, ai);
|
|
1214
|
+
mrb_gc_protect(mrb, result);
|
|
1215
|
+
|
|
1216
|
+
return result;
|
|
1217
|
+
}
|
|
1218
|
+
|
|
1219
|
+
/*
|
|
1220
|
+
* Task.tick class method
|
|
1221
|
+
*/
|
|
1222
|
+
static mrb_value
|
|
1223
|
+
mrb_task_s_tick(mrb_state *mrb, mrb_value self)
|
|
1224
|
+
{
|
|
1225
|
+
return mrb_int_value(mrb, tick_ * MRB_TICK_UNIT);
|
|
1226
|
+
}
|
|
1227
|
+
|
|
1228
|
+
/*
|
|
1229
|
+
* Create a task from a proc
|
|
1230
|
+
* This is called from mrc_create_task() in mrc_utils.c
|
|
1231
|
+
*/
|
|
1232
|
+
MRB_API mrb_value
|
|
1233
|
+
mrb_create_task(mrb_state *mrb, struct RProc *proc, mrb_value name, mrb_value priority, mrb_value top_self)
|
|
1234
|
+
{
|
|
1235
|
+
task_check_scheduler_lock(mrb);
|
|
1236
|
+
|
|
1237
|
+
/* Validate/default priority */
|
|
1238
|
+
mrb_int prio = 128; /* Default priority */
|
|
1239
|
+
if (!mrb_nil_p(priority)) {
|
|
1240
|
+
if (!mrb_integer_p(priority)) {
|
|
1241
|
+
mrb_raise(mrb, E_TYPE_ERROR, "priority must be an Integer");
|
|
1242
|
+
}
|
|
1243
|
+
prio = mrb_integer(priority);
|
|
1244
|
+
if (prio < 0 || prio > 255) {
|
|
1245
|
+
mrb_raise(mrb, E_ARGUMENT_ERROR, "priority must be 0-255");
|
|
1246
|
+
}
|
|
1247
|
+
}
|
|
1248
|
+
|
|
1249
|
+
/* Validate/default name */
|
|
1250
|
+
mrb_value name_val = mrb_nil_p(name) ? mrb_str_new_lit(mrb, "(noname)") : name;
|
|
1251
|
+
|
|
1252
|
+
/* Allocate and initialize task */
|
|
1253
|
+
mrb_task *t = task_alloc(mrb);
|
|
1254
|
+
t->priority = (uint8_t)prio;
|
|
1255
|
+
t->status = MRB_TASK_STATUS_READY;
|
|
1256
|
+
t->reason = MRB_TASK_REASON_NONE;
|
|
1257
|
+
t->name = name_val;
|
|
1258
|
+
|
|
1259
|
+
/* Create Ruby object to hold task */
|
|
1260
|
+
mrb_value task_obj = mrb_obj_value(mrb_data_object_alloc(mrb, mrb_class_get(mrb, "Task"),
|
|
1261
|
+
t, &mrb_task_type));
|
|
1262
|
+
t->self = task_obj;
|
|
1263
|
+
|
|
1264
|
+
/* Register with GC to protect task object from collection */
|
|
1265
|
+
mrb_gc_register(mrb, task_obj);
|
|
1266
|
+
|
|
1267
|
+
/* Initialize task context */
|
|
1268
|
+
task_init_context(mrb, t, proc);
|
|
1269
|
+
|
|
1270
|
+
/* Set top_self if provided */
|
|
1271
|
+
if (!mrb_nil_p(top_self)) {
|
|
1272
|
+
t->c.ci->stack[0] = top_self;
|
|
1273
|
+
}
|
|
1274
|
+
|
|
1275
|
+
/* Insert into ready queue */
|
|
1276
|
+
mrb_task_disable_irq();
|
|
1277
|
+
q_insert_task(mrb, t);
|
|
1278
|
+
mrb_task_enable_irq();
|
|
1279
|
+
|
|
1280
|
+
/* Trigger context switch if this task has higher priority than current */
|
|
1281
|
+
if (q_ready_ && q_ready_->status == MRB_TASK_STATUS_RUNNING) {
|
|
1282
|
+
if (t->priority < q_ready_->priority) {
|
|
1283
|
+
switching_ = TRUE;
|
|
1284
|
+
}
|
|
1285
|
+
}
|
|
1286
|
+
|
|
1287
|
+
return task_obj;
|
|
1288
|
+
}
|
|
1289
|
+
|
|
1290
|
+
/*
|
|
1291
|
+
* Internal: Suspend a task (no validation, no scheduler_lock check)
|
|
1292
|
+
*/
|
|
1293
|
+
static void
|
|
1294
|
+
suspend_task_internal(mrb_state *mrb, mrb_task *t)
|
|
1295
|
+
{
|
|
1296
|
+
/*
|
|
1297
|
+
* WAITING task should also be suspended:
|
|
1298
|
+
* Suspend trigger may occur while the task is sleeping (WAITING).
|
|
1299
|
+
* DORMANT task should also be suspended:
|
|
1300
|
+
* e.g., IRB in PicoRuby suspends a DORMANT task to use it again.
|
|
1301
|
+
*/
|
|
1302
|
+
if (t->status == MRB_TASK_STATUS_SUSPENDED) return;
|
|
1303
|
+
|
|
1304
|
+
/*
|
|
1305
|
+
* Determine if context switch is needed BEFORE changing state.
|
|
1306
|
+
* Context switch is needed when suspending a RUNNING task or
|
|
1307
|
+
* the current ready task.
|
|
1308
|
+
*/
|
|
1309
|
+
mrb_bool need_switch = (t == q_ready_ || t->status == MRB_TASK_STATUS_RUNNING);
|
|
1310
|
+
|
|
1311
|
+
task_change_state(mrb, t, MRB_TASK_STATUS_SUSPENDED);
|
|
1312
|
+
|
|
1313
|
+
if (need_switch) {
|
|
1314
|
+
switching_ = TRUE;
|
|
1315
|
+
}
|
|
1316
|
+
}
|
|
1317
|
+
|
|
1318
|
+
/*
|
|
1319
|
+
* Suspend a task
|
|
1320
|
+
*/
|
|
1321
|
+
MRB_API void
|
|
1322
|
+
mrb_suspend_task(mrb_state *mrb, mrb_value task)
|
|
1323
|
+
{
|
|
1324
|
+
task_check_scheduler_lock(mrb);
|
|
1325
|
+
|
|
1326
|
+
mrb_task *t = (mrb_task*)mrb_data_check_get_ptr(mrb, task, &mrb_task_type);
|
|
1327
|
+
if (!t) return;
|
|
1328
|
+
|
|
1329
|
+
suspend_task_internal(mrb, t);
|
|
1330
|
+
}
|
|
1331
|
+
|
|
1332
|
+
/*
|
|
1333
|
+
* Internal: Resume a task (no validation, no scheduler_lock check)
|
|
1334
|
+
*/
|
|
1335
|
+
static void
|
|
1336
|
+
resume_task_internal(mrb_state *mrb, mrb_task *t)
|
|
1337
|
+
{
|
|
1338
|
+
if (t->status != MRB_TASK_STATUS_SUSPENDED) return;
|
|
1339
|
+
|
|
1340
|
+
/* Determine target state based on reason */
|
|
1341
|
+
uint8_t target_status = (t->reason == MRB_TASK_REASON_NONE) ?
|
|
1342
|
+
MRB_TASK_STATUS_READY : MRB_TASK_STATUS_WAITING;
|
|
1343
|
+
|
|
1344
|
+
task_change_state(mrb, t, target_status);
|
|
1345
|
+
|
|
1346
|
+
/* Trigger context switch if resumed task has higher priority */
|
|
1347
|
+
if (target_status == MRB_TASK_STATUS_READY && q_ready_ &&
|
|
1348
|
+
q_ready_->status == MRB_TASK_STATUS_RUNNING) {
|
|
1349
|
+
if (t->priority < q_ready_->priority) {
|
|
1350
|
+
switching_ = TRUE;
|
|
1351
|
+
}
|
|
1352
|
+
}
|
|
1353
|
+
|
|
1354
|
+
/* Update wakeup_tick if task has sleep reason */
|
|
1355
|
+
if (t->reason == MRB_TASK_REASON_SLEEP) {
|
|
1356
|
+
if ((int32_t)(t->wait.wakeup_tick - wakeup_tick_) < 0) {
|
|
1357
|
+
wakeup_tick_ = t->wait.wakeup_tick;
|
|
1358
|
+
}
|
|
1359
|
+
}
|
|
1360
|
+
}
|
|
1361
|
+
|
|
1362
|
+
/*
|
|
1363
|
+
* Resume a task
|
|
1364
|
+
*/
|
|
1365
|
+
MRB_API void
|
|
1366
|
+
mrb_resume_task(mrb_state *mrb, mrb_value task)
|
|
1367
|
+
{
|
|
1368
|
+
task_check_scheduler_lock(mrb);
|
|
1369
|
+
|
|
1370
|
+
mrb_task *t = (mrb_task*)mrb_data_check_get_ptr(mrb, task, &mrb_task_type);
|
|
1371
|
+
if (!t) return;
|
|
1372
|
+
|
|
1373
|
+
resume_task_internal(mrb, t);
|
|
1374
|
+
}
|
|
1375
|
+
|
|
1376
|
+
/*
|
|
1377
|
+
* Internal: Terminate a task (no validation, no scheduler_lock check)
|
|
1378
|
+
*/
|
|
1379
|
+
static void
|
|
1380
|
+
terminate_task_internal(mrb_state *mrb, mrb_task *t)
|
|
1381
|
+
{
|
|
1382
|
+
if (t->status == MRB_TASK_STATUS_DORMANT) return;
|
|
1383
|
+
|
|
1384
|
+
mrb_task_disable_irq();
|
|
1385
|
+
q_delete_task(mrb, t);
|
|
1386
|
+
t->status = MRB_TASK_STATUS_DORMANT;
|
|
1387
|
+
t->c.status = MRB_TASK_STOPPED;
|
|
1388
|
+
q_insert_task(mrb, t);
|
|
1389
|
+
mrb_task_enable_irq();
|
|
1390
|
+
|
|
1391
|
+
wake_up_join_waiters(mrb, t);
|
|
1392
|
+
|
|
1393
|
+
/* If terminating self, trigger context switch */
|
|
1394
|
+
if (t == q_ready_) {
|
|
1395
|
+
switching_ = TRUE;
|
|
1396
|
+
}
|
|
1397
|
+
}
|
|
1398
|
+
|
|
1399
|
+
/*
|
|
1400
|
+
* Terminate a task
|
|
1401
|
+
*/
|
|
1402
|
+
MRB_API void
|
|
1403
|
+
mrb_terminate_task(mrb_state *mrb, mrb_value task)
|
|
1404
|
+
{
|
|
1405
|
+
task_check_scheduler_lock(mrb);
|
|
1406
|
+
|
|
1407
|
+
mrb_task *t = (mrb_task*)mrb_data_check_get_ptr(mrb, task, &mrb_task_type);
|
|
1408
|
+
if (!t) return;
|
|
1409
|
+
|
|
1410
|
+
terminate_task_internal(mrb, t);
|
|
1411
|
+
}
|
|
1412
|
+
|
|
1413
|
+
/*
|
|
1414
|
+
* Stop a task (mark as stopped but don't move to dormant)
|
|
1415
|
+
*/
|
|
1416
|
+
MRB_API mrb_bool
|
|
1417
|
+
mrb_stop_task(mrb_state *mrb, mrb_value task)
|
|
1418
|
+
{
|
|
1419
|
+
task_check_scheduler_lock(mrb);
|
|
1420
|
+
|
|
1421
|
+
mrb_task *t = (mrb_task*)mrb_data_check_get_ptr(mrb, task, &mrb_task_type);
|
|
1422
|
+
if (!t) return FALSE;
|
|
1423
|
+
|
|
1424
|
+
if (t->c.status == MRB_TASK_STOPPED) {
|
|
1425
|
+
return FALSE; /* Already stopped */
|
|
1426
|
+
}
|
|
1427
|
+
t->c.status = MRB_TASK_STOPPED;
|
|
1428
|
+
return TRUE;
|
|
1429
|
+
}
|
|
1430
|
+
|
|
1431
|
+
/*
|
|
1432
|
+
* Get task result value
|
|
1433
|
+
*/
|
|
1434
|
+
MRB_API mrb_value
|
|
1435
|
+
mrb_task_value(mrb_state *mrb, mrb_value task)
|
|
1436
|
+
{
|
|
1437
|
+
mrb_task *t = (mrb_task*)mrb_data_check_get_ptr(mrb, task, &mrb_task_type);
|
|
1438
|
+
if (!t) return mrb_nil_value();
|
|
1439
|
+
|
|
1440
|
+
return t->state.result;
|
|
1441
|
+
}
|
|
1442
|
+
|
|
1443
|
+
/*
|
|
1444
|
+
* Initialize task context with a new proc
|
|
1445
|
+
*/
|
|
1446
|
+
MRB_API void
|
|
1447
|
+
mrb_task_init_context(mrb_state *mrb, mrb_value task, struct RProc *proc)
|
|
1448
|
+
{
|
|
1449
|
+
task_check_scheduler_lock(mrb);
|
|
1450
|
+
|
|
1451
|
+
mrb_task *t = (mrb_task*)mrb_data_check_get_ptr(mrb, task, &mrb_task_type);
|
|
1452
|
+
if (!t) return;
|
|
1453
|
+
|
|
1454
|
+
struct mrb_context *c = &t->c;
|
|
1455
|
+
|
|
1456
|
+
/* Cleanup existing context if any */
|
|
1457
|
+
if (c->stbase) {
|
|
1458
|
+
mrb_free(mrb, c->stbase);
|
|
1459
|
+
c->stbase = NULL;
|
|
1460
|
+
}
|
|
1461
|
+
if (c->cibase) {
|
|
1462
|
+
mrb_free(mrb, c->cibase);
|
|
1463
|
+
c->cibase = NULL;
|
|
1464
|
+
}
|
|
1465
|
+
|
|
1466
|
+
/* Re-initialize context */
|
|
1467
|
+
task_init_context(mrb, t, proc);
|
|
1468
|
+
}
|
|
1469
|
+
|
|
1470
|
+
/*
|
|
1471
|
+
* Reset task context to initial state
|
|
1472
|
+
*/
|
|
1473
|
+
MRB_API void
|
|
1474
|
+
mrb_task_reset_context(mrb_state *mrb, mrb_value task)
|
|
1475
|
+
{
|
|
1476
|
+
task_check_scheduler_lock(mrb);
|
|
1477
|
+
|
|
1478
|
+
mrb_task *t = (mrb_task*)mrb_data_check_get_ptr(mrb, task, &mrb_task_type);
|
|
1479
|
+
if (!t) return;
|
|
1480
|
+
|
|
1481
|
+
struct mrb_context *c = &t->c;
|
|
1482
|
+
c->ci = c->cibase;
|
|
1483
|
+
c->status = MRB_TASK_CREATED;
|
|
1484
|
+
if (c->ci) {
|
|
1485
|
+
mrb_vm_ci_target_class_set(c->ci, mrb->object_class);
|
|
1486
|
+
}
|
|
1487
|
+
}
|
|
1488
|
+
|
|
1489
|
+
/*
|
|
1490
|
+
* Set proc for task
|
|
1491
|
+
*/
|
|
1492
|
+
MRB_API void
|
|
1493
|
+
mrb_task_proc_set(mrb_state *mrb, mrb_value task, struct RProc *proc)
|
|
1494
|
+
{
|
|
1495
|
+
task_check_scheduler_lock(mrb);
|
|
1496
|
+
|
|
1497
|
+
mrb_task *t = (mrb_task*)mrb_data_check_get_ptr(mrb, task, &mrb_task_type);
|
|
1498
|
+
if (!t) return;
|
|
1499
|
+
|
|
1500
|
+
/* Handle environment resize if needed */
|
|
1501
|
+
if (t->c.cibase && t->c.cibase->u.env) {
|
|
1502
|
+
struct REnv *e = mrb_vm_ci_env(t->c.cibase);
|
|
1503
|
+
if (e && MRB_ENV_LEN(e) < proc->body.irep->nlocals) {
|
|
1504
|
+
MRB_ENV_SET_LEN(e, proc->body.irep->nlocals);
|
|
1505
|
+
}
|
|
1506
|
+
}
|
|
1507
|
+
|
|
1508
|
+
if (t->c.ci) {
|
|
1509
|
+
mrb_vm_ci_proc_set(t->c.ci, proc);
|
|
1510
|
+
}
|
|
1511
|
+
}
|
|
1512
|
+
|
|
1513
|
+
/*
|
|
1514
|
+
* Initialization
|
|
1515
|
+
*/
|
|
1516
|
+
|
|
1517
|
+
void
|
|
1518
|
+
mrb_mruby_task_gem_init(mrb_state *mrb)
|
|
1519
|
+
{
|
|
1520
|
+
struct RClass *task_class;
|
|
1521
|
+
|
|
1522
|
+
/* Initialize HAL (timer and interrupts) */
|
|
1523
|
+
mrb_hal_task_init(mrb);
|
|
1524
|
+
|
|
1525
|
+
/* Initialize main task to NULL and scheduler_lock to 0 */
|
|
1526
|
+
mrb->task.main_task = NULL;
|
|
1527
|
+
mrb->task.scheduler_lock = 0;
|
|
1528
|
+
|
|
1529
|
+
task_class = mrb_define_class_id(mrb, MRB_SYM(Task), mrb->object_class);
|
|
1530
|
+
MRB_SET_INSTANCE_TT(task_class, MRB_TT_DATA);
|
|
1531
|
+
|
|
1532
|
+
/* Class methods */
|
|
1533
|
+
mrb_define_class_method_id(mrb, task_class, MRB_SYM(new), mrb_task_s_new, MRB_ARGS_KEY(2,0)|MRB_ARGS_BLOCK());
|
|
1534
|
+
mrb_define_class_method_id(mrb, task_class, MRB_SYM(current), mrb_task_s_current, MRB_ARGS_NONE());
|
|
1535
|
+
mrb_define_class_method_id(mrb, task_class, MRB_SYM(list), mrb_task_s_list, MRB_ARGS_NONE());
|
|
1536
|
+
mrb_define_class_method_id(mrb, task_class, MRB_SYM(pass), mrb_task_s_pass, MRB_ARGS_NONE());
|
|
1537
|
+
mrb_define_class_method_id(mrb, task_class, MRB_SYM(stat), mrb_task_s_stat, MRB_ARGS_NONE());
|
|
1538
|
+
mrb_define_class_method_id(mrb, task_class, MRB_SYM(get), mrb_task_s_get, MRB_ARGS_REQ(1));
|
|
1539
|
+
mrb_define_class_method_id(mrb, task_class, MRB_SYM(run), mrb_task_s_run, MRB_ARGS_NONE());
|
|
1540
|
+
mrb_define_class_method_id(mrb, task_class, MRB_SYM(tick), mrb_task_s_tick, MRB_ARGS_NONE());
|
|
1541
|
+
|
|
1542
|
+
/* Instance methods */
|
|
1543
|
+
mrb_define_method_id(mrb, task_class, MRB_SYM(status), mrb_task_status, MRB_ARGS_NONE());
|
|
1544
|
+
mrb_define_method_id(mrb, task_class, MRB_SYM(inspect), mrb_task_inspect, MRB_ARGS_NONE());
|
|
1545
|
+
mrb_define_method_id(mrb, task_class, MRB_SYM(name), mrb_task_name, MRB_ARGS_NONE());
|
|
1546
|
+
mrb_define_method_id(mrb, task_class, MRB_SYM_E(name), mrb_task_set_name, MRB_ARGS_REQ(1));
|
|
1547
|
+
mrb_define_method_id(mrb, task_class, MRB_SYM(priority), mrb_task_priority, MRB_ARGS_NONE());
|
|
1548
|
+
mrb_define_method_id(mrb, task_class, MRB_SYM_E(priority), mrb_task_set_priority, MRB_ARGS_REQ(1));
|
|
1549
|
+
mrb_define_method_id(mrb, task_class, MRB_SYM(suspend), mrb_task_suspend, MRB_ARGS_NONE());
|
|
1550
|
+
mrb_define_method_id(mrb, task_class, MRB_SYM(resume), mrb_task_resume, MRB_ARGS_NONE());
|
|
1551
|
+
mrb_define_method_id(mrb, task_class, MRB_SYM(terminate), mrb_task_terminate, MRB_ARGS_NONE());
|
|
1552
|
+
mrb_define_method_id(mrb, task_class, MRB_SYM(join), mrb_task_join, MRB_ARGS_NONE());
|
|
1553
|
+
|
|
1554
|
+
/* Kernel methods (module functions like CRuby)
|
|
1555
|
+
* Note: sleep and usleep override mruby-sleep's implementation to be task-aware
|
|
1556
|
+
* (cooperative sleep within tasks, blocking sleep otherwise)
|
|
1557
|
+
*/
|
|
1558
|
+
mrb_define_module_function_id(mrb, mrb->kernel_module, MRB_SYM(sleep), mrb_f_sleep, MRB_ARGS_OPT(1));
|
|
1559
|
+
mrb_define_module_function_id(mrb, mrb->kernel_module, MRB_SYM(usleep), mrb_f_usleep, MRB_ARGS_REQ(1));
|
|
1560
|
+
mrb_define_module_function_id(mrb, mrb->kernel_module, MRB_SYM(sleep_ms), mrb_f_sleep_ms, MRB_ARGS_REQ(1));
|
|
1561
|
+
}
|
|
1562
|
+
|
|
1563
|
+
void
|
|
1564
|
+
mrb_mruby_task_gem_final(mrb_state *mrb)
|
|
1565
|
+
{
|
|
1566
|
+
/* Clear main task pointer - GC will handle freeing the object */
|
|
1567
|
+
if (mrb->task.main_task) {
|
|
1568
|
+
mrb_gc_unregister(mrb, mrb->task.main_task->self);
|
|
1569
|
+
mrb->task.main_task = NULL;
|
|
1570
|
+
}
|
|
1571
|
+
|
|
1572
|
+
mrb_hal_task_final(mrb);
|
|
1573
|
+
}
|