Как автоматически создать контейнер времени компиляции строк - PullRequest
2 голосов
/ 02 июля 2019

Я пытаюсь создать инструмент для измерения различных аспектов синхронизации многопоточных кодов.Для этой цели я создал несколько объектов записывающего устройства, и, поскольку эта система использует виртуальную память и атомарную переменную для выделения страниц памяти, для регистрации информации размер используемой памяти ограничен и должен быть исправлен.Каждый из этих тестов имеет идентификатор (должен быть предоставлен конструктору), чтобы сделать их уникальными, я использовал COUNTER из компилятора.Для применения этих зондов существуют макросы, которые применяются к коду измерения, и они фактически создают объекты, а время жизни этих объектов измеряется временем.Так что никаких накладных расходов.Этим зондам присваивается имя, и для лучшего и более легкого использования этой информации о зондах мне нужно зарегистрировать эти имена в некоторой константной и статической строке, а затем использовать их для приписывания этих имен ранее цитируемым идентификаторам.Для того чтобы архивировать цель отсутствия издержек, поскольку эти пробники являются измерительными инструментами, во время компиляции должен быть создан тип контейнера const, содержащий эти имена и, возможно, идентификаторы.Кто-нибудь знает, как такой статический постоянный контейнер времени компиляции может быть создан автоматически, в то время как генерирование макросов зондов может появиться где-нибудь в коде?

В заголовочном файле 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 (любой) для дальнейшегоинтерпретация полученной информации.Заранее спасибо за ваше время и помощь.

...