@shd101wyy/yo 0.0.2
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.
- package/LICENSE.md +17 -0
- package/README.md +80 -0
- package/out/cjs/index.cjs +51 -0
- package/out/cjs/yo-cli.cjs +2158 -0
- package/out/esm/index.mjs +51 -0
- package/out/types/src/codegen/async/runtime.d.ts +2 -0
- package/out/types/src/codegen/async/state-code-gen.d.ts +10 -0
- package/out/types/src/codegen/async/state-machine.d.ts +13 -0
- package/out/types/src/codegen/c/collection.d.ts +3 -0
- package/out/types/src/codegen/codegen-c.d.ts +12 -0
- package/out/types/src/codegen/constants.d.ts +3 -0
- package/out/types/src/codegen/expressions/array.d.ts +4 -0
- package/out/types/src/codegen/expressions/generation.d.ts +11 -0
- package/out/types/src/codegen/expressions/index.d.ts +2 -0
- package/out/types/src/codegen/functions/collection.d.ts +5 -0
- package/out/types/src/codegen/functions/context.d.ts +57 -0
- package/out/types/src/codegen/functions/generation.d.ts +25 -0
- package/out/types/src/codegen/functions/index.d.ts +2 -0
- package/out/types/src/codegen/index.d.ts +20 -0
- package/out/types/src/codegen/parallelism/runtime.d.ts +2 -0
- package/out/types/src/codegen/types/collection.d.ts +8 -0
- package/out/types/src/codegen/types/generation.d.ts +13 -0
- package/out/types/src/codegen/types/index.d.ts +2 -0
- package/out/types/src/codegen/utils/fixup.d.ts +2 -0
- package/out/types/src/codegen/utils/index.d.ts +77 -0
- package/out/types/src/codegen/values/index.d.ts +1 -0
- package/out/types/src/emitter.d.ts +11 -0
- package/out/types/src/env.d.ts +85 -0
- package/out/types/src/error.d.ts +45 -0
- package/out/types/src/evaluator/async/await-analysis-types.d.ts +23 -0
- package/out/types/src/evaluator/async/await-analysis.d.ts +5 -0
- package/out/types/src/evaluator/builtins/alignof.d.ts +8 -0
- package/out/types/src/evaluator/builtins/and_or.d.ts +8 -0
- package/out/types/src/evaluator/builtins/arc_fns.d.ts +58 -0
- package/out/types/src/evaluator/builtins/array_fns.d.ts +0 -0
- package/out/types/src/evaluator/builtins/as.d.ts +8 -0
- package/out/types/src/evaluator/builtins/async_fns.d.ts +8 -0
- package/out/types/src/evaluator/builtins/compt_assert.d.ts +8 -0
- package/out/types/src/evaluator/builtins/compt_boolean_fns.d.ts +8 -0
- package/out/types/src/evaluator/builtins/compt_expect_error.d.ts +8 -0
- package/out/types/src/evaluator/builtins/compt_list_fns.d.ts +33 -0
- package/out/types/src/evaluator/builtins/compt_print.d.ts +8 -0
- package/out/types/src/evaluator/builtins/compt_string_fns.d.ts +8 -0
- package/out/types/src/evaluator/builtins/consume.d.ts +8 -0
- package/out/types/src/evaluator/builtins/drop.d.ts +8 -0
- package/out/types/src/evaluator/builtins/dup.d.ts +8 -0
- package/out/types/src/evaluator/builtins/expr_fns.d.ts +33 -0
- package/out/types/src/evaluator/builtins/future_fns.d.ts +8 -0
- package/out/types/src/evaluator/builtins/gc.d.ts +8 -0
- package/out/types/src/evaluator/builtins/gensym.d.ts +8 -0
- package/out/types/src/evaluator/builtins/impl_constraint.d.ts +8 -0
- package/out/types/src/evaluator/builtins/macro_expand.d.ts +8 -0
- package/out/types/src/evaluator/builtins/numeric_fns.d.ts +8 -0
- package/out/types/src/evaluator/builtins/panic.d.ts +8 -0
- package/out/types/src/evaluator/builtins/ptr_fns.d.ts +8 -0
- package/out/types/src/evaluator/builtins/quote.d.ts +13 -0
- package/out/types/src/evaluator/builtins/rc.d.ts +8 -0
- package/out/types/src/evaluator/builtins/sizeof.d.ts +8 -0
- package/out/types/src/evaluator/builtins/the.d.ts +8 -0
- package/out/types/src/evaluator/builtins/type_fns.d.ts +28 -0
- package/out/types/src/evaluator/builtins/va_start.d.ts +8 -0
- package/out/types/src/evaluator/builtins/var_fns.d.ts +18 -0
- package/out/types/src/evaluator/calls/array.d.ts +13 -0
- package/out/types/src/evaluator/calls/array_type.d.ts +11 -0
- package/out/types/src/evaluator/calls/closure_type.d.ts +11 -0
- package/out/types/src/evaluator/calls/compt_function.d.ts +19 -0
- package/out/types/src/evaluator/calls/compt_list_type.d.ts +11 -0
- package/out/types/src/evaluator/calls/function.d.ts +16 -0
- package/out/types/src/evaluator/calls/function_type.d.ts +15 -0
- package/out/types/src/evaluator/calls/helper.d.ts +42 -0
- package/out/types/src/evaluator/calls/iso.d.ts +15 -0
- package/out/types/src/evaluator/calls/module_type.d.ts +11 -0
- package/out/types/src/evaluator/calls/numeric_type.d.ts +15 -0
- package/out/types/src/evaluator/calls/pointer.d.ts +8 -0
- package/out/types/src/evaluator/calls/pointer_type.d.ts +14 -0
- package/out/types/src/evaluator/calls/type.d.ts +12 -0
- package/out/types/src/evaluator/context.d.ts +169 -0
- package/out/types/src/evaluator/exprs/_expr.d.ts +8 -0
- package/out/types/src/evaluator/exprs/assignment.d.ts +9 -0
- package/out/types/src/evaluator/exprs/begin.d.ts +10 -0
- package/out/types/src/evaluator/exprs/binding.d.ts +12 -0
- package/out/types/src/evaluator/exprs/c_include.d.ts +8 -0
- package/out/types/src/evaluator/exprs/cond.d.ts +8 -0
- package/out/types/src/evaluator/exprs/destructuring_assignment.d.ts +33 -0
- package/out/types/src/evaluator/exprs/exists.d.ts +0 -0
- package/out/types/src/evaluator/exprs/expr.d.ts +9 -0
- package/out/types/src/evaluator/exprs/extern.d.ts +8 -0
- package/out/types/src/evaluator/exprs/identifer_and_operator.d.ts +9 -0
- package/out/types/src/evaluator/exprs/import.d.ts +9 -0
- package/out/types/src/evaluator/exprs/initialization_assignment.d.ts +8 -0
- package/out/types/src/evaluator/exprs/match.d.ts +8 -0
- package/out/types/src/evaluator/exprs/open.d.ts +8 -0
- package/out/types/src/evaluator/exprs/property_access.d.ts +8 -0
- package/out/types/src/evaluator/exprs/recur.d.ts +8 -0
- package/out/types/src/evaluator/exprs/subtype_of.d.ts +21 -0
- package/out/types/src/evaluator/exprs/test.d.ts +8 -0
- package/out/types/src/evaluator/exprs/typeof.d.ts +8 -0
- package/out/types/src/evaluator/exprs/while.d.ts +8 -0
- package/out/types/src/evaluator/index.d.ts +26 -0
- package/out/types/src/evaluator/types/array.d.ts +8 -0
- package/out/types/src/evaluator/types/closure.d.ts +8 -0
- package/out/types/src/evaluator/types/compt_list.d.ts +8 -0
- package/out/types/src/evaluator/types/concrete_module.d.ts +8 -0
- package/out/types/src/evaluator/types/dyn.d.ts +8 -0
- package/out/types/src/evaluator/types/enum.d.ts +8 -0
- package/out/types/src/evaluator/types/expr_synthesizer.d.ts +14 -0
- package/out/types/src/evaluator/types/field.d.ts +14 -0
- package/out/types/src/evaluator/types/fn_module.d.ts +8 -0
- package/out/types/src/evaluator/types/function.d.ts +58 -0
- package/out/types/src/evaluator/types/future_module.d.ts +8 -0
- package/out/types/src/evaluator/types/module.d.ts +19 -0
- package/out/types/src/evaluator/types/newtype.d.ts +8 -0
- package/out/types/src/evaluator/types/object.d.ts +8 -0
- package/out/types/src/evaluator/types/proofs.d.ts +0 -0
- package/out/types/src/evaluator/types/slice.d.ts +8 -0
- package/out/types/src/evaluator/types/struct.d.ts +8 -0
- package/out/types/src/evaluator/types/synthesizer.d.ts +16 -0
- package/out/types/src/evaluator/types/tuple.d.ts +18 -0
- package/out/types/src/evaluator/types/union.d.ts +8 -0
- package/out/types/src/evaluator/types/utils.d.ts +71 -0
- package/out/types/src/evaluator/types/validation.d.ts +3 -0
- package/out/types/src/evaluator/utils/array-utils.d.ts +15 -0
- package/out/types/src/evaluator/utils/closure.d.ts +35 -0
- package/out/types/src/evaluator/utils.d.ts +4 -0
- package/out/types/src/evaluator/values/anonymous_function.d.ts +8 -0
- package/out/types/src/evaluator/values/anonymous_module.d.ts +17 -0
- package/out/types/src/evaluator/values/anonymous_struct.d.ts +8 -0
- package/out/types/src/evaluator/values/array.d.ts +8 -0
- package/out/types/src/evaluator/values/boolean.d.ts +3 -0
- package/out/types/src/evaluator/values/char.d.ts +3 -0
- package/out/types/src/evaluator/values/compt_list.d.ts +8 -0
- package/out/types/src/evaluator/values/dyn.d.ts +8 -0
- package/out/types/src/evaluator/values/float.d.ts +4 -0
- package/out/types/src/evaluator/values/integer.d.ts +4 -0
- package/out/types/src/evaluator/values/module.d.ts +58 -0
- package/out/types/src/evaluator/values/string.d.ts +3 -0
- package/out/types/src/evaluator/values/tuple.d.ts +32 -0
- package/out/types/src/expr.d.ts +456 -0
- package/out/types/src/function-value.d.ts +42 -0
- package/out/types/src/index.d.ts +4 -0
- package/out/types/src/lexer.d.ts +2 -0
- package/out/types/src/logger.d.ts +1 -0
- package/out/types/src/module-manager.d.ts +30 -0
- package/out/types/src/naming-checker.d.ts +4 -0
- package/out/types/src/parser.d.ts +33 -0
- package/out/types/src/test-runner.d.ts +30 -0
- package/out/types/src/tests/codegen.test.d.ts +1 -0
- package/out/types/src/tests/fixme.test.d.ts +1 -0
- package/out/types/src/tests/module-manager.test.d.ts +1 -0
- package/out/types/src/tests/parser.test.d.ts +1 -0
- package/out/types/src/tests/sample.test.d.ts +0 -0
- package/out/types/src/tests/std.test.d.ts +1 -0
- package/out/types/src/token.d.ts +40 -0
- package/out/types/src/type-value.d.ts +7 -0
- package/out/types/src/types/compatibility.d.ts +16 -0
- package/out/types/src/types/creators.d.ts +73 -0
- package/out/types/src/types/definitions.d.ts +218 -0
- package/out/types/src/types/guards.d.ts +70 -0
- package/out/types/src/types/hierarchy.d.ts +4 -0
- package/out/types/src/types/index.d.ts +7 -0
- package/out/types/src/types/module_field.d.ts +2 -0
- package/out/types/src/types/tags.d.ts +45 -0
- package/out/types/src/types/utils.d.ts +50 -0
- package/out/types/src/unit-value.d.ts +7 -0
- package/out/types/src/utils.d.ts +6 -0
- package/out/types/src/value-tag.d.ts +29 -0
- package/out/types/src/value.d.ts +110 -0
- package/out/types/src/yo-cli.d.ts +1 -0
- package/out/types/tsconfig.tsbuildinfo +1 -0
- package/package.json +57 -0
- package/scripts/check-liburing.js +76 -0
- package/std/alg/hash.yo +50 -0
- package/std/allocator.yo +113 -0
- package/std/allocators/c_allocator.yo +118 -0
- package/std/async.yo +13 -0
- package/std/collections/array_list.yo +415 -0
- package/std/collections/hash_map.yo +482 -0
- package/std/collections/hash_set.yo +706 -0
- package/std/collections/index.yo +11 -0
- package/std/collections/linked_list.yo +439 -0
- package/std/error.yo +0 -0
- package/std/gc.yo +10 -0
- package/std/index.yo +12 -0
- package/std/io/file.yo +191 -0
- package/std/io/index.yo +5 -0
- package/std/libc/assert.yo +39 -0
- package/std/libc/ctype.yo +57 -0
- package/std/libc/errno.yo +182 -0
- package/std/libc/float.yo +87 -0
- package/std/libc/index.yo +29 -0
- package/std/libc/limits.yo +65 -0
- package/std/libc/math.yo +679 -0
- package/std/libc/signal.yo +101 -0
- package/std/libc/stdatomic.yo +213 -0
- package/std/libc/stdint.yo +214 -0
- package/std/libc/stdio.yo +225 -0
- package/std/libc/stdlib.yo +204 -0
- package/std/libc/string.yo +151 -0
- package/std/libc/time.yo +92 -0
- package/std/libc/unistd.yo +130 -0
- package/std/monad.yo +152 -0
- package/std/prelude.yo +3094 -0
- package/std/string/index.yo +8 -0
- package/std/string/rune.yo +82 -0
- package/std/string/string.yo +288 -0
- package/std/sync.yo +95 -0
- package/std/thread.yo +36 -0
- package/std/time.yo +13 -0
- package/std/worker.yo +36 -0
- package/vendor/mimalloc/.gitattributes +12 -0
- package/vendor/mimalloc/CMakeLists.txt +763 -0
- package/vendor/mimalloc/LICENSE +21 -0
- package/vendor/mimalloc/SECURITY.md +41 -0
- package/vendor/mimalloc/azure-pipelines.yml +251 -0
- package/vendor/mimalloc/bin/mimalloc-redirect-arm64.dll +0 -0
- package/vendor/mimalloc/bin/mimalloc-redirect-arm64.lib +0 -0
- package/vendor/mimalloc/bin/mimalloc-redirect-arm64ec.dll +0 -0
- package/vendor/mimalloc/bin/mimalloc-redirect-arm64ec.lib +0 -0
- package/vendor/mimalloc/bin/mimalloc-redirect.dll +0 -0
- package/vendor/mimalloc/bin/mimalloc-redirect.lib +0 -0
- package/vendor/mimalloc/bin/mimalloc-redirect32.dll +0 -0
- package/vendor/mimalloc/bin/mimalloc-redirect32.lib +0 -0
- package/vendor/mimalloc/bin/minject-arm64.exe +0 -0
- package/vendor/mimalloc/bin/minject.exe +0 -0
- package/vendor/mimalloc/bin/minject32.exe +0 -0
- package/vendor/mimalloc/bin/readme.md +118 -0
- package/vendor/mimalloc/cmake/JoinPaths.cmake +23 -0
- package/vendor/mimalloc/cmake/mimalloc-config-version.cmake +19 -0
- package/vendor/mimalloc/cmake/mimalloc-config.cmake +14 -0
- package/vendor/mimalloc/contrib/docker/alpine/Dockerfile +23 -0
- package/vendor/mimalloc/contrib/docker/alpine-arm32v7/Dockerfile +28 -0
- package/vendor/mimalloc/contrib/docker/alpine-x86/Dockerfile +28 -0
- package/vendor/mimalloc/contrib/docker/manylinux-x64/Dockerfile +23 -0
- package/vendor/mimalloc/contrib/docker/readme.md +10 -0
- package/vendor/mimalloc/contrib/vcpkg/portfile.cmake +64 -0
- package/vendor/mimalloc/contrib/vcpkg/readme.md +40 -0
- package/vendor/mimalloc/contrib/vcpkg/usage +20 -0
- package/vendor/mimalloc/contrib/vcpkg/vcpkg-cmake-wrapper.cmake +20 -0
- package/vendor/mimalloc/contrib/vcpkg/vcpkg.json +48 -0
- package/vendor/mimalloc/doc/bench-2020/bench-c5-18xlarge-2020-01-20-a.svg +887 -0
- package/vendor/mimalloc/doc/bench-2020/bench-c5-18xlarge-2020-01-20-b.svg +1185 -0
- package/vendor/mimalloc/doc/bench-2020/bench-c5-18xlarge-2020-01-20-rss-a.svg +757 -0
- package/vendor/mimalloc/doc/bench-2020/bench-c5-18xlarge-2020-01-20-rss-b.svg +1028 -0
- package/vendor/mimalloc/doc/bench-2020/bench-r5a-1.svg +769 -0
- package/vendor/mimalloc/doc/bench-2020/bench-r5a-12xlarge-2020-01-16-a.svg +868 -0
- package/vendor/mimalloc/doc/bench-2020/bench-r5a-12xlarge-2020-01-16-b.svg +1157 -0
- package/vendor/mimalloc/doc/bench-2020/bench-r5a-2.svg +983 -0
- package/vendor/mimalloc/doc/bench-2020/bench-r5a-rss-1.svg +683 -0
- package/vendor/mimalloc/doc/bench-2020/bench-r5a-rss-2.svg +854 -0
- package/vendor/mimalloc/doc/bench-2020/bench-spec-rss.svg +713 -0
- package/vendor/mimalloc/doc/bench-2020/bench-spec.svg +713 -0
- package/vendor/mimalloc/doc/bench-2020/bench-z4-1.svg +890 -0
- package/vendor/mimalloc/doc/bench-2020/bench-z4-2.svg +1146 -0
- package/vendor/mimalloc/doc/bench-2020/bench-z4-rss-1.svg +796 -0
- package/vendor/mimalloc/doc/bench-2020/bench-z4-rss-2.svg +974 -0
- package/vendor/mimalloc/doc/bench-2021/bench-amd5950x-2021-01-30-a.svg +952 -0
- package/vendor/mimalloc/doc/bench-2021/bench-amd5950x-2021-01-30-b.svg +1255 -0
- package/vendor/mimalloc/doc/bench-2021/bench-c5-18xlarge-2021-01-30-a.svg +955 -0
- package/vendor/mimalloc/doc/bench-2021/bench-c5-18xlarge-2021-01-30-b.svg +1269 -0
- package/vendor/mimalloc/doc/bench-2021/bench-c5-18xlarge-2021-01-30-rss-a.svg +836 -0
- package/vendor/mimalloc/doc/bench-2021/bench-c5-18xlarge-2021-01-30-rss-b.svg +1131 -0
- package/vendor/mimalloc/doc/bench-2021/bench-macmini-2021-01-30.svg +766 -0
- package/vendor/mimalloc/doc/doxyfile +2895 -0
- package/vendor/mimalloc/doc/ds-logo.jpg +0 -0
- package/vendor/mimalloc/doc/ds-logo.png +0 -0
- package/vendor/mimalloc/doc/mimalloc-doc.h +1452 -0
- package/vendor/mimalloc/doc/mimalloc-doxygen.css +60 -0
- package/vendor/mimalloc/doc/mimalloc-logo-100.png +0 -0
- package/vendor/mimalloc/doc/mimalloc-logo.png +0 -0
- package/vendor/mimalloc/doc/mimalloc-logo.svg +161 -0
- package/vendor/mimalloc/doc/spades-logo.png +0 -0
- package/vendor/mimalloc/doc/unreal-logo.svg +43 -0
- package/vendor/mimalloc/ide/vs2022/mimalloc-lib.vcxproj +500 -0
- package/vendor/mimalloc/ide/vs2022/mimalloc-lib.vcxproj.filters +108 -0
- package/vendor/mimalloc/ide/vs2022/mimalloc-override-dll.vcxproj +508 -0
- package/vendor/mimalloc/ide/vs2022/mimalloc-override-dll.vcxproj.filters +111 -0
- package/vendor/mimalloc/ide/vs2022/mimalloc-override-test-dep.vcxproj +355 -0
- package/vendor/mimalloc/ide/vs2022/mimalloc-override-test.vcxproj +360 -0
- package/vendor/mimalloc/ide/vs2022/mimalloc-test-api.vcxproj +295 -0
- package/vendor/mimalloc/ide/vs2022/mimalloc-test-stress.vcxproj +292 -0
- package/vendor/mimalloc/ide/vs2022/mimalloc-test.vcxproj +289 -0
- package/vendor/mimalloc/ide/vs2022/mimalloc.sln +151 -0
- package/vendor/mimalloc/include/mimalloc/atomic.h +557 -0
- package/vendor/mimalloc/include/mimalloc/internal.h +1153 -0
- package/vendor/mimalloc/include/mimalloc/prim.h +421 -0
- package/vendor/mimalloc/include/mimalloc/track.h +145 -0
- package/vendor/mimalloc/include/mimalloc/types.h +685 -0
- package/vendor/mimalloc/include/mimalloc-new-delete.h +66 -0
- package/vendor/mimalloc/include/mimalloc-override.h +68 -0
- package/vendor/mimalloc/include/mimalloc-stats.h +103 -0
- package/vendor/mimalloc/include/mimalloc.h +612 -0
- package/vendor/mimalloc/mimalloc.pc.in +11 -0
- package/vendor/mimalloc/readme.md +946 -0
- package/vendor/mimalloc/src/alloc-aligned.c +360 -0
- package/vendor/mimalloc/src/alloc-override.c +316 -0
- package/vendor/mimalloc/src/alloc-posix.c +185 -0
- package/vendor/mimalloc/src/alloc.c +692 -0
- package/vendor/mimalloc/src/arena-abandon.c +346 -0
- package/vendor/mimalloc/src/arena.c +1043 -0
- package/vendor/mimalloc/src/bitmap.c +441 -0
- package/vendor/mimalloc/src/bitmap.h +119 -0
- package/vendor/mimalloc/src/free.c +572 -0
- package/vendor/mimalloc/src/heap.c +733 -0
- package/vendor/mimalloc/src/init.c +714 -0
- package/vendor/mimalloc/src/libc.c +334 -0
- package/vendor/mimalloc/src/options.c +663 -0
- package/vendor/mimalloc/src/os.c +770 -0
- package/vendor/mimalloc/src/page-queue.c +390 -0
- package/vendor/mimalloc/src/page.c +1049 -0
- package/vendor/mimalloc/src/prim/emscripten/prim.c +249 -0
- package/vendor/mimalloc/src/prim/osx/alloc-override-zone.c +461 -0
- package/vendor/mimalloc/src/prim/osx/prim.c +9 -0
- package/vendor/mimalloc/src/prim/prim.c +76 -0
- package/vendor/mimalloc/src/prim/readme.md +9 -0
- package/vendor/mimalloc/src/prim/unix/prim.c +934 -0
- package/vendor/mimalloc/src/prim/wasi/prim.c +284 -0
- package/vendor/mimalloc/src/prim/windows/etw-mimalloc.wprp +61 -0
- package/vendor/mimalloc/src/prim/windows/etw.h +905 -0
- package/vendor/mimalloc/src/prim/windows/etw.man +0 -0
- package/vendor/mimalloc/src/prim/windows/prim.c +878 -0
- package/vendor/mimalloc/src/prim/windows/readme.md +17 -0
- package/vendor/mimalloc/src/random.c +258 -0
- package/vendor/mimalloc/src/segment-map.c +142 -0
- package/vendor/mimalloc/src/segment.c +1702 -0
- package/vendor/mimalloc/src/static.c +41 -0
- package/vendor/mimalloc/src/stats.c +635 -0
- package/vendor/mimalloc/test/CMakeLists.txt +56 -0
- package/vendor/mimalloc/test/main-override-dep.cpp +51 -0
- package/vendor/mimalloc/test/main-override-dep.h +11 -0
- package/vendor/mimalloc/test/main-override-static.c +539 -0
- package/vendor/mimalloc/test/main-override.c +36 -0
- package/vendor/mimalloc/test/main-override.cpp +497 -0
- package/vendor/mimalloc/test/main.c +46 -0
- package/vendor/mimalloc/test/readme.md +16 -0
- package/vendor/mimalloc/test/test-api-fill.c +343 -0
- package/vendor/mimalloc/test/test-api.c +466 -0
- package/vendor/mimalloc/test/test-stress.c +428 -0
- package/vendor/mimalloc/test/test-wrong.c +92 -0
- package/vendor/mimalloc/test/testhelper.h +49 -0
|
@@ -0,0 +1,428 @@
|
|
|
1
|
+
/* ----------------------------------------------------------------------------
|
|
2
|
+
Copyright (c) 2018-2020 Microsoft Research, Daan Leijen
|
|
3
|
+
This is free software; you can redistribute it and/or modify it under the
|
|
4
|
+
terms of the MIT license.
|
|
5
|
+
-----------------------------------------------------------------------------*/
|
|
6
|
+
|
|
7
|
+
/* This is a stress test for the allocator, using multiple threads and
|
|
8
|
+
transferring objects between threads. It tries to reflect real-world workloads:
|
|
9
|
+
- allocation size is distributed linearly in powers of two
|
|
10
|
+
- with some fraction extra large (and some very large)
|
|
11
|
+
- the allocations are initialized and read again at free
|
|
12
|
+
- pointers transfer between threads
|
|
13
|
+
- threads are terminated and recreated with some objects surviving in between
|
|
14
|
+
- uses deterministic "randomness", but execution can still depend on
|
|
15
|
+
(random) thread scheduling. Do not use this test as a benchmark!
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
#include <stdio.h>
|
|
19
|
+
#include <stdlib.h>
|
|
20
|
+
#include <stdint.h>
|
|
21
|
+
#include <stdbool.h>
|
|
22
|
+
#include <string.h>
|
|
23
|
+
#include <assert.h>
|
|
24
|
+
|
|
25
|
+
// #define MI_GUARDED
|
|
26
|
+
// #define USE_STD_MALLOC
|
|
27
|
+
|
|
28
|
+
// > mimalloc-test-stress [THREADS] [SCALE] [ITER]
|
|
29
|
+
//
|
|
30
|
+
// argument defaults
|
|
31
|
+
#if defined(MI_TSAN) // with thread-sanitizer reduce the threads to test within the azure pipeline limits
|
|
32
|
+
static int THREADS = 8;
|
|
33
|
+
static int SCALE = 25;
|
|
34
|
+
static int ITER = 400;
|
|
35
|
+
#elif defined(MI_UBSAN) // with undefined behavious sanitizer reduce parameters to stay within the azure pipeline limits
|
|
36
|
+
static int THREADS = 8;
|
|
37
|
+
static int SCALE = 25;
|
|
38
|
+
static int ITER = 20;
|
|
39
|
+
#elif defined(MI_GUARDED) // with debug guard pages reduce parameters to stay within the azure pipeline limits
|
|
40
|
+
static int THREADS = 8;
|
|
41
|
+
static int SCALE = 10;
|
|
42
|
+
static int ITER = 10;
|
|
43
|
+
#else
|
|
44
|
+
static int THREADS = 32; // more repeatable if THREADS <= #processors
|
|
45
|
+
static int SCALE = 50; // scaling factor
|
|
46
|
+
static int ITER = 50; // N full iterations destructing and re-creating all threads
|
|
47
|
+
#endif
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
#define STRESS // undefine for leak test
|
|
52
|
+
|
|
53
|
+
static bool allow_large_objects = false; // allow very large objects? (set to `true` if SCALE>100)
|
|
54
|
+
static size_t use_one_size = 0; // use single object size of `N * sizeof(uintptr_t)`?
|
|
55
|
+
|
|
56
|
+
static bool main_participates = false; // main thread participates as a worker too
|
|
57
|
+
|
|
58
|
+
#ifdef USE_STD_MALLOC
|
|
59
|
+
#define custom_calloc(n,s) calloc(n,s)
|
|
60
|
+
#define custom_realloc(p,s) realloc(p,s)
|
|
61
|
+
#define custom_free(p) free(p)
|
|
62
|
+
#else
|
|
63
|
+
#include <mimalloc.h>
|
|
64
|
+
#include <mimalloc-stats.h>
|
|
65
|
+
#define custom_calloc(n,s) mi_calloc(n,s)
|
|
66
|
+
#define custom_realloc(p,s) mi_realloc(p,s)
|
|
67
|
+
#define custom_free(p) mi_free(p)
|
|
68
|
+
|
|
69
|
+
#ifndef NDEBUG
|
|
70
|
+
#define HEAP_WALK // walk the heap objects?
|
|
71
|
+
#endif
|
|
72
|
+
#endif
|
|
73
|
+
|
|
74
|
+
// transfer pointer between threads
|
|
75
|
+
#define TRANSFERS (1000)
|
|
76
|
+
static volatile void* transfer[TRANSFERS];
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
#if (UINTPTR_MAX != UINT32_MAX)
|
|
80
|
+
const uintptr_t cookie = 0xbf58476d1ce4e5b9UL;
|
|
81
|
+
#else
|
|
82
|
+
const uintptr_t cookie = 0x1ce4e5b9UL;
|
|
83
|
+
#endif
|
|
84
|
+
|
|
85
|
+
static void* atomic_exchange_ptr(volatile void** p, void* newval);
|
|
86
|
+
|
|
87
|
+
typedef uintptr_t* random_t;
|
|
88
|
+
|
|
89
|
+
static uintptr_t pick(random_t r) {
|
|
90
|
+
uintptr_t x = *r;
|
|
91
|
+
#if (UINTPTR_MAX > UINT32_MAX)
|
|
92
|
+
// by Sebastiano Vigna, see: <http://xoshiro.di.unimi.it/splitmix64.c>
|
|
93
|
+
x ^= x >> 30;
|
|
94
|
+
x *= 0xbf58476d1ce4e5b9UL;
|
|
95
|
+
x ^= x >> 27;
|
|
96
|
+
x *= 0x94d049bb133111ebUL;
|
|
97
|
+
x ^= x >> 31;
|
|
98
|
+
#else
|
|
99
|
+
// by Chris Wellons, see: <https://nullprogram.com/blog/2018/07/31/>
|
|
100
|
+
x ^= x >> 16;
|
|
101
|
+
x *= 0x7feb352dUL;
|
|
102
|
+
x ^= x >> 15;
|
|
103
|
+
x *= 0x846ca68bUL;
|
|
104
|
+
x ^= x >> 16;
|
|
105
|
+
#endif
|
|
106
|
+
*r = x;
|
|
107
|
+
return x;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
static bool chance(size_t perc, random_t r) {
|
|
111
|
+
return (pick(r) % 100 <= perc);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
static void* alloc_items(size_t items, random_t r) {
|
|
115
|
+
if (chance(1, r)) {
|
|
116
|
+
if (chance(1, r) && allow_large_objects) items *= 10000; // 0.01% giant
|
|
117
|
+
else if (chance(10, r) && allow_large_objects) items *= 1000; // 0.1% huge
|
|
118
|
+
else items *= 100; // 1% large objects;
|
|
119
|
+
}
|
|
120
|
+
if (items>=32 && items<=40) items*=2; // pthreads uses 320b allocations (this shows that more clearly in the stats)
|
|
121
|
+
if (use_one_size > 0) items = (use_one_size / sizeof(uintptr_t));
|
|
122
|
+
if (items==0) items = 1;
|
|
123
|
+
uintptr_t* p = (uintptr_t*)custom_calloc(items,sizeof(uintptr_t));
|
|
124
|
+
if (p != NULL) {
|
|
125
|
+
for (uintptr_t i = 0; i < items; i++) {
|
|
126
|
+
assert(p[i] == 0);
|
|
127
|
+
p[i] = (items - i) ^ cookie;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
return p;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
static void free_items(void* p) {
|
|
134
|
+
if (p != NULL) {
|
|
135
|
+
uintptr_t* q = (uintptr_t*)p;
|
|
136
|
+
uintptr_t items = (q[0] ^ cookie);
|
|
137
|
+
for (uintptr_t i = 0; i < items; i++) {
|
|
138
|
+
if ((q[i] ^ cookie) != items - i) {
|
|
139
|
+
fprintf(stderr, "memory corruption at block %p at %zu\n", p, i);
|
|
140
|
+
abort();
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
custom_free(p);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
#ifdef HEAP_WALK
|
|
148
|
+
static bool visit_blocks(const mi_heap_t* heap, const mi_heap_area_t* area, void* block, size_t block_size, void* arg) {
|
|
149
|
+
(void)(heap); (void)(area);
|
|
150
|
+
size_t* total = (size_t*)arg;
|
|
151
|
+
if (block != NULL) {
|
|
152
|
+
*total += block_size;
|
|
153
|
+
}
|
|
154
|
+
return true;
|
|
155
|
+
}
|
|
156
|
+
#endif
|
|
157
|
+
|
|
158
|
+
static void stress(intptr_t tid) {
|
|
159
|
+
//bench_start_thread();
|
|
160
|
+
uintptr_t r = ((tid + 1) * 43); // rand();
|
|
161
|
+
const size_t max_item_shift = 5; // 128
|
|
162
|
+
const size_t max_item_retained_shift = max_item_shift + 2;
|
|
163
|
+
size_t allocs = 100 * ((size_t)SCALE) * (tid % 8 + 1); // some threads do more
|
|
164
|
+
size_t retain = allocs / 2;
|
|
165
|
+
void** data = NULL;
|
|
166
|
+
size_t data_size = 0;
|
|
167
|
+
size_t data_top = 0;
|
|
168
|
+
void** retained = (void**)custom_calloc(retain,sizeof(void*));
|
|
169
|
+
size_t retain_top = 0;
|
|
170
|
+
|
|
171
|
+
while (allocs > 0 || retain > 0) {
|
|
172
|
+
if (retain == 0 || (chance(50, &r) && allocs > 0)) {
|
|
173
|
+
// 50%+ alloc
|
|
174
|
+
allocs--;
|
|
175
|
+
if (data_top >= data_size) {
|
|
176
|
+
data_size += 100000;
|
|
177
|
+
data = (void**)custom_realloc(data, data_size * sizeof(void*));
|
|
178
|
+
}
|
|
179
|
+
data[data_top++] = alloc_items(1ULL << (pick(&r) % max_item_shift), &r);
|
|
180
|
+
}
|
|
181
|
+
else {
|
|
182
|
+
// 25% retain
|
|
183
|
+
retained[retain_top++] = alloc_items( 1ULL << (pick(&r) % max_item_retained_shift), &r);
|
|
184
|
+
retain--;
|
|
185
|
+
}
|
|
186
|
+
if (chance(66, &r) && data_top > 0) {
|
|
187
|
+
// 66% free previous alloc
|
|
188
|
+
size_t idx = pick(&r) % data_top;
|
|
189
|
+
free_items(data[idx]);
|
|
190
|
+
data[idx] = NULL;
|
|
191
|
+
}
|
|
192
|
+
if (chance(25, &r) && data_top > 0) {
|
|
193
|
+
// 25% exchange a local pointer with the (shared) transfer buffer.
|
|
194
|
+
size_t data_idx = pick(&r) % data_top;
|
|
195
|
+
size_t transfer_idx = pick(&r) % TRANSFERS;
|
|
196
|
+
void* p = data[data_idx];
|
|
197
|
+
void* q = atomic_exchange_ptr(&transfer[transfer_idx], p);
|
|
198
|
+
data[data_idx] = q;
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
#ifdef HEAP_WALK
|
|
203
|
+
// walk the heap
|
|
204
|
+
size_t total = 0;
|
|
205
|
+
mi_heap_visit_blocks(mi_heap_get_default(), true, visit_blocks, &total);
|
|
206
|
+
#endif
|
|
207
|
+
|
|
208
|
+
// free everything that is left
|
|
209
|
+
for (size_t i = 0; i < retain_top; i++) {
|
|
210
|
+
free_items(retained[i]);
|
|
211
|
+
}
|
|
212
|
+
for (size_t i = 0; i < data_top; i++) {
|
|
213
|
+
free_items(data[i]);
|
|
214
|
+
}
|
|
215
|
+
custom_free(retained);
|
|
216
|
+
custom_free(data);
|
|
217
|
+
//bench_end_thread();
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
static void run_os_threads(size_t nthreads, void (*entry)(intptr_t tid));
|
|
221
|
+
|
|
222
|
+
static void test_stress(void) {
|
|
223
|
+
uintptr_t r = rand();
|
|
224
|
+
for (int n = 0; n < ITER; n++) {
|
|
225
|
+
run_os_threads(THREADS, &stress);
|
|
226
|
+
#if !defined(NDEBUG) && !defined(USE_STD_MALLOC)
|
|
227
|
+
// switch between arena and OS allocation for testing
|
|
228
|
+
// mi_option_set_enabled(mi_option_disallow_arena_alloc, (n%2)==1);
|
|
229
|
+
#endif
|
|
230
|
+
#ifdef HEAP_WALK
|
|
231
|
+
size_t total = 0;
|
|
232
|
+
mi_abandoned_visit_blocks(mi_subproc_main(), -1, true, visit_blocks, &total);
|
|
233
|
+
#endif
|
|
234
|
+
for (int i = 0; i < TRANSFERS; i++) {
|
|
235
|
+
if (chance(50, &r) || n + 1 == ITER) { // free all on last run, otherwise free half of the transfers
|
|
236
|
+
void* p = atomic_exchange_ptr(&transfer[i], NULL);
|
|
237
|
+
free_items(p);
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
#ifndef NDEBUG
|
|
241
|
+
//mi_collect(false);
|
|
242
|
+
//mi_debug_show_arenas(true);
|
|
243
|
+
#endif
|
|
244
|
+
#if !defined(NDEBUG) || defined(MI_TSAN)
|
|
245
|
+
if ((n + 1) % 10 == 0) { printf("- iterations left: %3d\n", ITER - (n + 1)); }
|
|
246
|
+
#endif
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
#ifndef STRESS
|
|
251
|
+
static void leak(intptr_t tid) {
|
|
252
|
+
uintptr_t r = rand();
|
|
253
|
+
void* p = alloc_items(1 /*pick(&r)%128*/, &r);
|
|
254
|
+
if (chance(50, &r)) {
|
|
255
|
+
intptr_t i = (pick(&r) % TRANSFERS);
|
|
256
|
+
void* q = atomic_exchange_ptr(&transfer[i], p);
|
|
257
|
+
free_items(q);
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
static void test_leak(void) {
|
|
262
|
+
for (int n = 0; n < ITER; n++) {
|
|
263
|
+
run_os_threads(THREADS, &leak);
|
|
264
|
+
mi_collect(false);
|
|
265
|
+
#ifndef NDEBUG
|
|
266
|
+
if ((n + 1) % 10 == 0) { printf("- iterations left: %3d\n", ITER - (n + 1)); }
|
|
267
|
+
#endif
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
#endif
|
|
271
|
+
|
|
272
|
+
#if defined(USE_STD_MALLOC) && defined(MI_LINK_VERSION)
|
|
273
|
+
#ifdef __cplusplus
|
|
274
|
+
extern "C"
|
|
275
|
+
#endif
|
|
276
|
+
int mi_version(void);
|
|
277
|
+
#endif
|
|
278
|
+
|
|
279
|
+
int main(int argc, char** argv) {
|
|
280
|
+
#ifdef MI_LINK_VERSION
|
|
281
|
+
mi_version();
|
|
282
|
+
#endif
|
|
283
|
+
#ifdef HEAP_WALK
|
|
284
|
+
mi_option_enable(mi_option_visit_abandoned);
|
|
285
|
+
#endif
|
|
286
|
+
#if !defined(NDEBUG) && !defined(USE_STD_MALLOC)
|
|
287
|
+
mi_option_set(mi_option_arena_reserve, 32 * 1024 /* in kib = 32MiB */);
|
|
288
|
+
#endif
|
|
289
|
+
|
|
290
|
+
// > mimalloc-test-stress [THREADS] [SCALE] [ITER]
|
|
291
|
+
if (argc >= 2) {
|
|
292
|
+
char* end;
|
|
293
|
+
long n = strtol(argv[1], &end, 10);
|
|
294
|
+
if (n > 0) THREADS = n;
|
|
295
|
+
}
|
|
296
|
+
if (argc >= 3) {
|
|
297
|
+
char* end;
|
|
298
|
+
long n = (strtol(argv[2], &end, 10));
|
|
299
|
+
if (n > 0) SCALE = n;
|
|
300
|
+
}
|
|
301
|
+
if (argc >= 4) {
|
|
302
|
+
char* end;
|
|
303
|
+
long n = (strtol(argv[3], &end, 10));
|
|
304
|
+
if (n > 0) ITER = n;
|
|
305
|
+
}
|
|
306
|
+
if (SCALE > 100) {
|
|
307
|
+
allow_large_objects = true;
|
|
308
|
+
}
|
|
309
|
+
printf("Using %d threads with a %d%% load-per-thread and %d iterations %s\n", THREADS, SCALE, ITER, (allow_large_objects ? "(allow large objects)" : ""));
|
|
310
|
+
|
|
311
|
+
#if !defined(NDEBUG) && !defined(USE_STD_MALLOC)
|
|
312
|
+
mi_stats_reset();
|
|
313
|
+
#endif
|
|
314
|
+
|
|
315
|
+
//mi_reserve_os_memory(1024*1024*1024ULL, false, true);
|
|
316
|
+
//int res = mi_reserve_huge_os_pages(4,1);
|
|
317
|
+
//printf("(reserve huge: %i\n)", res);
|
|
318
|
+
|
|
319
|
+
//bench_start_program();
|
|
320
|
+
|
|
321
|
+
// Run ITER full iterations where half the objects in the transfer buffer survive to the next round.
|
|
322
|
+
srand(0x7feb352d);
|
|
323
|
+
|
|
324
|
+
//mi_reserve_os_memory(512ULL << 20, true, true);
|
|
325
|
+
|
|
326
|
+
#if !defined(NDEBUG) && !defined(USE_STD_MALLOC)
|
|
327
|
+
mi_stats_reset();
|
|
328
|
+
#endif
|
|
329
|
+
|
|
330
|
+
#ifdef STRESS
|
|
331
|
+
test_stress();
|
|
332
|
+
#else
|
|
333
|
+
test_leak();
|
|
334
|
+
#endif
|
|
335
|
+
|
|
336
|
+
#ifndef USE_STD_MALLOC
|
|
337
|
+
#ifndef NDEBUG
|
|
338
|
+
mi_debug_show_arenas();
|
|
339
|
+
mi_collect(true);
|
|
340
|
+
char* json = mi_stats_get_json(0, NULL);
|
|
341
|
+
if (json != NULL) {
|
|
342
|
+
fputs(json,stderr);
|
|
343
|
+
mi_free(json);
|
|
344
|
+
}
|
|
345
|
+
#endif
|
|
346
|
+
mi_collect(true);
|
|
347
|
+
mi_stats_print(NULL);
|
|
348
|
+
#endif
|
|
349
|
+
//bench_end_program();
|
|
350
|
+
return 0;
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
|
|
354
|
+
static void (*thread_entry_fun)(intptr_t) = &stress;
|
|
355
|
+
|
|
356
|
+
#ifdef _WIN32
|
|
357
|
+
|
|
358
|
+
#include <windows.h>
|
|
359
|
+
|
|
360
|
+
static DWORD WINAPI thread_entry(LPVOID param) {
|
|
361
|
+
thread_entry_fun((intptr_t)param);
|
|
362
|
+
return 0;
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
static void run_os_threads(size_t nthreads, void (*fun)(intptr_t)) {
|
|
366
|
+
thread_entry_fun = fun;
|
|
367
|
+
DWORD* tids = (DWORD*)custom_calloc(nthreads,sizeof(DWORD));
|
|
368
|
+
HANDLE* thandles = (HANDLE*)custom_calloc(nthreads,sizeof(HANDLE));
|
|
369
|
+
const size_t start = (main_participates ? 1 : 0);
|
|
370
|
+
for (size_t i = start; i < nthreads; i++) {
|
|
371
|
+
thandles[i] = CreateThread(0, 8*1024, &thread_entry, (void*)(i), 0, &tids[i]);
|
|
372
|
+
}
|
|
373
|
+
if (main_participates) fun(0); // run the main thread as well
|
|
374
|
+
for (size_t i = start; i < nthreads; i++) {
|
|
375
|
+
WaitForSingleObject(thandles[i], INFINITE);
|
|
376
|
+
}
|
|
377
|
+
for (size_t i = start; i < nthreads; i++) {
|
|
378
|
+
CloseHandle(thandles[i]);
|
|
379
|
+
}
|
|
380
|
+
custom_free(tids);
|
|
381
|
+
custom_free(thandles);
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
static void* atomic_exchange_ptr(volatile void** p, void* newval) {
|
|
385
|
+
#if (INTPTR_MAX == INT32_MAX)
|
|
386
|
+
return (void*)InterlockedExchange((volatile LONG*)p, (LONG)newval);
|
|
387
|
+
#else
|
|
388
|
+
return (void*)InterlockedExchange64((volatile LONG64*)p, (LONG64)newval);
|
|
389
|
+
#endif
|
|
390
|
+
}
|
|
391
|
+
#else
|
|
392
|
+
|
|
393
|
+
#include <pthread.h>
|
|
394
|
+
|
|
395
|
+
static void* thread_entry(void* param) {
|
|
396
|
+
thread_entry_fun((uintptr_t)param);
|
|
397
|
+
return NULL;
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
static void run_os_threads(size_t nthreads, void (*fun)(intptr_t)) {
|
|
401
|
+
thread_entry_fun = fun;
|
|
402
|
+
pthread_t* threads = (pthread_t*)custom_calloc(nthreads,sizeof(pthread_t));
|
|
403
|
+
memset(threads, 0, sizeof(pthread_t) * nthreads);
|
|
404
|
+
const size_t start = (main_participates ? 1 : 0);
|
|
405
|
+
//pthread_setconcurrency(nthreads);
|
|
406
|
+
for (size_t i = start; i < nthreads; i++) {
|
|
407
|
+
pthread_create(&threads[i], NULL, &thread_entry, (void*)i);
|
|
408
|
+
}
|
|
409
|
+
if (main_participates) fun(0); // run the main thread as well
|
|
410
|
+
for (size_t i = start; i < nthreads; i++) {
|
|
411
|
+
pthread_join(threads[i], NULL);
|
|
412
|
+
}
|
|
413
|
+
custom_free(threads);
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
#ifdef __cplusplus
|
|
417
|
+
#include <atomic>
|
|
418
|
+
static void* atomic_exchange_ptr(volatile void** p, void* newval) {
|
|
419
|
+
return std::atomic_exchange((volatile std::atomic<void*>*)p, newval);
|
|
420
|
+
}
|
|
421
|
+
#else
|
|
422
|
+
#include <stdatomic.h>
|
|
423
|
+
static void* atomic_exchange_ptr(volatile void** p, void* newval) {
|
|
424
|
+
return atomic_exchange((volatile _Atomic(void*)*)p, newval);
|
|
425
|
+
}
|
|
426
|
+
#endif
|
|
427
|
+
|
|
428
|
+
#endif
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/* ----------------------------------------------------------------------------
|
|
2
|
+
Copyright (c) 2018-2020, Microsoft Research, Daan Leijen
|
|
3
|
+
This is free software; you can redistribute it and/or modify it under the
|
|
4
|
+
terms of the MIT license. A copy of the license can be found in the file
|
|
5
|
+
"LICENSE" at the root of this distribution.
|
|
6
|
+
-----------------------------------------------------------------------------*/
|
|
7
|
+
|
|
8
|
+
/* test file for valgrind/asan support.
|
|
9
|
+
|
|
10
|
+
VALGRIND:
|
|
11
|
+
----------
|
|
12
|
+
Compile in an "out/debug" folder:
|
|
13
|
+
|
|
14
|
+
> cd out/debug
|
|
15
|
+
> cmake ../.. -DMI_TRACK_VALGRIND=1
|
|
16
|
+
> make -j8
|
|
17
|
+
|
|
18
|
+
and then compile this file as:
|
|
19
|
+
|
|
20
|
+
> gcc -g -o test-wrong -I../../include ../../test/test-wrong.c libmimalloc-valgrind-debug.a -lpthread
|
|
21
|
+
|
|
22
|
+
and test as:
|
|
23
|
+
|
|
24
|
+
> valgrind ./test-wrong
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
ASAN
|
|
28
|
+
----------
|
|
29
|
+
Compile in an "out/debug" folder:
|
|
30
|
+
|
|
31
|
+
> cd out/debug
|
|
32
|
+
> cmake ../.. -DMI_TRACK_ASAN=1
|
|
33
|
+
> make -j8
|
|
34
|
+
|
|
35
|
+
and then compile this file as:
|
|
36
|
+
|
|
37
|
+
> clang -g -o test-wrong -I../../include ../../test/test-wrong.c libmimalloc-asan-debug.a -lpthread -fsanitize=address -fsanitize-recover=address
|
|
38
|
+
|
|
39
|
+
and test as:
|
|
40
|
+
|
|
41
|
+
> ASAN_OPTIONS=verbosity=1:halt_on_error=0 ./test-wrong
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
*/
|
|
45
|
+
#include <stdio.h>
|
|
46
|
+
#include <stdlib.h>
|
|
47
|
+
#include "mimalloc.h"
|
|
48
|
+
|
|
49
|
+
#ifdef USE_STD_MALLOC
|
|
50
|
+
# define mi(x) x
|
|
51
|
+
#else
|
|
52
|
+
# define mi(x) mi_##x
|
|
53
|
+
#endif
|
|
54
|
+
|
|
55
|
+
int main(int argc, char** argv) {
|
|
56
|
+
int* p = (int*)mi(malloc)(3*sizeof(int));
|
|
57
|
+
|
|
58
|
+
int* r = (int*)mi_malloc_aligned(8,16);
|
|
59
|
+
mi_free(r);
|
|
60
|
+
|
|
61
|
+
// illegal byte wise read
|
|
62
|
+
char* c = (char*)mi(malloc)(3);
|
|
63
|
+
printf("invalid byte: over: %d, under: %d\n", c[4], c[-1]);
|
|
64
|
+
mi(free)(c);
|
|
65
|
+
|
|
66
|
+
// undefined access
|
|
67
|
+
int* q = (int*)mi(malloc)(sizeof(int));
|
|
68
|
+
printf("undefined: %d\n", *q);
|
|
69
|
+
|
|
70
|
+
// illegal int read
|
|
71
|
+
printf("invalid: over: %d, under: %d\n", q[1], q[-1]);
|
|
72
|
+
|
|
73
|
+
*q = 42;
|
|
74
|
+
|
|
75
|
+
// buffer overflow
|
|
76
|
+
q[1] = 43;
|
|
77
|
+
|
|
78
|
+
// buffer underflow
|
|
79
|
+
q[-1] = 44;
|
|
80
|
+
|
|
81
|
+
mi(free)(q);
|
|
82
|
+
|
|
83
|
+
// double free
|
|
84
|
+
mi(free)(q);
|
|
85
|
+
|
|
86
|
+
// use after free
|
|
87
|
+
printf("use-after-free: %d\n", *q);
|
|
88
|
+
|
|
89
|
+
// leak p
|
|
90
|
+
// mi_free(p)
|
|
91
|
+
return 0;
|
|
92
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/* ----------------------------------------------------------------------------
|
|
2
|
+
Copyright (c) 2018-2020, Microsoft Research, Daan Leijen
|
|
3
|
+
This is free software; you can redistribute it and/or modify it under the
|
|
4
|
+
terms of the MIT license. A copy of the license can be found in the file
|
|
5
|
+
"LICENSE" at the root of this distribution.
|
|
6
|
+
-----------------------------------------------------------------------------*/
|
|
7
|
+
#ifndef TESTHELPER_H_
|
|
8
|
+
#define TESTHELPER_H_
|
|
9
|
+
|
|
10
|
+
#include <stdbool.h>
|
|
11
|
+
#include <stdio.h>
|
|
12
|
+
#include <errno.h>
|
|
13
|
+
|
|
14
|
+
// ---------------------------------------------------------------------------
|
|
15
|
+
// Test macros: CHECK(name,predicate) and CHECK_BODY(name,body)
|
|
16
|
+
// ---------------------------------------------------------------------------
|
|
17
|
+
static int ok = 0;
|
|
18
|
+
static int failed = 0;
|
|
19
|
+
|
|
20
|
+
static bool check_result(bool result, const char* testname, const char* fname, long lineno) {
|
|
21
|
+
if (!(result)) {
|
|
22
|
+
failed++;
|
|
23
|
+
fprintf(stderr,"\n FAILED: %s: %s:%ld\n", testname, fname, lineno);
|
|
24
|
+
/* exit(1); */
|
|
25
|
+
}
|
|
26
|
+
else {
|
|
27
|
+
ok++;
|
|
28
|
+
fprintf(stderr, "ok.\n");
|
|
29
|
+
}
|
|
30
|
+
return true;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
#define CHECK_BODY(name) \
|
|
34
|
+
fprintf(stderr,"test: %s... ", name ); \
|
|
35
|
+
errno = 0; \
|
|
36
|
+
for(bool done = false, result = true; !done; done = check_result(result,name,__FILE__,__LINE__))
|
|
37
|
+
|
|
38
|
+
#define CHECK(name,expr) CHECK_BODY(name){ result = (expr); }
|
|
39
|
+
|
|
40
|
+
// Print summary of test. Return value can be directly use as a return value for main().
|
|
41
|
+
static inline int print_test_summary(void)
|
|
42
|
+
{
|
|
43
|
+
fprintf(stderr,"\n\n---------------------------------------------\n"
|
|
44
|
+
"succeeded: %i\n"
|
|
45
|
+
"failed : %i\n\n", ok, failed);
|
|
46
|
+
return failed;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
#endif // TESTHELPER_H_
|