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
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
|
#include <string.h>
#include "stack-man.h"
typedef struct
{
int begin;
int end;
} alloc_t;
bool_t
stack_manager_init (stack_man_t *st)
{
st->total_size = 0;
return array_create (&st->allocations, sizeof (alloc_t));
}
bool_t
stack_manager_alloc (stack_man_t *st, int size, int *offset)
{
array_t *new_allocs;
alloc_t *all;
size_t n_allocs;
size_t i;
int location;
alloc_t *tail;
if (!array_create (&new_allocs, sizeof (alloc_t)))
return FALSE;
all = array_get_data (&st->allocations, &n_allocs);
location = 0;
for (i = 0; i < n_allocs; ++i)
{
if (!array_append (&new_allocs, 1, &tail))
goto out;
memcpy (tail, all, sizeof (alloc_t));
if (all->begin - location >= size)
break;
location = all->end;
all++;
}
if (!array_append (&new_allocs, 1, &tail))
goto out;
if (location + size > st->total_size)
st->total_size = location + size;
tail->begin = location;
tail->end = location + size;
for (; i < n_allocs; ++i)
{
if (!array_append (&new_allocs, 1, &tail))
goto out;
memcpy (tail, all, sizeof (alloc_t));
all++;
}
*offset = location;
array_free (&st->allocations);
st->allocations = new_allocs;
return TRUE;
out:
array_free (&new_allocs);
return FALSE;
}
void
stack_manager_free (stack_man_t *st, int offset)
{
alloc_t *alloc;
size_t n_allocs;
int i, d;
alloc = array_get_data (&st->allocations, &n_allocs);
d = 0;
for (i = 0; i < n_allocs; ++i)
{
if (alloc[i].begin == offset)
d++;
else
alloc[i - d] = alloc[i];
}
array_delete_tail (&st->allocations, d);
}
|