File: heap-libc.ha

package info (click to toggle)
hare 0.26.0-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 7,352 kB
  • sloc: asm: 1,374; makefile: 123; sh: 117; lisp: 101
file content (56 lines) | stat: -rw-r--r-- 1,711 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
// SPDX-License-Identifier: MPL-2.0
// (c) Hare authors <https://harelang.org>

// A group of blocks that were allocated together.
export type chunk = union {
	padding: size, // TODO: track number of active allocations here
	data: [*]u8,
};

// Metadata for a block.
export type meta = struct {
	union {
		sz: size,
		next: uintptr,
	},
	user: [*]u8,
};

export type memory_heap = struct {
	// Number of allocations currently in flight.
	cur_allocs: size,
	// Freelists for blocks up to 2048 bytes.
	bins: [9]nullable *meta,
	// The chunk to allocate from if there are no blocks available in the
	// right freelist.
	cur_chunk: (*chunk, size),
};

// An empty memory heap, used to initialize a [[memory_heap]] for use with
// [[setheap]].
export def EMPTY_HEAP = memory_heap {
	cur_allocs = 0,
	bins = [null...],
	cur_chunk = (null: *chunk, CHUNKSZ),
};

let static_heap = EMPTY_HEAP;
let heap = &static_heap;

// Switches the internal runtime allocator to a new memory heap. The caller
// should provision a [[memory_heap]] initialized to [[EMPTY_HEAP]] somehow
// (statically, or in a second memory_heap, or even on the stack if you're brave
// enough) and pass it to this function to enable it. Returns a pointer to the
// heap which was previously in use, should you wish to restore it later.
//
// The caller is responsible for ensuring that any use of free() or delete()
// makes use of an object which was allocated (via alloc(), insert(), or
// append()) from the same heap.
//
// This function is designed for debugging use, and exists in particular to
// satisfy the needs of [[debug::]].
export fn setheap(new_heap: *memory_heap) *memory_heap = {
	const old = heap;
	heap = new_heap;
	return old;
};