summaryrefslogtreecommitdiff
path: root/src/code/TwoHeadArena.c
blob: 83d5be3d13640386f6f98aff995cfacecea43c5d (plain)
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
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
#include "global.h"

void* THA_GetHead(TwoHeadArena* tha) {
    return tha->head;
}

void THA_SetHead(TwoHeadArena* tha, void* start) {
    tha->head = start;
}

void* THA_GetTail(TwoHeadArena* tha) {
    return tha->tail;
}

void* THA_AllocStart(TwoHeadArena* tha, size_t size) {
    void* start = tha->head;

    tha->head = (u32)tha->head + size;
    return start;
}

void* THA_AllocStart1(TwoHeadArena* tha) {
    return THA_AllocStart(tha, 1);
}

void* THA_AllocEnd(TwoHeadArena* tha, size_t size) {
    u32 mask;

    if (size >= 0x10) {
        mask = ~0xF;
    } else if (size & 1) {
        mask = -1;
    } else if (size & 2) {
        mask = ~0x1;
    } else if (size & 4) {
        mask = ~0x3;
    } else {
        mask = (size & 8) ? ~0x7 : -1;
    }

    tha->tail = (((u32)tha->tail & mask) - size) & mask;
    return tha->tail;
}

void* THA_AllocEndAlign16(TwoHeadArena* tha, size_t size) {
    u32 mask = ~0xF;

    tha->tail = (((u32)tha->tail & mask) - size) & mask;
    return tha->tail;
}

void* THA_AllocEndAlign(TwoHeadArena* tha, size_t size, u32 mask) {
    tha->tail = (((u32)tha->tail & mask) - size) & mask;
    return tha->tail;
}

s32 THA_GetSize(TwoHeadArena* tha) {
    return (u32)tha->tail - (u32)tha->head;
}

u32 THA_IsCrash(TwoHeadArena* tha) {
    return THA_GetSize(tha) < 0;
}

void THA_Init(TwoHeadArena* tha) {
    tha->head = tha->bufp;
    tha->tail = (u32)tha->bufp + tha->size;
}

void THA_Ct(TwoHeadArena* tha, void* ptr, size_t size) {
    bzero(tha, sizeof(TwoHeadArena));
    tha->bufp = ptr;
    tha->size = size;
    THA_Init(tha);
}

void THA_Dt(TwoHeadArena* tha) {
    bzero(tha, sizeof(TwoHeadArena));
}