LispBM
Loading...
Searching...
No Matches
lbm_defrag_mem.h
Go to the documentation of this file.
1/*
2 Copyright 2024, 2025, 2026 Joel Svensson svenssonjoel@yahoo.se
3
4 This program is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation, either version 3 of the License, or
7 (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <http://www.gnu.org/licenses/>.
16*/
17
18
19/*
20 lbm_defrag_mem.h/c provides a memory area that is compacted when
21 needed. This means that allocations in the lbm_defrag_mem must be
22 able to find all places that reference it and update those
23 locations.
24
25 Here an earlier design choice came in useful! LispBM arrays are
26 allocated in a way such that the actual data in the array is only
27 referenced through a single pointer. This pointer is in a
28 heap-cell. The heap-cell itself can then be referenced from many
29 locations, but we never need to update those at all! So, because of
30 this design choice we just need to keep track of a single
31 cell-reference in the compactible memory allocation to be able to
32 update the reference upon a compaction.
33
34 **INVARIANT**
35 This comes with one invariant that must be upheld in all operations,
36 that an array-reference-cell is never duplicated.
37
38 A ByteArray header consists of a size and a data-pointer. So the
39 general layout of a ByteArray in memory is:
40
41 [size, data-pointer]->[data ..., padding]
42
43 The padding is either there or not depending on the data being a
44 multiple of the word size or not.
45
46 In defrag memory an allocation of a ByteArray is structured as
47 follows.
48
49 [size, data-pointer, cell-back-ptr, data ..., padding]
50 | |
51 -----------------------------
52
53 Note that the allocation in the defrag memory is large enough to
54 hold the header, the cell-back-ptr and the data consecutively.
55
56 It is important that the [size, data-pointer]..[data] areas are
57 compatible with the normal ByteArray header struct so that all the
58 functions that operate on regular ByteArrays also can operate
59 unchanged on ByteArrays stored in defrag memory.
60
61 The heap-cell that references the ByteArray data has the
62 following form:
63
64 [ptr-to-header, SYM_ARRAY_TYPE]
65
66 The reference to the heap_cell is a pointer with the LBM_TYPE_ARRAY
67 bit set in its type fields. Note that this reference can be duplicated.
68
69 A cell referring to a byte array in defrag memory has the following form:
70
71 [ptr-to-header, SYM_DEFRAG_ARRAY_TYPE]
72
73 The reference to this heap cell is also a pointer with the
74 LBM_TYPE_ARRAY bit set in its type field. This is how we make sure
75 that functions that operate on ByteArrays will work on both normal
76 and defrag ByteArrays.
77
78 **INVARIANT**
79 Functions that operate on arrays must not depend on the cdr field of
80 an array cell being SYM_ARRAY_TYPE.
81
82 Upholding this invariant should not be hard as the TYPE tag in the
83 cdr field is for GC to look at. When GC sees SYM_ARRAY_TYPE in a
84 cdr, it knows that the car part must be freed using a ByteArray free
85 operation. Likewise if the cdr field is SYM_DEFRAG_ARRAY_TYPE, GC
86 knows that the free function from the defrag memory module is needed.
87
88
89 -- The Defragmentable memory pool --------------------------------------
90
91 The defrag mem consists of a two word header and N words for storage
92 of arrays. The two word header consists of a size in words and a
93 flags field. The flags field is part of the algorithm that determines
94 if compaction should be performed:
95 1. A call to lbm_defrag_mem_alloc fails to find a free area of memory
96 - Sets flag.
97 - Returns MERROR
98 2. Caller of lbm_defrag_mem_alloc sees MERROR and runs GC.
99 3. GC runs and potentially frees some space in the defrag pool.
100 4. lbm_defrag_mem_alloc is called again after GC.
101 5. lbm_defrag_mem_alloc sees flag and initiates compaction.
102 6. lbm_defrag_mem_alloc attempts to allocate again.
103
104 So the purpose of the flag is to communicate the need of a compaction
105 between calls to lbm_defrag_mem_alloc in a typical
106 try_alloc -> gc -> try_alloc
107 flow.
108 */
109
110#ifndef LBM_DEFRAG_MEM_H_
111#define LBM_DEFRAG_MEM_H_
112
113#include <heap.h>
114#include <stdint.h>
115
117extern void lbm_defrag_mem_destroy(lbm_uint *ptr);
118extern lbm_value lbm_defrag_mem_alloc(lbm_uint *defrag_mem, lbm_uint nbytes);
119//extern lbm_value lbm_defrag_mem_alloc_lisparray(lbm_uint *defrag_mem, lbm_uint elts);
120extern void lbm_defrag_mem_free(lbm_uint* data);
121
122static inline bool lbm_defrag_mem_valid(lbm_value arr) {
123 return !(lbm_is_symbol_nil(lbm_car(arr)));
124}
125
126static inline bool lbm_is_defrag_mem(lbm_value x) {
127 lbm_type t = lbm_type_of(x);
128 return ((t == LBM_TYPE_DEFRAG_MEM) && lbm_defrag_mem_valid(x)) ;
129}
130
131
132#endif
static bool lbm_is_symbol_nil(lbm_value exp)
Definition heap.h:907
static lbm_type lbm_type_of(lbm_value x)
Definition heap.h:676
lbm_value lbm_car(lbm_value cons)
Definition heap.c:973
#define LBM_TYPE_DEFRAG_MEM
Definition lbm_defines.h:60
lbm_value lbm_defrag_mem_alloc(lbm_uint *defrag_mem, lbm_uint nbytes)
Definition lbm_defrag_mem.c:225
lbm_value lbm_defrag_mem_create(lbm_uint nbytes)
Definition lbm_defrag_mem.c:42
static bool lbm_is_defrag_mem(lbm_value x)
Definition lbm_defrag_mem.h:126
void lbm_defrag_mem_free(lbm_uint *data)
Definition lbm_defrag_mem.c:268
static bool lbm_defrag_mem_valid(lbm_value arr)
Definition lbm_defrag_mem.h:122
void lbm_defrag_mem_destroy(lbm_uint *ptr)
Definition lbm_defrag_mem.c:88
uint32_t lbm_uint
Definition lbm_types.h:48
uint32_t lbm_type
Definition lbm_types.h:46
uint32_t lbm_value
Definition lbm_types.h:44