LAMMP 4.1.0
Lamina High-Precision Arithmetic Library
载入中...
搜索中...
未找到
memory.c 文件参考
+ memory.c 的引用(Include)关系图:

浏览源代码.

宏定义

#define heap_alloc_func   global_heap.alloc
 
#define heap_free_func   global_heap.free
 
#define HSIZE   sizeof(void*)
 
#define realloc_func   global_heap.realloc
 
#define SIZE_SIZE   LMMP_ROUND_UP_MULTIPLE(sizeof(size_t), LAMMP_MAX_ALIGN)
 
#define stack_get_top_func()   (lmmp_stack_top)
 
#define stack_set_top_func(top)   (lmmp_stack_top = top)
 

函数

void * lmmp_alloc (size_t size)
 内存分配函数(调用lmmp_heap_alloc_fn)
 
int lmmp_alloc_count (int cnt)
 堆内存分配计数器(线程局部)
 
static void lmmp_chech_memory (size_t size, const char *func, int line)
 
void lmmp_free (void *ptr)
 内存释放函数(调用lmmp_heap_free_fn)
 
void lmmp_global_deinit (void)
 (线程局部的)全局共享的动态分配的堆内存资源释放函数
 
void lmmp_global_init (void)
 全局初始化函数(线程局部的)
 
void lmmp_leak_tracker (const char *func, int line)
 内存泄漏检测器
 
void * lmmp_realloc (void *oldptr, size_t new_size)
 内存重分配函数(调用lmmp_realloc_fn)
 
void lmmp_set_heap_allocator (const lmmp_heap_allocator_t *heap)
 设置 LAMMP 全局堆内存分配函数
 
void * lmmp_stack_alloc (size_t size)
 栈内存分配函数(使用stack_get_top和stack_set_top)
 
void lmmp_stack_free (void *ptr)
 栈内存释放函数(使用stack_get_top和stack_set_top)
 
void lmmp_stack_init (void)
 LAMMP 全局栈初始化函数(通常不需要手动调用)
 
void lmmp_stack_reset (size_t size)
 LAMMP 全局栈重置函数(通常不需要手动调用)
 
void * lmmp_temp_heap_alloc_ (void **pmarker, size_t size)
 临时堆内存分配函数
 
void lmmp_temp_heap_free_ (void *marker)
 临时堆内存释放函数
 

变量

static _Thread_local lmmp_heap_allocator_t global_heap
 
static _Thread_local int heap_alloc_count = 0
 
_Thread_local void * lmmp_stack_begin = NULL
 
_Thread_local void * lmmp_stack_end = NULL
 
_Thread_local void * lmmp_stack_top = NULL
 

宏定义说明

◆ heap_alloc_func

#define heap_alloc_func   global_heap.alloc

在文件 memory.c26 行定义.

◆ heap_free_func

#define heap_free_func   global_heap.free

在文件 memory.c27 行定义.

◆ HSIZE

#define HSIZE   sizeof(void*)

在文件 memory.c18 行定义.

◆ realloc_func

#define realloc_func   global_heap.realloc

在文件 memory.c28 行定义.

◆ SIZE_SIZE

#define SIZE_SIZE   LMMP_ROUND_UP_MULTIPLE(sizeof(size_t), LAMMP_MAX_ALIGN)

在文件 memory.c216 行定义.

◆ stack_get_top_func

#define stack_get_top_func ( )    (lmmp_stack_top)

在文件 memory.c36 行定义.

◆ stack_set_top_func

#define stack_set_top_func (   top)    (lmmp_stack_top = top)

在文件 memory.c37 行定义.

函数说明

◆ lmmp_alloc()

void * lmmp_alloc ( size_t  size)

内存分配函数(调用lmmp_heap_alloc_fn)

参数
size要分配的内存字节数
注解
调用堆内存分配器,分配失败将触发 lmmp_abort
返回
返回指向分配内存的指针(分配失败不会 return NULL,而是直接触发 lmmp_abort)

在文件 memory.c166 行定义.

166 {
167 if (size) {
168 void* ret = heap_alloc_func(size);
169 if (ret == NULL)
170 lmmp_chech_memory(size, __func__, __LINE__);
171#if LAMMP_DEBUG_MEMORY_LEAK == 1
173#endif
174 return ret;
175 }
176 return NULL;
177}
#define heap_alloc_func
Definition memory.c:26
static _Thread_local int heap_alloc_count
Definition memory.c:30
static void lmmp_chech_memory(size_t size, const char *func, int line)
Definition memory.c:117

引用了 heap_alloc_count, heap_alloc_func , 以及 lmmp_chech_memory().

被这些函数引用 lmmp_fft_memstack_() , 以及 lmmp_strong_rng_init_().

+ 函数调用图:
+ 这是这个函数的调用关系图:

◆ lmmp_alloc_count()

int lmmp_alloc_count ( int  cnt)

堆内存分配计数器(线程局部)

参数
cnt若不为0,则将堆内存计数器置为cnt
返回
返回当前的heap分配计数(如果被设置,即返回旧的计数值),即目前未被释放的堆内存数量

在文件 memory.c123 行定义.

123 {
124 if (cnt != 0) {
125 int new_cnt = cnt;
126 cnt = heap_alloc_count;
127 heap_alloc_count = new_cnt;
128 return cnt;
129 }
130 return heap_alloc_count;
131}

引用了 heap_alloc_count.

◆ lmmp_chech_memory()

static void lmmp_chech_memory ( size_t  size,
const char *  func,
int  line 
)
inlinestatic

在文件 memory.c117 行定义.

117 {
118 char msg[64];
119 snprintf(msg, sizeof(msg), "Memory allocation failed (size: %zu bytes)", size);
121}
void lmmp_abort(lmmp_error_t type, const char *msg, const char *func, int line)
LAMMP 全局退出函数,内部错误或断言失败时调用,若设置了全局退出函数,则会调用该函数,否则会调用默认的退出函数。
Definition abort.c:42
@ LAMMP_ERROR_MEMORY_ALLOC_FAILURE
Definition lmmp.h:136

引用了 LAMMP_ERROR_MEMORY_ALLOC_FAILURE , 以及 lmmp_abort().

被这些函数引用 lmmp_alloc() , 以及 lmmp_realloc().

+ 函数调用图:
+ 这是这个函数的调用关系图:

◆ lmmp_free()

void lmmp_free ( void *  ptr)

内存释放函数(调用lmmp_heap_free_fn)

参数
ptr要释放的内存指针

在文件 memory.c204 行定义.

204 {
205 if (ptr) {
206 heap_free_func(ptr);
207#if LAMMP_DEBUG_MEMORY_LEAK == 1
209#endif
210 }
211}
#define heap_free_func
Definition memory.c:27

引用了 heap_alloc_count , 以及 heap_free_func.

被这些函数引用 lmmp_fft_memstack_(), lmmp_limb_elem_mul_(), lmmp_mul_fft_(), lmmp_mul_fft_cache_(), lmmp_mul_fft_unbalance_(), lmmp_mullo_fft_(), lmmp_num_heap_free_(), lmmp_num_heap_mul_(), lmmp_prime_cache_free_(), lmmp_prime_int_table_free_(), lmmp_strong_rng_free_(), lmmp_trialdiv_short_() , 以及 lmmp_vec_elem_mul_().

+ 这是这个函数的调用关系图:

◆ lmmp_global_deinit()

void lmmp_global_deinit ( void  )

(线程局部的)全局共享的动态分配的堆内存资源释放函数

注解
调用此函数将释放全局范围内的所有动态分配的堆内存资源。 此函数可重入,多次调用不会导致重复释放。如需要再次使用,请重新调用 lmmp_global_init 初始化。 部分惰性初始化的资源将在再次首次使用时再次初始化,调用此函数可能导致部分缓存失效,导致性能下降。
警告
我们建议在线程结束时或程序进程结束时调用此函数。多线程下,每个线程都会拥有独立的副本, 未调用此函数结束线程可能导致内存泄漏。

在文件 memory.c406 行定义.

406 {
409}
void lmmp_stack_reset(size_t size)
LAMMP 全局栈重置函数(通常不需要手动调用)
Definition memory.c:39
void lmmp_prime_int_table_free_(void)
释放全局素数表

引用了 lmmp_prime_int_table_free_() , 以及 lmmp_stack_reset().

被这些函数引用 lmmp_set_heap_allocator().

+ 函数调用图:
+ 这是这个函数的调用关系图:

◆ lmmp_global_init()

void lmmp_global_init ( void  )

全局初始化函数(线程局部的)

注解
调用此函数将初始化全局范围内的所有线程局部资源,如栈式分配器等。 部分惰性初始化的资源将在首次使用时初始化。调用此函数不会进行初始化。 此函数可重入,多次调用不会导致重复初始化。
警告
我们建议在进程或线程启动时调用此函数,以保证线程安全。

在文件 memory.c402 行定义.

402 {
404}
void lmmp_stack_init(void)
LAMMP 全局栈初始化函数(通常不需要手动调用)
Definition memory.c:66

引用了 lmmp_stack_init().

被这些函数引用 lmmp_set_heap_allocator().

+ 函数调用图:
+ 这是这个函数的调用关系图:

◆ lmmp_leak_tracker()

void lmmp_leak_tracker ( const char *  func,
int  line 
)

内存泄漏检测器

参数
func泄漏发生的函数名
line泄漏发生的行号
警告
内存计数器均是线程局部的,仅会检测单线程的内存泄漏。
注解
将会同时检验堆内存和栈内存,若堆内存计数器不为0,或栈内存的栈顶不在栈底,都会触发lmmp_abort 两者同时发生则将输出两者的信息。

在文件 memory.c133 行定义.

133 {
134 char msg[192] = {0};
135 int offset = 0;
136 const int max_len = sizeof(msg) - 1;
137 int t = 0;
138 if (heap_alloc_count != 0) {
139 offset +=
140 snprintf(msg + offset, max_len - offset, "Heap allocations not freed: %d block(s)\n", heap_alloc_count);
141 t = 1;
142 }
144 offset += snprintf(msg + offset, max_len - offset,
145 "Default stack allocator is not empty. top: %p, begin: %p, end: %p\n",
147 t = 1;
148 }
149 if (t) {
150 lmmp_abort(LAMMP_ERROR_MEMORY_LEAK, msg, func, line);
151 }
152}
@ LAMMP_ERROR_MEMORY_LEAK
Definition lmmp.h:139
_Thread_local void * lmmp_stack_begin
Definition memory.c:32
_Thread_local void * lmmp_stack_top
Definition memory.c:34
_Thread_local void * lmmp_stack_end
Definition memory.c:33

引用了 heap_alloc_count, LAMMP_ERROR_MEMORY_LEAK, lmmp_abort(), lmmp_stack_begin, lmmp_stack_end , 以及 lmmp_stack_top.

+ 函数调用图:

◆ lmmp_realloc()

void * lmmp_realloc ( void *  ptr,
size_t  size 
)

内存重分配函数(调用lmmp_realloc_fn)

参数
ptr已分配的内存指针
size新的内存大小(字节)
注解
调用堆内存重新分配器,分配失败将触发 lmmp_abort
返回
成功返回指向新内存区域的指针(分配失败不会 return NULL,而是直接触发 lmmp_abort)

在文件 memory.c186 行定义.

186 {
187 void* ret = realloc_func(oldptr, new_size);
188 if (ret == NULL)
189 lmmp_chech_memory(new_size, __func__, __LINE__);
190 return ret;
191}
#define realloc_func
Definition memory.c:28

引用了 lmmp_chech_memory() , 以及 realloc_func.

被这些函数引用 lmmp_strong_rng_extern_().

+ 函数调用图:
+ 这是这个函数的调用关系图:

◆ lmmp_set_heap_allocator()

void lmmp_set_heap_allocator ( const lmmp_heap_allocator_t heap)

设置 LAMMP 全局堆内存分配函数

参数
heap新的堆内存分配器,可以为NULL,表示使用默认的 malloc, free, realloc
警告
由于所有共享内存都采用堆内存分配。因此,传入新的堆分配器将会首先调用 lmmp_global_deinit 函数,释放所有共享内存,以保证老旧的堆资源被释放。 然后将会自动调用 lmmp_global_init 函数,重新分配所有线程局部内存。 同时,为保证内存不泄露,在开启 LAMMP_DEBUG_MEMORY_LEAK 宏时,将会对堆 栈分配器进行检查。若此时堆栈分配计数器不为 0,则会触发lmmp_abort函数, 并输出相应的错误信息。
注解
堆分配器是线程局部的,因此,创建新线程时,如有需要,请自行设置新的堆分配器。 同时也请自行保证分配器和释放器相匹配。

在文件 memory.c76 行定义.

76 {
77 if (heap == NULL)
78 return;
80#if LAMMP_DEBUG_MEMORY_LEAK == 1
81 if (heap_alloc_count != 0) {
82 char msg[64];
83 snprintf(msg, sizeof(msg), "Older heap allocations not freed: %d block(s)", heap_alloc_count);
84 lmmp_abort(LAMMP_ERROR_MEMORY_LEAK, msg, __func__, __LINE__);
85 }
86#endif
87 global_heap = *heap;
89}
void lmmp_global_init(void)
全局初始化函数(线程局部的)
Definition memory.c:402
void lmmp_global_deinit(void)
(线程局部的)全局共享的动态分配的堆内存资源释放函数
Definition memory.c:406
static _Thread_local lmmp_heap_allocator_t global_heap
Definition memory.c:20

引用了 global_heap, heap_alloc_count, LAMMP_ERROR_MEMORY_LEAK, lmmp_abort(), lmmp_global_deinit() , 以及 lmmp_global_init().

+ 函数调用图:

◆ lmmp_stack_alloc()

void * lmmp_stack_alloc ( size_t  size)

栈内存分配函数(使用stack_get_top和stack_set_top)

参数
size要分配的内存字节数
警告
请严格按照分配顺序的逆序释放内存,否则会导致未定义行为或导致栈溢出触发lmmp_abort 且严禁用于分配持久内存,如全局变量等。
返回
成功返回指向分配内存的指针,栈溢出时,会触发lmmp_abort

在文件 memory.c218 行定义.

218 {
219 if (size == 0) {
220 return NULL;
221 }
222 size_t total_size = SIZE_SIZE + LMMP_ROUND_UP_MULTIPLE(size, LAMMP_MAX_ALIGN);
223 void* old_top = stack_get_top_func();
224 void* new_top = (mp_byte_t*)old_top + total_size;
225#if LAMMP_DEBUG_STACK_OVERFLOW_CHECK == 1
226 if (new_top > lmmp_stack_end) {
227 char msg[128];
228 snprintf(msg, sizeof(msg), "Stack overflow (trying to allocate: %zu bytes, stack remaining: %zu bytes)",
229 total_size, (size_t)((mp_byte_t*)lmmp_stack_end - (mp_byte_t*)old_top));
230 lmmp_abort(LAMMP_ERROR_MEMORY_ALLOC_FAILURE, msg, __func__, __LINE__);
231 }
232#endif // LAMMP_DEBUG_STACK_OVERFLOW_CHECK == 1
233 stack_set_top_func(new_top);
234 *(size_t*)old_top = total_size;
235 return (mp_byte_t*)old_top + SIZE_SIZE;
236}
uint8_t mp_byte_t
Definition lmmp.h:210
#define LAMMP_MAX_ALIGN
Definition lmmp.h:219
#define LMMP_ROUND_UP_MULTIPLE(a, m)
Definition lmmp.h:361
#define stack_set_top_func(top)
Definition memory.c:37
#define stack_get_top_func()
Definition memory.c:36
#define SIZE_SIZE
Definition memory.c:216

引用了 LAMMP_ERROR_MEMORY_ALLOC_FAILURE, LAMMP_MAX_ALIGN, lmmp_abort(), LMMP_ROUND_UP_MULTIPLE, lmmp_stack_end, SIZE_SIZE, stack_get_top_func , 以及 stack_set_top_func.

+ 函数调用图:

◆ lmmp_stack_free()

void lmmp_stack_free ( void *  ptr)

栈内存释放函数(使用stack_get_top和stack_set_top)

参数
ptr要释放的内存指针
警告
请严格按照分配顺序的逆序释放内存(后分配者先释放)

在文件 memory.c238 行定义.

238 {
239 if (ptr == NULL) {
240 return;
241 }
242#if LAMMP_DEBUG_STACK_OVERFLOW_CHECK == 1
243 if (ptr < lmmp_stack_begin || ptr >= lmmp_stack_end) {
244 char msg[128];
245 snprintf(msg, sizeof(msg), "Invalid stack pointer (trying to free: %p ; stack start: %p , stack end: %p )", ptr,
247 lmmp_abort(LAMMP_ERROR_MEMORY_FREE_FAILURE, msg, __func__, __LINE__);
248 }
249#endif // LAMMP_DEBUG_STACK_OVERFLOW_CHECK == 1
250 void* old_top = stack_get_top_func();
251 size_t total_size = *(size_t*)((mp_byte_t*)ptr - SIZE_SIZE);
252 void* new_top = (mp_byte_t*)old_top - total_size;
253#if LAMMP_DEBUG_STACK_OVERFLOW_CHECK == 1
254 if (new_top < lmmp_stack_begin || new_top > lmmp_stack_end) {
255 char msg[256];
256 snprintf(msg, sizeof(msg),
257 "Stack underflow (trying to free: %p , size: %zu bytes ; stack start: %p , stack end: %p ) \n%s", ptr,
259 "Likely cause: Previous stack buffer overflow corrupted the memory header.");
260 lmmp_abort(LAMMP_ERROR_MEMORY_FREE_FAILURE, msg, __func__, __LINE__);
261 }
262#endif // LAMMP_DEBUG_STACK_OVERFLOW_CHECK == 1
263 stack_set_top_func(new_top);
264}
@ LAMMP_ERROR_MEMORY_FREE_FAILURE
Definition lmmp.h:137

引用了 LAMMP_ERROR_MEMORY_FREE_FAILURE, lmmp_abort(), lmmp_stack_begin, lmmp_stack_end, SIZE_SIZE, stack_get_top_func , 以及 stack_set_top_func.

+ 函数调用图:

◆ lmmp_stack_init()

void lmmp_stack_init ( void  )

LAMMP 全局栈初始化函数(通常不需要手动调用)

注解
按照默认的栈大小(320kb),对栈进行初始化,可多次重入。 lmmp_global_init 函数会自动调用此函数,无需手动调用。

在文件 memory.c66 行定义.

66 {
67 if (lmmp_stack_begin != NULL) {
68 return;
69 } else {
73 }
74}
#define LAMMP_DEFAULT_STACK_SIZE
Definition mparam.h:23

引用了 heap_alloc_func, LAMMP_DEFAULT_STACK_SIZE, lmmp_stack_begin, lmmp_stack_end , 以及 lmmp_stack_top.

被这些函数引用 lmmp_global_init().

+ 这是这个函数的调用关系图:

◆ lmmp_stack_reset()

void lmmp_stack_reset ( size_t  size)

LAMMP 全局栈重置函数(通常不需要手动调用)

参数
size新的默认栈大小,单位为字节(不建议设置少于 256KB 的栈,少于此值可能导致栈溢出)
警告
请注意调用此函数后,访问之前的分配的栈空间将会导致未定义行为。在定义了 LAMMP_DEBUG_MEMORY_LEAK 宏时,释放默认栈时,会检查默认栈是否为空, 若默认栈不为空,则会触发lmmp_abort函数。栈为空时,或者无法确定栈是否初始化, 均可以调用此函数,如果设置的大小比此前的大小小,则会直接重置栈顶,否则,会重新分 配一块新的栈内存。同时,为保证内存不泄露,请自行确保调用此函数时,栈为空。 在开启 LAMMP_DEBUG_MEMORY_LEAK 宏时,将会对栈进行检查。若此时栈不为空, 则会触发lmmp_abort函数。
注解
当 size 为 0 时,将会释放栈,如果此后再使用栈内存。

在文件 memory.c39 行定义.

39 {
40 if (size) {
44 }
45 if (lmmp_stack_begin == NULL) {
46 lmmp_abort(LAMMP_ERROR_MEMORY_ALLOC_FAILURE, "Default stack allocation failed", __func__, __LINE__);
47 }
49 } else {
50#if LAMMP_DEBUG_MEMORY_LEAK == 1
52 char msg[128];
53 snprintf(msg, sizeof(msg), "Default stack allocator is not empty. top: %p, begin: %p, end: %p\n",
55 lmmp_abort(LAMMP_ERROR_MEMORY_LEAK, msg, __func__, __LINE__);
56 }
57#endif
60 lmmp_stack_begin = NULL;
61 lmmp_stack_end = NULL;
62 lmmp_stack_top = NULL;
63 }
64}

引用了 heap_free_func, LAMMP_ERROR_MEMORY_ALLOC_FAILURE, LAMMP_ERROR_MEMORY_LEAK, lmmp_abort(), lmmp_stack_begin, lmmp_stack_end, lmmp_stack_top , 以及 realloc_func.

被这些函数引用 lmmp_global_deinit().

+ 函数调用图:
+ 这是这个函数的调用关系图:

◆ lmmp_temp_heap_alloc_()

void * lmmp_temp_heap_alloc_ ( void **  pmarker,
size_t  size 
)

临时堆内存分配函数

参数
pmarker标记
size要分配的内存字节数

在文件 memory.c91 行定义.

91 {
92 /*
93 * pmarker is a head pointer to a linked list of allocated memory blocks.
94 * Each allocated block has a header of size HSIZE, which is used to store the
95 * next pointer of the block. The actual data starts at (mp_byte_t*)p + offset.
96 */
97 const size_t offset = LMMP_ROUND_UP_MULTIPLE(HSIZE, LAMMP_MAX_ALIGN);
98 void* p = heap_alloc_func(size + offset);
99 *(void**)p = *pmarker;
100 *pmarker = p;
101 return (mp_byte_t*)p + offset;
102}
#define HSIZE
Definition memory.c:18

引用了 heap_alloc_func, HSIZE, LAMMP_MAX_ALIGN , 以及 LMMP_ROUND_UP_MULTIPLE.

◆ lmmp_temp_heap_free_()

void lmmp_temp_heap_free_ ( void *  marker)

临时堆内存释放函数

参数
marker要释放的临时内存标记

在文件 memory.c104 行定义.

104 {
105 /*
106 * Free all allocated memory blocks in the linked list pointed to by pmarker.
107 */
108 while (marker) {
109 void* next = *(void**)marker;
110 heap_free_func(marker);
111 marker = next;
112 }
113}

引用了 heap_free_func.

变量说明

◆ global_heap

_Thread_local lmmp_heap_allocator_t global_heap
static
初始值:
= {
malloc,
free,
realloc,
}

在文件 memory.c20 行定义.

20 {
21 malloc,
22 free,
23 realloc,
24};

被这些函数引用 lmmp_set_heap_allocator().

◆ heap_alloc_count

_Thread_local int heap_alloc_count = 0
static

在文件 memory.c30 行定义.

被这些函数引用 lmmp_alloc(), lmmp_alloc_count(), lmmp_free(), lmmp_leak_tracker() , 以及 lmmp_set_heap_allocator().

◆ lmmp_stack_begin

_Thread_local void* lmmp_stack_begin = NULL

在文件 memory.c32 行定义.

被这些函数引用 lmmp_leak_tracker(), lmmp_stack_free(), lmmp_stack_init() , 以及 lmmp_stack_reset().

◆ lmmp_stack_end

_Thread_local void* lmmp_stack_end = NULL

◆ lmmp_stack_top

_Thread_local void* lmmp_stack_top = NULL