==> 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}