File indexing completed on 2024-09-15 13:07:08
0001 /* 0002 SPDX-FileCopyrightText: 2018 Milian Wolff <mail@milianw.de> 0003 0004 SPDX-License-Identifier: LGPL-2.1-or-later 0005 */ 0006 0007 #define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN 0008 #include "3rdparty/doctest.h" 0009 0010 #include "track/libheaptrack.h" 0011 #include "util/linewriter.h" 0012 0013 #include <cmath> 0014 #include <cstdio> 0015 0016 #include <future> 0017 #include <iostream> 0018 #include <thread> 0019 #include <vector> 0020 0021 #include "tempfile.h" 0022 0023 bool initBeforeCalled = false; 0024 bool initAfterCalled = false; 0025 bool stopCalled = false; 0026 0027 using namespace std; 0028 0029 TEST_CASE ("api") { 0030 TempFile tmp; // opened/closed by heaptrack_init 0031 0032 SUBCASE("init") 0033 { 0034 heaptrack_init( 0035 tmp.fileName.c_str(), 0036 []() { 0037 REQUIRE(!initBeforeCalled); 0038 REQUIRE(!initAfterCalled); 0039 REQUIRE(!stopCalled); 0040 initBeforeCalled = true; 0041 }, 0042 [](LineWriter& /*out*/) { 0043 REQUIRE(initBeforeCalled); 0044 REQUIRE(!initAfterCalled); 0045 REQUIRE(!stopCalled); 0046 initAfterCalled = true; 0047 }, 0048 []() { 0049 REQUIRE(initBeforeCalled); 0050 REQUIRE(initAfterCalled); 0051 REQUIRE(!stopCalled); 0052 stopCalled = true; 0053 }); 0054 0055 REQUIRE(initBeforeCalled); 0056 REQUIRE(initAfterCalled); 0057 REQUIRE(!stopCalled); 0058 0059 int data[2] = {0}; 0060 0061 SUBCASE("no-op-malloc") 0062 { 0063 heaptrack_malloc(0, 0); 0064 } 0065 SUBCASE("no-op-malloc-free") 0066 { 0067 heaptrack_free(0); 0068 } 0069 SUBCASE("no-op-malloc-realloc") 0070 { 0071 heaptrack_realloc(data, 1, 0); 0072 } 0073 0074 SUBCASE("malloc-free") 0075 { 0076 heaptrack_malloc(data, 4); 0077 heaptrack_free(data); 0078 } 0079 0080 SUBCASE("realloc") 0081 { 0082 heaptrack_malloc(data, 4); 0083 heaptrack_realloc(data, 8, data); 0084 heaptrack_realloc(data, 16, data + 1); 0085 heaptrack_free(data + 1); 0086 } 0087 0088 SUBCASE("invalidate-cache") 0089 { 0090 heaptrack_invalidate_module_cache(); 0091 } 0092 0093 SUBCASE("multi-threaded") 0094 { 0095 const auto numThreads = min(4u, thread::hardware_concurrency()); 0096 0097 cout << "start threads" << endl; 0098 { 0099 vector<future<void>> futures; 0100 for (unsigned i = 0; i < numThreads; ++i) { 0101 futures.emplace_back(async(launch::async, []() { 0102 for (int i = 0; i < 10000; ++i) { 0103 heaptrack_malloc(&i, i); 0104 heaptrack_realloc(&i, i + 1, &i); 0105 heaptrack_free(&i); 0106 if (i % 100 == 0) { 0107 heaptrack_invalidate_module_cache(); 0108 } 0109 } 0110 })); 0111 } 0112 } 0113 cout << "threads finished" << endl; 0114 } 0115 0116 SUBCASE("stop") 0117 { 0118 heaptrack_stop(); 0119 REQUIRE(stopCalled); 0120 } 0121 } 0122 }