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#include <stddef.h>
20#include <stdint.h>
21#include <stdlib.h>
22#include <string.h>
23
24#ifdef __cplusplus
25extern "C" {
26#endif
27
28#if defined(DEBUG)
29
30/* LAMMP 调试宏,定义为1时,会开启相应的调试功能,共有四个开销等级:低、中、高、很高。 */
31
32// 开启时,将会检查栈溢出;开销:中
33#define LAMMP_DEBUG_STACK_OVERFLOW_CHECK 1
34// 开启时,将会开启debug_assert的检查;开销:低
35#define LAMMP_DEBUG_ASSERT_CHECK 1
36// 开启时,将会进行参数检查;开销:中
37#define LAMMP_DEBUG_PARAM_ASSERT_CHECK 1
38// 开启时,将会进行全面的堆栈内存检查,包括堆栈溢出、指针释放检查、缓冲区溢出检查;开销:很高
39#define LAMMP_DEBUG_MEMORY_CHECK 1
40// 堆栈溢出检查中额外分配的内存倍数,额外分配的内存空间=单次分配的内存空间*(MORE_ALLOC_TIMES/10)
41#define LAMMP_MEMORY_MORE_ALLOC_TIMES 1
42// 开启时,会增加内存分配和释放次数的统计功能;开销:中
43#define LAMMP_DEBUG_MEMORY_LEAK 1
44
45#else
46
47#define LAMMP_DEBUG_STACK_OVERFLOW_CHECK 0
48#define LAMMP_DEBUG_ASSERT_CHECK 0
49#define LAMMP_DEBUG_PARAM_ASSERT_CHECK 0
50#define LAMMP_DEBUG_MEMORY_CHECK 0
51#define LAMMP_MEMORY_MORE_ALLOC_TIMES 1
52#define LAMMP_DEBUG_MEMORY_LEAK 0
53
54#endif
55
56#if defined(LAMMP_WINDOWS)
57 // Windows: MSVC / MinGW / Clang
58 #ifdef LAMMP_CORE_EXPORTS
59 #define LAMMP_API __declspec(dllexport)
60 #else
61 #define LAMMP_API __declspec(dllimport)
62 #endif
63#else
64// Linux/macOS: GCC / Clang
65 #define LAMMP_API __attribute__((visibility("default")))
66#endif
67
68#if defined(USE_ASM)
69#if defined(__x86_64__) || defined(_M_X64)
70#else
71#error "USE_ASM is only supported on x86_64 platforms"
72#endif
73#endif
74
75typedef uint8_t mp_byte_t; // 字节类型 (8位无符号整数)
76typedef uint64_t mp_limb_t; // 基本运算单元(limb)类型 (64位无符号整数)
77typedef uint64_t mp_size_t; // 表示limb数量的无符号整数类型
78typedef int64_t mp_slimb_t; // 有符号limb类型 (64位有符号整数)
79typedef int64_t mp_ssize_t; // 表示limb数量的有符号整数类型
80typedef mp_limb_t* mp_ptr; // 指向limb类型的指针
81typedef const mp_limb_t* mp_srcptr; // 指向const limb类型的指针(源操作数指针)
82typedef size_t mp_bitcnt_t; // 表示bit数量的无符号整数类型
83
84#define LAMMP_MAX_ALIGN 16 // 最大对齐单位(字节)
85
86#define LIMB_BITS 64
87#define LIMB_BYTES 8
88#define LOG2_LIMB_BITS 6
89#define LIMB_MAX (~(mp_limb_t)0)
90#define LLIMB_BITS 32
91#define LLIMB_BYTES 4
92#define LLIMB_MASK ((mp_limb_t)0xffffffff)
93
94#if defined(LAMMP_WINDOWS) && (defined(__GNUC__) || defined(__clang__))
95 // MinGW on Windows: use native TLS section
96 #define LAMMP_THREAD_LOCAL __thread
97#elif defined(_MSC_VER)
98 #define LAMMP_THREAD_LOCAL __declspec(thread)
99#elif defined(__GNUC__) // Linux/macOS
100 #define LAMMP_THREAD_LOCAL __thread
101#else
102 #define LAMMP_THREAD_LOCAL _Thread_local
103#endif
104
105#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L
106 #define STATIC_ASSERT _Static_assert
107#elif defined(__cplusplus) && __cplusplus >= 201103L
108 #define STATIC_ASSERT static_assert
109#else
110 // C99/C89 fallback (no message)
111 #define STATIC_ASSERT(cond, msg) typedef char static_assert_##__LINE__[(cond) ? 1 : -1]
112#endif
113
114STATIC_ASSERT(sizeof(void*) == 8, "64-bit architecture required");
115
116#undef STATIC_ASSERT
117
118#ifdef __cplusplus
119 /* C++ */
120 #if __cplusplus >= 201103L
121 /* C++11 and higher */
122 #define LAMMP_NORETURN [[noreturn]]
123 #else
124 #if defined(__GNUC__) || defined(__clang__)
125 #define LAMMP_NORETURN __attribute__((noreturn))
126 #elif defined(_MSC_VER)
127 #define LAMMP_NORETURN __declspec(noreturn)
128 #else
129 #define LAMMP_NORETURN /* no definition */
130 #endif
131 #endif
132#else
133 /* C */
134 #if defined(__STDC_VERSION__)
135 #if __STDC_VERSION__ >= 202311L
136 /* C23 and higher */
137 #define LAMMP_NORETURN [[noreturn]]
138 #elif __STDC_VERSION__ >= 201112L
139 /* C11 / C17 */
140 #define LAMMP_NORETURN _Noreturn
141 #endif
142 #endif
143
144 /* fallback */
145 #ifndef LAMMP_NORETURN
146 #if defined(__GNUC__) || defined(__clang__)
147 #define LAMMP_NORETURN __attribute__((noreturn))
148 #elif defined(_MSC_VER)
149 #define LAMMP_NORETURN __declspec(noreturn)
150 #else
151 #define LAMMP_NORETURN /* no definition */
152 #endif
153 #endif
154#endif
155
156/*
157 LAMMP 内存分配函数指针类型:
158 1. heap_alloc : 堆内存分配器
159 2. heap_free : 堆内存释放器
160 3. realloc : 堆内存重新分配器
161
162 默认使用 malloc、free、realloc 实现。
163 */
164
165typedef void* (*lmmp_heap_alloc_fn)(size_t size);
166typedef void (*lmmp_heap_free_fn )(void* ptr);
167typedef void* (*lmmp_realloc_fn )(void* ptr, size_t size);
168
174
175/**
176 * @brief 设置 LAMMP 全局堆内存分配函数
177 * @param heap 新的堆内存分配器,可以为NULL,此时会直接返回,而不进行任何操作。
178 * @warning 由于所有共享内存都采用堆内存分配。因此,传入新的堆分配器将会首先调用
179 * lmmp_global_deinit 函数,释放所有共享内存,以保证老旧的堆资源被释放。
180 * 然后将会自动调用 lmmp_global_init 函数,重新分配所有线程局部内存。
181 * 同时,为保证内存不泄露,将会对堆计数器和栈顶以及缓冲池顶进行检查。
182 * 若此时堆栈分配计数器不为 0,或当前栈帧不在栈底,都会触发lmmp_abort函数,
183 * 并输出相应的错误信息。
184 * @note 堆分配器是线程局部的,因此,创建新线程时,如有需要,请自行设置新的堆分配器。
185 * 同时也请自行保证分配器和释放器相匹配。
186 */
188
189/**
190 * @brief LAMMP 全局栈释放函数(通常不需要手动调用)
191 * @warning 请注意调用此函数后,访问之前的分配的栈空间将会导致未定义行为。在定义了
192 * LAMMP_DEBUG_MEMORY_LEAK 宏时,会检查默认栈是否为空,
193 * 则会触发lmmp_abort函数。
194 * @note 如果此后再使用栈内存,请调用 lmmp_stack_init 函数,以重置栈空间。
195 * @return 返回0表示成功释放,返回-1表示已经释放(并非错误)。
196 */
198
199/**
200 * @brief LAMMP 全局栈初始化函数(通常不需要手动调用)
201 * @note 初始化默认栈,并分配大小为size的额外内存池。如果已经初始化,
202 * 则会直接返回-1,表示已经初始化(并非错误),且不进行任何其他操作。
203 * lmmp_global_init 函数会自动调用此函数,分配的额外缓冲池大小为 LAMMP_POOL_SIZE 的大小
204 * (默认为512kb),无需手动调用。
205 * 如果你想手动设置缓冲池的大小,可以先调用 lmmp_stack_deinit 函数,再调用此函数,将 POOL_SIZE
206 * 设置为你想要的值。同时你也可以禁用缓冲池(即size为0),此时不会分配额外缓冲池。
207 * @return 返回0表示成功初始化,返回-1表示已经初始化(并非错误)。
208 */
209LAMMP_API int lmmp_stack_init(size_t size);
210
221
222/**
223 * @brief LAMMP 全局退出函数指针类型
224 * @param type 退出类型(可以查看lmmp_abort函数对此参数的说明,这里不再重复)
225 * @param msg 退出信息,取决于type
226 * @param func 退出处的函数名
227 * @param line 退出处的行号
228 */
229typedef void (*lmmp_abort_fn)(lmmp_error_t type, const char* msg, const char* func, int line);
230
231/**
232 * @brief 设置 LAMMP 全局退出函数(所有线程均生效)
233 * @param func 退出函数指针,可以为NULL
234 * @warning 请注意,我们将不会对 func 的调用做任何保护,因此请不要在 func 里做任何危险的操作,
235 * 本库的开发者不对 func 函数的调用产生的影响做任何保证。
236 * @note 若 func 为 NULL,则代表使用默认的退出机制。lmmp_abort 函数被标记为无返回值,因此
237 * 设置的函数也应当无返回值,即使自定义的func函数真的会返回了,那么也将会调用 abort 函数中断程序。
238 * @return 返回之前的退出函数指针,若原指针为NULL,则返回NULL。
239 */
241
242/**
243 * @brief LAMMP 全局退出函数,内部错误或断言失败时调用,若设置了全局退出函数,则会调用该函数,否则会调用默认的退出函数。
244 * @param msg 退出信息,assert类型的错误信息通常仅包含断言内容,其他类型的错误则因类型不同而不同。
245 * @param func 退出处的函数名
246 * @param line 退出处的行号
247 * @param type 退出类型。有以下几个类型:
248 *
249 * 1. ASSERT_FAILURE (枚举值为1)为lmmp_assert触发的退出,lmmp_assert触发的普通退出几乎不可能发生,
250 * 其通常代表不可能发生的计算错误,可能表明程序执行此处时必须正确的输入错误。比如预期无进位的加法产生了进位。
251 * 此类错误不可接受,会导致计算无法继续进行,导致程序崩溃。
252 *
253 * 2. DEBUG_ASSERT_FAILURE (枚举值为2)为lmmp_debug_assert触发的退出。其通常表明预期之外的错误,
254 * 这通常是调用者的UB,如无UB的情况下触发此错误;也可能是LAMMP内部的逻辑错误,开发者期待的输入错误,
255 * 在该逻辑处仅简单考虑了某些情况。如有此类错误,可以报告给开发者。此类型只会在定义了
256 * LAMMP_DEBUG_ASSERT_CHECK 宏为 1 的情况下才会触发。
257 *
258 * 3. PARAM_ASSERT_FAILURE (枚举值为3)为参数检查失败导致的退出。其通常表明调用者传入了无效的参数,
259 * 导致函数的行为不符合预期。此类错误不可接受,会导致计算无法继续进行,导致程序崩溃。此类型的错误只有在
260 * 定义了 LAMMP_DEBUG_PARAM_ASSERT_CHECK 宏为 1 的情况下才会触发。
261 *
262 * 4. MEMORY_ALLOC_FAILURE (枚举值为4)为内存分配失败退出。在使用堆分配器时,申请内存失败,导致触发此错误。
263 * 此类型错误不受明确的宏调控,Realse模式下,会保留必要的触发场景,部分场景下,在一些检查宏定义时,可能会额外触发此错误。
264 *
265 * 5. MEMORY_FREE_FAILURE (枚举值为5)为内存释放错误。当释放堆内存时可能触发,原因通常为头部信息被损坏,极有可能
266 * 源于传入错误的指针,又或者缓冲区溢出导致此头部损坏。LAMMP_DEBUG_MEMORY_CHECK 宏为 1 时,才可能触发。
267 *
268 * 6. OUT_OF_BOUNDS (枚举值为6)为数组越界访问导致的退出。通常表明未按规定使用空间。此类型的错误在堆分配器中,当释放
269 * 堆内存时,检测到数组尾部魔数不匹配,导致此错误。LAMMP_DEBUG_MEMORY_CHECK 宏为 1 时,才可能触发。
270 *
271 * 7. MEMORY_LEAK (枚举值为7)为内存泄漏导致的退出。在检查点处,堆内存计数器不为0,或者当前栈帧不在栈底,又或者缓冲池
272 * 定不在缓冲池底,都会触发此错误。触发原因可能为,在调用堆分配器重置函数时,显式检查到此时的堆计数器不为0或者栈帧
273 * 以及缓冲池不为底部。又或者手动调用 lmmp_leak_tracker 宏来进行检查,检查到了相同的情况。需注意,手动调用此宏时,
274 * 请先调用 lmmp_global_deinit 进行全局共享的堆资源的安全释放(因为部分全局共享资源也会被计数)。
275 *
276 * 8. UNEXPECTED_ERROR (枚举值为8)为其他未知错误导致的退出。
277 *
278 * @warning LAMMP内部中断都将会调用此函数,如果全局退出函数为NULL,则使用默认的退出函数,会打印出全部错误信息,并调用
279 * abort 函数中断程序。自定义全局退出函数请通过 lmmp_set_abort_fn 函数进行设置。请不要在全局退出函数里做任
280 * 何危险的操作,本库的开发者不对其调用产生的影响做任何保证。
281 */
282LAMMP_NORETURN LAMMP_API void lmmp_abort(lmmp_error_t type, const char *msg, const char *func, int line);
283
284#if LAMMP_DEBUG_MEMORY_CHECK == 1
285LAMMP_API void* lmmp_alloc(size_t size, const char* func, int line);
286#define lmmp_alloc(size) lmmp_alloc(size, __func__, __LINE__)
287#else
288/**
289 * @brief 内存分配函数(调用lmmp_heap_alloc_fn)
290 * @param size 要分配的内存字节数
291 * @note 调用堆内存分配器,分配失败将触发 lmmp_abort
292 * @return 返回指向分配内存的指针(分配失败不会 return NULL,而是直接触发 lmmp_abort)
293 */
294LAMMP_API void* lmmp_alloc(size_t size);
295#endif
296
297#if LAMMP_DEBUG_MEMORY_CHECK == 1
298LAMMP_API void* lmmp_realloc(void* ptr, size_t size, const char* func, int line);
299#define lmmp_realloc(ptr, size) lmmp_realloc(ptr, size, __func__, __LINE__)
300#else
301/**
302 * @brief 内存重分配函数(调用lmmp_realloc_fn)
303 * @param ptr 已分配的内存指针
304 * @param size 新的内存大小(字节)
305 * @note 调用堆内存重新分配器,分配失败将触发 lmmp_abort
306 * @return 成功返回指向新内存区域的指针(分配失败不会 return NULL,而是直接触发 lmmp_abort)
307 */
308LAMMP_API void* lmmp_realloc(void* ptr, size_t size);
309#endif
310
311#if LAMMP_DEBUG_MEMORY_CHECK == 1
312LAMMP_API void lmmp_free(void* ptr, const char* func, int line);
313#define lmmp_free(ptr) lmmp_free(ptr, __func__, __LINE__)
314#else
315/**
316 * @brief 内存释放函数(调用lmmp_heap_free_fn)
317 * @param ptr 要释放的内存指针
318 */
319LAMMP_API void lmmp_free(void* ptr);
320#endif
321
322/**
323 * @brief 堆内存分配计数器(线程局部)
324 * @param cnt 若不为0,则将堆内存计数器置为cnt
325 * @return 返回当前的heap分配计数(如果被设置,即返回旧的计数值),即目前未被释放的堆内存数量
326 */
328
329/**
330 * @brief 内存泄漏检测器
331 * @param func 泄漏发生的函数名
332 * @param line 泄漏发生的行号
333 * @warning 内存计数器均是线程局部的,仅会检测单线程的内存泄漏。
334 * @note 将会同时检验堆内存和栈内存,若堆内存计数器不为0,或栈内存的栈顶不在栈底,都会触发lmmp_abort
335 * 两者同时发生则将输出两者的信息。
336 */
337LAMMP_API void lmmp_leak_tracker(const char* func, int line);
338
339#if LAMMP_DEBUG_MEMORY_LEAK == 1
340// 同时检验堆内存和栈内存,若堆内存计数器不为0,或栈内存的栈顶不在栈底,都会触发lmmp_abort
341// 两者同时发生则将输出两者的信息。
342// 请注意,内存计数器均是线程局部的,仅会检测单线程的内存泄漏。
343#define lmmp_leak_tracker lmmp_leak_tracker(__func__, __LINE__)
344#else
345#define lmmp_leak_tracker ((void)0)
346#endif
347
348// 计算整数的绝对值
349#define LMMP_ABS(x) ((x) >= 0 ? (x) : -(x))
350// 返回两个数中的较小值
351#define LMMP_MIN(l, o) ((l) < (o) ? (l) : (o))
352// 返回两个数中的较大值
353#define LMMP_MAX(h, i) ((h) > (i) ? (h) : (i))
354// 交换两个同类型变量的值
355#define LMMP_SWAP(x, y, type) \
356 do { \
357 type _swap_ = (x); \
358 (x) = (y); \
359 (y) = _swap_; \
360 } while (0)
361// 检查n是否为2的整数次幂
362#define LMMP_POW2_Q(n) (((n) & ((n) - 1)) == 0)
363// 将a向上取整为m的整数倍
364#define LMMP_ROUND_UP_MULTIPLE(a, m) ((a) + (m) - 1 - ((a) + (m) - 1) % (m))
365
366// 内存拷贝宏:拷贝n个limb(每个8字节),使用memmove保证重叠安全
367#define lmmp_copy(dst, src, n) memmove((dst), (src), ((size_t)(n) << 3))
368// 内存置零宏:将n个limb置零(每个8字节)
369#define lmmp_zero(dst, n) memset((dst), 0, ((size_t)(n) << 3))
370
371// 断言宏:检查条件x是否成立,不成立则触发段错误(严格的错误检查)
372// RELEASE 版本也会检查
373#define lmmp_assert(x) \
374 do { \
375 if (!(x)) { \
376 lmmp_abort(LAMMP_ERROR_ASSERT_FAILURE, #x, __func__, __LINE__); \
377 } \
378 } while (0)
379
380#if LAMMP_DEBUG_ASSERT_CHECK == 1
381// 调试断言宏:检查条件x是否成立,不成立则触发段错误(调试版本)
382#define lmmp_debug_assert(x) \
383 do { \
384 if (!(x)) { \
385 lmmp_abort(LAMMP_ERROR_DEBUG_ASSERT_FAILURE, #x, __func__, __LINE__); \
386 } \
387 } while (0)
388#else
389// 调试断言宏:检查条件x是否成立,不成立则触发段错误(调试版本)
390#define lmmp_debug_assert(x) ((void)0)
391#endif
392
393#if LAMMP_DEBUG_PARAM_ASSERT_CHECK == 1
394#define lmmp_param_assert(x) \
395 do { \
396 if (!(x)) { \
397 lmmp_abort(LAMMP_ERROR_PARAM_ASSERT_FAILURE, #x, __func__, __LINE__); \
398 } \
399 } while (0)
400#else
401#define lmmp_param_assert(x) ((void)0)
402#endif
403
404/**
405 * @brief 全局初始化函数(线程局部的)
406 * @note 调用此函数将初始化全局范围内的所有线程局部资源,如栈式分配器等。
407 * 部分惰性初始化的资源将在首次使用时初始化。调用此函数不会进行初始化。
408 * 此函数可重入,多次调用不会导致重复初始化。
409 * @warning 我们建议在进程或线程启动时调用此函数,以保证线程安全。
410 */
411LAMMP_API void lmmp_global_init(void);
412
413/**
414 * @brief (线程局部的)全局共享的动态分配的堆内存资源释放函数
415 * @note 调用此函数将释放全局范围内的所有动态分配的堆内存资源。
416 * 此函数可重入,多次调用不会导致重复释放。如需要再次使用,请重新调用 lmmp_global_init 初始化。
417 * 部分惰性初始化的资源将在再次首次使用时再次初始化,调用此函数可能导致部分缓存失效,导致性能下降。
418 * @warning 我们建议在线程结束时或程序进程结束时调用此函数。多线程下,每个线程都会拥有独立的副本,
419 * 未调用此函数结束线程可能导致内存泄漏。
420 */
422
423#ifdef __cplusplus
424} // extern "C"
425#endif
426
427#endif // LAMMP_LMMP_H
void * lmmp_realloc(void *ptr, size_t size)
内存重分配函数(调用lmmp_realloc_fn)
Definition memory.c:184
mp_limb_t * mp_ptr
Definition lmmp.h:80
uint8_t mp_byte_t
Definition lmmp.h:75
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:166
#define LAMMP_NORETURN
Definition lmmp.h:151
lmmp_realloc_fn realloc
Definition lmmp.h:172
lmmp_heap_alloc_fn alloc
Definition lmmp.h:170
size_t mp_bitcnt_t
Definition lmmp.h:82
uint64_t mp_size_t
Definition lmmp.h:77
int64_t mp_slimb_t
Definition lmmp.h:78
void * lmmp_alloc(size_t size)
内存分配函数(调用lmmp_heap_alloc_fn)
Definition memory.c:164
const mp_limb_t * mp_srcptr
Definition lmmp.h:81
void *(* lmmp_realloc_fn)(void *ptr, size_t size)
Definition lmmp.h:167
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:111
int lmmp_stack_init(size_t size)
LAMMP 全局栈初始化函数(通常不需要手动调用)
Definition memory.c:69
void lmmp_free(void *ptr)
内存释放函数(调用lmmp_heap_free_fn)
Definition memory.c:202
lmmp_heap_free_fn free
Definition lmmp.h:171
int64_t mp_ssize_t
Definition lmmp.h:79
void lmmp_global_init(void)
全局初始化函数(线程局部的)
Definition memory.c:212
uint64_t mp_limb_t
Definition lmmp.h:76
void *(* lmmp_heap_alloc_fn)(size_t size)
Definition lmmp.h:165
void lmmp_global_deinit(void)
(线程局部的)全局共享的动态分配的堆内存资源释放函数
Definition memory.c:216
void(* lmmp_abort_fn)(lmmp_error_t type, const char *msg, const char *func, int line)
LAMMP 全局退出函数指针类型
Definition lmmp.h:229
lmmp_error_t
Definition lmmp.h:211
@ LAMMP_ERROR_MEMORY_ALLOC_FAILURE
Definition lmmp.h:215
@ LAMMP_ERROR_DEBUG_ASSERT_FAILURE
Definition lmmp.h:213
@ LAMMP_ERROR_UNEXPECTED_ERROR
Definition lmmp.h:219
@ LAMMP_ERROR_MEMORY_LEAK
Definition lmmp.h:218
@ LAMMP_ERROR_ASSERT_FAILURE
Definition lmmp.h:212
@ LAMMP_ERROR_PARAM_ASSERT_FAILURE
Definition lmmp.h:214
@ LAMMP_ERROR_MEMORY_FREE_FAILURE
Definition lmmp.h:216
@ LAMMP_ERROR_OUT_OF_BOUNDS
Definition lmmp.h:217
#define LAMMP_API
Definition lmmp.h:61
#define lmmp_leak_tracker
Definition lmmp.h:345
int lmmp_alloc_count(int cnt)
堆内存分配计数器(线程局部)
Definition memory.c:113
#define n