4004353cbf4e06a25e51caf809491fca1a4047f0
[akaros.git] / kern / src / kmalloc.c
1 /* Copyright (c) 2009 The Regents of the University of California. 
2  * See the COPYRIGHT files at the top of this source tree for full 
3  * license information.
4  * 
5  * Kevin Klues <klueska@cs.berkeley.edu>    
6  */
7
8 #include <arch/types.h>
9 #include <ros/error.h>
10 #include <pmap.h>
11 #include <kmalloc.h>
12
13 #define kmallocdebug(args...)  //printk(args)
14
15 static page_list_t pages_list;  //List of physical pages used by kmalloc
16 extern size_t naddrpage;
17
18 void kmalloc_init() {
19         LIST_INIT(&pages_list);
20 }
21
22 void* kmalloc(size_t size, int flags) {
23         if(size == 0)
24                 return NULL;
25         int npages = ROUNDUP(size, PGSIZE) / PGSIZE;
26         
27         // Find 'npages' free consecutive pages
28         int first = -1;
29         kmallocdebug("naddrpage: %u\n", naddrpage);
30         kmallocdebug("npages: %u\n", npages);
31         for(int i=(naddrpage-1); i>=(npages-1); i--) {
32                 int j;
33                 for(j=i; j>=(i-(npages-1)); j--) {
34                         if( !page_is_free(j) )
35                                 break;
36                 }
37                 if( j == (i-(npages-1)-1)) {
38                         first = j+1;
39                         break;
40                 }
41         }
42         //If we couldn't find them, return NULL
43         if( first == -1 )
44                 return NULL;
45                 
46         //Otherwise go ahead and allocate them to ourselves now
47         for(int i=0; i<npages; i++) {
48                 page_t* page;
49                 page_alloc_specific(&page, first+i);
50                 page->pp_ref++; // Kevin doesnt like this.
51                 page->num_cons_links = npages-i;
52                 LIST_INSERT_HEAD(&pages_list, page, pp_link);
53                 kmallocdebug("mallocing page: %u\n", first+i);
54                 kmallocdebug("at addr: %p\n", ppn2kva(first+i));
55         }
56         //And return the address of the first one
57         return ppn2kva(first);
58 }
59 void kfree(void *addr) {
60         kmallocdebug("incoming address: %p\n", addr);
61         page_t* page = kva2page(addr);
62         int num_links = page->num_cons_links;
63         kmallocdebug("getting page: %u\n", page2ppn(page));
64         for(int i=0; i<num_links; i++) {
65                 page_t* p = ppn2page((page2ppn(page) + i));
66                 LIST_REMOVE(p, pp_link);
67                 page_decref(p);
68                 kmallocdebug("freeing page: %d\n", page2ppn(p));
69         }
70 }