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