ActionLabel.cc 3.53 KB
Newer Older
Philip Trettner's avatar
Philip Trettner committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include "ActionLabel.hh"

#include "common/format.hh"

#include <vector>
#include <mutex>

#include <QString>
#include <QFileInfo>

#include "ActionEntry.hh"

using namespace aion;

#ifdef _MSC_VER
Philip Trettner's avatar
Philip Trettner committed
16
#include <Windows.h>
Philip Trettner's avatar
Philip Trettner committed
17
18
19
20
21
22
23
24
25
26
27
28
#define AION_THREADLOCAL __declspec(thread)
#else
#define AION_THREADLOCAL __thread // GCC 4.7 has no thread_local yet
#endif

namespace
{
AION_THREADLOCAL std::vector<ActionEntry> *sEntries = nullptr;
std::mutex sLabelLock;
std::vector<ActionLabel *> sLabels;
std::vector<std::vector<ActionEntry> *> sEntriesPerThread;

Philip Trettner's avatar
Philip Trettner committed
29
30
31
32
#if _MSC_VER
LARGE_INTEGER sFrequency; // null init
#endif

Philip Trettner's avatar
Philip Trettner committed
33
34
35
void writeTime(ActionEntry &e)
{
#if _MSC_VER
Philip Trettner's avatar
Philip Trettner committed
36
37
38
39
    LARGE_INTEGER time;
    QueryPerformanceCounter(&time);
    e.secs = int32_t(time.QuadPart / sFrequency.QuadPart);
    e.nsecs = int32_t((time.QuadPart % sFrequency.QuadPart) * 1000000000LL / sFrequency.QuadPart);
Philip Trettner's avatar
Philip Trettner committed
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
#else
    struct timespec t;
    clock_gettime(CLOCK_MONOTONIC, &t);
    e.secs = t.tv_sec;
    e.nsecs = t.tv_nsec;
#endif
}
}

std::string ActionLabel::shortDesc() const
{
    auto filename = QFileInfo(QString::fromStdString(mFile)).fileName().toStdString();

    auto name = mName;
    if (name.empty())
    {
        QString n = QString::fromStdString(mFunction);
        n = n.mid(0, n.indexOf('('));
        n = n.mid(n.lastIndexOf(' ') + 1);
        if (n.contains(':'))
            n = n.mid(n.lastIndexOf(':') + 1);
        name = n.toStdString() + "()";
    }
    else
        name = "\"" + name + "\"";

    return aion_fmt::format("{}, {}:{}", name, filename, mLine);
}

std::string ActionLabel::nameOrFunc() const
{
    auto name = mName;
    if (name.empty())
    {
        QString n = QString::fromStdString(mFunction);
        n = n.mid(0, n.indexOf('('));
        n = n.mid(n.lastIndexOf(' ') + 1);
        name = n.toStdString() + "()";
    }

    return name;
}

ActionLabel::ActionLabel(const char *file, int line, const char *function, const char *name)
  : mName(name), mFile(file), mLine(line), mFunction(function)
{
    sLabelLock.lock();
Philip Trettner's avatar
Philip Trettner committed
87
88
89
90
91
92

#if _MSC_VER
    if (sFrequency.QuadPart == 0)
        QueryPerformanceFrequency(&sFrequency);
#endif

Philip Trettner's avatar
Philip Trettner committed
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
    mIndex = sLabels.size();
    sLabels.push_back(this);
    if (!sEntries)
    {
        sEntries = new std::vector<ActionEntry>();
        sEntriesPerThread.push_back(sEntries);
    }
    sLabelLock.unlock();
}

void ActionLabel::startEntry()
{
    ActionEntry e;
    e.labelIdx = mIndex;
    writeTime(e);
    sEntries->push_back(e);
}

void ActionLabel::endEntry()
{
    ActionEntry e;
    e.labelIdx = -1; // end
    writeTime(e);
    sEntries->push_back(e);
}

std::vector<ActionLabel *> ActionLabel::getAllLabels()
{
    sLabelLock.lock();
    auto copy = sLabels;
    sLabelLock.unlock();
    return copy;
}

int64_t ActionLabel::getLastEntryIdx()
{
    return sEntries ? (int64_t)sEntries->size() - 1 : -1;
}

std::vector<ActionEntry> ActionLabel::copyEntries(int64_t startIdx, int64_t endIdx)
{
    if (startIdx < 0 || startIdx > endIdx)
        return {};
    if (!sEntries)
        return {};

    return std::vector<ActionEntry>(sEntries->begin() + startIdx, sEntries->begin() + endIdx + 1);
}

std::vector<ActionEntry> ActionLabel::copyAllEntries()
{
    std::vector<ActionEntry> entries;
    sLabelLock.lock();
    for (auto const &pes : sEntriesPerThread)
        entries.insert(end(entries), begin(*pes), end(*pes));
    sLabelLock.unlock();
    return entries;
}

ActionLabel::ActionLabel(const std::string &name, const std::string &function, const std::string &file, int line, int idx)
  : mName(name), mFile(file), mLine(line), mFunction(function), mIndex(idx)
{
}