LAMMP 4.2.0
Lamina High-Precision Arithmetic Library
载入中...
搜索中...
未找到
tmp_alloc.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_TMP_ALLOC_H__
17#define __LAMMP_TMP_ALLOC_H__
18
19#include "../lmmp.h"
20#include <stdio.h>
21
22typedef struct {
23 void* stack_begin; // 栈内存起始地址
24 void* stack_end; // 栈内存结束地址
25 void* stack_top; // 栈内存当前指针位置
26 void* pool_begin; // 缓冲池起始地址
27 void* pool_top; // 缓冲池当前指针位置
28 size_t remain; // 缓冲池剩余内存字节数
29 size_t capacity; // 缓冲池容量(初始化后不变)
31
34
35typedef struct {
36 void* stack_marker; // 栈内存标记
37 void* pool_marker; // 缓冲池标记
38 void* heap_marker; // 堆内存标记
40
41static inline void* lmmp_temp_heap_alloc_(lmmp_alloc_marker* pmarker, size_t size) {
42 /*
43 * pmarker->heap_marker is a head pointer to a linked list of allocated memory blocks.
44 * Each allocated block has a header of size HSIZE, which is used to store the
45 * next pointer of the block. The actual data starts at (mp_byte_t*)p + offset.
46 */
47 // 在经过缓冲池后,size已经对齐至LAMMP_MAX_ALIGN
48 // size = LMMP_ROUND_UP_MULTIPLE(size, LAMMP_MAX_ALIGN);
49#define HSIZE sizeof(void*)
51#undef HSIZE
52 void* p = global_heap.alloc(size + offset);
53#if LAMMP_DEBUG_MEMORY_CHECK == 1
54 if (p == NULL) {
55 char msg[128];
56 snprintf(msg, sizeof(msg), "Memory allocation failure (trying to allocate: %zu bytes)", size);
58 }
59#endif
60 *(void**)p = pmarker->heap_marker;
61 pmarker->heap_marker = p;
62 return (mp_byte_t*)p + offset;
63}
64
66 /*
67 * Free all allocated memory blocks in the linked list pointed to by pmarker->heap_marker.
68 */
69 while (pmarker->heap_marker) {
70 void* next = *(void**)(pmarker->heap_marker);
71 global_heap.free(pmarker->heap_marker);
72 pmarker->heap_marker = next;
73 }
74}
75
76static inline void* lmmp_temp_stack_alloc_(lmmp_alloc_marker* pmarker, size_t size) {
77 /*
78 * On the first call, pmarker->stack_marker is a null pointer.
79 * We will use pmarker->stack_marker to record the stack frame at this time.
80 * When allocating memory subsequently, we will not modify pmarker->stack_marker.
81 * Until all stack memory is finally released, we will move to the initial stack position at once,
82 * which is the position recorded by pmarker->stack_marker.
83 */
87#if LAMMP_DEBUG_STACK_OVERFLOW_CHECK == 1
89 char msg[128];
90 snprintf(msg, sizeof(msg), "Stack overflow (trying to allocate: %zu bytes, stack remaining: %zu bytes)", offset,
93 }
94#endif
96 if (pmarker->stack_marker == NULL)
97 pmarker->stack_marker = p;
98 return p;
99}
100
102 // pmarker->stack_marker is not NULL
103 lmmp_tmpmem_ctx.stack_top = pmarker->stack_marker;
104}
105
106static inline void* lmmp_temp_pool_alloc_(lmmp_alloc_marker* pmarker, size_t size) {
110 if (remaining < 2 * offset) {
111 // 保证pool留有一个offset的空间,使得递归后子问题也尽可能分配到pool中,避免递归时子问题分配到堆上
113 } else {
114 mp_byte_t* new_top = p + offset;
117 if (pmarker->pool_marker == NULL)
118 pmarker->pool_marker = p;
119 return p;
120 }
121}
122
124 // pmarker->pool_marker is not NULL
125 size_t freed = (mp_byte_t*)(lmmp_tmpmem_ctx.pool_top) - (mp_byte_t*)(pmarker->pool_marker);
127 lmmp_tmpmem_ctx.pool_top = pmarker->pool_marker;
128}
129
130// 临时内存标记声明:用于跟踪临时内存分配
131#define TEMP_DECL lmmp_alloc_marker __lmmp_marker_ = {NULL, NULL, NULL}
132#define TEMP_B_DECL TEMP_DECL
133#define TEMP_S_DECL TEMP_DECL
134
135#define TEMP_SALLOC_THRESHOLD 0x7f00 // 小内存分配阈值(小于等于该值的内存分配在栈上)
136
137// 栈内存分配:使用lmmp_temp_stack_alloc_在栈上分配n字节内存(小内存)
138#define TEMP_SALLOC(n) lmmp_temp_stack_alloc_(&__lmmp_marker_, (n))
139// 缓冲池分配:使用lmmp_temp_pool_alloc_优先在pool上分配n字节内存(大内存)
140#define TEMP_BALLOC(n) lmmp_temp_pool_alloc_(&__lmmp_marker_, (n))
141// 临时内存分配:小内存用栈,大内存用堆
142#define TEMP_TALLOC(n) ((n) <= TEMP_SALLOC_THRESHOLD ? TEMP_SALLOC(n) : TEMP_BALLOC(n))
143// 类型化栈内存分配:分配n个type类型的栈内存
144#define SALLOC_TYPE(n, type) ((type*)TEMP_SALLOC((n) * sizeof(type)))
145// 类型化堆内存分配:分配n个type类型的堆内存
146#define BALLOC_TYPE(n, type) ((type*)TEMP_BALLOC((n) * sizeof(type)))
147// 类型化临时内存分配:智能选择栈/堆分配n个type类型内存
148#define TALLOC_TYPE(n, type) ((type*)TEMP_TALLOC((n) * sizeof(type)))
149// 临时内存释放:释放所有通过TEMP_XALLOC系列函数分配的临时内存
150#define TEMP_FREE \
151 do { \
152 if (__lmmp_marker_.heap_marker != NULL) \
153 lmmp_temp_heap_free_(&__lmmp_marker_); \
154 if (__lmmp_marker_.stack_marker != NULL) \
155 lmmp_temp_stack_free_(&__lmmp_marker_); \
156 if (__lmmp_marker_.pool_marker != NULL) \
157 lmmp_temp_pool_free_(&__lmmp_marker_); \
158 } while (0)
159#define TEMP_B_FREE \
160 do { \
161 if (__lmmp_marker_.pool_marker != NULL) \
162 lmmp_temp_pool_free_(&__lmmp_marker_); \
163 if (__lmmp_marker_.heap_marker != NULL) \
164 lmmp_temp_heap_free_(&__lmmp_marker_); \
165 } while (0)
166#define TEMP_S_FREE \
167 do { \
168 if (__lmmp_marker_.stack_marker != NULL) \
169 lmmp_temp_stack_free_(&__lmmp_marker_); \
170 } while (0)
171
172// 类型化内存分配:分配n个type类型的内存(堆)
173#define ALLOC_TYPE(n, type) ((type*)lmmp_alloc((size_t)(n) * sizeof(type)))
174// 类型化内存重分配:将p指向的内存重分配为new_size个type类型
175#define REALLOC_TYPE(p, new_size, type) ((type*)lmmp_realloc((p), (new_size) * sizeof(type)))
176
177#endif /* __LAMMP_TMP_ALLOC_H__ */
uint8_t mp_byte_t
Definition lmmp.h:75
#define LAMMP_MAX_ALIGN
Definition lmmp.h:84
lmmp_heap_alloc_fn alloc
Definition lmmp.h:170
void lmmp_abort(lmmp_error_t type, const char *msg, const char *func, int line)
LAMMP 全局退出函数,内部错误或断言失败时调用,若设置了全局退出函数,则会调用该函数,否则会调用默认的退出函数。
Definition abort.c:102
#define LAMMP_THREAD_LOCAL
Definition lmmp.h:102
lmmp_heap_free_fn free
Definition lmmp.h:171
@ LAMMP_ERROR_MEMORY_ALLOC_FAILURE
Definition lmmp.h:215
#define LMMP_ROUND_UP_MULTIPLE(a, m)
Definition lmmp.h:364
#define n
void * stack_top
Definition tmp_alloc.h:25
size_t capacity
Definition tmp_alloc.h:29
void * pool_begin
Definition tmp_alloc.h:26
static void * lmmp_temp_heap_alloc_(lmmp_alloc_marker *pmarker, size_t size)
Definition tmp_alloc.h:41
static void * lmmp_temp_stack_alloc_(lmmp_alloc_marker *pmarker, size_t size)
Definition tmp_alloc.h:76
static void lmmp_temp_stack_free_(lmmp_alloc_marker *pmarker)
Definition tmp_alloc.h:101
_Thread_local lmmp_memory_ctx lmmp_tmpmem_ctx
Definition memory.c:41
void * stack_end
Definition tmp_alloc.h:24
static void lmmp_temp_heap_free_(lmmp_alloc_marker *pmarker)
Definition tmp_alloc.h:65
void * stack_marker
Definition tmp_alloc.h:36
static void * lmmp_temp_pool_alloc_(lmmp_alloc_marker *pmarker, size_t size)
Definition tmp_alloc.h:106
static void lmmp_temp_pool_free_(lmmp_alloc_marker *pmarker)
Definition tmp_alloc.h:123
#define HSIZE
void * stack_begin
Definition tmp_alloc.h:23
_Thread_local lmmp_heap_allocator_t global_heap
Definition memory.c:29
void * pool_top
Definition tmp_alloc.h:27
Copyright (C) 2026 HJimmyK(Jericho Knox)
Definition tmp_alloc.h:22