stdlib.c 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. #include <priv-vars.h>
  2. #include <stdint.h>
  3. #include <stdlib.h>
  4. #include <syscall.h>
  5. #include <unistd.h>
  6. int atoi(const char* str)
  7. {
  8. int ret = 0;
  9. while (*str) {
  10. ret *= 10;
  11. ret += *str - '0';
  12. }
  13. return ret;
  14. }
  15. void __attribute__((noreturn)) exit(int status)
  16. {
  17. syscall1(SYS_exit, status);
  18. for (;;)
  19. ;
  20. }
  21. #define MINIMUM_ALLOCATION_SIZE (8)
  22. #define MEM_ALLOCATED (1)
  23. struct mem {
  24. uint32_t sz;
  25. uint32_t flag;
  26. };
  27. static inline void _init_heap(void)
  28. {
  29. sbrk(128 * 1024);
  30. struct mem* first = start_brk;
  31. first->sz = 0;
  32. first->flag = 0;
  33. }
  34. static inline int _is_end(struct mem* p)
  35. {
  36. return p->sz == 0;
  37. }
  38. static inline int _is_allocated(struct mem* p)
  39. {
  40. return !!(p->flag & MEM_ALLOCATED);
  41. }
  42. static inline size_t _max(size_t a, size_t b)
  43. {
  44. return a > b ? a : b;
  45. }
  46. static inline size_t _size(struct mem* from)
  47. {
  48. if (!_is_end(from))
  49. return from->sz;
  50. size_t sz = curr_brk - (void*)from;
  51. if (sz < sizeof(struct mem))
  52. return 0;
  53. return sz - sizeof(struct mem);
  54. }
  55. static inline struct mem* _next(struct mem* p, size_t sz)
  56. {
  57. return (void*)p + sizeof(struct mem) + sz;
  58. }
  59. static inline void _union(struct mem* p)
  60. {
  61. if (_is_end(p))
  62. return;
  63. for (struct mem* next = _next(p, p->sz);
  64. !(next->flag & MEM_ALLOCATED);
  65. next = _next(p, p->sz)) {
  66. if (_is_end(next)) {
  67. p->sz = 0;
  68. break;
  69. }
  70. p->sz += sizeof(struct mem);
  71. p->sz += next->sz;
  72. }
  73. }
  74. void* malloc(size_t size)
  75. {
  76. if (curr_brk == start_brk)
  77. _init_heap();
  78. if (size < MINIMUM_ALLOCATION_SIZE)
  79. size = MINIMUM_ALLOCATION_SIZE;
  80. struct mem* p = start_brk;
  81. size_t sz = 0;
  82. for (;; p = _next(p, p->sz)) {
  83. if (_is_allocated(p))
  84. continue;
  85. _union(p);
  86. sz = _size(p);
  87. if (_is_end(p)) {
  88. if (sz < size + sizeof(struct mem))
  89. sbrk(_max(128 * 1024, size + sizeof(struct mem)));
  90. sz = p->sz = size;
  91. struct mem* next = _next(p, size);
  92. next->flag = 0;
  93. next->sz = 0;
  94. break;
  95. }
  96. if (sz >= size)
  97. break;
  98. }
  99. p->flag |= MEM_ALLOCATED;
  100. if (sz >= size + sizeof(struct mem) + MINIMUM_ALLOCATION_SIZE) {
  101. p->sz = size;
  102. struct mem* next = _next(p, size);
  103. next->flag = 0;
  104. next->sz = sz - size - sizeof(struct mem);
  105. }
  106. return _next(p, 0);
  107. }
  108. void free(void* ptr)
  109. {
  110. struct mem* p = ptr - sizeof(struct mem);
  111. p->flag &= ~MEM_ALLOCATED;
  112. _union(p);
  113. }