@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,441 @@
1
+ /* ----------------------------------------------------------------------------
2
+ Copyright (c) 2019-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
+ /* ----------------------------------------------------------------------------
9
+ Concurrent bitmap that can set/reset sequences of bits atomically,
10
+ represented as an array of fields where each field is a machine word (`size_t`)
11
+
12
+ There are two api's; the standard one cannot have sequences that cross
13
+ between the bitmap fields (and a sequence must be <= MI_BITMAP_FIELD_BITS).
14
+
15
+ The `_across` postfixed functions do allow sequences that can cross over
16
+ between the fields. (This is used in arena allocation)
17
+ ---------------------------------------------------------------------------- */
18
+
19
+ #include "mimalloc.h"
20
+ #include "mimalloc/internal.h"
21
+ #include "bitmap.h"
22
+
23
+ /* -----------------------------------------------------------
24
+ Bitmap definition
25
+ ----------------------------------------------------------- */
26
+
27
+ // The bit mask for a given number of blocks at a specified bit index.
28
+ static inline size_t mi_bitmap_mask_(size_t count, size_t bitidx) {
29
+ mi_assert_internal(count + bitidx <= MI_BITMAP_FIELD_BITS);
30
+ mi_assert_internal(count > 0);
31
+ if (count >= MI_BITMAP_FIELD_BITS) return MI_BITMAP_FIELD_FULL;
32
+ if (count == 0) return 0;
33
+ return ((((size_t)1 << count) - 1) << bitidx);
34
+ }
35
+
36
+
37
+ /* -----------------------------------------------------------
38
+ Claim a bit sequence atomically
39
+ ----------------------------------------------------------- */
40
+
41
+ // Try to atomically claim a sequence of `count` bits in a single
42
+ // field at `idx` in `bitmap`. Returns `true` on success.
43
+ inline bool _mi_bitmap_try_find_claim_field(mi_bitmap_t bitmap, size_t idx, const size_t count, mi_bitmap_index_t* bitmap_idx)
44
+ {
45
+ mi_assert_internal(bitmap_idx != NULL);
46
+ mi_assert_internal(count <= MI_BITMAP_FIELD_BITS);
47
+ mi_assert_internal(count > 0);
48
+ mi_bitmap_field_t* field = &bitmap[idx];
49
+ size_t map = mi_atomic_load_relaxed(field);
50
+ if (map==MI_BITMAP_FIELD_FULL) return false; // short cut
51
+
52
+ // search for 0-bit sequence of length count
53
+ const size_t mask = mi_bitmap_mask_(count, 0);
54
+ const size_t bitidx_max = MI_BITMAP_FIELD_BITS - count;
55
+
56
+ #ifdef MI_HAVE_FAST_BITSCAN
57
+ size_t bitidx = mi_ctz(~map); // quickly find the first zero bit if possible
58
+ #else
59
+ size_t bitidx = 0; // otherwise start at 0
60
+ #endif
61
+ size_t m = (mask << bitidx); // invariant: m == mask shifted by bitidx
62
+
63
+ // scan linearly for a free range of zero bits
64
+ while (bitidx <= bitidx_max) {
65
+ const size_t mapm = (map & m);
66
+ if (mapm == 0) { // are the mask bits free at bitidx?
67
+ mi_assert_internal((m >> bitidx) == mask); // no overflow?
68
+ const size_t newmap = (map | m);
69
+ mi_assert_internal((newmap^map) >> bitidx == mask);
70
+ if (!mi_atomic_cas_strong_acq_rel(field, &map, newmap)) { // TODO: use weak cas here?
71
+ // no success, another thread claimed concurrently.. keep going (with updated `map`)
72
+ continue;
73
+ }
74
+ else {
75
+ // success, we claimed the bits!
76
+ *bitmap_idx = mi_bitmap_index_create(idx, bitidx);
77
+ return true;
78
+ }
79
+ }
80
+ else {
81
+ // on to the next bit range
82
+ #ifdef MI_HAVE_FAST_BITSCAN
83
+ mi_assert_internal(mapm != 0);
84
+ const size_t shift = (count == 1 ? 1 : (MI_SIZE_BITS - mi_clz(mapm) - bitidx));
85
+ mi_assert_internal(shift > 0 && shift <= count);
86
+ #else
87
+ const size_t shift = 1;
88
+ #endif
89
+ bitidx += shift;
90
+ m <<= shift;
91
+ }
92
+ }
93
+ // no bits found
94
+ return false;
95
+ }
96
+
97
+ // Find `count` bits of 0 and set them to 1 atomically; returns `true` on success.
98
+ // Starts at idx, and wraps around to search in all `bitmap_fields` fields.
99
+ // `count` can be at most MI_BITMAP_FIELD_BITS and will never cross fields.
100
+ bool _mi_bitmap_try_find_from_claim(mi_bitmap_t bitmap, const size_t bitmap_fields, const size_t start_field_idx, const size_t count, mi_bitmap_index_t* bitmap_idx) {
101
+ size_t idx = start_field_idx;
102
+ for (size_t visited = 0; visited < bitmap_fields; visited++, idx++) {
103
+ if (idx >= bitmap_fields) { idx = 0; } // wrap
104
+ if (_mi_bitmap_try_find_claim_field(bitmap, idx, count, bitmap_idx)) {
105
+ return true;
106
+ }
107
+ }
108
+ return false;
109
+ }
110
+
111
+ // Like _mi_bitmap_try_find_from_claim but with an extra predicate that must be fullfilled
112
+ bool _mi_bitmap_try_find_from_claim_pred(mi_bitmap_t bitmap, const size_t bitmap_fields,
113
+ const size_t start_field_idx, const size_t count,
114
+ mi_bitmap_pred_fun_t pred_fun, void* pred_arg,
115
+ mi_bitmap_index_t* bitmap_idx) {
116
+ size_t idx = start_field_idx;
117
+ for (size_t visited = 0; visited < bitmap_fields; visited++, idx++) {
118
+ if (idx >= bitmap_fields) idx = 0; // wrap
119
+ if (_mi_bitmap_try_find_claim_field(bitmap, idx, count, bitmap_idx)) {
120
+ if (pred_fun == NULL || pred_fun(*bitmap_idx, pred_arg)) {
121
+ return true;
122
+ }
123
+ // predicate returned false, unclaim and look further
124
+ _mi_bitmap_unclaim(bitmap, bitmap_fields, count, *bitmap_idx);
125
+ }
126
+ }
127
+ return false;
128
+ }
129
+
130
+ // Set `count` bits at `bitmap_idx` to 0 atomically
131
+ // Returns `true` if all `count` bits were 1 previously.
132
+ bool _mi_bitmap_unclaim(mi_bitmap_t bitmap, size_t bitmap_fields, size_t count, mi_bitmap_index_t bitmap_idx) {
133
+ const size_t idx = mi_bitmap_index_field(bitmap_idx);
134
+ const size_t bitidx = mi_bitmap_index_bit_in_field(bitmap_idx);
135
+ const size_t mask = mi_bitmap_mask_(count, bitidx);
136
+ mi_assert_internal(bitmap_fields > idx); MI_UNUSED(bitmap_fields);
137
+ // mi_assert_internal((bitmap[idx] & mask) == mask);
138
+ const size_t prev = mi_atomic_and_acq_rel(&bitmap[idx], ~mask);
139
+ return ((prev & mask) == mask);
140
+ }
141
+
142
+
143
+ // Set `count` bits at `bitmap_idx` to 1 atomically
144
+ // Returns `true` if all `count` bits were 0 previously. `any_zero` is `true` if there was at least one zero bit.
145
+ bool _mi_bitmap_claim(mi_bitmap_t bitmap, size_t bitmap_fields, size_t count, mi_bitmap_index_t bitmap_idx, bool* any_zero) {
146
+ const size_t idx = mi_bitmap_index_field(bitmap_idx);
147
+ const size_t bitidx = mi_bitmap_index_bit_in_field(bitmap_idx);
148
+ const size_t mask = mi_bitmap_mask_(count, bitidx);
149
+ mi_assert_internal(bitmap_fields > idx); MI_UNUSED(bitmap_fields);
150
+ //mi_assert_internal(any_zero != NULL || (bitmap[idx] & mask) == 0);
151
+ size_t prev = mi_atomic_or_acq_rel(&bitmap[idx], mask);
152
+ if (any_zero != NULL) { *any_zero = ((prev & mask) != mask); }
153
+ return ((prev & mask) == 0);
154
+ }
155
+
156
+ // Returns `true` if all `count` bits were 1. `any_ones` is `true` if there was at least one bit set to one.
157
+ static bool mi_bitmap_is_claimedx(mi_bitmap_t bitmap, size_t bitmap_fields, size_t count, mi_bitmap_index_t bitmap_idx, bool* any_ones) {
158
+ const size_t idx = mi_bitmap_index_field(bitmap_idx);
159
+ const size_t bitidx = mi_bitmap_index_bit_in_field(bitmap_idx);
160
+ const size_t mask = mi_bitmap_mask_(count, bitidx);
161
+ mi_assert_internal(bitmap_fields > idx); MI_UNUSED(bitmap_fields);
162
+ const size_t field = mi_atomic_load_relaxed(&bitmap[idx]);
163
+ if (any_ones != NULL) { *any_ones = ((field & mask) != 0); }
164
+ return ((field & mask) == mask);
165
+ }
166
+
167
+ // Try to set `count` bits at `bitmap_idx` from 0 to 1 atomically.
168
+ // Returns `true` if successful when all previous `count` bits were 0.
169
+ bool _mi_bitmap_try_claim(mi_bitmap_t bitmap, size_t bitmap_fields, size_t count, mi_bitmap_index_t bitmap_idx) {
170
+ const size_t idx = mi_bitmap_index_field(bitmap_idx);
171
+ const size_t bitidx = mi_bitmap_index_bit_in_field(bitmap_idx);
172
+ const size_t mask = mi_bitmap_mask_(count, bitidx);
173
+ mi_assert_internal(bitmap_fields > idx); MI_UNUSED(bitmap_fields);
174
+ size_t expected = mi_atomic_load_relaxed(&bitmap[idx]);
175
+ do {
176
+ if ((expected & mask) != 0) return false;
177
+ }
178
+ while (!mi_atomic_cas_strong_acq_rel(&bitmap[idx], &expected, expected | mask));
179
+ mi_assert_internal((expected & mask) == 0);
180
+ return true;
181
+ }
182
+
183
+
184
+ bool _mi_bitmap_is_claimed(mi_bitmap_t bitmap, size_t bitmap_fields, size_t count, mi_bitmap_index_t bitmap_idx) {
185
+ return mi_bitmap_is_claimedx(bitmap, bitmap_fields, count, bitmap_idx, NULL);
186
+ }
187
+
188
+ bool _mi_bitmap_is_any_claimed(mi_bitmap_t bitmap, size_t bitmap_fields, size_t count, mi_bitmap_index_t bitmap_idx) {
189
+ bool any_ones;
190
+ mi_bitmap_is_claimedx(bitmap, bitmap_fields, count, bitmap_idx, &any_ones);
191
+ return any_ones;
192
+ }
193
+
194
+
195
+ //--------------------------------------------------------------------------
196
+ // the `_across` functions work on bitmaps where sequences can cross over
197
+ // between the fields. This is used in arena allocation
198
+ //--------------------------------------------------------------------------
199
+
200
+ // Try to atomically claim a sequence of `count` bits starting from the field
201
+ // at `idx` in `bitmap` and crossing into subsequent fields. Returns `true` on success.
202
+ // Only needs to consider crossing into the next fields (see `mi_bitmap_try_find_from_claim_across`)
203
+ static bool mi_bitmap_try_find_claim_field_across(mi_bitmap_t bitmap, size_t bitmap_fields, size_t idx, const size_t count, const size_t retries, mi_bitmap_index_t* bitmap_idx)
204
+ {
205
+ mi_assert_internal(bitmap_idx != NULL);
206
+
207
+ // check initial trailing zeros
208
+ mi_bitmap_field_t* field = &bitmap[idx];
209
+ size_t map = mi_atomic_load_relaxed(field);
210
+ const size_t initial = mi_clz(map); // count of initial zeros starting at idx
211
+ mi_assert_internal(initial <= MI_BITMAP_FIELD_BITS);
212
+ if (initial == 0) return false;
213
+ if (initial >= count) return _mi_bitmap_try_find_claim_field(bitmap, idx, count, bitmap_idx); // no need to cross fields (this case won't happen for us)
214
+ if (_mi_divide_up(count - initial, MI_BITMAP_FIELD_BITS) >= (bitmap_fields - idx)) return false; // not enough entries
215
+
216
+ // scan ahead
217
+ size_t found = initial;
218
+ size_t mask = 0; // mask bits for the final field
219
+ while(found < count) {
220
+ field++;
221
+ map = mi_atomic_load_relaxed(field);
222
+ const size_t mask_bits = (found + MI_BITMAP_FIELD_BITS <= count ? MI_BITMAP_FIELD_BITS : (count - found));
223
+ mi_assert_internal(mask_bits > 0 && mask_bits <= MI_BITMAP_FIELD_BITS);
224
+ mask = mi_bitmap_mask_(mask_bits, 0);
225
+ if ((map & mask) != 0) return false; // some part is already claimed
226
+ found += mask_bits;
227
+ }
228
+ mi_assert_internal(field < &bitmap[bitmap_fields]);
229
+
230
+ // we found a range of contiguous zeros up to the final field; mask contains mask in the final field
231
+ // now try to claim the range atomically
232
+ mi_bitmap_field_t* const final_field = field;
233
+ const size_t final_mask = mask;
234
+ mi_bitmap_field_t* const initial_field = &bitmap[idx];
235
+ const size_t initial_idx = MI_BITMAP_FIELD_BITS - initial;
236
+ const size_t initial_mask = mi_bitmap_mask_(initial, initial_idx);
237
+
238
+ // initial field
239
+ size_t newmap;
240
+ field = initial_field;
241
+ map = mi_atomic_load_relaxed(field);
242
+ do {
243
+ newmap = (map | initial_mask);
244
+ if ((map & initial_mask) != 0) { goto rollback; };
245
+ } while (!mi_atomic_cas_strong_acq_rel(field, &map, newmap));
246
+
247
+ // intermediate fields
248
+ while (++field < final_field) {
249
+ newmap = MI_BITMAP_FIELD_FULL;
250
+ map = 0;
251
+ if (!mi_atomic_cas_strong_acq_rel(field, &map, newmap)) { goto rollback; }
252
+ }
253
+
254
+ // final field
255
+ mi_assert_internal(field == final_field);
256
+ map = mi_atomic_load_relaxed(field);
257
+ do {
258
+ newmap = (map | final_mask);
259
+ if ((map & final_mask) != 0) { goto rollback; }
260
+ } while (!mi_atomic_cas_strong_acq_rel(field, &map, newmap));
261
+
262
+ // claimed!
263
+ *bitmap_idx = mi_bitmap_index_create(idx, initial_idx);
264
+ return true;
265
+
266
+ rollback:
267
+ // roll back intermediate fields
268
+ // (we just failed to claim `field` so decrement first)
269
+ while (--field > initial_field) {
270
+ newmap = 0;
271
+ map = MI_BITMAP_FIELD_FULL;
272
+ mi_assert_internal(mi_atomic_load_relaxed(field) == map);
273
+ mi_atomic_store_release(field, newmap);
274
+ }
275
+ if (field == initial_field) { // (if we failed on the initial field, `field + 1 == initial_field`)
276
+ map = mi_atomic_load_relaxed(field);
277
+ do {
278
+ mi_assert_internal((map & initial_mask) == initial_mask);
279
+ newmap = (map & ~initial_mask);
280
+ } while (!mi_atomic_cas_strong_acq_rel(field, &map, newmap));
281
+ }
282
+ mi_stat_counter_increase(_mi_stats_main.arena_rollback_count,1);
283
+ // retry? (we make a recursive call instead of goto to be able to use const declarations)
284
+ if (retries <= 2) {
285
+ return mi_bitmap_try_find_claim_field_across(bitmap, bitmap_fields, idx, count, retries+1, bitmap_idx);
286
+ }
287
+ else {
288
+ return false;
289
+ }
290
+ }
291
+
292
+
293
+ // Find `count` bits of zeros and set them to 1 atomically; returns `true` on success.
294
+ // Starts at idx, and wraps around to search in all `bitmap_fields` fields.
295
+ bool _mi_bitmap_try_find_from_claim_across(mi_bitmap_t bitmap, const size_t bitmap_fields, const size_t start_field_idx, const size_t count, mi_bitmap_index_t* bitmap_idx) {
296
+ mi_assert_internal(count > 0);
297
+ if (count <= 2) {
298
+ // we don't bother with crossover fields for small counts
299
+ return _mi_bitmap_try_find_from_claim(bitmap, bitmap_fields, start_field_idx, count, bitmap_idx);
300
+ }
301
+
302
+ // visit the fields
303
+ size_t idx = start_field_idx;
304
+ for (size_t visited = 0; visited < bitmap_fields; visited++, idx++) {
305
+ if (idx >= bitmap_fields) { idx = 0; } // wrap
306
+ // first try to claim inside a field
307
+ /*
308
+ if (count <= MI_BITMAP_FIELD_BITS) {
309
+ if (_mi_bitmap_try_find_claim_field(bitmap, idx, count, bitmap_idx)) {
310
+ return true;
311
+ }
312
+ }
313
+ */
314
+ // if that fails, then try to claim across fields
315
+ if (mi_bitmap_try_find_claim_field_across(bitmap, bitmap_fields, idx, count, 0, bitmap_idx)) {
316
+ return true;
317
+ }
318
+ }
319
+ return false;
320
+ }
321
+
322
+ // Helper for masks across fields; returns the mid count, post_mask may be 0
323
+ static size_t mi_bitmap_mask_across(mi_bitmap_index_t bitmap_idx, size_t bitmap_fields, size_t count, size_t* pre_mask, size_t* mid_mask, size_t* post_mask) {
324
+ MI_UNUSED(bitmap_fields);
325
+ const size_t bitidx = mi_bitmap_index_bit_in_field(bitmap_idx);
326
+ if mi_likely(bitidx + count <= MI_BITMAP_FIELD_BITS) {
327
+ *pre_mask = mi_bitmap_mask_(count, bitidx);
328
+ *mid_mask = 0;
329
+ *post_mask = 0;
330
+ mi_assert_internal(mi_bitmap_index_field(bitmap_idx) < bitmap_fields);
331
+ return 0;
332
+ }
333
+ else {
334
+ const size_t pre_bits = MI_BITMAP_FIELD_BITS - bitidx;
335
+ mi_assert_internal(pre_bits < count);
336
+ *pre_mask = mi_bitmap_mask_(pre_bits, bitidx);
337
+ count -= pre_bits;
338
+ const size_t mid_count = (count / MI_BITMAP_FIELD_BITS);
339
+ *mid_mask = MI_BITMAP_FIELD_FULL;
340
+ count %= MI_BITMAP_FIELD_BITS;
341
+ *post_mask = (count==0 ? 0 : mi_bitmap_mask_(count, 0));
342
+ mi_assert_internal(mi_bitmap_index_field(bitmap_idx) + mid_count + (count==0 ? 0 : 1) < bitmap_fields);
343
+ return mid_count;
344
+ }
345
+ }
346
+
347
+ // Set `count` bits at `bitmap_idx` to 0 atomically
348
+ // Returns `true` if all `count` bits were 1 previously.
349
+ bool _mi_bitmap_unclaim_across(mi_bitmap_t bitmap, size_t bitmap_fields, size_t count, mi_bitmap_index_t bitmap_idx) {
350
+ size_t idx = mi_bitmap_index_field(bitmap_idx);
351
+ size_t pre_mask;
352
+ size_t mid_mask;
353
+ size_t post_mask;
354
+ size_t mid_count = mi_bitmap_mask_across(bitmap_idx, bitmap_fields, count, &pre_mask, &mid_mask, &post_mask);
355
+ bool all_one = true;
356
+ mi_bitmap_field_t* field = &bitmap[idx];
357
+ size_t prev = mi_atomic_and_acq_rel(field++, ~pre_mask); // clear first part
358
+ if ((prev & pre_mask) != pre_mask) all_one = false;
359
+ while(mid_count-- > 0) {
360
+ prev = mi_atomic_and_acq_rel(field++, ~mid_mask); // clear mid part
361
+ if ((prev & mid_mask) != mid_mask) all_one = false;
362
+ }
363
+ if (post_mask!=0) {
364
+ prev = mi_atomic_and_acq_rel(field, ~post_mask); // clear end part
365
+ if ((prev & post_mask) != post_mask) all_one = false;
366
+ }
367
+ return all_one;
368
+ }
369
+
370
+ // Set `count` bits at `bitmap_idx` to 1 atomically
371
+ // Returns `true` if all `count` bits were 0 previously. `any_zero` is `true` if there was at least one zero bit.
372
+ bool _mi_bitmap_claim_across(mi_bitmap_t bitmap, size_t bitmap_fields, size_t count, mi_bitmap_index_t bitmap_idx, bool* pany_zero, size_t* already_set) {
373
+ size_t idx = mi_bitmap_index_field(bitmap_idx);
374
+ size_t pre_mask;
375
+ size_t mid_mask;
376
+ size_t post_mask;
377
+ size_t mid_count = mi_bitmap_mask_across(bitmap_idx, bitmap_fields, count, &pre_mask, &mid_mask, &post_mask);
378
+ bool all_zero = true;
379
+ bool any_zero = false;
380
+ size_t one_count = 0;
381
+ _Atomic(size_t)*field = &bitmap[idx];
382
+ size_t prev = mi_atomic_or_acq_rel(field++, pre_mask);
383
+ if ((prev & pre_mask) != 0) { all_zero = false; one_count += mi_popcount(prev & pre_mask); }
384
+ if ((prev & pre_mask) != pre_mask) any_zero = true;
385
+ while (mid_count-- > 0) {
386
+ prev = mi_atomic_or_acq_rel(field++, mid_mask);
387
+ if ((prev & mid_mask) != 0) { all_zero = false; one_count += mi_popcount(prev & mid_mask); }
388
+ if ((prev & mid_mask) != mid_mask) any_zero = true;
389
+ }
390
+ if (post_mask!=0) {
391
+ prev = mi_atomic_or_acq_rel(field, post_mask);
392
+ if ((prev & post_mask) != 0) { all_zero = false; one_count += mi_popcount(prev & post_mask); }
393
+ if ((prev & post_mask) != post_mask) any_zero = true;
394
+ }
395
+ if (pany_zero != NULL) { *pany_zero = any_zero; }
396
+ if (already_set != NULL) { *already_set = one_count; };
397
+ mi_assert_internal(all_zero ? one_count == 0 : one_count <= count);
398
+ return all_zero;
399
+ }
400
+
401
+
402
+ // Returns `true` if all `count` bits were 1.
403
+ // `any_ones` is `true` if there was at least one bit set to one.
404
+ static bool mi_bitmap_is_claimedx_across(mi_bitmap_t bitmap, size_t bitmap_fields, size_t count, mi_bitmap_index_t bitmap_idx, bool* pany_ones, size_t* already_set) {
405
+ size_t idx = mi_bitmap_index_field(bitmap_idx);
406
+ size_t pre_mask;
407
+ size_t mid_mask;
408
+ size_t post_mask;
409
+ size_t mid_count = mi_bitmap_mask_across(bitmap_idx, bitmap_fields, count, &pre_mask, &mid_mask, &post_mask);
410
+ bool all_ones = true;
411
+ bool any_ones = false;
412
+ size_t one_count = 0;
413
+ mi_bitmap_field_t* field = &bitmap[idx];
414
+ size_t prev = mi_atomic_load_relaxed(field++);
415
+ if ((prev & pre_mask) != pre_mask) all_ones = false;
416
+ if ((prev & pre_mask) != 0) { any_ones = true; one_count += mi_popcount(prev & pre_mask); }
417
+ while (mid_count-- > 0) {
418
+ prev = mi_atomic_load_relaxed(field++);
419
+ if ((prev & mid_mask) != mid_mask) all_ones = false;
420
+ if ((prev & mid_mask) != 0) { any_ones = true; one_count += mi_popcount(prev & mid_mask); }
421
+ }
422
+ if (post_mask!=0) {
423
+ prev = mi_atomic_load_relaxed(field);
424
+ if ((prev & post_mask) != post_mask) all_ones = false;
425
+ if ((prev & post_mask) != 0) { any_ones = true; one_count += mi_popcount(prev & post_mask); }
426
+ }
427
+ if (pany_ones != NULL) { *pany_ones = any_ones; }
428
+ if (already_set != NULL) { *already_set = one_count; }
429
+ mi_assert_internal(all_ones ? one_count == count : one_count < count);
430
+ return all_ones;
431
+ }
432
+
433
+ bool _mi_bitmap_is_claimed_across(mi_bitmap_t bitmap, size_t bitmap_fields, size_t count, mi_bitmap_index_t bitmap_idx, size_t* already_set) {
434
+ return mi_bitmap_is_claimedx_across(bitmap, bitmap_fields, count, bitmap_idx, NULL, already_set);
435
+ }
436
+
437
+ bool _mi_bitmap_is_any_claimed_across(mi_bitmap_t bitmap, size_t bitmap_fields, size_t count, mi_bitmap_index_t bitmap_idx) {
438
+ bool any_ones;
439
+ mi_bitmap_is_claimedx_across(bitmap, bitmap_fields, count, bitmap_idx, &any_ones, NULL);
440
+ return any_ones;
441
+ }
@@ -0,0 +1,119 @@
1
+ /* ----------------------------------------------------------------------------
2
+ Copyright (c) 2019-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
+ /* ----------------------------------------------------------------------------
9
+ Concurrent bitmap that can set/reset sequences of bits atomically,
10
+ represented as an array of fields where each field is a machine word (`size_t`)
11
+
12
+ There are two api's; the standard one cannot have sequences that cross
13
+ between the bitmap fields (and a sequence must be <= MI_BITMAP_FIELD_BITS).
14
+ (this is used in region allocation)
15
+
16
+ The `_across` postfixed functions do allow sequences that can cross over
17
+ between the fields. (This is used in arena allocation)
18
+ ---------------------------------------------------------------------------- */
19
+ #pragma once
20
+ #ifndef MI_BITMAP_H
21
+ #define MI_BITMAP_H
22
+
23
+ /* -----------------------------------------------------------
24
+ Bitmap definition
25
+ ----------------------------------------------------------- */
26
+
27
+ #define MI_BITMAP_FIELD_BITS (8*MI_SIZE_SIZE)
28
+ #define MI_BITMAP_FIELD_FULL (~((size_t)0)) // all bits set
29
+
30
+ // An atomic bitmap of `size_t` fields
31
+ typedef _Atomic(size_t) mi_bitmap_field_t;
32
+ typedef mi_bitmap_field_t* mi_bitmap_t;
33
+
34
+ // A bitmap index is the index of the bit in a bitmap.
35
+ typedef size_t mi_bitmap_index_t;
36
+
37
+ // Create a bit index.
38
+ static inline mi_bitmap_index_t mi_bitmap_index_create_ex(size_t idx, size_t bitidx) {
39
+ mi_assert_internal(bitidx <= MI_BITMAP_FIELD_BITS);
40
+ return (idx*MI_BITMAP_FIELD_BITS) + bitidx;
41
+ }
42
+ static inline mi_bitmap_index_t mi_bitmap_index_create(size_t idx, size_t bitidx) {
43
+ mi_assert_internal(bitidx < MI_BITMAP_FIELD_BITS);
44
+ return mi_bitmap_index_create_ex(idx,bitidx);
45
+ }
46
+
47
+ // Create a bit index.
48
+ static inline mi_bitmap_index_t mi_bitmap_index_create_from_bit(size_t full_bitidx) {
49
+ return mi_bitmap_index_create(full_bitidx / MI_BITMAP_FIELD_BITS, full_bitidx % MI_BITMAP_FIELD_BITS);
50
+ }
51
+
52
+ // Get the field index from a bit index.
53
+ static inline size_t mi_bitmap_index_field(mi_bitmap_index_t bitmap_idx) {
54
+ return (bitmap_idx / MI_BITMAP_FIELD_BITS);
55
+ }
56
+
57
+ // Get the bit index in a bitmap field
58
+ static inline size_t mi_bitmap_index_bit_in_field(mi_bitmap_index_t bitmap_idx) {
59
+ return (bitmap_idx % MI_BITMAP_FIELD_BITS);
60
+ }
61
+
62
+ // Get the full bit index
63
+ static inline size_t mi_bitmap_index_bit(mi_bitmap_index_t bitmap_idx) {
64
+ return bitmap_idx;
65
+ }
66
+
67
+ /* -----------------------------------------------------------
68
+ Claim a bit sequence atomically
69
+ ----------------------------------------------------------- */
70
+
71
+ // Try to atomically claim a sequence of `count` bits in a single
72
+ // field at `idx` in `bitmap`. Returns `true` on success.
73
+ bool _mi_bitmap_try_find_claim_field(mi_bitmap_t bitmap, size_t idx, const size_t count, mi_bitmap_index_t* bitmap_idx);
74
+
75
+ // Starts at idx, and wraps around to search in all `bitmap_fields` fields.
76
+ // For now, `count` can be at most MI_BITMAP_FIELD_BITS and will never cross fields.
77
+ bool _mi_bitmap_try_find_from_claim(mi_bitmap_t bitmap, const size_t bitmap_fields, const size_t start_field_idx, const size_t count, mi_bitmap_index_t* bitmap_idx);
78
+
79
+ // Like _mi_bitmap_try_find_from_claim but with an extra predicate that must be fullfilled
80
+ typedef bool (mi_cdecl *mi_bitmap_pred_fun_t)(mi_bitmap_index_t bitmap_idx, void* pred_arg);
81
+ bool _mi_bitmap_try_find_from_claim_pred(mi_bitmap_t bitmap, const size_t bitmap_fields, const size_t start_field_idx, const size_t count, mi_bitmap_pred_fun_t pred_fun, void* pred_arg, mi_bitmap_index_t* bitmap_idx);
82
+
83
+ // Set `count` bits at `bitmap_idx` to 0 atomically
84
+ // Returns `true` if all `count` bits were 1 previously.
85
+ bool _mi_bitmap_unclaim(mi_bitmap_t bitmap, size_t bitmap_fields, size_t count, mi_bitmap_index_t bitmap_idx);
86
+
87
+ // Try to set `count` bits at `bitmap_idx` from 0 to 1 atomically.
88
+ // Returns `true` if successful when all previous `count` bits were 0.
89
+ bool _mi_bitmap_try_claim(mi_bitmap_t bitmap, size_t bitmap_fields, size_t count, mi_bitmap_index_t bitmap_idx);
90
+
91
+ // Set `count` bits at `bitmap_idx` to 1 atomically
92
+ // Returns `true` if all `count` bits were 0 previously. `any_zero` is `true` if there was at least one zero bit.
93
+ bool _mi_bitmap_claim(mi_bitmap_t bitmap, size_t bitmap_fields, size_t count, mi_bitmap_index_t bitmap_idx, bool* any_zero);
94
+
95
+ bool _mi_bitmap_is_claimed(mi_bitmap_t bitmap, size_t bitmap_fields, size_t count, mi_bitmap_index_t bitmap_idx);
96
+ bool _mi_bitmap_is_any_claimed(mi_bitmap_t bitmap, size_t bitmap_fields, size_t count, mi_bitmap_index_t bitmap_idx);
97
+
98
+
99
+ //--------------------------------------------------------------------------
100
+ // the `_across` functions work on bitmaps where sequences can cross over
101
+ // between the fields. This is used in arena allocation
102
+ //--------------------------------------------------------------------------
103
+
104
+ // Find `count` bits of zeros and set them to 1 atomically; returns `true` on success.
105
+ // Starts at idx, and wraps around to search in all `bitmap_fields` fields.
106
+ bool _mi_bitmap_try_find_from_claim_across(mi_bitmap_t bitmap, const size_t bitmap_fields, const size_t start_field_idx, const size_t count, mi_bitmap_index_t* bitmap_idx);
107
+
108
+ // Set `count` bits at `bitmap_idx` to 0 atomically
109
+ // Returns `true` if all `count` bits were 1 previously.
110
+ bool _mi_bitmap_unclaim_across(mi_bitmap_t bitmap, size_t bitmap_fields, size_t count, mi_bitmap_index_t bitmap_idx);
111
+
112
+ // Set `count` bits at `bitmap_idx` to 1 atomically
113
+ // Returns `true` if all `count` bits were 0 previously. `any_zero` is `true` if there was at least one zero bit.
114
+ bool _mi_bitmap_claim_across(mi_bitmap_t bitmap, size_t bitmap_fields, size_t count, mi_bitmap_index_t bitmap_idx, bool* pany_zero, size_t* already_set);
115
+
116
+ bool _mi_bitmap_is_claimed_across(mi_bitmap_t bitmap, size_t bitmap_fields, size_t count, mi_bitmap_index_t bitmap_idx, size_t* already_set);
117
+ bool _mi_bitmap_is_any_claimed_across(mi_bitmap_t bitmap, size_t bitmap_fields, size_t count, mi_bitmap_index_t bitmap_idx);
118
+
119
+ #endif