diff --git a/CMakeLists.txt b/CMakeLists.txt index 44d118d..1d2533d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,8 +11,8 @@ file(GLOB prj_src src/*) target_sources(${PROJECT_NAME} PRIVATE ${prj_src}) -# target_compile_options(${PROJECT_NAME} PRIVATE -fsanitize=thread) -# target_link_options(${PROJECT_NAME} PRIVATE -fsanitize=thread) +target_compile_options(${PROJECT_NAME} PRIVATE -fsanitize=thread) +target_link_options(${PROJECT_NAME} PRIVATE -fsanitize=thread) add_subdirectory(bench) add_subdirectory(tests) \ No newline at end of file diff --git a/bench/CMakeLists.txt b/bench/CMakeLists.txt index d389f97..2d3a969 100644 --- a/bench/CMakeLists.txt +++ b/bench/CMakeLists.txt @@ -12,5 +12,5 @@ target_link_libraries(${NAME} PRIVATE ${PROJECT_NAME} ) -# target_compile_options(${NAME} PRIVATE -fsanitize=thread) -# target_link_options(${NAME} PRIVATE -fsanitize=thread) \ No newline at end of file +target_compile_options(${NAME} PRIVATE -fsanitize=thread) +target_link_options(${NAME} PRIVATE -fsanitize=thread) \ No newline at end of file diff --git a/include/logger.hh b/include/logger.hh index ac04bfb..91a542e 100644 --- a/include/logger.hh +++ b/include/logger.hh @@ -36,8 +36,7 @@ class Logger { template >> void add(const std::string& field, Metric metric) { - auto locked = active.load(std::memory_order_acquire); - // auto locked = active; + std::shared_ptr locked = active.load(std::memory_order_acquire); auto it = locked->find(field); if (it == locked->end()) { throw configErrorMsg; // additional 30ns on bench ? diff --git a/src/logger.cc b/src/logger.cc index b3c8ab4..c8c0a0b 100644 --- a/src/logger.cc +++ b/src/logger.cc @@ -68,18 +68,22 @@ void Logger::Worker::unroll() { if (!parent.isConfigured()) return; - auto tmp = parent.active.load(std::memory_order_acquire); - // auto tmp = parent.active; + auto tmp = parent.active.load(std::memory_order_relaxed); auto toBeActive = tmp == parent.m1 ? parent.m2 : parent.m1; - while (!parent.active.compare_exchange_weak(tmp, toBeActive)) { - std::this_thread::yield(); - } - // parent.active = toBeActive; + parent.active.store(toBeActive, std::memory_order_release); + + // hmm, seems that we can receive situation here there use_count is less or + // equal 2 but in reality we still have instance how? store and load is + // tighted, so we have guarantee that this check will be happens before while (tmp.use_count() > 2) { std::this_thread::yield(); } + // it's needed thread fence to guarantee use count change + // __tsan_acquire(tmp.use_count()); + std::atomic_thread_fence(std::memory_order_acquire); + // at this place we are guarantee that tmp is only ours or not? std::string output; bool haveToPush{false}; diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 4d806a7..53d7714 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -12,5 +12,5 @@ target_link_libraries(${NAME} PRIVATE ${PROJECT_NAME} ) -# target_compile_options(${NAME} PRIVATE -fsanitize=thread) -# target_link_options(${NAME} PRIVATE -fsanitize=thread) \ No newline at end of file +target_compile_options(${NAME} PRIVATE -fsanitize=thread) +target_link_options(${NAME} PRIVATE -fsanitize=thread) \ No newline at end of file