LAMMP 4.2.0
Lamina High-Precision Arithmetic Library
载入中...
搜索中...
未找到
lmmp.h
浏览该文件的文档.
1/**
2 * Copyright (C) 2026 HJimmyK(Jericho Knox)
3 *
4 * This file is part of LAMMP.
5 *
6 * LAMMP is free software: you can redistribute it and/or modify it under
7 * the terms of the GNU Lesser General Public License (LGPL) as published
8 * by the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed WITHOUT ANY WARRANTY.
12 *
13 * See <https://www.gnu.org/licenses/>.
14 */
15
16#ifndef LAMMP_LMMP_H
17#define LAMMP_LMMP_H
18
19/*
20 本库的实现部分灵感来源于或改编自
21
22 GNU-MP (https://gmplib.org/),
23 FLINT (https://www.flintlib.org/),
24
25 符号说明:
26
27 B 基数,已被硬编码为 2^64
28
29 [p,n,b] 表示指针p指向的、以b为基数的n位数
30 p[i-1] 代表其第i位最低有效位 (0<i<=n)
31 如果省略b,则默认基数为B。通常情况下,
32 用此符号表示函数参数时,一般暗指高位不存在0,
33 在不太严格场景中,比如乘法和加减法中,即使存在高位0
34 通常也不会导致错误,在严格的除法或者其他运算中,会强调
35 高位不能是0。
36 用此符号表示函数返回值时,也表示将会写入的区间,
37 即使可能写入为0。
38
39 sep 指针指向的内存区域完全分离
40
41 eqsep 完全相同的内存区域或者完全分离
42
43 备注:我们都假定地址是向上增长的,dst <= num+1
44 的内存布局可以这样表示
45 dst ──┐
46 num ──┐ |00000000|00000000|
47 |********|********|
48
49 MSB(x) x的最高有效位,比如最高有效位为1,MSB(x)=1
50 代表 x >= B / 2
51
52 [x|y] x或y,用于表示参数或返回值的取值范围
53
54*/
55
56#include <stddef.h>
57#include <stdint.h>
58#include <stdlib.h>
59#include <string.h>
60
61#ifdef __cplusplus
62extern "C" {
63#endif
64
65#if defined(DEBUG)
66
67/* LAMMP 调试宏,定义为1时,会开启相应的调试功能,共有四个开销等级:低、中、高、很高。 */
68
69// 开启时,将会检查栈溢出;开销:高
70#define LAMMP_DEBUG_STACK_OVERFLOW_CHECK 1
71// 开启时,将会开启debug_assert的检查;开销:中
72#define LAMMP_DEBUG_ASSERT_CHECK 1
73// 开启时,将会进行参数检查;开销:中
74#define LAMMP_DEBUG_PARAM_ASSERT_CHECK 1
75// 开启时,将会进行全面的堆栈内存检查,包括堆栈溢出、指针释放检查、缓冲区溢出检查;开销:很高
76#define LAMMP_DEBUG_MEMORY_CHECK 1
77// 堆栈溢出检查中额外分配的内存倍数,额外分配的内存空间=单次分配的内存空间*(MORE_ALLOC_TIMES/10)
78#define LAMMP_MEMORY_MORE_ALLOC_TIMES 1
79// 开启时,会增加内存分配和释放次数的统计功能;开销:低
80#define LAMMP_DEBUG_MEMORY_LEAK 1
81
82#else
83
84#define LAMMP_DEBUG_STACK_OVERFLOW_CHECK 0
85#define LAMMP_DEBUG_ASSERT_CHECK 0
86#define LAMMP_DEBUG_PARAM_ASSERT_CHECK 0
87#define LAMMP_DEBUG_MEMORY_CHECK 0
88#define LAMMP_MEMORY_MORE_ALLOC_TIMES 1
89#define LAMMP_DEBUG_MEMORY_LEAK 0
90
91#endif
92
93#if defined(LAMMP_WINDOWS)
94 // Windows: MSVC / MinGW / Clang
95 #ifdef LAMMP_CORE_EXPORTS
96 #define LAMMP_API __declspec(dllexport)
97 #else
98 #define LAMMP_API __declspec(dllimport)
99 #endif
100#else
101// Linux/macOS: GCC / Clang
102 #define LAMMP_API __attribute__((visibility("default")))
103#endif
104
105#if defined(USE_ASM)
106#if defined(__x86_64__) || defined(_M_X64)
107#else
108#error "USE_ASM is only supported on x86_64 platforms"
109#endif
110#endif
111
112typedef uint8_t mp_byte_t; // 字节类型 (8位无符号整数)
113typedef uint64_t mp_limb_t; // 基本运算单元(limb)类型 (64位无符号整数)
114typedef uint64_t mp_size_t; // 表示limb数量的无符号整数类型
115typedef int64_t mp_slimb_t; // 有符号limb类型 (64位有符号整数)
116typedef int64_t mp_ssize_t; // 表示limb数量的有符号整数类型
117typedef mp_limb_t* mp_ptr; // 指向limb类型的指针
118typedef const mp_limb_t* mp_srcptr; // 指向const limb类型的指针(源操作数指针)
119typedef size_t mp_bitcnt_t; // 表示bit数量的无符号整数类型
120
121#define LAMMP_MAX_ALIGN 16 // 最大对齐单位(字节)
122
123#define LIMB_BITS 64
124#define LIMB_BYTES 8
125#define LOG2_LIMB_BITS 6
126#define LIMB_MAX (~(mp_limb_t)0)
127#define LLIMB_BITS 32
128#define LLIMB_BYTES 4
129#define LLIMB_MASK ((mp_limb_t)0xffffffff)
130
131#if defined(LAMMP_WINDOWS) && (defined(__GNUC__) || defined(__clang__))
132 // MinGW on Windows: use native TLS section
133 #define LAMMP_THREAD_LOCAL __thread
134#elif defined(_MSC_VER)
135 #define LAMMP_THREAD_LOCAL __declspec(thread)
136#elif defined(__GNUC__) // Linux/macOS
137 #define LAMMP_THREAD_LOCAL __thread
138#else
139 #define LAMMP_THREAD_LOCAL _Thread_local
140#endif
141
142#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L
143 #define STATIC_ASSERT _Static_assert
144#elif defined(__cplusplus) && __cplusplus >= 201103L
145 #define STATIC_ASSERT static_assert
146#else
147 // C99/C89 fallback (no message)
148 #define STATIC_ASSERT(cond, msg) typedef char static_assert_##__LINE__[(cond) ? 1 : -1]
149#endif
150
151STATIC_ASSERT(sizeof(void*) == 8, "64-bit architecture required");
152
153#undef STATIC_ASSERT
154
155#ifdef __cplusplus
156 /* C++ */
157 #if __cplusplus >= 201103L
158 /* C++11 and higher */
159 #define LAMMP_NORETURN [[noreturn]]
160 #else
161 #if defined(__GNUC__) || defined(__clang__)
162 #define LAMMP_NORETURN __attribute__((noreturn))
163 #elif defined(_MSC_VER)
164 #define LAMMP_NORETURN __declspec(noreturn)
165 #else
166 #define LAMMP_NORETURN /* no definition */
167 #endif
168 #endif
169#else
170 /* C */
171 #if defined(__STDC_VERSION__)
172 #if __STDC_VERSION__ >= 202311L
173 /* C23 and higher */
174 #define LAMMP_NORETURN [[noreturn]]
175 #elif __STDC_VERSION__ >= 201112L
176 /* C11 / C17 */
177 #define LAMMP_NORETURN _Noreturn
178 #endif
179 #endif
180
181 /* fallback */
182 #ifndef LAMMP_NORETURN
183 #if defined(__GNUC__) || defined(__clang__)
184 #define LAMMP_NORETURN __attribute__((noreturn))
185 #elif defined(_MSC_VER)
186 #define LAMMP_NORETURN __declspec(noreturn)
187 #else
188 #define LAMMP_NORETURN /* no definition */
189 #endif
190 #endif
191#endif
192
193#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L
194 /* C23 std */
195 #define LAMMP_ASSUME(expr) do { [[assume(expr)]]; } while(0)
196#elif defined(__clang__)
197 /* Clang */
198 #define LAMMP_ASSUME(expr) __builtin_assume(expr)
199#elif defined(_MSC_VER)
200 /* MSVC */
201 #define LAMMP_ASSUME(expr) __assume(expr)
202#elif defined(__GNUC__)
203 /* GCC */
204 #if __GNUC__ >= 13
205 /* GCC 13+ */
206 #define LAMMP_ASSUME(expr) do { __attribute__((assume(expr))); } while(0)
207 #else
208 /* GCC 13 lower */
209 #define LAMMP_ASSUME(expr) do { if (!(expr)) __builtin_unreachable(); } while(0)
210 #endif
211#else
212 /* fallback noassume */
213 #define LAMMP_ASSUME(expr) ((void)(expr))
214#endif
215
216/*
217 LAMMP 内存分配函数指针类型:
218 1. heap_alloc : 堆内存分配器
219 2. heap_free : 堆内存释放器
220 3. realloc : 堆内存重新分配器
221
222 默认使用 malloc、free、realloc 实现。
223 如果你需要传入自定义的分配器,为了避免重复处理,且由于LAMMP内部几乎不直接
224 通过指定的指针来进行内存分配,所以为了避免不必要的错误处理,建议遵循一下的行为:
225 1. 传给free的指针应可以为NULL
226 2. malloc(size)可以假定size>0,若size为0,可以是未定义行为,可以直接中断。
227 3. realloc(p, size)可以假定size>0,若size为0,可以是未定义行为,可以直接中断。
228 4. realloc/malloc(p, size)若内存耗尽,或者无空闲块,可以返回NULL,代表分配失败。
229 */
230
231typedef void* (*lmmp_heap_alloc_fn)(size_t size);
232typedef void (*lmmp_heap_free_fn )(void* ptr);
233typedef void* (*lmmp_realloc_fn )(void* ptr, size_t size);
234
240
241/**
242 * @brief 设置 LAMMP 全局堆内存分配函数
243 * @param heap 新的堆内存分配器,可以为NULL,此时会直接返回,而不进行任何操作。
244 * @warning 由于所有共享内存都采用堆内存分配。因此,传入新的堆分配器将会首先调用
245 * lmmp_global_deinit 函数,释放所有共享内存,以保证老旧的堆资源被释放。
246 * 然后将会自动调用 lmmp_global_init 函数,重新分配所有线程局部内存。
247 * 同时,为保证内存不泄露,将会对堆计数器和栈顶以及缓冲池顶进行检查。
248 * 若此时堆栈分配计数器不为 0,或当前栈帧不在栈底,都会触发lmmp_abort函数,
249 * 并输出相应的错误信息。
250 * @note 堆分配器是线程局部的,因此,创建新线程时,如有需要,请自行设置新的堆分配器。
251 * 同时也请自行保证分配器和释放器相匹配。
252 */
254
255/**
256 * @brief LAMMP 全局栈释放函数(通常不需要手动调用)
257 * @warning 请注意调用此函数后,访问之前的分配的栈空间将会导致未定义行为。在定义了
258 * LAMMP_DEBUG_MEMORY_LEAK 宏时,会检查默认栈是否为空,
259 * 则会触发lmmp_abort函数。
260 * @note 如果此后再使用栈内存,请调用 lmmp_stack_init 函数,以重置栈空间。
261 * @return 返回0表示成功释放,返回-1表示已经释放(并非错误)。
262 */
264
265/**
266 * @brief LAMMP 全局栈初始化函数(通常不需要手动调用)
267 * @note 初始化默认栈,并分配大小为size的额外内存池。如果已经初始化,
268 * 则会直接返回-1,表示已经初始化(并非错误),且不进行任何其他操作。
269 * lmmp_global_init 函数会自动调用此函数,分配的额外缓冲池大小为 LAMMP_POOL_SIZE 的大小
270 * (默认为512kb),无需手动调用。
271 * 如果你想手动设置缓冲池的大小,可以先调用 lmmp_stack_deinit 函数,再调用此函数,将 POOL_SIZE
272 * 设置为你想要的值。同时你也可以禁用缓冲池(即size为0),此时不会分配额外缓冲池。
273 * @return 返回0表示成功初始化,返回-1表示已经初始化(并非错误)。
274 */
275LAMMP_API int lmmp_stack_init(size_t size);
276
287
288/**
289 * @brief LAMMP 全局退出函数指针类型
290 * @param type 退出类型(可以查看lmmp_abort函数对此参数的说明,这里不再重复)
291 * @param msg 退出信息,取决于type
292 * @param func 退出处的函数名
293 * @param line 退出处的行号
294 */
295typedef void (*lmmp_abort_fn)(lmmp_error_t type, const char* msg, const char* func, int line);
296
297/**
298 * @brief 设置 LAMMP 全局退出函数(所有线程均生效)
299 * @param func 退出函数指针,可以为NULL
300 * @warning 请注意,我们将不会对 func 的调用做任何保护,因此请不要在 func 里做任何危险的操作,
301 * 本库的开发者不对 func 函数的调用产生的影响做任何保证。
302 * @note 若 func 为 NULL,则代表使用默认的退出机制。lmmp_abort 函数被标记为无返回值,因此
303 * 设置的函数也应当无返回值,即使自定义的func函数真的会返回了,那么也将会调用 abort 函数中断程序。
304 * @return 返回之前的退出函数指针,若原指针为NULL,则返回NULL。
305 */
307
308/**
309 * @brief LAMMP 全局退出函数,内部错误或断言失败时调用,若设置了全局退出函数,则会调用该函数,否则会调用默认的退出函数。
310 * @param msg 退出信息,assert类型的错误信息通常仅包含断言内容,其他类型的错误则因类型不同而不同。
311 * @param func 退出处的函数名
312 * @param line 退出处的行号
313 * @param type 退出类型。有以下几个类型:
314 *
315 * 1. ASSERT_FAILURE (枚举值为1)为lmmp_assert触发的退出,lmmp_assert触发的普通退出几乎不可能发生,
316 * 其通常代表不可能发生的计算错误,可能表明程序执行此处时必须正确的输入错误。比如预期无进位的加法产生了进位。
317 * 此类错误不可接受,会导致计算无法继续进行,导致程序崩溃。
318 *
319 * 2. DEBUG_ASSERT_FAILURE (枚举值为2)为lmmp_debug_assert触发的退出。其通常表明预期之外的错误,
320 * 这通常是调用者的UB,如无UB的情况下触发此错误;也可能是LAMMP内部的逻辑错误,开发者期待的输入错误,
321 * 在该逻辑处仅简单考虑了某些情况。如有此类错误,可以报告给开发者。此类型只会在定义了
322 * LAMMP_DEBUG_ASSERT_CHECK 宏为 1 的情况下才会触发。
323 *
324 * 3. PARAM_ASSERT_FAILURE (枚举值为3)为参数检查失败导致的退出。其通常表明调用者传入了无效的参数,
325 * 导致函数的行为不符合预期。此类错误不可接受,会导致计算无法继续进行,导致程序崩溃。此类型的错误只有在
326 * 定义了 LAMMP_DEBUG_PARAM_ASSERT_CHECK 宏为 1 的情况下才会触发。
327 *
328 * 4. MEMORY_ALLOC_FAILURE (枚举值为4)为内存分配失败退出。在使用堆分配器时,申请内存失败,导致触发此错误。
329 * 此类型错误不受明确的宏调控,Realse模式下,会保留必要的触发场景,部分场景下,在一些检查宏定义时,可能会额外触发此错误。
330 *
331 * 5. MEMORY_FREE_FAILURE (枚举值为5)为内存释放错误。当释放堆内存时可能触发,原因通常为头部信息被损坏,极有可能
332 * 源于传入错误的指针,又或者缓冲区溢出导致此头部损坏。LAMMP_DEBUG_MEMORY_CHECK 宏为 1 时,才可能触发。
333 *
334 * 6. OUT_OF_BOUNDS (枚举值为6)为数组越界访问导致的退出。通常表明未按规定使用空间。此类型的错误在堆分配器中,当释放
335 * 堆内存时,检测到数组尾部魔数不匹配,导致此错误。LAMMP_DEBUG_MEMORY_CHECK 宏为 1 时,才可能触发。
336 *
337 * 7. MEMORY_LEAK (枚举值为7)为内存泄漏导致的退出。在检查点处,堆内存计数器不为0,或者当前栈帧不在栈底,又或者缓冲池
338 * 定不在缓冲池底,都会触发此错误。触发原因可能为,在调用堆分配器重置函数时,显式检查到此时的堆计数器不为0或者栈帧
339 * 以及缓冲池不为底部。又或者手动调用 lmmp_leak_tracker 宏来进行检查,检查到了相同的情况。需注意,手动调用此宏时,
340 * 请先调用 lmmp_global_deinit 进行全局共享的堆资源的安全释放(因为部分全局共享资源也会被计数)。
341 *
342 * 8. UNEXPECTED_ERROR (枚举值为8)为其他未知错误导致的退出。
343 *
344 * @warning LAMMP内部中断都将会调用此函数,如果全局退出函数为NULL,则使用默认的退出函数,会打印出全部错误信息,并调用
345 * abort 函数中断程序。自定义全局退出函数请通过 lmmp_set_abort_fn 函数进行设置。请不要在全局退出函数里做任
346 * 何危险的操作,本库的开发者不对其调用产生的影响做任何保证。
347 */
348LAMMP_NORETURN LAMMP_API void lmmp_abort(lmmp_error_t type, const char *msg, const char *func, int line);
349
350#if LAMMP_DEBUG_MEMORY_CHECK == 1
351LAMMP_API void* lmmp_alloc(size_t size, const char* func, int line);
352/**
353 * @brief 内存分配函数(调用lmmp_heap_alloc_fn)
354 * @param size 要分配的内存字节数
355 * @warning size>0
356 * @note 调用堆内存分配器,分配失败将触发 lmmp_abort
357 * @return 返回指向分配内存的指针(分配失败不会 return NULL,而是直接触发 lmmp_abort)
358 */
359#define lmmp_alloc(size) lmmp_alloc(size, __func__, __LINE__)
360#else
361/**
362 * @brief 内存分配函数(调用lmmp_heap_alloc_fn)
363 * @param size 要分配的内存字节数
364 * @warning size>0
365 * @note 调用堆内存分配器,分配失败将触发 lmmp_abort
366 * @return 返回指向分配内存的指针(分配失败不会 return NULL,而是直接触发 lmmp_abort)
367 */
368LAMMP_API void* lmmp_alloc(size_t size);
369#endif
370
371#if LAMMP_DEBUG_MEMORY_CHECK == 1
372LAMMP_API void* lmmp_realloc(void* ptr, size_t size, const char* func, int line);
373#define lmmp_realloc(ptr, size) lmmp_realloc(ptr, size, __func__, __LINE__)
374#else
375/**
376 * @brief 内存重分配函数(调用lmmp_realloc_fn)
377 * @param ptr 已分配的内存指针
378 * @param size 新的内存大小(字节)
379 * @warning size>0
380 * @note 调用堆内存重新分配器,分配失败将触发 lmmp_abort
381 * 在LAMMP_DEBUG_PARAM_ASSERT_CHECK宏为1时,重分配 0 字节将触发 lmmp_abort
382 * @return 成功返回指向新内存区域的指针(分配失败不会 return NULL,而是直接触发 lmmp_abort)
383 */
384LAMMP_API void* lmmp_realloc(void* ptr, size_t size);
385#endif
386
387#if LAMMP_DEBUG_MEMORY_CHECK == 1
388LAMMP_API void lmmp_free(void* ptr, const char* func, int line);
389/**
390 * @brief 内存释放函数(调用lmmp_heap_free_fn)
391 * @param ptr 要释放的内存指针
392 * @note ptr 可以为空指针
393 */
394#define lmmp_free(ptr) lmmp_free(ptr, __func__, __LINE__)
395#else
396/**
397 * @brief 内存释放函数(调用lmmp_heap_free_fn)
398 * @param ptr 要释放的内存指针
399 * @note ptr 可以为空指针
400 */
401LAMMP_API void lmmp_free(void* ptr);
402#endif
403
404/**
405 * @brief 堆内存分配计数器(线程局部)
406 * @param cnt 若不为0,则将堆内存计数器置为cnt
407 * @return 返回当前的heap分配计数(如果被设置,即返回旧的计数值),即目前未被释放的堆内存数量
408 */
410
411/**
412 * @brief 内存泄漏检测器
413 * @param func 泄漏发生的函数名
414 * @param line 泄漏发生的行号
415 * @warning 内存计数器均是线程局部的,仅会检测单线程的内存泄漏。
416 * @note 将会同时检验堆内存和栈内存,若堆内存计数器不为0,或栈内存的栈顶不在栈底,都会触发lmmp_abort
417 * 两者同时发生则将输出两者的信息。
418 */
419LAMMP_API void lmmp_leak_tracker(const char* func, int line);
420
421#if LAMMP_DEBUG_MEMORY_LEAK == 1
422// 同时检验堆内存和栈内存,若堆内存计数器不为0,或栈内存的栈顶不在栈底,都会触发lmmp_abort
423// 两者同时发生则将输出两者的信息。
424// 请注意,内存计数器均是线程局部的,仅会检测单线程的内存泄漏。
425#define lmmp_leak_tracker lmmp_leak_tracker(__func__, __LINE__)
426#else
427#define lmmp_leak_tracker ((void)0)
428#endif
429
430/**
431 * @brief 计算绝对值
432 */
433#define LMMP_ABS(x) ((x) >= 0 ? (x) : -(x))
434/**
435 * @brief 返回两个数中的较小值
436 */
437#define LMMP_MIN(l, o) ((l) < (o) ? (l) : (o))
438/**
439 * @brief 返回两个数中的较大值
440 */
441#define LMMP_MAX(h, i) ((h) > (i) ? (h) : (i))
442/**
443 * @brief 交换两个变量的值
444 */
445#define LMMP_SWAP(x, y, type) \
446 do { \
447 type _swap_ = (x); \
448 (x) = (y); \
449 (y) = _swap_; \
450 } while (0)
451/**
452 * @brief 检查n是否为2的幂次方
453 */
454#define LMMP_POW2_Q(n) (((n) & ((n) - 1)) == 0)
455/**
456 * @brief 将a向上取整到m的倍数
457 */
458#define LMMP_ROUND_UP_MULTIPLE(a, m) ((a) + (m) - 1 - ((a) + (m) - 1) % (m))
459
460// 内存拷贝宏:拷贝n个limb(每个8字节),使用memmove保证重叠安全
461#define lmmp_copy(dst, src, n) memmove((dst), (src), ((size_t)(n) << 3))
462// 内存置零宏:将n个limb置零(每个8字节)
463#define lmmp_zero(dst, n) memset((dst), 0, ((size_t)(n) << 3))
464
465// 断言宏:检查条件x是否成立,不成立则触发段错误(严格的错误检查)
466// RELEASE 版本也会检查
467// 不可使用有副作用的表达式
468#define lmmp_assert(x) \
469 do { \
470 if (!(x)) { \
471 lmmp_abort(LAMMP_ERROR_ASSERT_FAILURE, #x, __func__, __LINE__); \
472 } \
473 } while (0)
474
475#if LAMMP_DEBUG_ASSERT_CHECK == 1
476// 调试断言宏:检查条件x是否成立,不成立则触发段错误(调试版本)
477#define lmmp_debug_assert(x) \
478 do { \
479 if (!(x)) { \
480 lmmp_abort(LAMMP_ERROR_DEBUG_ASSERT_FAILURE, #x, __func__, __LINE__); \
481 } \
482 } while (0)
483#else
484// 调试断言宏:检查条件x是否成立,不成立则触发段错误(调试版本)
485#define lmmp_debug_assert(x) LAMMP_ASSUME(x)
486#endif
487
488#if LAMMP_DEBUG_PARAM_ASSERT_CHECK == 1
489#define lmmp_param_assert(x) \
490 do { \
491 if (!(x)) { \
492 lmmp_abort(LAMMP_ERROR_PARAM_ASSERT_FAILURE, #x, __func__, __LINE__); \
493 } \
494 } while (0)
495#else
496#define lmmp_param_assert(x) LAMMP_ASSUME(x)
497#endif
498
500
501/**
502 * @brief 全局初始化函数(线程局部的)
503 * @note 调用此函数将初始化全局范围内的所有线程局部资源,如栈式分配器等。
504 * 部分惰性初始化的资源将在首次使用时初始化。调用此函数不会进行初始化。
505 * 此函数多次调用不会导致重复初始化。
506 * @warning 我们建议在进程或线程启动时调用此函数,以保证线程安全。
507 */
508LAMMP_API void lmmp_global_init(void);
509
510/**
511 * @brief (线程局部的)全局共享的动态分配的堆内存资源释放函数
512 * @note 调用此函数将释放全局范围内的所有动态分配的堆内存资源。
513 * 此函数多次调用不会导致重复释放。如需要再次使用,请重新调用 lmmp_global_init 初始化。
514 * 部分惰性初始化的资源将在再次首次使用时再次初始化,调用此函数可能导致部分缓存失效,导致性能下降。
515 * @warning 我们建议在线程结束时或程序进程结束时调用此函数。多线程下,每个线程都会拥有独立的副本,
516 * 未调用此函数结束线程可能导致内存泄漏。
517 */
519
520#ifdef __cplusplus
521} // extern "C"
522#endif
523
524#endif // LAMMP_LMMP_H
void * lmmp_realloc(void *ptr, size_t size)
内存重分配函数(调用lmmp_realloc_fn)
Definition memory.c:399
mp_limb_t * mp_ptr
Definition lmmp.h:117
uint8_t mp_byte_t
Definition lmmp.h:112
void lmmp_set_heap_allocator(const lmmp_heap_allocator_t *heap)
设置 LAMMP 全局堆内存分配函数
Definition memory.c:94
void(* lmmp_heap_free_fn)(void *ptr)
Definition lmmp.h:232
#define LAMMP_NORETURN
Definition lmmp.h:188
lmmp_realloc_fn realloc
Definition lmmp.h:238
lmmp_heap_alloc_fn alloc
Definition lmmp.h:236
size_t mp_bitcnt_t
Definition lmmp.h:119
uint64_t mp_size_t
Definition lmmp.h:114
int64_t mp_slimb_t
Definition lmmp.h:115
void * lmmp_alloc(size_t size)
内存分配函数(调用lmmp_heap_alloc_fn)
Definition memory.c:376
const mp_limb_t * mp_srcptr
Definition lmmp.h:118
void *(* lmmp_realloc_fn)(void *ptr, size_t size)
Definition lmmp.h:233
lmmp_abort_fn lmmp_set_abort_fn(lmmp_abort_fn func)
设置 LAMMP 全局退出函数(所有线程均生效)
Definition abort.c:70
void lmmp_abort(lmmp_error_t type, const char *msg, const char *func, int line)
LAMMP 全局退出函数,内部错误或断言失败时调用,若设置了全局退出函数,则会调用该函数,否则会调用默认的退出函数。
Definition abort.c:102
int lmmp_stack_deinit(void)
LAMMP 全局栈释放函数(通常不需要手动调用)
Definition memory.c:51
#define STATIC_ASSERT(cond, msg)
Definition lmmp.h:148
int lmmp_stack_init(size_t size)
LAMMP 全局栈初始化函数(通常不需要手动调用)
Definition memory.c:69
void lmmp_free(void *ptr)
内存释放函数(调用lmmp_heap_free_fn)
Definition memory.c:423
lmmp_heap_free_fn free
Definition lmmp.h:237
void lmmp_fill(mp_ptr dst, mp_size_t begin, mp_size_t end, mp_limb_t val)
Copyright (C) 2026 HJimmyK(Jericho Knox)
Definition fill.c:19
int64_t mp_ssize_t
Definition lmmp.h:116
void lmmp_global_init(void)
全局初始化函数(线程局部的)
Definition memory.c:432
uint64_t mp_limb_t
Definition lmmp.h:113
void *(* lmmp_heap_alloc_fn)(size_t size)
Definition lmmp.h:231
void lmmp_global_deinit(void)
(线程局部的)全局共享的动态分配的堆内存资源释放函数
Definition memory.c:436
void(* lmmp_abort_fn)(lmmp_error_t type, const char *msg, const char *func, int line)
LAMMP 全局退出函数指针类型
Definition lmmp.h:295
lmmp_error_t
Definition lmmp.h:277
@ LAMMP_ERROR_MEMORY_ALLOC_FAILURE
Definition lmmp.h:281
@ LAMMP_ERROR_DEBUG_ASSERT_FAILURE
Definition lmmp.h:279
@ LAMMP_ERROR_UNEXPECTED_ERROR
Definition lmmp.h:285
@ LAMMP_ERROR_MEMORY_LEAK
Definition lmmp.h:284
@ LAMMP_ERROR_ASSERT_FAILURE
Definition lmmp.h:278
@ LAMMP_ERROR_PARAM_ASSERT_FAILURE
Definition lmmp.h:280
@ LAMMP_ERROR_MEMORY_FREE_FAILURE
Definition lmmp.h:282
@ LAMMP_ERROR_OUT_OF_BOUNDS
Definition lmmp.h:283
#define LAMMP_API
Definition lmmp.h:98
#define lmmp_leak_tracker
Definition lmmp.h:427
int lmmp_alloc_count(int cnt)
堆内存分配计数器(线程局部)
Definition memory.c:322
#define n