1 /****************************************************************************
2 * Copyright (C) 2014-2015 Intel Corporation. All Rights Reserved.
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:
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
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
23 * @file rdtsc_buckets.h
25 * @brief declaration for rdtsc buckets.
29 ******************************************************************************/
37 #include "rdtsc_buckets_shared.h"
40 // unique thread id stored in thread local storage
41 extern THREAD UINT tlsThreadId
;
43 //////////////////////////////////////////////////////////////////////////
44 /// @brief BucketManager encapsulates a single instance of the buckets
45 /// functionality. There can be one or many bucket managers active
46 /// at any time. The manager owns all the threads and
47 /// bucket information that have been registered to it.
54 // removes all registered thread data
59 mThreadMutex
.unlock();
62 // removes all registered buckets
67 mThreadMutex
.unlock();
70 /// Registers a new thread with the manager.
71 /// @param name - name of thread, used for labels in reports and threadviz
72 void RegisterThread(const std::string
& name
);
74 /// Registers a new bucket type with the manager. Returns a unique
75 /// id which should be used in subsequent calls to start/stop the bucket
76 /// @param desc - description of the bucket
78 UINT
RegisterBucket(const BUCKET_DESC
& desc
);
81 void PrintReport(const std::string
& filename
);
88 INLINE
void StopCapture()
92 // wait for all threads to pop back to root bucket
93 bool stillCapturing
= true;
94 while (stillCapturing
)
96 stillCapturing
= false;
97 for (const BUCKET_THREAD
& t
: mThreads
)
101 stillCapturing
= true;
107 mDoneCapturing
= true;
108 printf("Capture Stopped\n");
112 // @param id generated by RegisterBucket
113 INLINE
void StartBucket(UINT id
)
115 if (!mCapturing
) return;
117 SWR_ASSERT(tlsThreadId
< mThreads
.size());
119 BUCKET_THREAD
& bt
= mThreads
[tlsThreadId
];
121 uint64_t tsc
= __rdtsc();
124 if (bt
.pCurrent
->children
.size() < mBuckets
.size())
126 bt
.pCurrent
->children
.resize(mBuckets
.size());
128 BUCKET
&child
= bt
.pCurrent
->children
[id
];
129 child
.pParent
= bt
.pCurrent
;
133 // update thread's currently executing bucket
134 bt
.pCurrent
= &child
;
141 // stop the currently executing bucket
142 INLINE
void StopBucket(UINT id
)
144 SWR_ASSERT(tlsThreadId
< mThreads
.size());
145 BUCKET_THREAD
&bt
= mThreads
[tlsThreadId
];
152 uint64_t tsc
= __rdtsc();
155 if (bt
.pCurrent
->start
== 0) return;
156 SWR_ASSERT(bt
.pCurrent
->id
== id
, "Mismatched buckets detected");
158 bt
.pCurrent
->elapsed
+= (tsc
- bt
.pCurrent
->start
);
159 bt
.pCurrent
->count
++;
162 bt
.pCurrent
= bt
.pCurrent
->pParent
;
168 INLINE
void AddEvent(uint32_t id
, uint32_t count
)
170 if (!mCapturing
) return;
172 SWR_ASSERT(tlsThreadId
< mThreads
.size());
174 BUCKET_THREAD
& bt
= mThreads
[tlsThreadId
];
176 // don't record events for threadviz
178 if (bt
.pCurrent
->children
.size() < mBuckets
.size())
180 bt
.pCurrent
->children
.resize(mBuckets
.size());
182 BUCKET
&child
= bt
.pCurrent
->children
[id
];
183 child
.pParent
= bt
.pCurrent
;
185 child
.count
+= count
;
190 void PrintBucket(FILE* f
, UINT level
, uint64_t threadCycles
, uint64_t parentCycles
, const BUCKET
& bucket
);
191 void PrintThread(FILE* f
, const BUCKET_THREAD
& thread
);
193 // list of active threads that have registered with this manager
194 std::vector
<BUCKET_THREAD
> mThreads
;
196 // list of buckets registered with this manager
197 std::vector
<BUCKET_DESC
> mBuckets
;
199 // is capturing currently enabled
200 volatile bool mCapturing
{ false };
202 // has capturing completed
203 volatile bool mDoneCapturing
{ false };
205 std::mutex mThreadMutex
;
207 std::string mThreadVizDir
;
212 // C helpers for jitter
213 void BucketManager_StartBucket(BucketManager
* pBucketMgr
, uint32_t id
);
214 void BucketManager_StopBucket(BucketManager
* pBucketMgr
, uint32_t id
);