mdbxmou 0.1.26

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 (220) hide show
  1. package/.github/workflows/ci.yml +32 -0
  2. package/.github/workflows/publish.yml +27 -0
  3. package/.gitmodules +3 -0
  4. package/CMakeLists.txt +53 -0
  5. package/LICENSE +201 -0
  6. package/README.md +639 -0
  7. package/build.js +11 -0
  8. package/deps/libmdbx/.clang-format +3 -0
  9. package/deps/libmdbx/.cmake-format.yaml +3 -0
  10. package/deps/libmdbx/.le.ini +40 -0
  11. package/deps/libmdbx/CMakeLists.txt +1269 -0
  12. package/deps/libmdbx/COPYRIGHT +159 -0
  13. package/deps/libmdbx/ChangeLog.md +2786 -0
  14. package/deps/libmdbx/GNUmakefile +950 -0
  15. package/deps/libmdbx/LICENSE +177 -0
  16. package/deps/libmdbx/Makefile +16 -0
  17. package/deps/libmdbx/NOTICE +39 -0
  18. package/deps/libmdbx/README.md +863 -0
  19. package/deps/libmdbx/TODO.md +43 -0
  20. package/deps/libmdbx/cmake/compiler.cmake +1221 -0
  21. package/deps/libmdbx/cmake/profile.cmake +58 -0
  22. package/deps/libmdbx/cmake/utils.cmake +524 -0
  23. package/deps/libmdbx/conanfile.py +323 -0
  24. package/deps/libmdbx/docs/Doxyfile.in +2734 -0
  25. package/deps/libmdbx/docs/_preface.md +47 -0
  26. package/deps/libmdbx/docs/_restrictions.md +248 -0
  27. package/deps/libmdbx/docs/_starting.md +245 -0
  28. package/deps/libmdbx/docs/_toc.md +34 -0
  29. package/deps/libmdbx/docs/header.html +96 -0
  30. package/deps/libmdbx/example/CMakeLists.txt +6 -0
  31. package/deps/libmdbx/example/README.md +1 -0
  32. package/deps/libmdbx/example/example-mdbx.c +154 -0
  33. package/deps/libmdbx/example/sample-bdb.txt +77 -0
  34. package/deps/libmdbx/mdbx.h +6655 -0
  35. package/deps/libmdbx/mdbx.h++ +6428 -0
  36. package/deps/libmdbx/packages/buildroot/0001-package-libmdbx-new-package-library-database.patch +173 -0
  37. package/deps/libmdbx/src/alloy.c +54 -0
  38. package/deps/libmdbx/src/api-cold.c +543 -0
  39. package/deps/libmdbx/src/api-copy.c +912 -0
  40. package/deps/libmdbx/src/api-cursor.c +754 -0
  41. package/deps/libmdbx/src/api-dbi.c +315 -0
  42. package/deps/libmdbx/src/api-env.c +1434 -0
  43. package/deps/libmdbx/src/api-extra.c +165 -0
  44. package/deps/libmdbx/src/api-key-transform.c +197 -0
  45. package/deps/libmdbx/src/api-misc.c +286 -0
  46. package/deps/libmdbx/src/api-opts.c +575 -0
  47. package/deps/libmdbx/src/api-range-estimate.c +365 -0
  48. package/deps/libmdbx/src/api-txn-data.c +454 -0
  49. package/deps/libmdbx/src/api-txn.c +921 -0
  50. package/deps/libmdbx/src/atomics-ops.h +364 -0
  51. package/deps/libmdbx/src/atomics-types.h +97 -0
  52. package/deps/libmdbx/src/audit.c +109 -0
  53. package/deps/libmdbx/src/bits.md +34 -0
  54. package/deps/libmdbx/src/chk.c +1796 -0
  55. package/deps/libmdbx/src/cogs.c +309 -0
  56. package/deps/libmdbx/src/cogs.h +506 -0
  57. package/deps/libmdbx/src/coherency.c +170 -0
  58. package/deps/libmdbx/src/config.h.in +88 -0
  59. package/deps/libmdbx/src/cursor.c +2396 -0
  60. package/deps/libmdbx/src/cursor.h +391 -0
  61. package/deps/libmdbx/src/dbi.c +717 -0
  62. package/deps/libmdbx/src/dbi.h +142 -0
  63. package/deps/libmdbx/src/debug_begin.h +36 -0
  64. package/deps/libmdbx/src/debug_end.h +15 -0
  65. package/deps/libmdbx/src/dpl.c +486 -0
  66. package/deps/libmdbx/src/dpl.h +134 -0
  67. package/deps/libmdbx/src/dxb.c +1335 -0
  68. package/deps/libmdbx/src/env.c +607 -0
  69. package/deps/libmdbx/src/essentials.h +125 -0
  70. package/deps/libmdbx/src/gc-get.c +1345 -0
  71. package/deps/libmdbx/src/gc-put.c +970 -0
  72. package/deps/libmdbx/src/gc.h +40 -0
  73. package/deps/libmdbx/src/global.c +474 -0
  74. package/deps/libmdbx/src/internals.h +585 -0
  75. package/deps/libmdbx/src/layout-dxb.h +288 -0
  76. package/deps/libmdbx/src/layout-lck.h +289 -0
  77. package/deps/libmdbx/src/lck-posix.c +859 -0
  78. package/deps/libmdbx/src/lck-windows.c +607 -0
  79. package/deps/libmdbx/src/lck.c +174 -0
  80. package/deps/libmdbx/src/lck.h +110 -0
  81. package/deps/libmdbx/src/logging_and_debug.c +250 -0
  82. package/deps/libmdbx/src/logging_and_debug.h +159 -0
  83. package/deps/libmdbx/src/man1/mdbx_chk.1 +106 -0
  84. package/deps/libmdbx/src/man1/mdbx_copy.1 +95 -0
  85. package/deps/libmdbx/src/man1/mdbx_drop.1 +48 -0
  86. package/deps/libmdbx/src/man1/mdbx_dump.1 +101 -0
  87. package/deps/libmdbx/src/man1/mdbx_load.1 +105 -0
  88. package/deps/libmdbx/src/man1/mdbx_stat.1 +86 -0
  89. package/deps/libmdbx/src/mdbx.c++ +1837 -0
  90. package/deps/libmdbx/src/meta.c +656 -0
  91. package/deps/libmdbx/src/meta.h +168 -0
  92. package/deps/libmdbx/src/mvcc-readers.c +414 -0
  93. package/deps/libmdbx/src/node.c +365 -0
  94. package/deps/libmdbx/src/node.h +102 -0
  95. package/deps/libmdbx/src/ntdll.def +1246 -0
  96. package/deps/libmdbx/src/options.h +534 -0
  97. package/deps/libmdbx/src/osal.c +3485 -0
  98. package/deps/libmdbx/src/osal.h +587 -0
  99. package/deps/libmdbx/src/page-get.c +483 -0
  100. package/deps/libmdbx/src/page-iov.c +185 -0
  101. package/deps/libmdbx/src/page-iov.h +34 -0
  102. package/deps/libmdbx/src/page-ops.c +744 -0
  103. package/deps/libmdbx/src/page-ops.h +142 -0
  104. package/deps/libmdbx/src/pnl.c +236 -0
  105. package/deps/libmdbx/src/pnl.h +146 -0
  106. package/deps/libmdbx/src/preface.h +990 -0
  107. package/deps/libmdbx/src/proto.h +105 -0
  108. package/deps/libmdbx/src/refund.c +212 -0
  109. package/deps/libmdbx/src/sort.h +484 -0
  110. package/deps/libmdbx/src/spill.c +431 -0
  111. package/deps/libmdbx/src/spill.h +74 -0
  112. package/deps/libmdbx/src/table.c +107 -0
  113. package/deps/libmdbx/src/tls.c +551 -0
  114. package/deps/libmdbx/src/tls.h +43 -0
  115. package/deps/libmdbx/src/tools/chk.c +673 -0
  116. package/deps/libmdbx/src/tools/copy.c +166 -0
  117. package/deps/libmdbx/src/tools/drop.c +199 -0
  118. package/deps/libmdbx/src/tools/dump.c +515 -0
  119. package/deps/libmdbx/src/tools/load.c +831 -0
  120. package/deps/libmdbx/src/tools/stat.c +516 -0
  121. package/deps/libmdbx/src/tools/wingetopt.c +87 -0
  122. package/deps/libmdbx/src/tools/wingetopt.h +30 -0
  123. package/deps/libmdbx/src/tree-ops.c +1554 -0
  124. package/deps/libmdbx/src/tree-search.c +140 -0
  125. package/deps/libmdbx/src/txl.c +99 -0
  126. package/deps/libmdbx/src/txl.h +26 -0
  127. package/deps/libmdbx/src/txn.c +1083 -0
  128. package/deps/libmdbx/src/unaligned.h +205 -0
  129. package/deps/libmdbx/src/utils.c +32 -0
  130. package/deps/libmdbx/src/utils.h +76 -0
  131. package/deps/libmdbx/src/version.c.in +44 -0
  132. package/deps/libmdbx/src/walk.c +290 -0
  133. package/deps/libmdbx/src/walk.h +20 -0
  134. package/deps/libmdbx/src/windows-import.c +152 -0
  135. package/deps/libmdbx/src/windows-import.h +128 -0
  136. package/deps/libmdbx/test/CMakeLists.txt +317 -0
  137. package/deps/libmdbx/test/append.c++ +237 -0
  138. package/deps/libmdbx/test/base.h++ +92 -0
  139. package/deps/libmdbx/test/battery-tmux.sh +64 -0
  140. package/deps/libmdbx/test/cases.c++ +118 -0
  141. package/deps/libmdbx/test/chrono.c++ +134 -0
  142. package/deps/libmdbx/test/chrono.h++ +85 -0
  143. package/deps/libmdbx/test/config.c++ +643 -0
  144. package/deps/libmdbx/test/config.h++ +334 -0
  145. package/deps/libmdbx/test/copy.c++ +62 -0
  146. package/deps/libmdbx/test/dead.c++ +39 -0
  147. package/deps/libmdbx/test/dump-load.sh +40 -0
  148. package/deps/libmdbx/test/extra/crunched_delete.c++ +409 -0
  149. package/deps/libmdbx/test/extra/cursor_closing.c++ +410 -0
  150. package/deps/libmdbx/test/extra/dbi.c++ +229 -0
  151. package/deps/libmdbx/test/extra/doubtless_positioning.c++ +253 -0
  152. package/deps/libmdbx/test/extra/dupfix_addodd.c +94 -0
  153. package/deps/libmdbx/test/extra/dupfix_multiple.c++ +311 -0
  154. package/deps/libmdbx/test/extra/early_close_dbi.c++ +137 -0
  155. package/deps/libmdbx/test/extra/hex_base64_base58.c++ +118 -0
  156. package/deps/libmdbx/test/extra/maindb_ordinal.c++ +61 -0
  157. package/deps/libmdbx/test/extra/open.c++ +96 -0
  158. package/deps/libmdbx/test/extra/pcrf/README.md +2 -0
  159. package/deps/libmdbx/test/extra/pcrf/pcrf_test.c +380 -0
  160. package/deps/libmdbx/test/extra/probe.c++ +10 -0
  161. package/deps/libmdbx/test/extra/txn.c++ +407 -0
  162. package/deps/libmdbx/test/extra/upsert_alldups.c +193 -0
  163. package/deps/libmdbx/test/fork.c++ +263 -0
  164. package/deps/libmdbx/test/hill.c++ +447 -0
  165. package/deps/libmdbx/test/jitter.c++ +197 -0
  166. package/deps/libmdbx/test/keygen.c++ +393 -0
  167. package/deps/libmdbx/test/keygen.h++ +130 -0
  168. package/deps/libmdbx/test/log.c++ +358 -0
  169. package/deps/libmdbx/test/log.h++ +91 -0
  170. package/deps/libmdbx/test/main.c++ +706 -0
  171. package/deps/libmdbx/test/nested.c++ +318 -0
  172. package/deps/libmdbx/test/osal-unix.c++ +647 -0
  173. package/deps/libmdbx/test/osal-windows.c++ +440 -0
  174. package/deps/libmdbx/test/osal.h++ +41 -0
  175. package/deps/libmdbx/test/stochastic.sh +690 -0
  176. package/deps/libmdbx/test/stub/LICENSE +24 -0
  177. package/deps/libmdbx/test/stub/README.md +8 -0
  178. package/deps/libmdbx/test/stub/pthread_barrier.c +104 -0
  179. package/deps/libmdbx/test/stub/pthread_barrier.h +77 -0
  180. package/deps/libmdbx/test/test.c++ +1551 -0
  181. package/deps/libmdbx/test/test.h++ +298 -0
  182. package/deps/libmdbx/test/tmux.conf +3 -0
  183. package/deps/libmdbx/test/try.c++ +30 -0
  184. package/deps/libmdbx/test/ttl.c++ +240 -0
  185. package/deps/libmdbx/test/utils.c++ +203 -0
  186. package/deps/libmdbx/test/utils.h++ +326 -0
  187. package/deps/libmdbx/test/valgrind_suppress.txt +536 -0
  188. package/lib/mdbx_evn_async.js +211 -0
  189. package/lib/mdbx_worker.js +195 -0
  190. package/lib/nativemou.js +6 -0
  191. package/package.json +38 -0
  192. package/src/async/envmou_close.cpp +34 -0
  193. package/src/async/envmou_close.hpp +32 -0
  194. package/src/async/envmou_copy_to.cpp +29 -0
  195. package/src/async/envmou_copy_to.hpp +38 -0
  196. package/src/async/envmou_keys.cpp +201 -0
  197. package/src/async/envmou_keys.hpp +50 -0
  198. package/src/async/envmou_open.cpp +38 -0
  199. package/src/async/envmou_open.hpp +33 -0
  200. package/src/async/envmou_query.cpp +167 -0
  201. package/src/async/envmou_query.hpp +53 -0
  202. package/src/dbimou.cpp +522 -0
  203. package/src/dbimou.hpp +82 -0
  204. package/src/env_arg0.hpp +24 -0
  205. package/src/envmou.cpp +445 -0
  206. package/src/envmou.hpp +116 -0
  207. package/src/modulemou.cpp +113 -0
  208. package/src/querymou.cpp +177 -0
  209. package/src/querymou.hpp +93 -0
  210. package/src/txnmou.cpp +254 -0
  211. package/src/txnmou.hpp +122 -0
  212. package/src/typemou.hpp +239 -0
  213. package/src/valuemou.hpp +194 -0
  214. package/test/async.js +67 -0
  215. package/test/e3.js +38 -0
  216. package/test/e4.js +89 -0
  217. package/test/e5.js +162 -0
  218. package/test/test-batch-ops.js +243 -0
  219. package/test/test-cursor-mode.js +84 -0
  220. package/test/test-multi-mode.js +87 -0
@@ -0,0 +1,587 @@
1
+ /// \copyright SPDX-License-Identifier: Apache-2.0
2
+ /// \author Леонид Юрьев aka Leonid Yuriev <leo@yuriev.ru> \date 2015-2025
3
+ ///
4
+ /// https://en.wikipedia.org/wiki/Operating_system_abstraction_layer
5
+
6
+ #pragma once
7
+
8
+ #include "essentials.h"
9
+
10
+ /*----------------------------------------------------------------------------*/
11
+ /* Memory/Compiler barriers, cache coherence */
12
+
13
+ #if __has_include(<sys/cachectl.h>)
14
+ #include <sys/cachectl.h>
15
+ #elif defined(__mips) || defined(__mips__) || defined(__mips64) || defined(__mips64__) || defined(_M_MRX000) || \
16
+ defined(_MIPS_) || defined(__MWERKS__) || defined(__sgi)
17
+ /* MIPS should have explicit cache control */
18
+ #include <sys/cachectl.h>
19
+ #endif
20
+
21
+ MDBX_MAYBE_UNUSED static inline void osal_compiler_barrier(void) {
22
+ #if defined(__clang__) || defined(__GNUC__)
23
+ __asm__ __volatile__("" ::: "memory");
24
+ #elif defined(_MSC_VER)
25
+ _ReadWriteBarrier();
26
+ #elif defined(__INTEL_COMPILER) /* LY: Intel Compiler may mimic GCC and MSC */
27
+ __memory_barrier();
28
+ #elif defined(__SUNPRO_C) || defined(__sun) || defined(sun)
29
+ __compiler_barrier();
30
+ #elif (defined(_HPUX_SOURCE) || defined(__hpux) || defined(__HP_aCC)) && (defined(HP_IA64) || defined(__ia64))
31
+ _Asm_sched_fence(/* LY: no-arg meaning 'all expect ALU', e.g. 0x3D3D */);
32
+ #elif defined(_AIX) || defined(__ppc__) || defined(__powerpc__) || defined(__ppc64__) || defined(__powerpc64__)
33
+ __fence();
34
+ #else
35
+ #error "Could not guess the kind of compiler, please report to us."
36
+ #endif
37
+ }
38
+
39
+ MDBX_MAYBE_UNUSED static inline void osal_memory_barrier(void) {
40
+ #ifdef MDBX_HAVE_C11ATOMICS
41
+ atomic_thread_fence(memory_order_seq_cst);
42
+ #elif defined(__ATOMIC_SEQ_CST)
43
+ #ifdef __clang__
44
+ __c11_atomic_thread_fence(__ATOMIC_SEQ_CST);
45
+ #else
46
+ __atomic_thread_fence(__ATOMIC_SEQ_CST);
47
+ #endif
48
+ #elif defined(__clang__) || defined(__GNUC__)
49
+ __sync_synchronize();
50
+ #elif defined(_WIN32) || defined(_WIN64)
51
+ MemoryBarrier();
52
+ #elif defined(__INTEL_COMPILER) /* LY: Intel Compiler may mimic GCC and MSC */
53
+ #if defined(__ia32__)
54
+ _mm_mfence();
55
+ #else
56
+ __mf();
57
+ #endif
58
+ #elif defined(__SUNPRO_C) || defined(__sun) || defined(sun)
59
+ __machine_rw_barrier();
60
+ #elif (defined(_HPUX_SOURCE) || defined(__hpux) || defined(__HP_aCC)) && (defined(HP_IA64) || defined(__ia64))
61
+ _Asm_mf();
62
+ #elif defined(_AIX) || defined(__ppc__) || defined(__powerpc__) || defined(__ppc64__) || defined(__powerpc64__)
63
+ __lwsync();
64
+ #else
65
+ #error "Could not guess the kind of compiler, please report to us."
66
+ #endif
67
+ }
68
+
69
+ /*----------------------------------------------------------------------------*/
70
+ /* system-depended definitions */
71
+
72
+ #if defined(_WIN32) || defined(_WIN64)
73
+ #define HAVE_SYS_STAT_H
74
+ #define HAVE_SYS_TYPES_H
75
+ typedef HANDLE osal_thread_t;
76
+ typedef unsigned osal_thread_key_t;
77
+ #define MAP_FAILED nullptr
78
+ #define HIGH_DWORD(v) ((DWORD)((sizeof(v) > 4) ? ((uint64_t)(v) >> 32) : 0))
79
+ #define THREAD_CALL WINAPI
80
+ #define THREAD_RESULT DWORD
81
+ typedef struct {
82
+ HANDLE mutex;
83
+ HANDLE event[2];
84
+ } osal_condpair_t;
85
+ typedef CRITICAL_SECTION osal_fastmutex_t;
86
+
87
+ #if !defined(_MSC_VER) && !defined(__try)
88
+ /* *INDENT-OFF* */
89
+ /* clang-format off */
90
+ #define __try
91
+ #define __except(COND) if (/* (void)(COND), */ false)
92
+ /* *INDENT-ON* */
93
+ /* clang-format on */
94
+ #endif /* stub for MSVC's __try/__except */
95
+
96
+ #if MDBX_WITHOUT_MSVC_CRT
97
+
98
+ #ifndef osal_malloc
99
+ static inline void *osal_malloc(size_t bytes) { return HeapAlloc(GetProcessHeap(), 0, bytes); }
100
+ #endif /* osal_malloc */
101
+
102
+ #ifndef osal_calloc
103
+ static inline void *osal_calloc(size_t nelem, size_t size) {
104
+ return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, nelem * size);
105
+ }
106
+ #endif /* osal_calloc */
107
+
108
+ #ifndef osal_realloc
109
+ static inline void *osal_realloc(void *ptr, size_t bytes) {
110
+ return ptr ? HeapReAlloc(GetProcessHeap(), 0, ptr, bytes) : HeapAlloc(GetProcessHeap(), 0, bytes);
111
+ }
112
+ #endif /* osal_realloc */
113
+
114
+ #ifndef osal_free
115
+ static inline void osal_free(void *ptr) { HeapFree(GetProcessHeap(), 0, ptr); }
116
+ #endif /* osal_free */
117
+
118
+ #else /* MDBX_WITHOUT_MSVC_CRT */
119
+
120
+ #define osal_malloc malloc
121
+ #define osal_calloc calloc
122
+ #define osal_realloc realloc
123
+ #define osal_free free
124
+ #define osal_strdup _strdup
125
+
126
+ #endif /* MDBX_WITHOUT_MSVC_CRT */
127
+
128
+ #ifndef snprintf
129
+ #define snprintf _snprintf /* ntdll */
130
+ #endif
131
+
132
+ #ifndef vsnprintf
133
+ #define vsnprintf _vsnprintf /* ntdll */
134
+ #endif
135
+
136
+ #else /*----------------------------------------------------------------------*/
137
+
138
+ typedef pthread_t osal_thread_t;
139
+ typedef pthread_key_t osal_thread_key_t;
140
+ #define INVALID_HANDLE_VALUE (-1)
141
+ #define THREAD_CALL
142
+ #define THREAD_RESULT void *
143
+ typedef struct {
144
+ pthread_mutex_t mutex;
145
+ pthread_cond_t cond[2];
146
+ } osal_condpair_t;
147
+ typedef pthread_mutex_t osal_fastmutex_t;
148
+ #define osal_malloc malloc
149
+ #define osal_calloc calloc
150
+ #define osal_realloc realloc
151
+ #define osal_free free
152
+ #define osal_strdup strdup
153
+ #endif /* Platform */
154
+
155
+ #if __GLIBC_PREREQ(2, 12) || defined(__FreeBSD__) || defined(malloc_usable_size)
156
+ #define osal_malloc_usable_size(ptr) malloc_usable_size(ptr)
157
+ #elif defined(__APPLE__)
158
+ #define osal_malloc_usable_size(ptr) malloc_size(ptr)
159
+ #elif defined(_MSC_VER) && !MDBX_WITHOUT_MSVC_CRT
160
+ #define osal_malloc_usable_size(ptr) _msize(ptr)
161
+ #endif /* osal_malloc_usable_size */
162
+
163
+ /*----------------------------------------------------------------------------*/
164
+ /* OS abstraction layer stuff */
165
+
166
+ #if defined(_WIN32) || defined(_WIN64)
167
+ typedef wchar_t pathchar_t;
168
+ #define MDBX_PRIsPATH "ls"
169
+ #else
170
+ typedef char pathchar_t;
171
+ #define MDBX_PRIsPATH "s"
172
+ #endif
173
+
174
+ typedef struct osal_mmap {
175
+ union {
176
+ void *base;
177
+ struct shared_lck *lck;
178
+ };
179
+ mdbx_filehandle_t fd;
180
+ size_t limit; /* mapping length, but NOT a size of file nor DB */
181
+ size_t current; /* mapped region size, i.e. the size of file and DB */
182
+ uint64_t filesize /* in-process cache of a file size */;
183
+ #if defined(_WIN32) || defined(_WIN64)
184
+ HANDLE section; /* memory-mapped section handle */
185
+ #endif
186
+ } osal_mmap_t;
187
+
188
+ #ifndef MDBX_HAVE_PWRITEV
189
+ #if defined(_WIN32) || defined(_WIN64)
190
+
191
+ #define MDBX_HAVE_PWRITEV 0
192
+
193
+ #elif defined(__ANDROID_API__)
194
+
195
+ #if __ANDROID_API__ < 24
196
+ /* https://android-developers.googleblog.com/2017/09/introducing-android-native-development.html
197
+ * https://android.googlesource.com/platform/bionic/+/master/docs/32-bit-abi.md */
198
+ #define MDBX_HAVE_PWRITEV 0
199
+ #if defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS != MDBX_WORDBITS
200
+ #error "_FILE_OFFSET_BITS != MDBX_WORDBITS and __ANDROID_API__ < 24" (_FILE_OFFSET_BITS != MDBX_WORDBITS)
201
+ #elif defined(__FILE_OFFSET_BITS) && __FILE_OFFSET_BITS != MDBX_WORDBITS
202
+ #error "__FILE_OFFSET_BITS != MDBX_WORDBITS and __ANDROID_API__ < 24" (__FILE_OFFSET_BITS != MDBX_WORDBITS)
203
+ #endif
204
+ #else
205
+ #define MDBX_HAVE_PWRITEV 1
206
+ #endif
207
+
208
+ #elif defined(__APPLE__) || defined(__MACH__) || defined(_DARWIN_C_SOURCE)
209
+
210
+ #if defined(MAC_OS_X_VERSION_MIN_REQUIRED) && defined(MAC_OS_VERSION_11_0) && \
211
+ MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_VERSION_11_0
212
+ /* FIXME: add checks for IOS versions, etc */
213
+ #define MDBX_HAVE_PWRITEV 1
214
+ #else
215
+ #define MDBX_HAVE_PWRITEV 0
216
+ #endif
217
+
218
+ #elif defined(_SC_IOV_MAX) || (defined(IOV_MAX) && IOV_MAX > 1)
219
+ #define MDBX_HAVE_PWRITEV 1
220
+ #else
221
+ #define MDBX_HAVE_PWRITEV 0
222
+ #endif
223
+ #endif /* MDBX_HAVE_PWRITEV */
224
+
225
+ typedef struct ior_item {
226
+ #if defined(_WIN32) || defined(_WIN64)
227
+ OVERLAPPED ov;
228
+ #define ior_sgv_gap4terminator 1
229
+ #define ior_sgv_element FILE_SEGMENT_ELEMENT
230
+ #else
231
+ size_t offset;
232
+ #if MDBX_HAVE_PWRITEV
233
+ size_t sgvcnt;
234
+ #define ior_sgv_gap4terminator 0
235
+ #define ior_sgv_element struct iovec
236
+ #endif /* MDBX_HAVE_PWRITEV */
237
+ #endif /* !Windows */
238
+ union {
239
+ MDBX_val single;
240
+ #if defined(ior_sgv_element)
241
+ ior_sgv_element sgv[1 + ior_sgv_gap4terminator];
242
+ #endif /* ior_sgv_element */
243
+ };
244
+ } ior_item_t;
245
+
246
+ typedef struct osal_ioring {
247
+ unsigned slots_left;
248
+ unsigned allocated;
249
+ #if defined(_WIN32) || defined(_WIN64)
250
+ #define IOR_STATE_LOCKED 1
251
+ HANDLE overlapped_fd;
252
+ unsigned pagesize;
253
+ unsigned last_sgvcnt;
254
+ size_t last_bytes;
255
+ uint8_t direct, state, pagesize_ln2;
256
+ unsigned event_stack;
257
+ HANDLE *event_pool;
258
+ volatile LONG async_waiting;
259
+ volatile LONG async_completed;
260
+ HANDLE async_done;
261
+
262
+ #define ior_last_sgvcnt(ior, item) (ior)->last_sgvcnt
263
+ #define ior_last_bytes(ior, item) (ior)->last_bytes
264
+ #elif MDBX_HAVE_PWRITEV
265
+ unsigned last_bytes;
266
+ #define ior_last_sgvcnt(ior, item) (item)->sgvcnt
267
+ #define ior_last_bytes(ior, item) (ior)->last_bytes
268
+ #else
269
+ #define ior_last_sgvcnt(ior, item) (1)
270
+ #define ior_last_bytes(ior, item) (item)->single.iov_len
271
+ #endif /* !Windows */
272
+ ior_item_t *last;
273
+ ior_item_t *pool;
274
+ char *boundary;
275
+ } osal_ioring_t;
276
+
277
+ /* Actually this is not ioring for now, but on the way. */
278
+ MDBX_INTERNAL int osal_ioring_create(osal_ioring_t *
279
+ #if defined(_WIN32) || defined(_WIN64)
280
+ ,
281
+ bool enable_direct, mdbx_filehandle_t overlapped_fd
282
+ #endif /* Windows */
283
+ );
284
+ MDBX_INTERNAL int osal_ioring_resize(osal_ioring_t *, size_t items);
285
+ MDBX_INTERNAL void osal_ioring_destroy(osal_ioring_t *);
286
+ MDBX_INTERNAL void osal_ioring_reset(osal_ioring_t *);
287
+ MDBX_INTERNAL int osal_ioring_add(osal_ioring_t *ctx, const size_t offset, void *data, const size_t bytes);
288
+ typedef struct osal_ioring_write_result {
289
+ int err;
290
+ unsigned wops;
291
+ } osal_ioring_write_result_t;
292
+ MDBX_INTERNAL osal_ioring_write_result_t osal_ioring_write(osal_ioring_t *ior, mdbx_filehandle_t fd);
293
+
294
+ MDBX_INTERNAL void osal_ioring_walk(osal_ioring_t *ior, iov_ctx_t *ctx,
295
+ void (*callback)(iov_ctx_t *ctx, size_t offset, void *data, size_t bytes));
296
+
297
+ MDBX_MAYBE_UNUSED static inline unsigned osal_ioring_left(const osal_ioring_t *ior) { return ior->slots_left; }
298
+
299
+ MDBX_MAYBE_UNUSED static inline unsigned osal_ioring_used(const osal_ioring_t *ior) {
300
+ return ior->allocated - ior->slots_left;
301
+ }
302
+
303
+ MDBX_MAYBE_UNUSED static inline int osal_ioring_prepare(osal_ioring_t *ior, size_t items, size_t bytes) {
304
+ items = (items > 32) ? items : 32;
305
+ #if defined(_WIN32) || defined(_WIN64)
306
+ if (ior->direct) {
307
+ const size_t npages = bytes >> ior->pagesize_ln2;
308
+ items = (items > npages) ? items : npages;
309
+ }
310
+ #else
311
+ (void)bytes;
312
+ #endif
313
+ items = (items < 65536) ? items : 65536;
314
+ if (likely(ior->allocated >= items))
315
+ return MDBX_SUCCESS;
316
+ return osal_ioring_resize(ior, items);
317
+ }
318
+
319
+ /*----------------------------------------------------------------------------*/
320
+ /* libc compatibility stuff */
321
+
322
+ #if (!defined(__GLIBC__) && __GLIBC_PREREQ(2, 1)) && (defined(_GNU_SOURCE) || defined(_BSD_SOURCE))
323
+ #define osal_asprintf asprintf
324
+ #define osal_vasprintf vasprintf
325
+ #else
326
+ MDBX_MAYBE_UNUSED MDBX_INTERNAL MDBX_PRINTF_ARGS(2, 3) int osal_asprintf(char **strp, const char *fmt, ...);
327
+ MDBX_INTERNAL int osal_vasprintf(char **strp, const char *fmt, va_list ap);
328
+ #endif
329
+
330
+ #if !defined(MADV_DODUMP) && defined(MADV_CORE)
331
+ #define MADV_DODUMP MADV_CORE
332
+ #endif /* MADV_CORE -> MADV_DODUMP */
333
+
334
+ #if !defined(MADV_DONTDUMP) && defined(MADV_NOCORE)
335
+ #define MADV_DONTDUMP MADV_NOCORE
336
+ #endif /* MADV_NOCORE -> MADV_DONTDUMP */
337
+
338
+ MDBX_MAYBE_UNUSED MDBX_INTERNAL void osal_jitter(bool tiny);
339
+
340
+ /* max bytes to write in one call */
341
+ #if defined(_WIN64)
342
+ #define MAX_WRITE UINT32_C(0x10000000)
343
+ #elif defined(_WIN32)
344
+ #define MAX_WRITE UINT32_C(0x04000000)
345
+ #else
346
+ #define MAX_WRITE UINT32_C(0x3f000000)
347
+
348
+ #if defined(F_GETLK64) && defined(F_SETLK64) && defined(F_SETLKW64) && !defined(__ANDROID_API__)
349
+ #define MDBX_F_SETLK F_SETLK64
350
+ #define MDBX_F_SETLKW F_SETLKW64
351
+ #define MDBX_F_GETLK F_GETLK64
352
+ #if (__GLIBC_PREREQ(2, 28) && (defined(__USE_LARGEFILE64) || defined(__LARGEFILE64_SOURCE) || \
353
+ defined(_USE_LARGEFILE64) || defined(_LARGEFILE64_SOURCE))) || \
354
+ defined(fcntl64)
355
+ #define MDBX_FCNTL fcntl64
356
+ #else
357
+ #define MDBX_FCNTL fcntl
358
+ #endif
359
+ #define MDBX_STRUCT_FLOCK struct flock64
360
+ #ifndef OFF_T_MAX
361
+ #define OFF_T_MAX UINT64_C(0x7fffFFFFfff00000)
362
+ #endif /* OFF_T_MAX */
363
+ #else
364
+ #define MDBX_F_SETLK F_SETLK
365
+ #define MDBX_F_SETLKW F_SETLKW
366
+ #define MDBX_F_GETLK F_GETLK
367
+ #define MDBX_FCNTL fcntl
368
+ #define MDBX_STRUCT_FLOCK struct flock
369
+ #endif /* MDBX_F_SETLK, MDBX_F_SETLKW, MDBX_F_GETLK */
370
+
371
+ #if defined(F_OFD_SETLK64) && defined(F_OFD_SETLKW64) && defined(F_OFD_GETLK64) && !defined(__ANDROID_API__)
372
+ #define MDBX_F_OFD_SETLK F_OFD_SETLK64
373
+ #define MDBX_F_OFD_SETLKW F_OFD_SETLKW64
374
+ #define MDBX_F_OFD_GETLK F_OFD_GETLK64
375
+ #else
376
+ #define MDBX_F_OFD_SETLK F_OFD_SETLK
377
+ #define MDBX_F_OFD_SETLKW F_OFD_SETLKW
378
+ #define MDBX_F_OFD_GETLK F_OFD_GETLK
379
+ #ifndef OFF_T_MAX
380
+ #define OFF_T_MAX (((sizeof(off_t) > 4) ? INT64_MAX : INT32_MAX) & ~(size_t)0xFffff)
381
+ #endif /* OFF_T_MAX */
382
+ #endif /* MDBX_F_OFD_SETLK64, MDBX_F_OFD_SETLKW64, MDBX_F_OFD_GETLK64 */
383
+
384
+ #endif /* !Windows */
385
+
386
+ #ifndef osal_strdup
387
+ LIBMDBX_API char *osal_strdup(const char *str);
388
+ #endif
389
+
390
+ MDBX_MAYBE_UNUSED static inline int osal_get_errno(void) {
391
+ #if defined(_WIN32) || defined(_WIN64)
392
+ DWORD rc = GetLastError();
393
+ #else
394
+ int rc = errno;
395
+ #endif
396
+ return rc;
397
+ }
398
+
399
+ #ifndef osal_memalign_alloc
400
+ MDBX_INTERNAL int osal_memalign_alloc(size_t alignment, size_t bytes, void **result);
401
+ #endif
402
+ #ifndef osal_memalign_free
403
+ MDBX_INTERNAL void osal_memalign_free(void *ptr);
404
+ #endif
405
+
406
+ MDBX_INTERNAL int osal_condpair_init(osal_condpair_t *condpair);
407
+ MDBX_INTERNAL int osal_condpair_lock(osal_condpair_t *condpair);
408
+ MDBX_INTERNAL int osal_condpair_unlock(osal_condpair_t *condpair);
409
+ MDBX_INTERNAL int osal_condpair_signal(osal_condpair_t *condpair, bool part);
410
+ MDBX_INTERNAL int osal_condpair_wait(osal_condpair_t *condpair, bool part);
411
+ MDBX_INTERNAL int osal_condpair_destroy(osal_condpair_t *condpair);
412
+
413
+ MDBX_INTERNAL int osal_fastmutex_init(osal_fastmutex_t *fastmutex);
414
+ MDBX_INTERNAL int osal_fastmutex_acquire(osal_fastmutex_t *fastmutex);
415
+ MDBX_INTERNAL int osal_fastmutex_release(osal_fastmutex_t *fastmutex);
416
+ MDBX_INTERNAL int osal_fastmutex_destroy(osal_fastmutex_t *fastmutex);
417
+
418
+ MDBX_INTERNAL int osal_pwritev(mdbx_filehandle_t fd, struct iovec *iov, size_t sgvcnt, uint64_t offset);
419
+ MDBX_INTERNAL int osal_pread(mdbx_filehandle_t fd, void *buf, size_t count, uint64_t offset);
420
+ MDBX_INTERNAL int osal_pwrite(mdbx_filehandle_t fd, const void *buf, size_t count, uint64_t offset);
421
+ MDBX_INTERNAL int osal_write(mdbx_filehandle_t fd, const void *buf, size_t count);
422
+
423
+ MDBX_INTERNAL int osal_thread_create(osal_thread_t *thread, THREAD_RESULT(THREAD_CALL *start_routine)(void *),
424
+ void *arg);
425
+ MDBX_INTERNAL int osal_thread_join(osal_thread_t thread);
426
+
427
+ enum osal_syncmode_bits {
428
+ MDBX_SYNC_NONE = 0,
429
+ MDBX_SYNC_KICK = 1,
430
+ MDBX_SYNC_DATA = 2,
431
+ MDBX_SYNC_SIZE = 4,
432
+ MDBX_SYNC_IODQ = 8
433
+ };
434
+
435
+ MDBX_INTERNAL int osal_fsync(mdbx_filehandle_t fd, const enum osal_syncmode_bits mode_bits);
436
+ MDBX_INTERNAL int osal_ftruncate(mdbx_filehandle_t fd, uint64_t length);
437
+ MDBX_INTERNAL int osal_fseek(mdbx_filehandle_t fd, uint64_t pos);
438
+ MDBX_INTERNAL int osal_filesize(mdbx_filehandle_t fd, uint64_t *length);
439
+
440
+ enum osal_openfile_purpose {
441
+ MDBX_OPEN_DXB_READ,
442
+ MDBX_OPEN_DXB_LAZY,
443
+ MDBX_OPEN_DXB_DSYNC,
444
+ #if defined(_WIN32) || defined(_WIN64)
445
+ MDBX_OPEN_DXB_OVERLAPPED,
446
+ MDBX_OPEN_DXB_OVERLAPPED_DIRECT,
447
+ #endif /* Windows */
448
+ MDBX_OPEN_LCK,
449
+ MDBX_OPEN_COPY,
450
+ MDBX_OPEN_DELETE
451
+ };
452
+
453
+ MDBX_MAYBE_UNUSED static inline bool osal_isdirsep(pathchar_t c) {
454
+ return
455
+ #if defined(_WIN32) || defined(_WIN64)
456
+ c == '\\' ||
457
+ #endif
458
+ c == '/';
459
+ }
460
+
461
+ MDBX_INTERNAL bool osal_pathequal(const pathchar_t *l, const pathchar_t *r, size_t len);
462
+ MDBX_INTERNAL pathchar_t *osal_fileext(const pathchar_t *pathname, size_t len);
463
+ MDBX_INTERNAL int osal_fileexists(const pathchar_t *pathname);
464
+ MDBX_INTERNAL int osal_openfile(const enum osal_openfile_purpose purpose, const MDBX_env *env,
465
+ const pathchar_t *pathname, mdbx_filehandle_t *fd, mdbx_mode_t unix_mode_bits);
466
+ MDBX_INTERNAL int osal_closefile(mdbx_filehandle_t fd);
467
+ MDBX_INTERNAL int osal_removefile(const pathchar_t *pathname);
468
+ MDBX_INTERNAL int osal_removedirectory(const pathchar_t *pathname);
469
+ MDBX_INTERNAL int osal_is_pipe(mdbx_filehandle_t fd);
470
+ MDBX_INTERNAL int osal_lockfile(mdbx_filehandle_t fd, bool wait);
471
+
472
+ #define MMAP_OPTION_TRUNCATE 1
473
+ #define MMAP_OPTION_SEMAPHORE 2
474
+ MDBX_INTERNAL int osal_mmap(const int flags, osal_mmap_t *map, size_t size, const size_t limit, const unsigned options,
475
+ const pathchar_t *pathname4logging);
476
+ MDBX_INTERNAL int osal_munmap(osal_mmap_t *map);
477
+ #define MDBX_MRESIZE_MAY_MOVE 0x00000100
478
+ #define MDBX_MRESIZE_MAY_UNMAP 0x00000200
479
+ MDBX_INTERNAL int osal_mresize(const int flags, osal_mmap_t *map, size_t size, size_t limit);
480
+ #if defined(_WIN32) || defined(_WIN64)
481
+ typedef struct {
482
+ unsigned limit, count;
483
+ HANDLE handles[31];
484
+ } mdbx_handle_array_t;
485
+ MDBX_INTERNAL int osal_suspend_threads_before_remap(MDBX_env *env, mdbx_handle_array_t **array);
486
+ MDBX_INTERNAL int osal_resume_threads_after_remap(mdbx_handle_array_t *array);
487
+ #endif /* Windows */
488
+ MDBX_INTERNAL int osal_msync(const osal_mmap_t *map, size_t offset, size_t length, enum osal_syncmode_bits mode_bits);
489
+ MDBX_INTERNAL int osal_check_fs_rdonly(mdbx_filehandle_t handle, const pathchar_t *pathname, int err);
490
+ MDBX_INTERNAL int osal_check_fs_incore(mdbx_filehandle_t handle);
491
+ MDBX_INTERNAL int osal_check_fs_local(mdbx_filehandle_t handle, int flags);
492
+
493
+ MDBX_MAYBE_UNUSED static inline uint32_t osal_getpid(void) {
494
+ STATIC_ASSERT(sizeof(mdbx_pid_t) <= sizeof(uint32_t));
495
+ #if defined(_WIN32) || defined(_WIN64)
496
+ return GetCurrentProcessId();
497
+ #else
498
+ STATIC_ASSERT(sizeof(pid_t) <= sizeof(uint32_t));
499
+ return getpid();
500
+ #endif
501
+ }
502
+
503
+ MDBX_MAYBE_UNUSED static inline uintptr_t osal_thread_self(void) {
504
+ mdbx_tid_t thunk;
505
+ STATIC_ASSERT(sizeof(uintptr_t) >= sizeof(thunk));
506
+ #if defined(_WIN32) || defined(_WIN64)
507
+ thunk = GetCurrentThreadId();
508
+ #else
509
+ thunk = pthread_self();
510
+ #endif
511
+ return (uintptr_t)thunk;
512
+ }
513
+
514
+ #if !defined(_WIN32) && !defined(_WIN64)
515
+ #if defined(__ANDROID_API__) || defined(ANDROID) || defined(BIONIC)
516
+ MDBX_INTERNAL int osal_check_tid4bionic(void);
517
+ #else
518
+ static inline int osal_check_tid4bionic(void) { return 0; }
519
+ #endif /* __ANDROID_API__ || ANDROID) || BIONIC */
520
+
521
+ MDBX_MAYBE_UNUSED static inline int osal_pthread_mutex_lock(pthread_mutex_t *mutex) {
522
+ int err = osal_check_tid4bionic();
523
+ return unlikely(err) ? err : pthread_mutex_lock(mutex);
524
+ }
525
+ #endif /* !Windows */
526
+
527
+ MDBX_INTERNAL uint64_t osal_monotime(void);
528
+ MDBX_INTERNAL uint64_t osal_cputime(size_t *optional_page_faults);
529
+ MDBX_INTERNAL uint64_t osal_16dot16_to_monotime(uint32_t seconds_16dot16);
530
+ MDBX_INTERNAL uint32_t osal_monotime_to_16dot16(uint64_t monotime);
531
+
532
+ MDBX_MAYBE_UNUSED static inline uint32_t osal_monotime_to_16dot16_noUnderflow(uint64_t monotime) {
533
+ uint32_t seconds_16dot16 = osal_monotime_to_16dot16(monotime);
534
+ return seconds_16dot16 ? seconds_16dot16 : /* fix underflow */ (monotime > 0);
535
+ }
536
+
537
+ /*----------------------------------------------------------------------------*/
538
+
539
+ MDBX_INTERNAL void osal_ctor(void);
540
+ MDBX_INTERNAL void osal_dtor(void);
541
+
542
+ #if defined(_WIN32) || defined(_WIN64)
543
+ MDBX_INTERNAL int osal_mb2w(const char *const src, wchar_t **const pdst);
544
+ #endif /* Windows */
545
+
546
+ typedef union bin128 {
547
+ __anonymous_struct_extension__ struct {
548
+ uint64_t x, y;
549
+ };
550
+ __anonymous_struct_extension__ struct {
551
+ uint32_t a, b, c, d;
552
+ };
553
+ } bin128_t;
554
+
555
+ MDBX_INTERNAL bin128_t osal_guid(const MDBX_env *);
556
+
557
+ /*----------------------------------------------------------------------------*/
558
+
559
+ MDBX_MAYBE_UNUSED MDBX_NOTHROW_PURE_FUNCTION static inline uint64_t osal_bswap64(uint64_t v) {
560
+ #if __GNUC_PREREQ(4, 4) || __CLANG_PREREQ(4, 0) || __has_builtin(__builtin_bswap64)
561
+ return __builtin_bswap64(v);
562
+ #elif defined(_MSC_VER) && !defined(__clang__)
563
+ return _byteswap_uint64(v);
564
+ #elif defined(__bswap_64)
565
+ return __bswap_64(v);
566
+ #elif defined(bswap_64)
567
+ return bswap_64(v);
568
+ #else
569
+ return v << 56 | v >> 56 | ((v << 40) & UINT64_C(0x00ff000000000000)) | ((v << 24) & UINT64_C(0x0000ff0000000000)) |
570
+ ((v << 8) & UINT64_C(0x000000ff00000000)) | ((v >> 8) & UINT64_C(0x00000000ff000000)) |
571
+ ((v >> 24) & UINT64_C(0x0000000000ff0000)) | ((v >> 40) & UINT64_C(0x000000000000ff00));
572
+ #endif
573
+ }
574
+
575
+ MDBX_MAYBE_UNUSED MDBX_NOTHROW_PURE_FUNCTION static inline uint32_t osal_bswap32(uint32_t v) {
576
+ #if __GNUC_PREREQ(4, 4) || __CLANG_PREREQ(4, 0) || __has_builtin(__builtin_bswap32)
577
+ return __builtin_bswap32(v);
578
+ #elif defined(_MSC_VER) && !defined(__clang__)
579
+ return _byteswap_ulong(v);
580
+ #elif defined(__bswap_32)
581
+ return __bswap_32(v);
582
+ #elif defined(bswap_32)
583
+ return bswap_32(v);
584
+ #else
585
+ return v << 24 | v >> 24 | ((v << 8) & UINT32_C(0x00ff0000)) | ((v >> 8) & UINT32_C(0x0000ff00));
586
+ #endif
587
+ }