-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathMemorySpace.c
98 lines (86 loc) · 2.66 KB
/
MemorySpace.c
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
97
98
/*
* memory_spaces.c
* scheme_compiler
*
*/
#include "MemorySpace.h"
/* Signaling the memory allocation errors clearly doesn't really appear to be
something we'd like to do only while debugging. Maybe it should rethink this.
*/
#ifdef DEBUG_MEMORYSPACE
#include <stdio.h>
#endif
void * allocate(struct _MemorySpace * this, int n_chunks) {
// in case we don't have enough space to return
if (this->current_allocation_position + n_chunks > this->end) {
#ifdef DEBUG_MEMORYSPACE
printf("We ran out of memory to allocate.\n");
printf("total : %d, used : %d\n", this->n_chunks_total, this->n_chunks_used);
#endif
return NULL;
} else {
void * start_of_segment = this->current_allocation_position;
this->current_allocation_position += n_chunks;
this->n_chunks_used += n_chunks;
return start_of_segment;
}
}
void init(struct _MemorySpace * this, int n_chunks_total) {
// assuming it all works fine
this->start = malloc(n_chunks_total);
this->end = this->start + n_chunks_total;
this->current_allocation_position = this->start;
this->n_chunks_total = n_chunks_total;
this->n_chunks_used = 0;
}
void destroy(struct _MemorySpace * this) {
free(this->start);
this->start = NULL;
this->end = NULL;
this->current_allocation_position = NULL;
this->n_chunks_total = 0;
this->n_chunks_used = 0;
}
int needs_reallocation(struct _MemorySpace * this) {
/* Using the 0.9 magic number.
We're assuming that with one operation, it's impossible that
we fill up 10% of the memory available. The only problem cases would
concern very large files, but those would be a problem anyways, to
be solved by changing the DEFAULT_MEMORY_FOR_MACHINE global definition,
probably.
*/
if (0.9 * (this->n_chunks_total) <= (this->n_chunks_used))
return 1;
else
return 0;
}
MemorySpace * make_MemorySpace(int n_chunks) {
MemorySpace * myspace = malloc(sizeof(MemorySpace));
/* We're using NULL at many places to indicate that a pointer
hasn't been allocated memory successfully. This means that we
can't have the start of the memory space be at NULL by accident.
We're not supposed to be able to get NULL by a regular malloc,
though, so it's probably all fine.
*/
myspace->allocate = &allocate;
myspace->destroy = &destroy;
myspace->init = &init;
myspace->needs_reallocation = &needs_reallocation;
myspace->init(myspace, n_chunks);
return myspace;
}
#ifdef TEST_MEMORYSPACE_ALONE
/* A little demo. Comment out if not used. */
int main() {
MemorySpace * ms = make_MemorySpace(100);
int * A;
A = ms->allocate(ms, sizeof(int));
*A = 0;
A = ms->allocate(ms, sizeof(int));
*A = 1;
A = ms->allocate(ms, sizeof(int));
*A = 2;
ms->destroy(ms);
return 0;
}
#endif