aboutsummaryrefslogtreecommitdiff
path: root/system/kernel/pdp_mem.c
blob: 33822ef3aa43a5cb790e9d1dcb506bf9583bef3d (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
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;
}