allocated.c 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. #include "test/jemalloc_test.h"
  2. static const bool config_stats =
  3. #ifdef JEMALLOC_STATS
  4. true
  5. #else
  6. false
  7. #endif
  8. ;
  9. void *
  10. thd_start(void *arg)
  11. {
  12. int err;
  13. void *p;
  14. uint64_t a0, a1, d0, d1;
  15. uint64_t *ap0, *ap1, *dp0, *dp1;
  16. size_t sz, usize;
  17. sz = sizeof(a0);
  18. if ((err = mallctl("thread.allocated", &a0, &sz, NULL, 0))) {
  19. if (err == ENOENT)
  20. goto label_ENOENT;
  21. test_fail("%s(): Error in mallctl(): %s", __func__,
  22. strerror(err));
  23. }
  24. sz = sizeof(ap0);
  25. if ((err = mallctl("thread.allocatedp", &ap0, &sz, NULL, 0))) {
  26. if (err == ENOENT)
  27. goto label_ENOENT;
  28. test_fail("%s(): Error in mallctl(): %s", __func__,
  29. strerror(err));
  30. }
  31. assert_u64_eq(*ap0, a0,
  32. "\"thread.allocatedp\" should provide a pointer to internal "
  33. "storage");
  34. sz = sizeof(d0);
  35. if ((err = mallctl("thread.deallocated", &d0, &sz, NULL, 0))) {
  36. if (err == ENOENT)
  37. goto label_ENOENT;
  38. test_fail("%s(): Error in mallctl(): %s", __func__,
  39. strerror(err));
  40. }
  41. sz = sizeof(dp0);
  42. if ((err = mallctl("thread.deallocatedp", &dp0, &sz, NULL, 0))) {
  43. if (err == ENOENT)
  44. goto label_ENOENT;
  45. test_fail("%s(): Error in mallctl(): %s", __func__,
  46. strerror(err));
  47. }
  48. assert_u64_eq(*dp0, d0,
  49. "\"thread.deallocatedp\" should provide a pointer to internal "
  50. "storage");
  51. p = malloc(1);
  52. assert_ptr_not_null(p, "Unexpected malloc() error");
  53. sz = sizeof(a1);
  54. mallctl("thread.allocated", &a1, &sz, NULL, 0);
  55. sz = sizeof(ap1);
  56. mallctl("thread.allocatedp", &ap1, &sz, NULL, 0);
  57. assert_u64_eq(*ap1, a1,
  58. "Dereferenced \"thread.allocatedp\" value should equal "
  59. "\"thread.allocated\" value");
  60. assert_ptr_eq(ap0, ap1,
  61. "Pointer returned by \"thread.allocatedp\" should not change");
  62. usize = malloc_usable_size(p);
  63. assert_u64_le(a0 + usize, a1,
  64. "Allocated memory counter should increase by at least the amount "
  65. "explicitly allocated");
  66. free(p);
  67. sz = sizeof(d1);
  68. mallctl("thread.deallocated", &d1, &sz, NULL, 0);
  69. sz = sizeof(dp1);
  70. mallctl("thread.deallocatedp", &dp1, &sz, NULL, 0);
  71. assert_u64_eq(*dp1, d1,
  72. "Dereferenced \"thread.deallocatedp\" value should equal "
  73. "\"thread.deallocated\" value");
  74. assert_ptr_eq(dp0, dp1,
  75. "Pointer returned by \"thread.deallocatedp\" should not change");
  76. assert_u64_le(d0 + usize, d1,
  77. "Deallocated memory counter should increase by at least the amount "
  78. "explicitly deallocated");
  79. return (NULL);
  80. label_ENOENT:
  81. assert_false(config_stats,
  82. "ENOENT should only be returned if stats are disabled");
  83. test_skip("\"thread.allocated\" mallctl not available");
  84. return (NULL);
  85. }
  86. TEST_BEGIN(test_main_thread)
  87. {
  88. thd_start(NULL);
  89. }
  90. TEST_END
  91. TEST_BEGIN(test_subthread)
  92. {
  93. thd_t thd;
  94. thd_create(&thd, thd_start, NULL);
  95. thd_join(thd, NULL);
  96. }
  97. TEST_END
  98. int
  99. main(void)
  100. {
  101. /* Run tests multiple times to check for bad interactions. */
  102. return (test(
  103. test_main_thread,
  104. test_subthread,
  105. test_main_thread,
  106. test_subthread,
  107. test_main_thread));
  108. }