skip to content
==> src/view_alloc.c <==
1/* First fit over a page map. */
2#include "mesh/view_alloc.h"
3
4#include <stdio.h>
5#include <stdlib.h>
6#include <string.h>
7
8void mesh_view_heap_init(mesh_view_heap *h) { memset(h->used, 0, sizeof h->used); }
9
10size_t mesh_view_pages(uint32_t bytes) { return ((size_t)bytes + MESH_VIEW_PAGE - 1) / MESH_VIEW_PAGE; }
11
12bool mesh_view_heap_alloc(mesh_view_heap *h, uint32_t bytes, uint32_t *off) {
13    size_t n = mesh_view_pages(bytes);
14    if (n == 0) { *off = 0; return true; }
15    size_t run = 0;
16    for (size_t p = 0; p < MESH_VIEW_PAGES; p++) {
17        run = h->used[p] ? 0 : run + 1;
18        if (run == n) {
19            size_t first = p + 1 - n;
20            for (size_t i = first; i <= p; i++) h->used[i] = true;
21            *off = (uint32_t)(MESH_VIEW_HEAP + first * MESH_VIEW_PAGE);
22            return true;
23        }
24    }
25    return false;
26}
27
28void mesh_view_heap_free(mesh_view_heap *h, uint32_t off, uint32_t bytes) {
29    size_t n = mesh_view_pages(bytes);
30    if (n == 0) return;
31    size_t first = ((size_t)off - MESH_VIEW_HEAP) / MESH_VIEW_PAGE;
32    for (size_t i = first; i < first + n; i++) {
33        if (!h->used[i]) {
34            fprintf(stderr, "view heap: freeing a free page at 0x%x\n", off);
35            abort();
36        }
37        h->used[i] = false;
38    }
39}
40
41uint32_t mesh_view_heap_free_pages(const mesh_view_heap *h) {
42    uint32_t n = 0;
43    for (size_t p = 0; p < MESH_VIEW_PAGES; p++) n += !h->used[p];
44    return n;
45}
46
47uint32_t mesh_view_heap_largest_run(const mesh_view_heap *h) {
48    uint32_t best = 0, run = 0;
49    for (size_t p = 0; p < MESH_VIEW_PAGES; p++) {
50        run = h->used[p] ? 0 : run + 1;
51        if (run > best) best = run;
52    }
53    return best;
54}