@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.
Files changed (339) hide show
  1. package/LICENSE.md +17 -0
  2. package/README.md +80 -0
  3. package/out/cjs/index.cjs +51 -0
  4. package/out/cjs/yo-cli.cjs +2158 -0
  5. package/out/esm/index.mjs +51 -0
  6. package/out/types/src/codegen/async/runtime.d.ts +2 -0
  7. package/out/types/src/codegen/async/state-code-gen.d.ts +10 -0
  8. package/out/types/src/codegen/async/state-machine.d.ts +13 -0
  9. package/out/types/src/codegen/c/collection.d.ts +3 -0
  10. package/out/types/src/codegen/codegen-c.d.ts +12 -0
  11. package/out/types/src/codegen/constants.d.ts +3 -0
  12. package/out/types/src/codegen/expressions/array.d.ts +4 -0
  13. package/out/types/src/codegen/expressions/generation.d.ts +11 -0
  14. package/out/types/src/codegen/expressions/index.d.ts +2 -0
  15. package/out/types/src/codegen/functions/collection.d.ts +5 -0
  16. package/out/types/src/codegen/functions/context.d.ts +57 -0
  17. package/out/types/src/codegen/functions/generation.d.ts +25 -0
  18. package/out/types/src/codegen/functions/index.d.ts +2 -0
  19. package/out/types/src/codegen/index.d.ts +20 -0
  20. package/out/types/src/codegen/parallelism/runtime.d.ts +2 -0
  21. package/out/types/src/codegen/types/collection.d.ts +8 -0
  22. package/out/types/src/codegen/types/generation.d.ts +13 -0
  23. package/out/types/src/codegen/types/index.d.ts +2 -0
  24. package/out/types/src/codegen/utils/fixup.d.ts +2 -0
  25. package/out/types/src/codegen/utils/index.d.ts +77 -0
  26. package/out/types/src/codegen/values/index.d.ts +1 -0
  27. package/out/types/src/emitter.d.ts +11 -0
  28. package/out/types/src/env.d.ts +85 -0
  29. package/out/types/src/error.d.ts +45 -0
  30. package/out/types/src/evaluator/async/await-analysis-types.d.ts +23 -0
  31. package/out/types/src/evaluator/async/await-analysis.d.ts +5 -0
  32. package/out/types/src/evaluator/builtins/alignof.d.ts +8 -0
  33. package/out/types/src/evaluator/builtins/and_or.d.ts +8 -0
  34. package/out/types/src/evaluator/builtins/arc_fns.d.ts +58 -0
  35. package/out/types/src/evaluator/builtins/array_fns.d.ts +0 -0
  36. package/out/types/src/evaluator/builtins/as.d.ts +8 -0
  37. package/out/types/src/evaluator/builtins/async_fns.d.ts +8 -0
  38. package/out/types/src/evaluator/builtins/compt_assert.d.ts +8 -0
  39. package/out/types/src/evaluator/builtins/compt_boolean_fns.d.ts +8 -0
  40. package/out/types/src/evaluator/builtins/compt_expect_error.d.ts +8 -0
  41. package/out/types/src/evaluator/builtins/compt_list_fns.d.ts +33 -0
  42. package/out/types/src/evaluator/builtins/compt_print.d.ts +8 -0
  43. package/out/types/src/evaluator/builtins/compt_string_fns.d.ts +8 -0
  44. package/out/types/src/evaluator/builtins/consume.d.ts +8 -0
  45. package/out/types/src/evaluator/builtins/drop.d.ts +8 -0
  46. package/out/types/src/evaluator/builtins/dup.d.ts +8 -0
  47. package/out/types/src/evaluator/builtins/expr_fns.d.ts +33 -0
  48. package/out/types/src/evaluator/builtins/future_fns.d.ts +8 -0
  49. package/out/types/src/evaluator/builtins/gc.d.ts +8 -0
  50. package/out/types/src/evaluator/builtins/gensym.d.ts +8 -0
  51. package/out/types/src/evaluator/builtins/impl_constraint.d.ts +8 -0
  52. package/out/types/src/evaluator/builtins/macro_expand.d.ts +8 -0
  53. package/out/types/src/evaluator/builtins/numeric_fns.d.ts +8 -0
  54. package/out/types/src/evaluator/builtins/panic.d.ts +8 -0
  55. package/out/types/src/evaluator/builtins/ptr_fns.d.ts +8 -0
  56. package/out/types/src/evaluator/builtins/quote.d.ts +13 -0
  57. package/out/types/src/evaluator/builtins/rc.d.ts +8 -0
  58. package/out/types/src/evaluator/builtins/sizeof.d.ts +8 -0
  59. package/out/types/src/evaluator/builtins/the.d.ts +8 -0
  60. package/out/types/src/evaluator/builtins/type_fns.d.ts +28 -0
  61. package/out/types/src/evaluator/builtins/va_start.d.ts +8 -0
  62. package/out/types/src/evaluator/builtins/var_fns.d.ts +18 -0
  63. package/out/types/src/evaluator/calls/array.d.ts +13 -0
  64. package/out/types/src/evaluator/calls/array_type.d.ts +11 -0
  65. package/out/types/src/evaluator/calls/closure_type.d.ts +11 -0
  66. package/out/types/src/evaluator/calls/compt_function.d.ts +19 -0
  67. package/out/types/src/evaluator/calls/compt_list_type.d.ts +11 -0
  68. package/out/types/src/evaluator/calls/function.d.ts +16 -0
  69. package/out/types/src/evaluator/calls/function_type.d.ts +15 -0
  70. package/out/types/src/evaluator/calls/helper.d.ts +42 -0
  71. package/out/types/src/evaluator/calls/iso.d.ts +15 -0
  72. package/out/types/src/evaluator/calls/module_type.d.ts +11 -0
  73. package/out/types/src/evaluator/calls/numeric_type.d.ts +15 -0
  74. package/out/types/src/evaluator/calls/pointer.d.ts +8 -0
  75. package/out/types/src/evaluator/calls/pointer_type.d.ts +14 -0
  76. package/out/types/src/evaluator/calls/type.d.ts +12 -0
  77. package/out/types/src/evaluator/context.d.ts +169 -0
  78. package/out/types/src/evaluator/exprs/_expr.d.ts +8 -0
  79. package/out/types/src/evaluator/exprs/assignment.d.ts +9 -0
  80. package/out/types/src/evaluator/exprs/begin.d.ts +10 -0
  81. package/out/types/src/evaluator/exprs/binding.d.ts +12 -0
  82. package/out/types/src/evaluator/exprs/c_include.d.ts +8 -0
  83. package/out/types/src/evaluator/exprs/cond.d.ts +8 -0
  84. package/out/types/src/evaluator/exprs/destructuring_assignment.d.ts +33 -0
  85. package/out/types/src/evaluator/exprs/exists.d.ts +0 -0
  86. package/out/types/src/evaluator/exprs/expr.d.ts +9 -0
  87. package/out/types/src/evaluator/exprs/extern.d.ts +8 -0
  88. package/out/types/src/evaluator/exprs/identifer_and_operator.d.ts +9 -0
  89. package/out/types/src/evaluator/exprs/import.d.ts +9 -0
  90. package/out/types/src/evaluator/exprs/initialization_assignment.d.ts +8 -0
  91. package/out/types/src/evaluator/exprs/match.d.ts +8 -0
  92. package/out/types/src/evaluator/exprs/open.d.ts +8 -0
  93. package/out/types/src/evaluator/exprs/property_access.d.ts +8 -0
  94. package/out/types/src/evaluator/exprs/recur.d.ts +8 -0
  95. package/out/types/src/evaluator/exprs/subtype_of.d.ts +21 -0
  96. package/out/types/src/evaluator/exprs/test.d.ts +8 -0
  97. package/out/types/src/evaluator/exprs/typeof.d.ts +8 -0
  98. package/out/types/src/evaluator/exprs/while.d.ts +8 -0
  99. package/out/types/src/evaluator/index.d.ts +26 -0
  100. package/out/types/src/evaluator/types/array.d.ts +8 -0
  101. package/out/types/src/evaluator/types/closure.d.ts +8 -0
  102. package/out/types/src/evaluator/types/compt_list.d.ts +8 -0
  103. package/out/types/src/evaluator/types/concrete_module.d.ts +8 -0
  104. package/out/types/src/evaluator/types/dyn.d.ts +8 -0
  105. package/out/types/src/evaluator/types/enum.d.ts +8 -0
  106. package/out/types/src/evaluator/types/expr_synthesizer.d.ts +14 -0
  107. package/out/types/src/evaluator/types/field.d.ts +14 -0
  108. package/out/types/src/evaluator/types/fn_module.d.ts +8 -0
  109. package/out/types/src/evaluator/types/function.d.ts +58 -0
  110. package/out/types/src/evaluator/types/future_module.d.ts +8 -0
  111. package/out/types/src/evaluator/types/module.d.ts +19 -0
  112. package/out/types/src/evaluator/types/newtype.d.ts +8 -0
  113. package/out/types/src/evaluator/types/object.d.ts +8 -0
  114. package/out/types/src/evaluator/types/proofs.d.ts +0 -0
  115. package/out/types/src/evaluator/types/slice.d.ts +8 -0
  116. package/out/types/src/evaluator/types/struct.d.ts +8 -0
  117. package/out/types/src/evaluator/types/synthesizer.d.ts +16 -0
  118. package/out/types/src/evaluator/types/tuple.d.ts +18 -0
  119. package/out/types/src/evaluator/types/union.d.ts +8 -0
  120. package/out/types/src/evaluator/types/utils.d.ts +71 -0
  121. package/out/types/src/evaluator/types/validation.d.ts +3 -0
  122. package/out/types/src/evaluator/utils/array-utils.d.ts +15 -0
  123. package/out/types/src/evaluator/utils/closure.d.ts +35 -0
  124. package/out/types/src/evaluator/utils.d.ts +4 -0
  125. package/out/types/src/evaluator/values/anonymous_function.d.ts +8 -0
  126. package/out/types/src/evaluator/values/anonymous_module.d.ts +17 -0
  127. package/out/types/src/evaluator/values/anonymous_struct.d.ts +8 -0
  128. package/out/types/src/evaluator/values/array.d.ts +8 -0
  129. package/out/types/src/evaluator/values/boolean.d.ts +3 -0
  130. package/out/types/src/evaluator/values/char.d.ts +3 -0
  131. package/out/types/src/evaluator/values/compt_list.d.ts +8 -0
  132. package/out/types/src/evaluator/values/dyn.d.ts +8 -0
  133. package/out/types/src/evaluator/values/float.d.ts +4 -0
  134. package/out/types/src/evaluator/values/integer.d.ts +4 -0
  135. package/out/types/src/evaluator/values/module.d.ts +58 -0
  136. package/out/types/src/evaluator/values/string.d.ts +3 -0
  137. package/out/types/src/evaluator/values/tuple.d.ts +32 -0
  138. package/out/types/src/expr.d.ts +456 -0
  139. package/out/types/src/function-value.d.ts +42 -0
  140. package/out/types/src/index.d.ts +4 -0
  141. package/out/types/src/lexer.d.ts +2 -0
  142. package/out/types/src/logger.d.ts +1 -0
  143. package/out/types/src/module-manager.d.ts +30 -0
  144. package/out/types/src/naming-checker.d.ts +4 -0
  145. package/out/types/src/parser.d.ts +33 -0
  146. package/out/types/src/test-runner.d.ts +30 -0
  147. package/out/types/src/tests/codegen.test.d.ts +1 -0
  148. package/out/types/src/tests/fixme.test.d.ts +1 -0
  149. package/out/types/src/tests/module-manager.test.d.ts +1 -0
  150. package/out/types/src/tests/parser.test.d.ts +1 -0
  151. package/out/types/src/tests/sample.test.d.ts +0 -0
  152. package/out/types/src/tests/std.test.d.ts +1 -0
  153. package/out/types/src/token.d.ts +40 -0
  154. package/out/types/src/type-value.d.ts +7 -0
  155. package/out/types/src/types/compatibility.d.ts +16 -0
  156. package/out/types/src/types/creators.d.ts +73 -0
  157. package/out/types/src/types/definitions.d.ts +218 -0
  158. package/out/types/src/types/guards.d.ts +70 -0
  159. package/out/types/src/types/hierarchy.d.ts +4 -0
  160. package/out/types/src/types/index.d.ts +7 -0
  161. package/out/types/src/types/module_field.d.ts +2 -0
  162. package/out/types/src/types/tags.d.ts +45 -0
  163. package/out/types/src/types/utils.d.ts +50 -0
  164. package/out/types/src/unit-value.d.ts +7 -0
  165. package/out/types/src/utils.d.ts +6 -0
  166. package/out/types/src/value-tag.d.ts +29 -0
  167. package/out/types/src/value.d.ts +110 -0
  168. package/out/types/src/yo-cli.d.ts +1 -0
  169. package/out/types/tsconfig.tsbuildinfo +1 -0
  170. package/package.json +57 -0
  171. package/scripts/check-liburing.js +76 -0
  172. package/std/alg/hash.yo +50 -0
  173. package/std/allocator.yo +113 -0
  174. package/std/allocators/c_allocator.yo +118 -0
  175. package/std/async.yo +13 -0
  176. package/std/collections/array_list.yo +415 -0
  177. package/std/collections/hash_map.yo +482 -0
  178. package/std/collections/hash_set.yo +706 -0
  179. package/std/collections/index.yo +11 -0
  180. package/std/collections/linked_list.yo +439 -0
  181. package/std/error.yo +0 -0
  182. package/std/gc.yo +10 -0
  183. package/std/index.yo +12 -0
  184. package/std/io/file.yo +191 -0
  185. package/std/io/index.yo +5 -0
  186. package/std/libc/assert.yo +39 -0
  187. package/std/libc/ctype.yo +57 -0
  188. package/std/libc/errno.yo +182 -0
  189. package/std/libc/float.yo +87 -0
  190. package/std/libc/index.yo +29 -0
  191. package/std/libc/limits.yo +65 -0
  192. package/std/libc/math.yo +679 -0
  193. package/std/libc/signal.yo +101 -0
  194. package/std/libc/stdatomic.yo +213 -0
  195. package/std/libc/stdint.yo +214 -0
  196. package/std/libc/stdio.yo +225 -0
  197. package/std/libc/stdlib.yo +204 -0
  198. package/std/libc/string.yo +151 -0
  199. package/std/libc/time.yo +92 -0
  200. package/std/libc/unistd.yo +130 -0
  201. package/std/monad.yo +152 -0
  202. package/std/prelude.yo +3094 -0
  203. package/std/string/index.yo +8 -0
  204. package/std/string/rune.yo +82 -0
  205. package/std/string/string.yo +288 -0
  206. package/std/sync.yo +95 -0
  207. package/std/thread.yo +36 -0
  208. package/std/time.yo +13 -0
  209. package/std/worker.yo +36 -0
  210. package/vendor/mimalloc/.gitattributes +12 -0
  211. package/vendor/mimalloc/CMakeLists.txt +763 -0
  212. package/vendor/mimalloc/LICENSE +21 -0
  213. package/vendor/mimalloc/SECURITY.md +41 -0
  214. package/vendor/mimalloc/azure-pipelines.yml +251 -0
  215. package/vendor/mimalloc/bin/mimalloc-redirect-arm64.dll +0 -0
  216. package/vendor/mimalloc/bin/mimalloc-redirect-arm64.lib +0 -0
  217. package/vendor/mimalloc/bin/mimalloc-redirect-arm64ec.dll +0 -0
  218. package/vendor/mimalloc/bin/mimalloc-redirect-arm64ec.lib +0 -0
  219. package/vendor/mimalloc/bin/mimalloc-redirect.dll +0 -0
  220. package/vendor/mimalloc/bin/mimalloc-redirect.lib +0 -0
  221. package/vendor/mimalloc/bin/mimalloc-redirect32.dll +0 -0
  222. package/vendor/mimalloc/bin/mimalloc-redirect32.lib +0 -0
  223. package/vendor/mimalloc/bin/minject-arm64.exe +0 -0
  224. package/vendor/mimalloc/bin/minject.exe +0 -0
  225. package/vendor/mimalloc/bin/minject32.exe +0 -0
  226. package/vendor/mimalloc/bin/readme.md +118 -0
  227. package/vendor/mimalloc/cmake/JoinPaths.cmake +23 -0
  228. package/vendor/mimalloc/cmake/mimalloc-config-version.cmake +19 -0
  229. package/vendor/mimalloc/cmake/mimalloc-config.cmake +14 -0
  230. package/vendor/mimalloc/contrib/docker/alpine/Dockerfile +23 -0
  231. package/vendor/mimalloc/contrib/docker/alpine-arm32v7/Dockerfile +28 -0
  232. package/vendor/mimalloc/contrib/docker/alpine-x86/Dockerfile +28 -0
  233. package/vendor/mimalloc/contrib/docker/manylinux-x64/Dockerfile +23 -0
  234. package/vendor/mimalloc/contrib/docker/readme.md +10 -0
  235. package/vendor/mimalloc/contrib/vcpkg/portfile.cmake +64 -0
  236. package/vendor/mimalloc/contrib/vcpkg/readme.md +40 -0
  237. package/vendor/mimalloc/contrib/vcpkg/usage +20 -0
  238. package/vendor/mimalloc/contrib/vcpkg/vcpkg-cmake-wrapper.cmake +20 -0
  239. package/vendor/mimalloc/contrib/vcpkg/vcpkg.json +48 -0
  240. package/vendor/mimalloc/doc/bench-2020/bench-c5-18xlarge-2020-01-20-a.svg +887 -0
  241. package/vendor/mimalloc/doc/bench-2020/bench-c5-18xlarge-2020-01-20-b.svg +1185 -0
  242. package/vendor/mimalloc/doc/bench-2020/bench-c5-18xlarge-2020-01-20-rss-a.svg +757 -0
  243. package/vendor/mimalloc/doc/bench-2020/bench-c5-18xlarge-2020-01-20-rss-b.svg +1028 -0
  244. package/vendor/mimalloc/doc/bench-2020/bench-r5a-1.svg +769 -0
  245. package/vendor/mimalloc/doc/bench-2020/bench-r5a-12xlarge-2020-01-16-a.svg +868 -0
  246. package/vendor/mimalloc/doc/bench-2020/bench-r5a-12xlarge-2020-01-16-b.svg +1157 -0
  247. package/vendor/mimalloc/doc/bench-2020/bench-r5a-2.svg +983 -0
  248. package/vendor/mimalloc/doc/bench-2020/bench-r5a-rss-1.svg +683 -0
  249. package/vendor/mimalloc/doc/bench-2020/bench-r5a-rss-2.svg +854 -0
  250. package/vendor/mimalloc/doc/bench-2020/bench-spec-rss.svg +713 -0
  251. package/vendor/mimalloc/doc/bench-2020/bench-spec.svg +713 -0
  252. package/vendor/mimalloc/doc/bench-2020/bench-z4-1.svg +890 -0
  253. package/vendor/mimalloc/doc/bench-2020/bench-z4-2.svg +1146 -0
  254. package/vendor/mimalloc/doc/bench-2020/bench-z4-rss-1.svg +796 -0
  255. package/vendor/mimalloc/doc/bench-2020/bench-z4-rss-2.svg +974 -0
  256. package/vendor/mimalloc/doc/bench-2021/bench-amd5950x-2021-01-30-a.svg +952 -0
  257. package/vendor/mimalloc/doc/bench-2021/bench-amd5950x-2021-01-30-b.svg +1255 -0
  258. package/vendor/mimalloc/doc/bench-2021/bench-c5-18xlarge-2021-01-30-a.svg +955 -0
  259. package/vendor/mimalloc/doc/bench-2021/bench-c5-18xlarge-2021-01-30-b.svg +1269 -0
  260. package/vendor/mimalloc/doc/bench-2021/bench-c5-18xlarge-2021-01-30-rss-a.svg +836 -0
  261. package/vendor/mimalloc/doc/bench-2021/bench-c5-18xlarge-2021-01-30-rss-b.svg +1131 -0
  262. package/vendor/mimalloc/doc/bench-2021/bench-macmini-2021-01-30.svg +766 -0
  263. package/vendor/mimalloc/doc/doxyfile +2895 -0
  264. package/vendor/mimalloc/doc/ds-logo.jpg +0 -0
  265. package/vendor/mimalloc/doc/ds-logo.png +0 -0
  266. package/vendor/mimalloc/doc/mimalloc-doc.h +1452 -0
  267. package/vendor/mimalloc/doc/mimalloc-doxygen.css +60 -0
  268. package/vendor/mimalloc/doc/mimalloc-logo-100.png +0 -0
  269. package/vendor/mimalloc/doc/mimalloc-logo.png +0 -0
  270. package/vendor/mimalloc/doc/mimalloc-logo.svg +161 -0
  271. package/vendor/mimalloc/doc/spades-logo.png +0 -0
  272. package/vendor/mimalloc/doc/unreal-logo.svg +43 -0
  273. package/vendor/mimalloc/ide/vs2022/mimalloc-lib.vcxproj +500 -0
  274. package/vendor/mimalloc/ide/vs2022/mimalloc-lib.vcxproj.filters +108 -0
  275. package/vendor/mimalloc/ide/vs2022/mimalloc-override-dll.vcxproj +508 -0
  276. package/vendor/mimalloc/ide/vs2022/mimalloc-override-dll.vcxproj.filters +111 -0
  277. package/vendor/mimalloc/ide/vs2022/mimalloc-override-test-dep.vcxproj +355 -0
  278. package/vendor/mimalloc/ide/vs2022/mimalloc-override-test.vcxproj +360 -0
  279. package/vendor/mimalloc/ide/vs2022/mimalloc-test-api.vcxproj +295 -0
  280. package/vendor/mimalloc/ide/vs2022/mimalloc-test-stress.vcxproj +292 -0
  281. package/vendor/mimalloc/ide/vs2022/mimalloc-test.vcxproj +289 -0
  282. package/vendor/mimalloc/ide/vs2022/mimalloc.sln +151 -0
  283. package/vendor/mimalloc/include/mimalloc/atomic.h +557 -0
  284. package/vendor/mimalloc/include/mimalloc/internal.h +1153 -0
  285. package/vendor/mimalloc/include/mimalloc/prim.h +421 -0
  286. package/vendor/mimalloc/include/mimalloc/track.h +145 -0
  287. package/vendor/mimalloc/include/mimalloc/types.h +685 -0
  288. package/vendor/mimalloc/include/mimalloc-new-delete.h +66 -0
  289. package/vendor/mimalloc/include/mimalloc-override.h +68 -0
  290. package/vendor/mimalloc/include/mimalloc-stats.h +103 -0
  291. package/vendor/mimalloc/include/mimalloc.h +612 -0
  292. package/vendor/mimalloc/mimalloc.pc.in +11 -0
  293. package/vendor/mimalloc/readme.md +946 -0
  294. package/vendor/mimalloc/src/alloc-aligned.c +360 -0
  295. package/vendor/mimalloc/src/alloc-override.c +316 -0
  296. package/vendor/mimalloc/src/alloc-posix.c +185 -0
  297. package/vendor/mimalloc/src/alloc.c +692 -0
  298. package/vendor/mimalloc/src/arena-abandon.c +346 -0
  299. package/vendor/mimalloc/src/arena.c +1043 -0
  300. package/vendor/mimalloc/src/bitmap.c +441 -0
  301. package/vendor/mimalloc/src/bitmap.h +119 -0
  302. package/vendor/mimalloc/src/free.c +572 -0
  303. package/vendor/mimalloc/src/heap.c +733 -0
  304. package/vendor/mimalloc/src/init.c +714 -0
  305. package/vendor/mimalloc/src/libc.c +334 -0
  306. package/vendor/mimalloc/src/options.c +663 -0
  307. package/vendor/mimalloc/src/os.c +770 -0
  308. package/vendor/mimalloc/src/page-queue.c +390 -0
  309. package/vendor/mimalloc/src/page.c +1049 -0
  310. package/vendor/mimalloc/src/prim/emscripten/prim.c +249 -0
  311. package/vendor/mimalloc/src/prim/osx/alloc-override-zone.c +461 -0
  312. package/vendor/mimalloc/src/prim/osx/prim.c +9 -0
  313. package/vendor/mimalloc/src/prim/prim.c +76 -0
  314. package/vendor/mimalloc/src/prim/readme.md +9 -0
  315. package/vendor/mimalloc/src/prim/unix/prim.c +934 -0
  316. package/vendor/mimalloc/src/prim/wasi/prim.c +284 -0
  317. package/vendor/mimalloc/src/prim/windows/etw-mimalloc.wprp +61 -0
  318. package/vendor/mimalloc/src/prim/windows/etw.h +905 -0
  319. package/vendor/mimalloc/src/prim/windows/etw.man +0 -0
  320. package/vendor/mimalloc/src/prim/windows/prim.c +878 -0
  321. package/vendor/mimalloc/src/prim/windows/readme.md +17 -0
  322. package/vendor/mimalloc/src/random.c +258 -0
  323. package/vendor/mimalloc/src/segment-map.c +142 -0
  324. package/vendor/mimalloc/src/segment.c +1702 -0
  325. package/vendor/mimalloc/src/static.c +41 -0
  326. package/vendor/mimalloc/src/stats.c +635 -0
  327. package/vendor/mimalloc/test/CMakeLists.txt +56 -0
  328. package/vendor/mimalloc/test/main-override-dep.cpp +51 -0
  329. package/vendor/mimalloc/test/main-override-dep.h +11 -0
  330. package/vendor/mimalloc/test/main-override-static.c +539 -0
  331. package/vendor/mimalloc/test/main-override.c +36 -0
  332. package/vendor/mimalloc/test/main-override.cpp +497 -0
  333. package/vendor/mimalloc/test/main.c +46 -0
  334. package/vendor/mimalloc/test/readme.md +16 -0
  335. package/vendor/mimalloc/test/test-api-fill.c +343 -0
  336. package/vendor/mimalloc/test/test-api.c +466 -0
  337. package/vendor/mimalloc/test/test-stress.c +428 -0
  338. package/vendor/mimalloc/test/test-wrong.c +92 -0
  339. package/vendor/mimalloc/test/testhelper.h +49 -0
@@ -0,0 +1,878 @@
1
+ /* ----------------------------------------------------------------------------
2
+ Copyright (c) 2018-2023, 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
+ // This file is included in `src/prim/prim.c`
9
+
10
+ #include "mimalloc.h"
11
+ #include "mimalloc/internal.h"
12
+ #include "mimalloc/prim.h"
13
+ #include <stdio.h> // fputs, stderr
14
+
15
+ // xbox has no console IO
16
+ #if !defined(WINAPI_FAMILY_PARTITION) || WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP | WINAPI_PARTITION_SYSTEM)
17
+ #define MI_HAS_CONSOLE_IO
18
+ #endif
19
+
20
+ //---------------------------------------------
21
+ // Dynamically bind Windows API points for portability
22
+ //---------------------------------------------
23
+
24
+ // We use VirtualAlloc2 for aligned allocation, but it is only supported on Windows 10 and Windows Server 2016.
25
+ // So, we need to look it up dynamically to run on older systems. (use __stdcall for 32-bit compatibility)
26
+ // NtAllocateVirtualAllocEx is used for huge OS page allocation (1GiB)
27
+ // We define a minimal MEM_EXTENDED_PARAMETER ourselves in order to be able to compile with older SDK's.
28
+ typedef enum MI_MEM_EXTENDED_PARAMETER_TYPE_E {
29
+ MiMemExtendedParameterInvalidType = 0,
30
+ MiMemExtendedParameterAddressRequirements,
31
+ MiMemExtendedParameterNumaNode,
32
+ MiMemExtendedParameterPartitionHandle,
33
+ MiMemExtendedParameterUserPhysicalHandle,
34
+ MiMemExtendedParameterAttributeFlags,
35
+ MiMemExtendedParameterMax
36
+ } MI_MEM_EXTENDED_PARAMETER_TYPE;
37
+
38
+ typedef struct DECLSPEC_ALIGN(8) MI_MEM_EXTENDED_PARAMETER_S {
39
+ struct { DWORD64 Type : 8; DWORD64 Reserved : 56; } Type;
40
+ union { DWORD64 ULong64; PVOID Pointer; SIZE_T Size; HANDLE Handle; DWORD ULong; } Arg;
41
+ } MI_MEM_EXTENDED_PARAMETER;
42
+
43
+ typedef struct MI_MEM_ADDRESS_REQUIREMENTS_S {
44
+ PVOID LowestStartingAddress;
45
+ PVOID HighestEndingAddress;
46
+ SIZE_T Alignment;
47
+ } MI_MEM_ADDRESS_REQUIREMENTS;
48
+
49
+ #define MI_MEM_EXTENDED_PARAMETER_NONPAGED_HUGE 0x00000010
50
+
51
+ #include <winternl.h>
52
+ typedef PVOID (__stdcall *PVirtualAlloc2)(HANDLE, PVOID, SIZE_T, ULONG, ULONG, MI_MEM_EXTENDED_PARAMETER*, ULONG);
53
+ typedef LONG (__stdcall *PNtAllocateVirtualMemoryEx)(HANDLE, PVOID*, SIZE_T*, ULONG, ULONG, MI_MEM_EXTENDED_PARAMETER*, ULONG); // avoid NTSTATUS as it is not defined on xbox (pr #1084)
54
+ static PVirtualAlloc2 pVirtualAlloc2 = NULL;
55
+ static PNtAllocateVirtualMemoryEx pNtAllocateVirtualMemoryEx = NULL;
56
+
57
+ // Similarly, GetNumaProcessorNodeEx is only supported since Windows 7 (and GetNumaNodeProcessorMask is not supported on xbox)
58
+ typedef struct MI_PROCESSOR_NUMBER_S { WORD Group; BYTE Number; BYTE Reserved; } MI_PROCESSOR_NUMBER;
59
+
60
+ typedef VOID (__stdcall *PGetCurrentProcessorNumberEx)(MI_PROCESSOR_NUMBER* ProcNumber);
61
+ typedef BOOL (__stdcall *PGetNumaProcessorNodeEx)(MI_PROCESSOR_NUMBER* Processor, PUSHORT NodeNumber);
62
+ typedef BOOL (__stdcall* PGetNumaNodeProcessorMaskEx)(USHORT Node, PGROUP_AFFINITY ProcessorMask);
63
+ typedef BOOL (__stdcall *PGetNumaProcessorNode)(UCHAR Processor, PUCHAR NodeNumber);
64
+ typedef BOOL (__stdcall* PGetNumaNodeProcessorMask)(UCHAR Node, PULONGLONG ProcessorMask);
65
+ typedef BOOL (__stdcall* PGetNumaHighestNodeNumber)(PULONG Node);
66
+ static PGetCurrentProcessorNumberEx pGetCurrentProcessorNumberEx = NULL;
67
+ static PGetNumaProcessorNodeEx pGetNumaProcessorNodeEx = NULL;
68
+ static PGetNumaNodeProcessorMaskEx pGetNumaNodeProcessorMaskEx = NULL;
69
+ static PGetNumaProcessorNode pGetNumaProcessorNode = NULL;
70
+ static PGetNumaNodeProcessorMask pGetNumaNodeProcessorMask = NULL;
71
+ static PGetNumaHighestNodeNumber pGetNumaHighestNodeNumber = NULL;
72
+
73
+ // Not available on xbox
74
+ typedef SIZE_T(__stdcall* PGetLargePageMinimum)(VOID);
75
+ static PGetLargePageMinimum pGetLargePageMinimum = NULL;
76
+
77
+ // Available after Windows XP
78
+ typedef BOOL (__stdcall *PGetPhysicallyInstalledSystemMemory)( PULONGLONG TotalMemoryInKilobytes );
79
+
80
+ //---------------------------------------------
81
+ // Enable large page support dynamically (if possible)
82
+ //---------------------------------------------
83
+
84
+ static bool win_enable_large_os_pages(size_t* large_page_size)
85
+ {
86
+ static bool large_initialized = false;
87
+ if (large_initialized) return (_mi_os_large_page_size() > 0);
88
+ large_initialized = true;
89
+ if (pGetLargePageMinimum==NULL) return false; // no large page support (xbox etc.)
90
+
91
+ // Try to see if large OS pages are supported
92
+ // To use large pages on Windows, we first need access permission
93
+ // Set "Lock pages in memory" permission in the group policy editor
94
+ // <https://devblogs.microsoft.com/oldnewthing/20110128-00/?p=11643>
95
+ unsigned long err = 0;
96
+ HANDLE token = NULL;
97
+ BOOL ok = OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &token);
98
+ if (ok) {
99
+ TOKEN_PRIVILEGES tp;
100
+ ok = LookupPrivilegeValue(NULL, TEXT("SeLockMemoryPrivilege"), &tp.Privileges[0].Luid);
101
+ if (ok) {
102
+ tp.PrivilegeCount = 1;
103
+ tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
104
+ ok = AdjustTokenPrivileges(token, FALSE, &tp, 0, (PTOKEN_PRIVILEGES)NULL, 0);
105
+ if (ok) {
106
+ err = GetLastError();
107
+ ok = (err == ERROR_SUCCESS);
108
+ if (ok && large_page_size != NULL && pGetLargePageMinimum != NULL) {
109
+ *large_page_size = (*pGetLargePageMinimum)();
110
+ }
111
+ }
112
+ }
113
+ CloseHandle(token);
114
+ }
115
+ if (!ok) {
116
+ if (err == 0) err = GetLastError();
117
+ _mi_warning_message("cannot enable large OS page support, error %lu\n", err);
118
+ }
119
+ return (ok!=0);
120
+ }
121
+
122
+
123
+ //---------------------------------------------
124
+ // Initialize
125
+ //---------------------------------------------
126
+
127
+ void _mi_prim_mem_init( mi_os_mem_config_t* config )
128
+ {
129
+ config->has_overcommit = false;
130
+ config->has_partial_free = false;
131
+ config->has_virtual_reserve = true;
132
+ // get the page size
133
+ SYSTEM_INFO si;
134
+ GetSystemInfo(&si);
135
+ if (si.dwPageSize > 0) { config->page_size = si.dwPageSize; }
136
+ if (si.dwAllocationGranularity > 0) { config->alloc_granularity = si.dwAllocationGranularity; }
137
+ // get virtual address bits
138
+ if ((uintptr_t)si.lpMaximumApplicationAddress > 0) {
139
+ const size_t vbits = MI_SIZE_BITS - mi_clz((uintptr_t)si.lpMaximumApplicationAddress);
140
+ config->virtual_address_bits = vbits;
141
+ }
142
+
143
+ // get the VirtualAlloc2 function
144
+ HINSTANCE hDll;
145
+ hDll = LoadLibrary(TEXT("kernelbase.dll"));
146
+ if (hDll != NULL) {
147
+ // use VirtualAlloc2FromApp if possible as it is available to Windows store apps
148
+ pVirtualAlloc2 = (PVirtualAlloc2)(void (*)(void))GetProcAddress(hDll, "VirtualAlloc2FromApp");
149
+ if (pVirtualAlloc2==NULL) pVirtualAlloc2 = (PVirtualAlloc2)(void (*)(void))GetProcAddress(hDll, "VirtualAlloc2");
150
+ FreeLibrary(hDll);
151
+ }
152
+ // NtAllocateVirtualMemoryEx is used for huge page allocation
153
+ hDll = LoadLibrary(TEXT("ntdll.dll"));
154
+ if (hDll != NULL) {
155
+ pNtAllocateVirtualMemoryEx = (PNtAllocateVirtualMemoryEx)(void (*)(void))GetProcAddress(hDll, "NtAllocateVirtualMemoryEx");
156
+ FreeLibrary(hDll);
157
+ }
158
+ // Try to use Win7+ numa API
159
+ hDll = LoadLibrary(TEXT("kernel32.dll"));
160
+ if (hDll != NULL) {
161
+ pGetCurrentProcessorNumberEx = (PGetCurrentProcessorNumberEx)(void (*)(void))GetProcAddress(hDll, "GetCurrentProcessorNumberEx");
162
+ pGetNumaProcessorNodeEx = (PGetNumaProcessorNodeEx)(void (*)(void))GetProcAddress(hDll, "GetNumaProcessorNodeEx");
163
+ pGetNumaNodeProcessorMaskEx = (PGetNumaNodeProcessorMaskEx)(void (*)(void))GetProcAddress(hDll, "GetNumaNodeProcessorMaskEx");
164
+ pGetNumaProcessorNode = (PGetNumaProcessorNode)(void (*)(void))GetProcAddress(hDll, "GetNumaProcessorNode");
165
+ pGetNumaNodeProcessorMask = (PGetNumaNodeProcessorMask)(void (*)(void))GetProcAddress(hDll, "GetNumaNodeProcessorMask");
166
+ pGetNumaHighestNodeNumber = (PGetNumaHighestNodeNumber)(void (*)(void))GetProcAddress(hDll, "GetNumaHighestNodeNumber");
167
+ pGetLargePageMinimum = (PGetLargePageMinimum)(void (*)(void))GetProcAddress(hDll, "GetLargePageMinimum");
168
+ // Get physical memory (not available on XP, so check dynamically)
169
+ PGetPhysicallyInstalledSystemMemory pGetPhysicallyInstalledSystemMemory = (PGetPhysicallyInstalledSystemMemory)(void (*)(void))GetProcAddress(hDll,"GetPhysicallyInstalledSystemMemory");
170
+ if (pGetPhysicallyInstalledSystemMemory != NULL) {
171
+ ULONGLONG memInKiB = 0;
172
+ if ((*pGetPhysicallyInstalledSystemMemory)(&memInKiB)) {
173
+ if (memInKiB > 0 && memInKiB <= SIZE_MAX) {
174
+ config->physical_memory_in_kib = (size_t)memInKiB;
175
+ }
176
+ }
177
+ }
178
+ FreeLibrary(hDll);
179
+ }
180
+ // Enable large/huge OS page support?
181
+ if (mi_option_is_enabled(mi_option_allow_large_os_pages) || mi_option_is_enabled(mi_option_reserve_huge_os_pages)) {
182
+ win_enable_large_os_pages(&config->large_page_size);
183
+ }
184
+ }
185
+
186
+
187
+ //---------------------------------------------
188
+ // Free
189
+ //---------------------------------------------
190
+
191
+ int _mi_prim_free(void* addr, size_t size ) {
192
+ MI_UNUSED(size);
193
+ DWORD errcode = 0;
194
+ bool err = (VirtualFree(addr, 0, MEM_RELEASE) == 0);
195
+ if (err) { errcode = GetLastError(); }
196
+ if (errcode == ERROR_INVALID_ADDRESS) {
197
+ // In mi_os_mem_alloc_aligned the fallback path may have returned a pointer inside
198
+ // the memory region returned by VirtualAlloc; in that case we need to free using
199
+ // the start of the region.
200
+ MEMORY_BASIC_INFORMATION info; _mi_memzero_var(info);
201
+ VirtualQuery(addr, &info, sizeof(info));
202
+ if (info.AllocationBase < addr && ((uint8_t*)addr - (uint8_t*)info.AllocationBase) < (ptrdiff_t)MI_SEGMENT_SIZE) {
203
+ errcode = 0;
204
+ err = (VirtualFree(info.AllocationBase, 0, MEM_RELEASE) == 0);
205
+ if (err) { errcode = GetLastError(); }
206
+ }
207
+ }
208
+ return (int)errcode;
209
+ }
210
+
211
+
212
+ //---------------------------------------------
213
+ // VirtualAlloc
214
+ //---------------------------------------------
215
+
216
+ static void* win_virtual_alloc_prim_once(void* addr, size_t size, size_t try_alignment, DWORD flags) {
217
+ #if (MI_INTPTR_SIZE >= 8)
218
+ // on 64-bit systems, try to use the virtual address area after 2TiB for 4MiB aligned allocations
219
+ if (addr == NULL) {
220
+ void* hint = _mi_os_get_aligned_hint(try_alignment,size);
221
+ if (hint != NULL) {
222
+ void* p = VirtualAlloc(hint, size, flags, PAGE_READWRITE);
223
+ if (p != NULL) return p;
224
+ _mi_verbose_message("warning: unable to allocate hinted aligned OS memory (%zu bytes, error code: 0x%x, address: %p, alignment: %zu, flags: 0x%x)\n", size, GetLastError(), hint, try_alignment, flags);
225
+ // fall through on error
226
+ }
227
+ }
228
+ #endif
229
+ // on modern Windows try use VirtualAlloc2 for aligned allocation
230
+ if (addr == NULL && try_alignment > 1 && (try_alignment % _mi_os_page_size()) == 0 && pVirtualAlloc2 != NULL) {
231
+ MI_MEM_ADDRESS_REQUIREMENTS reqs = { 0, 0, 0 };
232
+ reqs.Alignment = try_alignment;
233
+ MI_MEM_EXTENDED_PARAMETER param = { {0, 0}, {0} };
234
+ param.Type.Type = MiMemExtendedParameterAddressRequirements;
235
+ param.Arg.Pointer = &reqs;
236
+ void* p = (*pVirtualAlloc2)(GetCurrentProcess(), addr, size, flags, PAGE_READWRITE, &param, 1);
237
+ if (p != NULL) return p;
238
+ _mi_warning_message("unable to allocate aligned OS memory (0x%zx bytes, error code: 0x%x, address: %p, alignment: 0x%zx, flags: 0x%x)\n", size, GetLastError(), addr, try_alignment, flags);
239
+ // fall through on error
240
+ }
241
+ // last resort
242
+ return VirtualAlloc(addr, size, flags, PAGE_READWRITE);
243
+ }
244
+
245
+ static bool win_is_out_of_memory_error(DWORD err) {
246
+ switch (err) {
247
+ case ERROR_COMMITMENT_MINIMUM:
248
+ case ERROR_COMMITMENT_LIMIT:
249
+ case ERROR_PAGEFILE_QUOTA:
250
+ case ERROR_NOT_ENOUGH_MEMORY:
251
+ return true;
252
+ default:
253
+ return false;
254
+ }
255
+ }
256
+
257
+ static void* win_virtual_alloc_prim(void* addr, size_t size, size_t try_alignment, DWORD flags) {
258
+ long max_retry_msecs = mi_option_get_clamp(mi_option_retry_on_oom, 0, 2000); // at most 2 seconds
259
+ if (max_retry_msecs == 1) { max_retry_msecs = 100; } // if one sets the option to "true"
260
+ for (long tries = 1; tries <= 10; tries++) { // try at most 10 times (=2200ms)
261
+ void* p = win_virtual_alloc_prim_once(addr, size, try_alignment, flags);
262
+ if (p != NULL) {
263
+ // success, return the address
264
+ return p;
265
+ }
266
+ else if (max_retry_msecs > 0 && (try_alignment <= 2*MI_SEGMENT_ALIGN) &&
267
+ (flags&MEM_COMMIT) != 0 && (flags&MEM_LARGE_PAGES) == 0 &&
268
+ win_is_out_of_memory_error(GetLastError())) {
269
+ // if committing regular memory and being out-of-memory,
270
+ // keep trying for a bit in case memory frees up after all. See issue #894
271
+ _mi_warning_message("out-of-memory on OS allocation, try again... (attempt %lu, 0x%zx bytes, error code: 0x%x, address: %p, alignment: 0x%zx, flags: 0x%x)\n", tries, size, GetLastError(), addr, try_alignment, flags);
272
+ long sleep_msecs = tries*40; // increasing waits
273
+ if (sleep_msecs > max_retry_msecs) { sleep_msecs = max_retry_msecs; }
274
+ max_retry_msecs -= sleep_msecs;
275
+ Sleep(sleep_msecs);
276
+ }
277
+ else {
278
+ // otherwise return with an error
279
+ break;
280
+ }
281
+ }
282
+ return NULL;
283
+ }
284
+
285
+ static void* win_virtual_alloc(void* addr, size_t size, size_t try_alignment, DWORD flags, bool large_only, bool allow_large, bool* is_large) {
286
+ mi_assert_internal(!(large_only && !allow_large));
287
+ static _Atomic(size_t) large_page_try_ok; // = 0;
288
+ void* p = NULL;
289
+ // Try to allocate large OS pages (2MiB) if allowed or required.
290
+ if ((large_only || _mi_os_use_large_page(size, try_alignment))
291
+ && allow_large && (flags&MEM_COMMIT)!=0 && (flags&MEM_RESERVE)!=0) {
292
+ size_t try_ok = mi_atomic_load_acquire(&large_page_try_ok);
293
+ if (!large_only && try_ok > 0) {
294
+ // if a large page allocation fails, it seems the calls to VirtualAlloc get very expensive.
295
+ // therefore, once a large page allocation failed, we don't try again for `large_page_try_ok` times.
296
+ mi_atomic_cas_strong_acq_rel(&large_page_try_ok, &try_ok, try_ok - 1);
297
+ }
298
+ else {
299
+ // large OS pages must always reserve and commit.
300
+ *is_large = true;
301
+ p = win_virtual_alloc_prim(addr, size, try_alignment, flags | MEM_LARGE_PAGES);
302
+ if (large_only) return p;
303
+ // fall back to non-large page allocation on error (`p == NULL`).
304
+ if (p == NULL) {
305
+ mi_atomic_store_release(&large_page_try_ok,10UL); // on error, don't try again for the next N allocations
306
+ }
307
+ }
308
+ }
309
+ // Fall back to regular page allocation
310
+ if (p == NULL) {
311
+ *is_large = ((flags&MEM_LARGE_PAGES) != 0);
312
+ p = win_virtual_alloc_prim(addr, size, try_alignment, flags);
313
+ }
314
+ //if (p == NULL) { _mi_warning_message("unable to allocate OS memory (%zu bytes, error code: 0x%x, address: %p, alignment: %zu, flags: 0x%x, large only: %d, allow large: %d)\n", size, GetLastError(), addr, try_alignment, flags, large_only, allow_large); }
315
+ return p;
316
+ }
317
+
318
+ int _mi_prim_alloc(void* hint_addr, size_t size, size_t try_alignment, bool commit, bool allow_large, bool* is_large, bool* is_zero, void** addr) {
319
+ mi_assert_internal(size > 0 && (size % _mi_os_page_size()) == 0);
320
+ mi_assert_internal(commit || !allow_large);
321
+ mi_assert_internal(try_alignment > 0);
322
+ *is_zero = true;
323
+ int flags = MEM_RESERVE;
324
+ if (commit) { flags |= MEM_COMMIT; }
325
+ *addr = win_virtual_alloc(hint_addr, size, try_alignment, flags, false, allow_large, is_large);
326
+ return (*addr != NULL ? 0 : (int)GetLastError());
327
+ }
328
+
329
+
330
+ //---------------------------------------------
331
+ // Commit/Reset/Protect
332
+ //---------------------------------------------
333
+ #ifdef _MSC_VER
334
+ #pragma warning(disable:6250) // suppress warning calling VirtualFree without MEM_RELEASE (for decommit)
335
+ #endif
336
+
337
+ int _mi_prim_commit(void* addr, size_t size, bool* is_zero) {
338
+ *is_zero = false;
339
+ /*
340
+ // zero'ing only happens on an initial commit... but checking upfront seems expensive..
341
+ _MEMORY_BASIC_INFORMATION meminfo; _mi_memzero_var(meminfo);
342
+ if (VirtualQuery(addr, &meminfo, size) > 0) {
343
+ if ((meminfo.State & MEM_COMMIT) == 0) {
344
+ *is_zero = true;
345
+ }
346
+ }
347
+ */
348
+ // commit
349
+ void* p = VirtualAlloc(addr, size, MEM_COMMIT, PAGE_READWRITE);
350
+ if (p == NULL) return (int)GetLastError();
351
+ return 0;
352
+ }
353
+
354
+ int _mi_prim_decommit(void* addr, size_t size, bool* needs_recommit) {
355
+ BOOL ok = VirtualFree(addr, size, MEM_DECOMMIT);
356
+ *needs_recommit = true; // for safety, assume always decommitted even in the case of an error.
357
+ return (ok ? 0 : (int)GetLastError());
358
+ }
359
+
360
+ int _mi_prim_reset(void* addr, size_t size) {
361
+ void* p = VirtualAlloc(addr, size, MEM_RESET, PAGE_READWRITE);
362
+ mi_assert_internal(p == addr);
363
+ #if 0
364
+ if (p != NULL) {
365
+ VirtualUnlock(addr,size); // VirtualUnlock after MEM_RESET removes the memory directly from the working set
366
+ }
367
+ #endif
368
+ return (p != NULL ? 0 : (int)GetLastError());
369
+ }
370
+
371
+ int _mi_prim_reuse(void* addr, size_t size) {
372
+ MI_UNUSED(addr); MI_UNUSED(size);
373
+ return 0;
374
+ }
375
+
376
+ int _mi_prim_protect(void* addr, size_t size, bool protect) {
377
+ DWORD oldprotect = 0;
378
+ BOOL ok = VirtualProtect(addr, size, protect ? PAGE_NOACCESS : PAGE_READWRITE, &oldprotect);
379
+ return (ok ? 0 : (int)GetLastError());
380
+ }
381
+
382
+
383
+ //---------------------------------------------
384
+ // Huge page allocation
385
+ //---------------------------------------------
386
+
387
+ static void* _mi_prim_alloc_huge_os_pagesx(void* hint_addr, size_t size, int numa_node)
388
+ {
389
+ const DWORD flags = MEM_LARGE_PAGES | MEM_COMMIT | MEM_RESERVE;
390
+
391
+ win_enable_large_os_pages(NULL);
392
+
393
+ MI_MEM_EXTENDED_PARAMETER params[3] = { {{0,0},{0}},{{0,0},{0}},{{0,0},{0}} };
394
+ // on modern Windows try use NtAllocateVirtualMemoryEx for 1GiB huge pages
395
+ static bool mi_huge_pages_available = true;
396
+ if (pNtAllocateVirtualMemoryEx != NULL && mi_huge_pages_available) {
397
+ params[0].Type.Type = MiMemExtendedParameterAttributeFlags;
398
+ params[0].Arg.ULong64 = MI_MEM_EXTENDED_PARAMETER_NONPAGED_HUGE;
399
+ ULONG param_count = 1;
400
+ if (numa_node >= 0) {
401
+ param_count++;
402
+ params[1].Type.Type = MiMemExtendedParameterNumaNode;
403
+ params[1].Arg.ULong = (unsigned)numa_node;
404
+ }
405
+ SIZE_T psize = size;
406
+ void* base = hint_addr;
407
+ LONG err = (*pNtAllocateVirtualMemoryEx)(GetCurrentProcess(), &base, &psize, flags, PAGE_READWRITE, params, param_count);
408
+ if (err == 0 && base != NULL) {
409
+ return base;
410
+ }
411
+ else {
412
+ // fall back to regular large pages
413
+ mi_huge_pages_available = false; // don't try further huge pages
414
+ _mi_warning_message("unable to allocate using huge (1GiB) pages, trying large (2MiB) pages instead (status 0x%lx)\n", err);
415
+ }
416
+ }
417
+ // on modern Windows try use VirtualAlloc2 for numa aware large OS page allocation
418
+ if (pVirtualAlloc2 != NULL && numa_node >= 0) {
419
+ params[0].Type.Type = MiMemExtendedParameterNumaNode;
420
+ params[0].Arg.ULong = (unsigned)numa_node;
421
+ return (*pVirtualAlloc2)(GetCurrentProcess(), hint_addr, size, flags, PAGE_READWRITE, params, 1);
422
+ }
423
+
424
+ // otherwise use regular virtual alloc on older windows
425
+ return VirtualAlloc(hint_addr, size, flags, PAGE_READWRITE);
426
+ }
427
+
428
+ int _mi_prim_alloc_huge_os_pages(void* hint_addr, size_t size, int numa_node, bool* is_zero, void** addr) {
429
+ *is_zero = true;
430
+ *addr = _mi_prim_alloc_huge_os_pagesx(hint_addr,size,numa_node);
431
+ return (*addr != NULL ? 0 : (int)GetLastError());
432
+ }
433
+
434
+
435
+ //---------------------------------------------
436
+ // Numa nodes
437
+ //---------------------------------------------
438
+
439
+ size_t _mi_prim_numa_node(void) {
440
+ USHORT numa_node = 0;
441
+ if (pGetCurrentProcessorNumberEx != NULL && pGetNumaProcessorNodeEx != NULL) {
442
+ // Extended API is supported
443
+ MI_PROCESSOR_NUMBER pnum;
444
+ (*pGetCurrentProcessorNumberEx)(&pnum);
445
+ USHORT nnode = 0;
446
+ BOOL ok = (*pGetNumaProcessorNodeEx)(&pnum, &nnode);
447
+ if (ok) { numa_node = nnode; }
448
+ }
449
+ else if (pGetNumaProcessorNode != NULL) {
450
+ // Vista or earlier, use older API that is limited to 64 processors. Issue #277
451
+ DWORD pnum = GetCurrentProcessorNumber();
452
+ UCHAR nnode = 0;
453
+ BOOL ok = pGetNumaProcessorNode((UCHAR)pnum, &nnode);
454
+ if (ok) { numa_node = nnode; }
455
+ }
456
+ return numa_node;
457
+ }
458
+
459
+ size_t _mi_prim_numa_node_count(void) {
460
+ ULONG numa_max = 0;
461
+ if (pGetNumaHighestNodeNumber!=NULL) {
462
+ (*pGetNumaHighestNodeNumber)(&numa_max);
463
+ }
464
+ // find the highest node number that has actual processors assigned to it. Issue #282
465
+ while (numa_max > 0) {
466
+ if (pGetNumaNodeProcessorMaskEx != NULL) {
467
+ // Extended API is supported
468
+ GROUP_AFFINITY affinity;
469
+ if ((*pGetNumaNodeProcessorMaskEx)((USHORT)numa_max, &affinity)) {
470
+ if (affinity.Mask != 0) break; // found the maximum non-empty node
471
+ }
472
+ }
473
+ else {
474
+ // Vista or earlier, use older API that is limited to 64 processors.
475
+ ULONGLONG mask;
476
+ if (pGetNumaNodeProcessorMask != NULL) {
477
+ if ((*pGetNumaNodeProcessorMask)((UCHAR)numa_max, &mask)) {
478
+ if (mask != 0) break; // found the maximum non-empty node
479
+ }
480
+ };
481
+ }
482
+ // max node was invalid or had no processor assigned, try again
483
+ numa_max--;
484
+ }
485
+ return ((size_t)numa_max + 1);
486
+ }
487
+
488
+
489
+ //----------------------------------------------------------------
490
+ // Clock
491
+ //----------------------------------------------------------------
492
+
493
+ static mi_msecs_t mi_to_msecs(LARGE_INTEGER t) {
494
+ static LARGE_INTEGER mfreq; // = 0
495
+ if (mfreq.QuadPart == 0LL) {
496
+ LARGE_INTEGER f;
497
+ QueryPerformanceFrequency(&f);
498
+ mfreq.QuadPart = f.QuadPart/1000LL;
499
+ if (mfreq.QuadPart == 0) mfreq.QuadPart = 1;
500
+ }
501
+ return (mi_msecs_t)(t.QuadPart / mfreq.QuadPart);
502
+ }
503
+
504
+ mi_msecs_t _mi_prim_clock_now(void) {
505
+ LARGE_INTEGER t;
506
+ QueryPerformanceCounter(&t);
507
+ return mi_to_msecs(t);
508
+ }
509
+
510
+
511
+ //----------------------------------------------------------------
512
+ // Process Info
513
+ //----------------------------------------------------------------
514
+
515
+ #include <psapi.h>
516
+
517
+ static mi_msecs_t filetime_msecs(const FILETIME* ftime) {
518
+ ULARGE_INTEGER i;
519
+ i.LowPart = ftime->dwLowDateTime;
520
+ i.HighPart = ftime->dwHighDateTime;
521
+ mi_msecs_t msecs = (i.QuadPart / 10000); // FILETIME is in 100 nano seconds
522
+ return msecs;
523
+ }
524
+
525
+ typedef BOOL (WINAPI *PGetProcessMemoryInfo)(HANDLE, PPROCESS_MEMORY_COUNTERS, DWORD);
526
+ static PGetProcessMemoryInfo pGetProcessMemoryInfo = NULL;
527
+
528
+ void _mi_prim_process_info(mi_process_info_t* pinfo)
529
+ {
530
+ FILETIME ct;
531
+ FILETIME ut;
532
+ FILETIME st;
533
+ FILETIME et;
534
+ GetProcessTimes(GetCurrentProcess(), &ct, &et, &st, &ut);
535
+ pinfo->utime = filetime_msecs(&ut);
536
+ pinfo->stime = filetime_msecs(&st);
537
+
538
+ // load psapi on demand
539
+ if (pGetProcessMemoryInfo == NULL) {
540
+ HINSTANCE hDll = LoadLibrary(TEXT("psapi.dll"));
541
+ if (hDll != NULL) {
542
+ pGetProcessMemoryInfo = (PGetProcessMemoryInfo)(void (*)(void))GetProcAddress(hDll, "GetProcessMemoryInfo");
543
+ }
544
+ }
545
+
546
+ // get process info
547
+ PROCESS_MEMORY_COUNTERS info; _mi_memzero_var(info);
548
+ if (pGetProcessMemoryInfo != NULL) {
549
+ pGetProcessMemoryInfo(GetCurrentProcess(), &info, sizeof(info));
550
+ }
551
+ pinfo->current_rss = (size_t)info.WorkingSetSize;
552
+ pinfo->peak_rss = (size_t)info.PeakWorkingSetSize;
553
+ pinfo->current_commit = (size_t)info.PagefileUsage;
554
+ pinfo->peak_commit = (size_t)info.PeakPagefileUsage;
555
+ pinfo->page_faults = (size_t)info.PageFaultCount;
556
+ }
557
+
558
+ //----------------------------------------------------------------
559
+ // Output
560
+ //----------------------------------------------------------------
561
+
562
+ void _mi_prim_out_stderr( const char* msg )
563
+ {
564
+ // on windows with redirection, the C runtime cannot handle locale dependent output
565
+ // after the main thread closes so we use direct console output.
566
+ if (!_mi_preloading()) {
567
+ // _cputs(msg); // _cputs cannot be used as it aborts when failing to lock the console
568
+ static HANDLE hcon = INVALID_HANDLE_VALUE;
569
+ static bool hconIsConsole = false;
570
+ if (hcon == INVALID_HANDLE_VALUE) {
571
+ hcon = GetStdHandle(STD_ERROR_HANDLE);
572
+ #ifdef MI_HAS_CONSOLE_IO
573
+ CONSOLE_SCREEN_BUFFER_INFO sbi;
574
+ hconIsConsole = ((hcon != INVALID_HANDLE_VALUE) && GetConsoleScreenBufferInfo(hcon, &sbi));
575
+ #endif
576
+ }
577
+ const size_t len = _mi_strlen(msg);
578
+ if (len > 0 && len < UINT32_MAX) {
579
+ DWORD written = 0;
580
+ if (hconIsConsole) {
581
+ #ifdef MI_HAS_CONSOLE_IO
582
+ WriteConsoleA(hcon, msg, (DWORD)len, &written, NULL);
583
+ #endif
584
+ }
585
+ else if (hcon != INVALID_HANDLE_VALUE) {
586
+ // use direct write if stderr was redirected
587
+ WriteFile(hcon, msg, (DWORD)len, &written, NULL);
588
+ }
589
+ else {
590
+ // finally fall back to fputs after all
591
+ fputs(msg, stderr);
592
+ }
593
+ }
594
+ }
595
+ }
596
+
597
+
598
+ //----------------------------------------------------------------
599
+ // Environment
600
+ //----------------------------------------------------------------
601
+
602
+ // On Windows use GetEnvironmentVariable instead of getenv to work
603
+ // reliably even when this is invoked before the C runtime is initialized.
604
+ // i.e. when `_mi_preloading() == true`.
605
+ // Note: on windows, environment names are not case sensitive.
606
+ bool _mi_prim_getenv(const char* name, char* result, size_t result_size) {
607
+ result[0] = 0;
608
+ size_t len = GetEnvironmentVariableA(name, result, (DWORD)result_size);
609
+ return (len > 0 && len < result_size);
610
+ }
611
+
612
+
613
+ //----------------------------------------------------------------
614
+ // Random
615
+ //----------------------------------------------------------------
616
+
617
+ #if defined(MI_USE_RTLGENRANDOM) // || defined(__cplusplus)
618
+ // We prefer to use BCryptGenRandom instead of (the unofficial) RtlGenRandom but when using
619
+ // dynamic overriding, we observed it can raise an exception when compiled with C++, and
620
+ // sometimes deadlocks when also running under the VS debugger.
621
+ // In contrast, issue #623 implies that on Windows Server 2019 we need to use BCryptGenRandom.
622
+ // To be continued..
623
+ #pragma comment (lib,"advapi32.lib")
624
+ #define RtlGenRandom SystemFunction036
625
+ mi_decl_externc BOOLEAN NTAPI RtlGenRandom(PVOID RandomBuffer, ULONG RandomBufferLength);
626
+
627
+ bool _mi_prim_random_buf(void* buf, size_t buf_len) {
628
+ return (RtlGenRandom(buf, (ULONG)buf_len) != 0);
629
+ }
630
+
631
+ #else
632
+
633
+ #ifndef BCRYPT_USE_SYSTEM_PREFERRED_RNG
634
+ #define BCRYPT_USE_SYSTEM_PREFERRED_RNG 0x00000002
635
+ #endif
636
+
637
+ typedef LONG (NTAPI *PBCryptGenRandom)(HANDLE, PUCHAR, ULONG, ULONG);
638
+ static PBCryptGenRandom pBCryptGenRandom = NULL;
639
+
640
+ bool _mi_prim_random_buf(void* buf, size_t buf_len) {
641
+ if (pBCryptGenRandom == NULL) {
642
+ HINSTANCE hDll = LoadLibrary(TEXT("bcrypt.dll"));
643
+ if (hDll != NULL) {
644
+ pBCryptGenRandom = (PBCryptGenRandom)(void (*)(void))GetProcAddress(hDll, "BCryptGenRandom");
645
+ }
646
+ if (pBCryptGenRandom == NULL) return false;
647
+ }
648
+ return (pBCryptGenRandom(NULL, (PUCHAR)buf, (ULONG)buf_len, BCRYPT_USE_SYSTEM_PREFERRED_RNG) >= 0);
649
+ }
650
+
651
+ #endif // MI_USE_RTLGENRANDOM
652
+
653
+
654
+
655
+ //----------------------------------------------------------------
656
+ // Process & Thread Init/Done
657
+ //----------------------------------------------------------------
658
+
659
+ #if MI_WIN_USE_FIXED_TLS==1
660
+ mi_decl_cache_align size_t _mi_win_tls_offset = 0;
661
+ #endif
662
+
663
+ //static void mi_debug_out(const char* s) {
664
+ // HANDLE h = GetStdHandle(STD_ERROR_HANDLE);
665
+ // WriteConsole(h, s, (DWORD)_mi_strlen(s), NULL, NULL);
666
+ //}
667
+
668
+ static void mi_win_tls_init(DWORD reason) {
669
+ if (reason==DLL_PROCESS_ATTACH || reason==DLL_THREAD_ATTACH) {
670
+ #if MI_WIN_USE_FIXED_TLS==1 // we must allocate a TLS slot dynamically
671
+ if (_mi_win_tls_offset == 0 && reason == DLL_PROCESS_ATTACH) {
672
+ const DWORD tls_slot = TlsAlloc(); // usually returns slot 1
673
+ if (tls_slot == TLS_OUT_OF_INDEXES) {
674
+ _mi_error_message(EFAULT, "unable to allocate the a TLS slot (rebuild without MI_WIN_USE_FIXED_TLS?)\n");
675
+ }
676
+ _mi_win_tls_offset = (size_t)tls_slot * sizeof(void*);
677
+ }
678
+ #endif
679
+ #if MI_HAS_TLS_SLOT >= 2 // we must initialize the TLS slot before any allocation
680
+ if (mi_prim_get_default_heap() == NULL) {
681
+ _mi_heap_set_default_direct((mi_heap_t*)&_mi_heap_empty);
682
+ #if MI_DEBUG && MI_WIN_USE_FIXED_TLS==1
683
+ void* const p = TlsGetValue((DWORD)(_mi_win_tls_offset / sizeof(void*)));
684
+ mi_assert_internal(p == (void*)&_mi_heap_empty);
685
+ #endif
686
+ }
687
+ #endif
688
+ }
689
+ }
690
+
691
+ static void NTAPI mi_win_main(PVOID module, DWORD reason, LPVOID reserved) {
692
+ MI_UNUSED(reserved);
693
+ MI_UNUSED(module);
694
+ mi_win_tls_init(reason);
695
+ if (reason==DLL_PROCESS_ATTACH) {
696
+ _mi_auto_process_init();
697
+ }
698
+ else if (reason==DLL_PROCESS_DETACH) {
699
+ _mi_auto_process_done();
700
+ }
701
+ else if (reason==DLL_THREAD_DETACH && !_mi_is_redirected()) {
702
+ _mi_thread_done(NULL);
703
+ }
704
+ }
705
+
706
+
707
+ #if defined(MI_SHARED_LIB)
708
+ #define MI_PRIM_HAS_PROCESS_ATTACH 1
709
+
710
+ // Windows DLL: easy to hook into process_init and thread_done
711
+ BOOL WINAPI DllMain(HINSTANCE inst, DWORD reason, LPVOID reserved) {
712
+ mi_win_main((PVOID)inst,reason,reserved);
713
+ return TRUE;
714
+ }
715
+
716
+ // nothing to do since `_mi_thread_done` is handled through the DLL_THREAD_DETACH event.
717
+ void _mi_prim_thread_init_auto_done(void) { }
718
+ void _mi_prim_thread_done_auto_done(void) { }
719
+ void _mi_prim_thread_associate_default_heap(mi_heap_t* heap) {
720
+ MI_UNUSED(heap);
721
+ }
722
+
723
+ #elif !defined(MI_WIN_USE_FLS)
724
+ #define MI_PRIM_HAS_PROCESS_ATTACH 1
725
+
726
+ static void NTAPI mi_win_main_attach(PVOID module, DWORD reason, LPVOID reserved) {
727
+ if (reason == DLL_PROCESS_ATTACH || reason == DLL_THREAD_ATTACH) {
728
+ mi_win_main(module, reason, reserved);
729
+ }
730
+ }
731
+ static void NTAPI mi_win_main_detach(PVOID module, DWORD reason, LPVOID reserved) {
732
+ if (reason == DLL_PROCESS_DETACH || reason == DLL_THREAD_DETACH) {
733
+ mi_win_main(module, reason, reserved);
734
+ }
735
+ }
736
+
737
+ // Set up TLS callbacks in a statically linked library by using special data sections.
738
+ // See <https://stackoverflow.com/questions/14538159/tls-callback-in-windows>
739
+ // We use 2 entries to ensure we call attach events before constructors
740
+ // are called, and detach events after destructors are called.
741
+ #if defined(__cplusplus)
742
+ extern "C" {
743
+ #endif
744
+
745
+ #if defined(_WIN64)
746
+ #pragma comment(linker, "/INCLUDE:_tls_used")
747
+ #pragma comment(linker, "/INCLUDE:_mi_tls_callback_pre")
748
+ #pragma comment(linker, "/INCLUDE:_mi_tls_callback_post")
749
+ #pragma const_seg(".CRT$XLB")
750
+ extern const PIMAGE_TLS_CALLBACK _mi_tls_callback_pre[];
751
+ const PIMAGE_TLS_CALLBACK _mi_tls_callback_pre[] = { &mi_win_main_attach };
752
+ #pragma const_seg()
753
+ #pragma const_seg(".CRT$XLY")
754
+ extern const PIMAGE_TLS_CALLBACK _mi_tls_callback_post[];
755
+ const PIMAGE_TLS_CALLBACK _mi_tls_callback_post[] = { &mi_win_main_detach };
756
+ #pragma const_seg()
757
+ #else
758
+ #pragma comment(linker, "/INCLUDE:__tls_used")
759
+ #pragma comment(linker, "/INCLUDE:__mi_tls_callback_pre")
760
+ #pragma comment(linker, "/INCLUDE:__mi_tls_callback_post")
761
+ #pragma data_seg(".CRT$XLB")
762
+ PIMAGE_TLS_CALLBACK _mi_tls_callback_pre[] = { &mi_win_main_attach };
763
+ #pragma data_seg()
764
+ #pragma data_seg(".CRT$XLY")
765
+ PIMAGE_TLS_CALLBACK _mi_tls_callback_post[] = { &mi_win_main_detach };
766
+ #pragma data_seg()
767
+ #endif
768
+
769
+ #if defined(__cplusplus)
770
+ }
771
+ #endif
772
+
773
+ // nothing to do since `_mi_thread_done` is handled through the DLL_THREAD_DETACH event.
774
+ void _mi_prim_thread_init_auto_done(void) { }
775
+ void _mi_prim_thread_done_auto_done(void) { }
776
+ void _mi_prim_thread_associate_default_heap(mi_heap_t* heap) {
777
+ MI_UNUSED(heap);
778
+ }
779
+
780
+ #else // deprecated: statically linked, use fiber api
781
+
782
+ #if defined(_MSC_VER) // on clang/gcc use the constructor attribute (in `src/prim/prim.c`)
783
+ // MSVC: use data section magic for static libraries
784
+ // See <https://www.codeguru.com/cpp/misc/misc/applicationcontrol/article.php/c6945/Running-Code-Before-and-After-Main.htm>
785
+ #define MI_PRIM_HAS_PROCESS_ATTACH 1
786
+
787
+ static int mi_process_attach(void) {
788
+ mi_win_main(NULL,DLL_PROCESS_ATTACH,NULL);
789
+ atexit(&_mi_auto_process_done);
790
+ return 0;
791
+ }
792
+ typedef int(*mi_crt_callback_t)(void);
793
+ #if defined(_WIN64)
794
+ #pragma comment(linker, "/INCLUDE:_mi_tls_callback")
795
+ #pragma section(".CRT$XIU", long, read)
796
+ #else
797
+ #pragma comment(linker, "/INCLUDE:__mi_tls_callback")
798
+ #endif
799
+ #pragma data_seg(".CRT$XIU")
800
+ mi_decl_externc mi_crt_callback_t _mi_tls_callback[] = { &mi_process_attach };
801
+ #pragma data_seg()
802
+ #endif
803
+
804
+ // use the fiber api for calling `_mi_thread_done`.
805
+ #include <fibersapi.h>
806
+ #if (_WIN32_WINNT < 0x600) // before Windows Vista
807
+ WINBASEAPI DWORD WINAPI FlsAlloc( _In_opt_ PFLS_CALLBACK_FUNCTION lpCallback );
808
+ WINBASEAPI PVOID WINAPI FlsGetValue( _In_ DWORD dwFlsIndex );
809
+ WINBASEAPI BOOL WINAPI FlsSetValue( _In_ DWORD dwFlsIndex, _In_opt_ PVOID lpFlsData );
810
+ WINBASEAPI BOOL WINAPI FlsFree(_In_ DWORD dwFlsIndex);
811
+ #endif
812
+
813
+ static DWORD mi_fls_key = (DWORD)(-1);
814
+
815
+ static void NTAPI mi_fls_done(PVOID value) {
816
+ mi_heap_t* heap = (mi_heap_t*)value;
817
+ if (heap != NULL) {
818
+ _mi_thread_done(heap);
819
+ FlsSetValue(mi_fls_key, NULL); // prevent recursion as _mi_thread_done may set it back to the main heap, issue #672
820
+ }
821
+ }
822
+
823
+ void _mi_prim_thread_init_auto_done(void) {
824
+ mi_fls_key = FlsAlloc(&mi_fls_done);
825
+ }
826
+
827
+ void _mi_prim_thread_done_auto_done(void) {
828
+ // call thread-done on all threads (except the main thread) to prevent
829
+ // dangling callback pointer if statically linked with a DLL; Issue #208
830
+ FlsFree(mi_fls_key);
831
+ }
832
+
833
+ void _mi_prim_thread_associate_default_heap(mi_heap_t* heap) {
834
+ mi_assert_internal(mi_fls_key != (DWORD)(-1));
835
+ FlsSetValue(mi_fls_key, heap);
836
+ }
837
+ #endif
838
+
839
+ // ----------------------------------------------------
840
+ // Communicate with the redirection module on Windows
841
+ // ----------------------------------------------------
842
+ #if defined(MI_SHARED_LIB) && !defined(MI_WIN_NOREDIRECT)
843
+ #define MI_PRIM_HAS_ALLOCATOR_INIT 1
844
+
845
+ static bool mi_redirected = false; // true if malloc redirects to mi_malloc
846
+
847
+ bool _mi_is_redirected(void) {
848
+ return mi_redirected;
849
+ }
850
+
851
+ #ifdef __cplusplus
852
+ extern "C" {
853
+ #endif
854
+ mi_decl_export void _mi_redirect_entry(DWORD reason) {
855
+ // called on redirection; careful as this may be called before DllMain
856
+ mi_win_tls_init(reason);
857
+ if (reason == DLL_PROCESS_ATTACH) {
858
+ mi_redirected = true;
859
+ }
860
+ else if (reason == DLL_PROCESS_DETACH) {
861
+ mi_redirected = false;
862
+ }
863
+ else if (reason == DLL_THREAD_DETACH) {
864
+ _mi_thread_done(NULL);
865
+ }
866
+ }
867
+ __declspec(dllimport) bool mi_cdecl mi_allocator_init(const char** message);
868
+ __declspec(dllimport) void mi_cdecl mi_allocator_done(void);
869
+ #ifdef __cplusplus
870
+ }
871
+ #endif
872
+ bool _mi_allocator_init(const char** message) {
873
+ return mi_allocator_init(message);
874
+ }
875
+ void _mi_allocator_done(void) {
876
+ mi_allocator_done();
877
+ }
878
+ #endif