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
123
124
125
126
127
128
129
|
/*
* Pure Data Packet system file: memory allocation
* Copyright (c) by Tom Schouten <pdp@zzz.kotnet.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#include <stdlib.h>
#include "pdp_mem.h"
#include "pdp_debug.h"
/* malloc wrapper that calls garbage collector */
void *pdp_alloc(int size)
{
void *ptr = malloc(size);
PDP_ASSERT(ptr);
return ptr;
//TODO: REPAIR THIS
//post ("malloc failed in a pdp module: running garbage collector.");
//pdp_pool_collect_garbage();
//return malloc(size);
}
void pdp_dealloc(void *stuff)
{
free (stuff);
}
/* fast atom allocation object
well, this is not too fast yet, but will be later
when it suports linux futexes or atomic operations */
//#include <pthread.h>
/* private linked list struct */
typedef struct _fastalloc
{
struct _fastalloc * next;
} t_fastalloc;
static void _pdp_fastalloc_lock(t_pdp_fastalloc *x){pthread_mutex_lock(&x->mut);}
static void _pdp_fastalloc_unlock(t_pdp_fastalloc *x){pthread_mutex_unlock(&x->mut);}
static void _pdp_fastalloc_refill_freelist(t_pdp_fastalloc *x)
{
t_fastalloc *atom;
unsigned int i;
PDP_ASSERT(x->freelist == 0);
/* get a new block
there is no means of freeing the data afterwards,
this is a fast implementation with the tradeoff of data
fragmentation "memory leaks".. */
x->freelist = pdp_alloc(x->block_elements * x->atom_size);
/* link all atoms together */
atom = x->freelist;
for (i=0; i<x->block_elements-1; i++){
atom->next = (t_fastalloc *)(((char *)atom) + x->atom_size);
atom = atom->next;
}
atom->next = 0;
}
void *pdp_fastalloc_new_atom(t_pdp_fastalloc *x)
{
t_fastalloc *atom;
_pdp_fastalloc_lock(x);
/* get an atom from the freelist
or refill it and try again */
while (!(atom = x->freelist)){
_pdp_fastalloc_refill_freelist(x);
}
/* delete the element from the freelist */
x->freelist = x->freelist->next;
atom->next = 0;
_pdp_fastalloc_unlock(x);
return (void *)atom;
}
void pdp_fastalloc_save_atom(t_pdp_fastalloc *x, void *atom)
{
_pdp_fastalloc_lock(x);
((t_fastalloc *)atom)->next = x->freelist;
x->freelist = (t_fastalloc *)atom;
_pdp_fastalloc_unlock(x);
}
t_pdp_fastalloc *pdp_fastalloc_new(unsigned int size)
{
t_pdp_fastalloc *x = pdp_alloc(sizeof(*x));
if (size < sizeof(t_fastalloc)) size = sizeof(t_fastalloc);
x->freelist = 0;
x->atom_size = size;
x->block_elements = PDP_FASTALLOC_BLOCK_ELEMENTS;
pthread_mutex_init(&x->mut, NULL);
return x;
}
|