initial commit
[pfinal.git] / Routix / src / mm / alloc.c
blobdc0533673e9c9909f7fad30b3d1d57365666a892
1 /*! \addtogroup MemoryManager
2 \page alloc.c
3 Administración de bloques variables de memoria (malloc y free).
4 */
6 #ifndef __SYSTEM
7 #include "routix/system.h"
8 #endif
9 #include <routix/kstdio.h>
10 #include "routix/paging.h"
11 #include <routix/kalloc.h>
12 #include <routix/debug.h>
14 //! Cantidad de mallocs realizados desde la última llamada a "clear alloc"
15 volatile int num_mallocs = 0;
16 //! Cantidad de frees desde la última llamada a "clear alloc"
17 volatile int num_frees = 0;
19 unsigned int umalloc_alloc = 0, umalloc_free = 0;
21 void __free (void *);
23 //! Punteros utilizados por el stack de páginas libres
24 addr_t *_inicio,*_fin,*_sp;
27 //typedef union header Header;
29 static Header base;
30 static Header *freep=NULL;
32 Header *morecore(void);
34 void *__malloc (unsigned nbytes)
36 cli();
37 Header *p, *prevp;
38 unsigned nunits;
39 nunits = (nbytes + sizeof(Header)-1) / sizeof(Header) +1;
40 if ((prevp = freep)==NULL) {
41 base.s.ptr = freep = prevp = &base;
42 base.s.size = 0;
45 for ( p=prevp->s.ptr ; ; prevp=p , p=p->s.ptr) {
46 if (p->s.size >= nunits) {
47 if (p->s.size == nunits)
48 prevp->s.ptr = p->s.ptr;
49 else {
50 p->s.size -= nunits;
51 p += p->s.size;
52 p->s.size = nunits;
54 freep = prevp;
55 /*TEMP*/ num_mallocs++;
56 sti();
57 return (p+1);
59 else if (p==freep) {
60 if ( (p = morecore()) == NULL ) {
61 sti();
62 return NULL;
66 sti();
67 return NULL;
72 volatile word morecores=0;
74 Header *morecore(void)
76 Header *up;
78 up = (Header *) kmalloc_page();
79 if (up == NULL) {
80 return NULL;
83 morecores++;
85 up->s.size= PAGINA_SIZE / sizeof(Header);
86 __free ( (void *) (up+1));
87 return freep;
92 void __free (void *ap)
94 cli();
95 Header *bp, *p;
97 bp = (Header *) ap - 1;
98 for (p=freep; ! (bp > p && bp < p->s.ptr) ; p=p->s.ptr)
99 if ( (p >= p->s.ptr) && (bp > p || bp < p->s.ptr))
100 break;
101 if ( (bp + bp->s.size) == p->s.ptr) {
102 bp->s.size += p->s.ptr->s.size;
103 bp->s.ptr = p->s.ptr->s.ptr;
105 else bp->s.ptr = p->s.ptr;
107 if ( (p+p->s.size) == bp) {
108 p->s.size += bp->s.size;
109 p->s.ptr = bp->s.ptr;
111 else p->s.ptr = bp;
113 freep = p;
115 num_frees++;
116 sti();