stdlib.c 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. #include <alloca.h>
  2. #include <priv-vars.h>
  3. #include <stdint.h>
  4. #include <stdlib.h>
  5. #include <syscall.h>
  6. #include <unistd.h>
  7. #include <string.h>
  8. int atoi(const char* str)
  9. {
  10. int ret = 0;
  11. while (*str) {
  12. ret *= 10;
  13. ret += *str - '0';
  14. }
  15. return ret;
  16. }
  17. void __attribute__((noreturn)) exit(int status)
  18. {
  19. syscall1(SYS_exit, status);
  20. for (;;)
  21. ;
  22. }
  23. #define MINIMUM_ALLOCATION_SIZE (8)
  24. #define MEM_ALLOCATED (1)
  25. struct mem {
  26. uint32_t sz;
  27. uint32_t flag;
  28. };
  29. static inline void _init_heap(void)
  30. {
  31. sbrk(128 * 1024);
  32. struct mem* first = start_brk;
  33. first->sz = 0;
  34. first->flag = 0;
  35. }
  36. static inline int _is_end(struct mem* p)
  37. {
  38. return p->sz == 0;
  39. }
  40. static inline int _is_allocated(struct mem* p)
  41. {
  42. return !!(p->flag & MEM_ALLOCATED);
  43. }
  44. static inline size_t _max(size_t a, size_t b)
  45. {
  46. return a > b ? a : b;
  47. }
  48. static inline size_t _size(struct mem* from)
  49. {
  50. if (!_is_end(from))
  51. return from->sz;
  52. size_t sz = curr_brk - (void*)from;
  53. if (sz < sizeof(struct mem))
  54. return 0;
  55. return sz - sizeof(struct mem);
  56. }
  57. static inline struct mem* _next(struct mem* p, size_t sz)
  58. {
  59. return (void*)p + sizeof(struct mem) + sz;
  60. }
  61. static inline void _union(struct mem* p)
  62. {
  63. if (_is_end(p))
  64. return;
  65. for (struct mem* next = _next(p, p->sz);
  66. !(next->flag & MEM_ALLOCATED);
  67. next = _next(p, p->sz)) {
  68. if (_is_end(next)) {
  69. p->sz = 0;
  70. break;
  71. }
  72. p->sz += sizeof(struct mem);
  73. p->sz += next->sz;
  74. }
  75. }
  76. void* malloc(size_t size)
  77. {
  78. if (curr_brk == start_brk)
  79. _init_heap();
  80. if (size < MINIMUM_ALLOCATION_SIZE)
  81. size = MINIMUM_ALLOCATION_SIZE;
  82. struct mem* p = start_brk;
  83. size_t sz = 0;
  84. for (;; p = _next(p, p->sz)) {
  85. if (_is_allocated(p))
  86. continue;
  87. _union(p);
  88. sz = _size(p);
  89. if (_is_end(p)) {
  90. if (sz < size + sizeof(struct mem))
  91. sbrk(_max(128 * 1024, size + sizeof(struct mem)));
  92. sz = p->sz = size;
  93. struct mem* next = _next(p, size);
  94. next->flag = 0;
  95. next->sz = 0;
  96. break;
  97. }
  98. if (sz >= size)
  99. break;
  100. }
  101. p->flag |= MEM_ALLOCATED;
  102. if (sz >= size + sizeof(struct mem) + MINIMUM_ALLOCATION_SIZE) {
  103. p->sz = size;
  104. struct mem* next = _next(p, size);
  105. next->flag = 0;
  106. next->sz = sz - size - sizeof(struct mem);
  107. }
  108. return _next(p, 0);
  109. }
  110. void free(void* ptr)
  111. {
  112. struct mem* p = ptr - sizeof(struct mem);
  113. p->flag &= ~MEM_ALLOCATED;
  114. _union(p);
  115. }
  116. static inline void _swap(void* a, void* b, size_t sz)
  117. {
  118. void* tmp = alloca(sz);
  119. memcpy(tmp, a, sz);
  120. memcpy(a, b, sz);
  121. memcpy(b, tmp, sz);
  122. }
  123. void qsort(void* arr, size_t len, size_t sz, comparator_t cmp) {
  124. if (len <= 1)
  125. return;
  126. char* pivot = alloca(sz);
  127. memcpy(pivot, arr + sz * (rand() % len), sz);
  128. int i = 0, j = 0, k = len;
  129. while (i < k) {
  130. int res = cmp(arr + sz * i, pivot);
  131. if (res < 0)
  132. _swap(arr + sz * i++, arr + sz * j++, sz);
  133. else if (res > 0)
  134. _swap(arr + sz * i, arr + sz * --k, sz);
  135. else
  136. i++;
  137. }
  138. qsort(arr, j, sz, cmp);
  139. qsort(arr + sz * k, len - k, sz, cmp);
  140. }
  141. static unsigned int __next_rand;
  142. int rand(void)
  143. {
  144. return rand_r(&__next_rand);
  145. }
  146. int rand_r(unsigned int* seedp)
  147. {
  148. *seedp = *seedp * 1103515245 + 12345;
  149. return (unsigned int) (*seedp / 65536) % 32768;
  150. }
  151. void srand(unsigned int seed)
  152. {
  153. __next_rand = seed;
  154. rand();
  155. }
  156. void* bsearch(const void* key, const void* base, size_t num, size_t size, comparator_t cmp)
  157. {
  158. if (num == 0)
  159. return NULL;
  160. size_t mid = num / 2;
  161. int result = cmp(key, base + size * mid);
  162. if (result == 0)
  163. return (void*)base + size * mid;
  164. if (result > 0) {
  165. ++mid;
  166. return bsearch(key, base + size * mid, num - mid, size, cmp);
  167. }
  168. return bsearch(key, base, mid, size, cmp);
  169. }