aligned_alloc.c 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. #include "test/jemalloc_test.h"
  2. #define MAXALIGN (((size_t)1) << 23)
  3. /*
  4. * On systems which can't merge extents, tests that call this function generate
  5. * a lot of dirty memory very quickly. Purging between cycles mitigates
  6. * potential OOM on e.g. 32-bit Windows.
  7. */
  8. static void
  9. purge(void) {
  10. assert_d_eq(mallctl("arena.0.purge", NULL, NULL, NULL, 0), 0,
  11. "Unexpected mallctl error");
  12. }
  13. TEST_BEGIN(test_alignment_errors) {
  14. size_t alignment;
  15. void *p;
  16. alignment = 0;
  17. set_errno(0);
  18. p = aligned_alloc(alignment, 1);
  19. assert_false(p != NULL || get_errno() != EINVAL,
  20. "Expected error for invalid alignment %zu", alignment);
  21. for (alignment = sizeof(size_t); alignment < MAXALIGN;
  22. alignment <<= 1) {
  23. set_errno(0);
  24. p = aligned_alloc(alignment + 1, 1);
  25. assert_false(p != NULL || get_errno() != EINVAL,
  26. "Expected error for invalid alignment %zu",
  27. alignment + 1);
  28. }
  29. }
  30. TEST_END
  31. /*
  32. * GCC "-Walloc-size-larger-than" warning detects when one of the memory
  33. * allocation functions is called with a size larger than the maximum size that
  34. * they support. Here we want to explicitly test that the allocation functions
  35. * do indeed fail properly when this is the case, which triggers the warning.
  36. * Therefore we disable the warning for these tests.
  37. */
  38. JEMALLOC_DIAGNOSTIC_PUSH
  39. JEMALLOC_DIAGNOSTIC_IGNORE_ALLOC_SIZE_LARGER_THAN
  40. TEST_BEGIN(test_oom_errors) {
  41. size_t alignment, size;
  42. void *p;
  43. #if LG_SIZEOF_PTR == 3
  44. alignment = UINT64_C(0x8000000000000000);
  45. size = UINT64_C(0x8000000000000000);
  46. #else
  47. alignment = 0x80000000LU;
  48. size = 0x80000000LU;
  49. #endif
  50. set_errno(0);
  51. p = aligned_alloc(alignment, size);
  52. assert_false(p != NULL || get_errno() != ENOMEM,
  53. "Expected error for aligned_alloc(%zu, %zu)",
  54. alignment, size);
  55. #if LG_SIZEOF_PTR == 3
  56. alignment = UINT64_C(0x4000000000000000);
  57. size = UINT64_C(0xc000000000000001);
  58. #else
  59. alignment = 0x40000000LU;
  60. size = 0xc0000001LU;
  61. #endif
  62. set_errno(0);
  63. p = aligned_alloc(alignment, size);
  64. assert_false(p != NULL || get_errno() != ENOMEM,
  65. "Expected error for aligned_alloc(%zu, %zu)",
  66. alignment, size);
  67. alignment = 0x10LU;
  68. #if LG_SIZEOF_PTR == 3
  69. size = UINT64_C(0xfffffffffffffff0);
  70. #else
  71. size = 0xfffffff0LU;
  72. #endif
  73. set_errno(0);
  74. p = aligned_alloc(alignment, size);
  75. assert_false(p != NULL || get_errno() != ENOMEM,
  76. "Expected error for aligned_alloc(&p, %zu, %zu)",
  77. alignment, size);
  78. }
  79. TEST_END
  80. /* Re-enable the "-Walloc-size-larger-than=" warning */
  81. JEMALLOC_DIAGNOSTIC_POP
  82. TEST_BEGIN(test_alignment_and_size) {
  83. #define NITER 4
  84. size_t alignment, size, total;
  85. unsigned i;
  86. void *ps[NITER];
  87. for (i = 0; i < NITER; i++) {
  88. ps[i] = NULL;
  89. }
  90. for (alignment = 8;
  91. alignment <= MAXALIGN;
  92. alignment <<= 1) {
  93. total = 0;
  94. for (size = 1;
  95. size < 3 * alignment && size < (1U << 31);
  96. size += (alignment >> (LG_SIZEOF_PTR-1)) - 1) {
  97. for (i = 0; i < NITER; i++) {
  98. ps[i] = aligned_alloc(alignment, size);
  99. if (ps[i] == NULL) {
  100. char buf[BUFERROR_BUF];
  101. buferror(get_errno(), buf, sizeof(buf));
  102. test_fail(
  103. "Error for alignment=%zu, "
  104. "size=%zu (%#zx): %s",
  105. alignment, size, size, buf);
  106. }
  107. total += malloc_usable_size(ps[i]);
  108. if (total >= (MAXALIGN << 1)) {
  109. break;
  110. }
  111. }
  112. for (i = 0; i < NITER; i++) {
  113. if (ps[i] != NULL) {
  114. free(ps[i]);
  115. ps[i] = NULL;
  116. }
  117. }
  118. }
  119. purge();
  120. }
  121. #undef NITER
  122. }
  123. TEST_END
  124. TEST_BEGIN(test_zero_alloc) {
  125. void *res = aligned_alloc(8, 0);
  126. assert(res);
  127. size_t usable = malloc_usable_size(res);
  128. assert(usable > 0);
  129. free(res);
  130. }
  131. TEST_END
  132. int
  133. main(void) {
  134. return test(
  135. test_alignment_errors,
  136. test_oom_errors,
  137. test_alignment_and_size,
  138. test_zero_alloc);
  139. }