我正在尝试创建一个探测工具来测量多线程代码的各种计时方面。为此,我创建了一些记录器对象,并且由于该系统使用虚拟内存和原子变量来分配内存页面来注册已用内存的信息大小,因此该内存大小受到限制,应该固定。这些探针中的每一个都有一个ID(应提供给构造函数),以使其唯一。我使用了编译器中的 COUNTER 。为了应用这些探针,有一些宏适用于测量不足的代码,它们实际上创建了对象,并且这些对象的寿命是测量时间。因此没有开销。这些探针具有一个名称,为了更好,更轻松地使用这些探针信息,我需要在一些const和静态字符串中注册这些名称,然后使用它们将这些名称归因于先前引用的ID。由于这些探针是测量工具,因此为了归档没有开销的目标,应在编译时创建一种类型的const容器,其中应包含这些名称以及ID。有谁知道在生成探针宏时如何在代码中的任何地方自动创建这样的静态常量编译时容器?
在Probe头文件中:
class str_const {
// constexpr string
private:
const char* const p_;
const std::size_t sz_;
public:
template<std::size_t N>
constexpr str_const(const char(&a)[N]) :
// ctor
p_(a), sz_(N-1) {}
constexpr char operator[](std::size_t n) {
// []
return n < sz_ ? p_[n] :
throw std::out_of_range("");
}
constexpr std::size_t size() { return sz_; } // size()
};
#define CONCATENATE_DETAIL(x, y) x##y
#define REGISTER_PROBE( name )\
constexpr str_const str_##name = #name
#define THREAD_PROBE_DETAIL(n, x) THREADSCOPE::CollectorThread n(x);
#define THREAD_PROBE(x) THREAD_PROBE_DETAIL(CONCATENATE_DETAIL(_threadProbe_,x), __COUNTER__)\
REGISTER_PROBE(_threadProbe_##x)
#define LOCK_PROBE_DETAIL(n, x) THREADSCOPE::CollectorLock n(x);
#define LOCK_PROBE_BEGIN(x) LOCK_PROBE_DETAIL(CONCATENATE_DETAIL(_lockProbe_,x), __COUNTER__)\
REGISTER_PROBE(_lockProbe_##x)
#define LOCK_PROBE_END(x) CONCATENATE_DETAIL(_lockProbe_,x).end()
later in the code, usage of probes will be like this:
class Worker final : public BASE::ThreadBaseClass
{
private:
public:
Worker( void )
{
}
virtual ~Worker( void )
{
}
void test()
{
THREAD_PROBE(deepfoo);
}
protected:
void handle_() override
{
while(loopVariable_.load())
{
THREAD_PROBE(foo);
std::cout << "value of depth at start of thread is : " << depth;
test();
THREAD_PROBE(bar);
LOCK_PROBE_BEGIN(x);
std::cout << "value of depth after two of thread is : "<< depth;
this->waitForNotification_();
DelayMilSec(1);
LOCK_PROBE_END(x);
std::cout << "I was notified by the master."<<std::endl;
}
}
};
需要的是,诸如foo,bar,deepfoo和x之类的名称会自动收集在静态const容器(任意)中,以进一步解释所获取的信息。预先感谢您的时间和帮助。