File indexing completed on 2024-04-14 05:34:44

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 }