Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mesa
Path: blob/21.2-virgl/src/gallium/drivers/swr/rasterizer/common/rdtsc_buckets.cpp
4574 views
1
/****************************************************************************
2
* Copyright (C) 2014-2015 Intel Corporation. All Rights Reserved.
3
*
4
* Permission is hereby granted, free of charge, to any person obtaining a
5
* copy of this software and associated documentation files (the "Software"),
6
* to deal in the Software without restriction, including without limitation
7
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
8
* and/or sell copies of the Software, and to permit persons to whom the
9
* Software is furnished to do so, subject to the following conditions:
10
*
11
* The above copyright notice and this permission notice (including the next
12
* paragraph) shall be included in all copies or substantial portions of the
13
* Software.
14
*
15
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21
* IN THE SOFTWARE.
22
*
23
* @file rdtsc_buckets.cpp
24
*
25
* @brief implementation of rdtsc buckets.
26
*
27
* Notes:
28
*
29
******************************************************************************/
30
#include "rdtsc_buckets.h"
31
#include <inttypes.h>
32
33
#if defined(_WIN32)
34
#define PATH_SEPARATOR "\\"
35
#elif defined(__unix__) || defined(__APPLE__)
36
#define PATH_SEPARATOR "/"
37
#else
38
#error "Unsupported platform"
39
#endif
40
41
THREAD UINT tlsThreadId = 0;
42
43
BucketManager::~BucketManager()
44
{
45
}
46
47
void BucketManager::RegisterThread(const std::string& name)
48
{
49
50
BUCKET_THREAD newThread;
51
newThread.name = name;
52
newThread.root.children.reserve(mBuckets.size());
53
newThread.root.id = 0;
54
newThread.root.pParent = nullptr;
55
newThread.pCurrent = &newThread.root;
56
57
mThreadMutex.lock();
58
59
// assign unique thread id for this thread
60
size_t id = mThreads.size();
61
newThread.id = (UINT)id;
62
tlsThreadId = (UINT)id;
63
64
// store new thread
65
mThreads.push_back(newThread);
66
67
mThreadMutex.unlock();
68
}
69
70
UINT BucketManager::RegisterBucket(const BUCKET_DESC& desc)
71
{
72
mThreadMutex.lock();
73
size_t id = mBuckets.size();
74
mBuckets.push_back(desc);
75
mThreadMutex.unlock();
76
return (UINT)id;
77
}
78
79
void BucketManager::PrintBucket(
80
FILE* f, UINT level, uint64_t threadCycles, uint64_t parentCycles, const BUCKET& bucket)
81
{
82
const char* arrows[] = {
83
"",
84
"|-> ",
85
" |-> ",
86
" |-> ",
87
" |-> ",
88
" |-> ",
89
" |-> ",
90
" |-> ",
91
" |-> ",
92
};
93
94
// compute percent of total cycles used by this bucket
95
float percentTotal = (float)((double)bucket.elapsed / (double)threadCycles * 100.0);
96
97
// compute percent of parent cycles used by this bucket
98
float percentParent = (float)((double)bucket.elapsed / (double)parentCycles * 100.0);
99
100
// compute average cycle count per invocation
101
uint64_t CPE = bucket.elapsed / bucket.count;
102
103
BUCKET_DESC& desc = mBuckets[bucket.id];
104
105
// construct hierarchy visualization
106
std::string str = arrows[level];
107
str += desc.name;
108
char hier[80];
109
strcpy_s(hier, sizeof(hier)-1, str.c_str());
110
111
// print out
112
fprintf(f,
113
"%6.2f %6.2f %-10" PRIu64 " %-10" PRIu64 " %-10u %-10lu %-10u %s\n",
114
percentTotal,
115
percentParent,
116
bucket.elapsed,
117
CPE,
118
bucket.count,
119
(unsigned long)0,
120
(uint32_t)0,
121
hier);
122
123
// dump all children of this bucket
124
for (const BUCKET& child : bucket.children)
125
{
126
if (child.count)
127
{
128
PrintBucket(f, level + 1, threadCycles, bucket.elapsed, child);
129
}
130
}
131
}
132
133
void BucketManager::PrintThread(FILE* f, const BUCKET_THREAD& thread)
134
{
135
// print header
136
fprintf(f, "\nThread %u (%s)\n", thread.id, thread.name.c_str());
137
fprintf(f, " %%Tot %%Par Cycles CPE NumEvent CPE2 NumEvent2 Bucket\n");
138
139
// compute thread level total cycle counts across all buckets from root
140
const BUCKET& root = thread.root;
141
uint64_t totalCycles = 0;
142
for (const BUCKET& child : root.children)
143
{
144
totalCycles += child.elapsed;
145
}
146
147
for (const BUCKET& child : root.children)
148
{
149
if (child.count)
150
{
151
PrintBucket(f, 0, totalCycles, totalCycles, child);
152
}
153
}
154
}
155
156
void BucketManager::PrintReport(const std::string& filename)
157
{
158
{
159
FILE* f = fopen(filename.c_str(), "w");
160
assert(f);
161
162
mThreadMutex.lock();
163
for (const BUCKET_THREAD& thread : mThreads)
164
{
165
PrintThread(f, thread);
166
fprintf(f, "\n");
167
}
168
169
mThreadMutex.unlock();
170
171
fclose(f);
172
}
173
}
174
175
176
void BucketManager::StartCapture()
177
{
178
179
printf("Capture Starting\n");
180
181
mCapturing = true;
182
}
183
184
void BucketManager_StartBucket(BucketManager* pBucketMgr, uint32_t id)
185
{
186
pBucketMgr->StartBucket(id);
187
}
188
189
void BucketManager_StopBucket(BucketManager* pBucketMgr, uint32_t id)
190
{
191
pBucketMgr->StopBucket(id);
192
}
193
194