-
Notifications
You must be signed in to change notification settings - Fork 22
/
memory.c
123 lines (100 loc) · 2.31 KB
/
memory.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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "memory.h"
#include "lint.h"
#ifdef malloc
#undef malloc
#endif
extern char *reserved_area;
extern int slow_shut_down_to_do;
#define INITIAL_POOL 256
/*
* Track the allocation in the pools list
*/
void *
pool_track(struct allocation_pool *pool, void *ptr)
{
if (ptr == NULL)
return NULL;
if (!pool->size) {
pool->allocations = malloc(sizeof(void *) * INITIAL_POOL);
if (pool->allocations == NULL) {
return NULL;
}
pool->size = INITIAL_POOL;
}
if (pool->size == pool->used) {
size_t new_size = pool->size * 2;
void *new_allocations = realloc(pool->allocations, new_size * sizeof(void *));
if (new_allocations == NULL) {
return NULL;
}
pool->size = new_size;
pool->allocations = new_allocations;
}
return pool->allocations[pool->used++] = ptr;
}
/*
* Allocate a chunk of memory and keep track of it in a pool.
*/
void *
pool_alloc(struct allocation_pool *pool, size_t size)
{
void *ptr = xalloc(size);
if (ptr != NULL)
pool_track(pool, ptr);
return ptr;
}
/*
* Clear all allocations in the pool and prepare it for reuse
*/
void
pool_free(struct allocation_pool *pool) {
if (!pool->size) {
return;
}
for (size_t i = 0; i < pool->used; i++) {
free(pool->allocations[i]);
}
free(pool->allocations);
pool->size = 0;
pool->used = 0;
pool->allocations = NULL;
}
/*
* xalloc is a malloc wrapper which keeps a pool of 'extra' memory
*
*
*/
__attribute__((malloc))
void *
xalloc(size_t size)
{
char *p;
static int going_to_exit;
if (going_to_exit)
exit(3);
if (size == 0)
size = 1;
p = (char *)malloc(size);
if (p == 0)
{
if (reserved_area)
{
free(reserved_area);
reserved_area = 0;
p = "Temporary out of MEMORY. Freeing reserve.\n";
(void)write(1, p, strlen(p));
slow_shut_down_to_do = 6;
return xalloc(size); /* Try again */
}
going_to_exit = 1;
p = "Totally out of MEMORY.\n";
(void)write(1, p, strlen(p));
(void)dump_trace(0);
exit(2);
}
return p;
}