mallocx.c 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. #include "test/jemalloc_test.h"
  2. static unsigned
  3. get_nsizes_impl(const char *cmd)
  4. {
  5. unsigned ret;
  6. size_t z;
  7. z = sizeof(unsigned);
  8. assert_d_eq(mallctl(cmd, &ret, &z, NULL, 0), 0,
  9. "Unexpected mallctl(\"%s\", ...) failure", cmd);
  10. return (ret);
  11. }
  12. static unsigned
  13. get_nhuge(void)
  14. {
  15. return (get_nsizes_impl("arenas.nhchunks"));
  16. }
  17. static size_t
  18. get_size_impl(const char *cmd, size_t ind)
  19. {
  20. size_t ret;
  21. size_t z;
  22. size_t mib[4];
  23. size_t miblen = 4;
  24. z = sizeof(size_t);
  25. assert_d_eq(mallctlnametomib(cmd, mib, &miblen),
  26. 0, "Unexpected mallctlnametomib(\"%s\", ...) failure", cmd);
  27. mib[2] = ind;
  28. z = sizeof(size_t);
  29. assert_d_eq(mallctlbymib(mib, miblen, &ret, &z, NULL, 0),
  30. 0, "Unexpected mallctlbymib([\"%s\", %zu], ...) failure", cmd, ind);
  31. return (ret);
  32. }
  33. static size_t
  34. get_huge_size(size_t ind)
  35. {
  36. return (get_size_impl("arenas.hchunk.0.size", ind));
  37. }
  38. TEST_BEGIN(test_oom)
  39. {
  40. size_t hugemax, size, alignment;
  41. hugemax = get_huge_size(get_nhuge()-1);
  42. /*
  43. * It should be impossible to allocate two objects that each consume
  44. * more than half the virtual address space.
  45. */
  46. {
  47. void *p;
  48. p = mallocx(hugemax, 0);
  49. if (p != NULL) {
  50. assert_ptr_null(mallocx(hugemax, 0),
  51. "Expected OOM for mallocx(size=%#zx, 0)", hugemax);
  52. dallocx(p, 0);
  53. }
  54. }
  55. #if LG_SIZEOF_PTR == 3
  56. size = ZU(0x8000000000000000);
  57. alignment = ZU(0x8000000000000000);
  58. #else
  59. size = ZU(0x80000000);
  60. alignment = ZU(0x80000000);
  61. #endif
  62. assert_ptr_null(mallocx(size, MALLOCX_ALIGN(alignment)),
  63. "Expected OOM for mallocx(size=%#zx, MALLOCX_ALIGN(%#zx)", size,
  64. alignment);
  65. }
  66. TEST_END
  67. TEST_BEGIN(test_basic)
  68. {
  69. #define MAXSZ (((size_t)1) << 26)
  70. size_t sz;
  71. for (sz = 1; sz < MAXSZ; sz = nallocx(sz, 0) + 1) {
  72. size_t nsz, rsz;
  73. void *p;
  74. nsz = nallocx(sz, 0);
  75. assert_zu_ne(nsz, 0, "Unexpected nallocx() error");
  76. p = mallocx(sz, 0);
  77. assert_ptr_not_null(p, "Unexpected mallocx() error");
  78. rsz = sallocx(p, 0);
  79. assert_zu_ge(rsz, sz, "Real size smaller than expected");
  80. assert_zu_eq(nsz, rsz, "nallocx()/sallocx() size mismatch");
  81. dallocx(p, 0);
  82. p = mallocx(sz, 0);
  83. assert_ptr_not_null(p, "Unexpected mallocx() error");
  84. dallocx(p, 0);
  85. nsz = nallocx(sz, MALLOCX_ZERO);
  86. assert_zu_ne(nsz, 0, "Unexpected nallocx() error");
  87. p = mallocx(sz, MALLOCX_ZERO);
  88. assert_ptr_not_null(p, "Unexpected mallocx() error");
  89. rsz = sallocx(p, 0);
  90. assert_zu_eq(nsz, rsz, "nallocx()/sallocx() rsize mismatch");
  91. dallocx(p, 0);
  92. }
  93. #undef MAXSZ
  94. }
  95. TEST_END
  96. TEST_BEGIN(test_alignment_and_size)
  97. {
  98. #define MAXALIGN (((size_t)1) << 25)
  99. #define NITER 4
  100. size_t nsz, rsz, sz, alignment, total;
  101. unsigned i;
  102. void *ps[NITER];
  103. for (i = 0; i < NITER; i++)
  104. ps[i] = NULL;
  105. for (alignment = 8;
  106. alignment <= MAXALIGN;
  107. alignment <<= 1) {
  108. total = 0;
  109. for (sz = 1;
  110. sz < 3 * alignment && sz < (1U << 31);
  111. sz += (alignment >> (LG_SIZEOF_PTR-1)) - 1) {
  112. for (i = 0; i < NITER; i++) {
  113. nsz = nallocx(sz, MALLOCX_ALIGN(alignment) |
  114. MALLOCX_ZERO);
  115. assert_zu_ne(nsz, 0,
  116. "nallocx() error for alignment=%zu, "
  117. "size=%zu (%#zx)", alignment, sz, sz);
  118. ps[i] = mallocx(sz, MALLOCX_ALIGN(alignment) |
  119. MALLOCX_ZERO);
  120. assert_ptr_not_null(ps[i],
  121. "mallocx() error for alignment=%zu, "
  122. "size=%zu (%#zx)", alignment, sz, sz);
  123. rsz = sallocx(ps[i], 0);
  124. assert_zu_ge(rsz, sz,
  125. "Real size smaller than expected for "
  126. "alignment=%zu, size=%zu", alignment, sz);
  127. assert_zu_eq(nsz, rsz,
  128. "nallocx()/sallocx() size mismatch for "
  129. "alignment=%zu, size=%zu", alignment, sz);
  130. assert_ptr_null(
  131. (void *)((uintptr_t)ps[i] & (alignment-1)),
  132. "%p inadequately aligned for"
  133. " alignment=%zu, size=%zu", ps[i],
  134. alignment, sz);
  135. total += rsz;
  136. if (total >= (MAXALIGN << 1))
  137. break;
  138. }
  139. for (i = 0; i < NITER; i++) {
  140. if (ps[i] != NULL) {
  141. dallocx(ps[i], 0);
  142. ps[i] = NULL;
  143. }
  144. }
  145. }
  146. }
  147. #undef MAXALIGN
  148. #undef NITER
  149. }
  150. TEST_END
  151. int
  152. main(void)
  153. {
  154. return (test(
  155. test_oom,
  156. test_basic,
  157. test_alignment_and_size));
  158. }