// comment or empty line
continue;
} else if (reader.mode() == 'c') {
- // TODO: implement time tracking
size_t newStamp = 0;
if (!(reader >> newStamp)) {
cerr << "Failed to read time stamp: " << reader.line() << endl;
<< "time_unit: s\n";
}
- void writeMassifSnapshot(size_t snapshot, bool isLast)
+ void writeMassifSnapshot(size_t timeStamp, bool isLast)
{
// the heap consumption we annotate this snapshot with
size_t heapSize = 0;
<< "#-----------\n"
<< "snapshot=" << massifSnapshotId << '\n'
<< "#-----------\n"
- << "time=" << double(snapshot) * 0.01 << '\n'
+ << "time=" << (0.001 * timeStamp) << '\n'
<< "mem_heap_B=" << heapSize << '\n'
<< "mem_heap_extra_B=0\n"
<< "mem_stacks_B=0\n";
#include <memory>
#include <unordered_set>
#include <mutex>
+#include <thread>
#include <boost/algorithm/string/replace.hpp>
#include "tracetree.h"
-#include "timer.h"
/**
* uncomment this to get extended debug code for known pointers
struct Data
{
- void handleMalloc(void* ptr, size_t size, const Trace &trace, FILE* out)
+ Data()
{
- if (lastTimerElapsed != timer.timesElapsed()) {
- lastTimerElapsed = timer.timesElapsed();
- if (fprintf(out, "c %lx\n", lastTimerElapsed) < 0) {
- heaptrack_stop();
- return;
+ timerThread = thread([&] () {
+ using clock = chrono::steady_clock;
+ const auto start = clock::now();
+ while (!stopTimerThread) {
+ // TODO: make interval customizable
+ this_thread::sleep_for(chrono::milliseconds(10));
+ auto elapsed = chrono::duration_cast<chrono::milliseconds>(clock::now() - start);
+
+ if (FILE* out = outputHandle.load()) {
+ LockGuard lock(out);
+ if (fprintf(out, "c %lx\n", elapsed.count()) < 0) {
+ heaptrack_stop();
+ return;
+ }
+ }
}
- }
+ });
+ }
+
+ ~Data()
+ {
+ stopTimerThread = true;
+ timerThread.join();
+ }
+
+ void handleMalloc(void* ptr, size_t size, const Trace &trace, FILE* out)
+ {
if (moduleCacheDirty) {
updateModuleCache(out);
}
TraceTree traceTree;
- size_t lastTimerElapsed = 0;
- Timer timer;
+ atomic<bool> stopTimerThread;
+ thread timerThread;
#ifdef DEBUG_MALLOC_PTRS
unordered_set<void*> known;
HandleGuard guard;
if (outputHandle) {
flockfile(outputHandle.load());
- printf("shutting down heaptrack!\n");
fclose(outputHandle.exchange(nullptr));
delete data.exchange(nullptr);
if (auto stop = s_stopCallback.exchange(nullptr)) {
+++ /dev/null
-/*
- * Copyright 2014 Milian Wolff <mail@milianw.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Library General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public
- * License along with this program; if not, write to the
- * Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-#ifndef TIMER_H
-#define TIMER_H
-
-#include <stdlib.h>
-#include <unistd.h>
-#include <stdio.h>
-#include <signal.h>
-#include <time.h>
-#include <cassert>
-
-#include <limits>
-#include <atomic>
-
-class Timer
-{
-public:
- Timer()
- : m_timesElapsed(0)
- , m_timerId(0)
- {
- sigevent sev;
- sev.sigev_notify = SIGEV_THREAD;
- sev.sigev_notify_function = &Timer::handler;
- sev.sigev_notify_attributes = nullptr;
- sev.sigev_value.sival_ptr = this;
- if (timer_create(CLOCK_REALTIME, &sev, &m_timerId) == -1) {
- fprintf(stderr, "Failed to call timer_create in %s:%d: %s",
- __FILE__, __LINE__, strerror(errno));
- return;
- }
-
- /* Start/Stop the timer */
- itimerspec its;
- its.it_value.tv_sec = 0;
- its.it_value.tv_nsec = 10 * 1000 * 1000;
- its.it_interval.tv_sec = its.it_value.tv_sec;
- its.it_interval.tv_nsec = its.it_value.tv_nsec;
-
- if (timer_settime(m_timerId, 0, &its, nullptr) == -1) {
- fprintf(stderr, "Failed to call timer_settime in %s:%d: %s",
- __FILE__, __LINE__, strerror(errno));
- return;
- }
- }
-
- ~Timer()
- {
- timer_delete(m_timerId);
- }
-
- size_t timesElapsed() const
- {
- return m_timesElapsed;
- }
-
-private:
- static void handler(union sigval value)
- {
- Timer* timer = static_cast<Timer*>(value.sival_ptr);
-
- timer->m_timesElapsed += timer_getoverrun(timer->m_timerId) + 1;
- }
-
- std::atomic<size_t> m_timesElapsed;
- timer_t m_timerId;
-};
-
-#endif