run.c 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. #include "alloc/alloc.h"
  2. #include "tap.h"
  3. #include "alloc/alloc.c"
  4. #include <stdlib.h>
  5. #define POOL_ORD 16
  6. #define POOL_SIZE (1 << POOL_ORD)
  7. #define sort(p, num, cmp) \
  8. qsort((p), (num), sizeof(*p), (int(*)(const void *, const void *))cmp)
  9. static int addr_cmp(void **a, void **b)
  10. {
  11. return (*a) - (*b);
  12. }
  13. static bool unique(void *p[], unsigned int num)
  14. {
  15. unsigned int i;
  16. for (i = 1; i < num; i++)
  17. if (p[i] == p[i-1])
  18. return false;
  19. return true;
  20. }
  21. static bool free_every_second_one(void *mem, unsigned int num, void *p[])
  22. {
  23. unsigned int i;
  24. /* Free every second one. */
  25. for (i = 0; i < num; i += 2) {
  26. alloc_free(mem, POOL_SIZE, p[i]);
  27. if (!alloc_check(mem, POOL_SIZE))
  28. return false;
  29. }
  30. for (i = 1; i < num; i += 2) {
  31. alloc_free(mem, POOL_SIZE, p[i]);
  32. if (!alloc_check(mem, POOL_SIZE))
  33. return false;
  34. }
  35. return true;
  36. }
  37. int main(int argc, char *argv[])
  38. {
  39. void *mem;
  40. unsigned int i, num, max_size;
  41. void *p[POOL_SIZE];
  42. plan_tests(139);
  43. /* FIXME: Needs to be page aligned for now. */
  44. posix_memalign(&mem, getpagesize(), POOL_SIZE);
  45. /* Small pool, all allocs fail, even 0-length. */
  46. alloc_init(mem, 0);
  47. ok1(alloc_check(mem, 0));
  48. ok1(alloc_get(mem, 0, 1, 1) == NULL);
  49. ok1(alloc_get(mem, 0, 128, 1) == NULL);
  50. ok1(alloc_get(mem, 0, 0, 1) == NULL);
  51. /* Free of NULL should work. */
  52. alloc_free(mem, 0, NULL);
  53. alloc_init(mem, POOL_SIZE);
  54. ok1(alloc_check(mem, POOL_SIZE));
  55. /* Find largest allocation which works. */
  56. for (max_size = POOL_SIZE * 2; max_size; max_size--) {
  57. p[0] = alloc_get(mem, POOL_SIZE, max_size, 1);
  58. if (p[0])
  59. break;
  60. }
  61. ok1(max_size < POOL_SIZE);
  62. ok1(max_size > 0);
  63. ok1(alloc_check(mem, POOL_SIZE));
  64. /* Free it, should be able to reallocate it. */
  65. alloc_free(mem, POOL_SIZE, p[0]);
  66. ok1(alloc_check(mem, POOL_SIZE));
  67. p[0] = alloc_get(mem, POOL_SIZE, max_size, 1);
  68. ok1(p[0]);
  69. ok1(alloc_check(mem, POOL_SIZE));
  70. alloc_free(mem, POOL_SIZE, p[0]);
  71. ok1(alloc_check(mem, POOL_SIZE));
  72. /* Allocate a whole heap. */
  73. for (i = 0; i < POOL_SIZE; i++) {
  74. p[i] = alloc_get(mem, POOL_SIZE, 1, 1);
  75. if (!p[i])
  76. break;
  77. }
  78. /* Uncomment this for a more intuitive view of what the
  79. * allocator looks like after all these 1 byte allocs. */
  80. #if 0
  81. alloc_visualize(stderr, mem, POOL_SIZE);
  82. #endif
  83. num = i;
  84. /* Can't allocate this many. */
  85. ok1(num != POOL_SIZE);
  86. ok1(alloc_check(mem, POOL_SIZE));
  87. /* Sort them. */
  88. sort(p, num, addr_cmp);
  89. /* Uniqueness check */
  90. ok1(unique(p, num));
  91. ok1(free_every_second_one(mem, num, p));
  92. ok1(alloc_check(mem, POOL_SIZE));
  93. /* Should be able to reallocate max size. */
  94. p[0] = alloc_get(mem, POOL_SIZE, max_size, 1);
  95. ok1(p[0]);
  96. ok1(alloc_check(mem, POOL_SIZE));
  97. /* Re-initializing should be the same as freeing everything */
  98. alloc_init(mem, POOL_SIZE);
  99. ok1(alloc_check(mem, POOL_SIZE));
  100. p[0] = alloc_get(mem, POOL_SIZE, max_size, 1);
  101. ok1(p[0]);
  102. ok1(alloc_check(mem, POOL_SIZE));
  103. alloc_free(mem, POOL_SIZE, p[0]);
  104. ok1(alloc_check(mem, POOL_SIZE));
  105. /* Alignment constraints should be met, as long as powers of two */
  106. for (i = 0; i < POOL_ORD-1; i++) {
  107. p[i] = alloc_get(mem, POOL_SIZE, i, 1 << i);
  108. ok1(p[i]);
  109. ok1(((unsigned long)p[i] % (1 << i)) == 0);
  110. ok1(alloc_check(mem, POOL_SIZE));
  111. }
  112. for (i = 0; i < POOL_ORD-1; i++) {
  113. alloc_free(mem, POOL_SIZE, p[i]);
  114. ok1(alloc_check(mem, POOL_SIZE));
  115. }
  116. /* Alignment constraints for a single-byte allocation. */
  117. for (i = 0; i < POOL_ORD; i++) {
  118. p[0] = alloc_get(mem, POOL_SIZE, 1, 1 << i);
  119. ok1(p[0]);
  120. ok1(alloc_check(mem, POOL_SIZE));
  121. alloc_free(mem, POOL_SIZE, p[0]);
  122. ok1(alloc_check(mem, POOL_SIZE));
  123. }
  124. /* Alignment check for a 0-byte allocation. Corner case. */
  125. p[0] = alloc_get(mem, POOL_SIZE, 0, 1 << (POOL_ORD - 1));
  126. ok1(alloc_check(mem, POOL_SIZE));
  127. alloc_free(mem, POOL_SIZE, p[0]);
  128. ok1(alloc_check(mem, POOL_SIZE));
  129. /* Force the testing of split metadata. */
  130. alloc_init(mem, POOL_SIZE);
  131. for (i = 0; i < POOL_SIZE; i++) {
  132. p[i] = alloc_get(mem, POOL_SIZE, getpagesize(), getpagesize());
  133. if (!p[i])
  134. break;
  135. }
  136. ok1(alloc_check(mem, POOL_SIZE));
  137. /* Sort them. */
  138. sort(p, i-1, addr_cmp);
  139. /* Free all but the one next to the metadata. */
  140. for (i = 1; p[i]; i++)
  141. alloc_free(mem, POOL_SIZE, p[i]);
  142. ok1(alloc_check(mem, POOL_SIZE));
  143. /* Now do a whole heap of subpage allocs. */
  144. for (i = 1; i < POOL_SIZE; i++) {
  145. p[i] = alloc_get(mem, POOL_SIZE, 1, 1);
  146. if (!p[i])
  147. break;
  148. }
  149. ok1(alloc_check(mem, POOL_SIZE));
  150. /* Free up our page next to metadata, and should be able to alloc */
  151. alloc_free(mem, POOL_SIZE, p[0]);
  152. ok1(alloc_check(mem, POOL_SIZE));
  153. p[0] = alloc_get(mem, POOL_SIZE, 1, 1);
  154. ok1(p[0]);
  155. /* Clean up. */
  156. for (i = 0; p[i]; i++)
  157. alloc_free(mem, POOL_SIZE, p[i]);
  158. ok1(alloc_check(mem, POOL_SIZE));
  159. return exit_status();
  160. }