slab.c 1.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. /* -*- mode:c; c-file-style:"k&r"; c-basic-offset: 4; tab-width:4; indent-tabs-mode:nil; mode:auto-fill; fill-column:78; -*- */
  2. /* vim: set ts=4 sw=4 et tw=78 fo=cqt wm=0: */
  3. #include <linux/unistd.h>
  4. #include <asm/mman.h>
  5. #include <linux_list.h>
  6. #include "utils.h"
  7. int heap_alloc_size = 4096 * 4;
  8. struct heap {
  9. struct list_head list;
  10. int used;
  11. int size;
  12. };
  13. LIST_HEAD(heap_list);
  14. void * malloc (int size)
  15. {
  16. void * ptr = NULL;
  17. struct heap * h;
  18. list_for_each_entry(h, &heap_list, list)
  19. if (h->used + size <= h->size) {
  20. ptr = (void *) h + h->used;
  21. h->used += size;
  22. return ptr;
  23. }
  24. while (heap_alloc_size < size)
  25. heap_alloc_size *= 2;
  26. h = (void *) INLINE_SYSCALL(mmap, 6, NULL, heap_alloc_size,
  27. PROT_READ|PROT_WRITE,
  28. MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
  29. if (IS_ERR_P(h))
  30. return NULL;
  31. ptr = (void *) h + sizeof(struct heap);
  32. h->used = sizeof(struct heap) + size;
  33. h->size = heap_alloc_size;
  34. INIT_LIST_HEAD(&h->list);
  35. list_add_tail(&h->list, &heap_list);
  36. heap_alloc_size *= 2;
  37. return ptr;
  38. }
  39. void free (void * mem)
  40. {
  41. /* no freeing, the memory will be freed in the end */
  42. }
  43. int free_heaps (void)
  44. {
  45. struct heap * h, * n;
  46. list_for_each_entry_safe(h, n, &heap_list, list) {
  47. list_del(&h->list);
  48. INLINE_SYSCALL(munmap, 2, h, h->size);
  49. }
  50. return 0;
  51. }