From 7538d23b0e1c559aa2cfe0859f07484d6c1f1189 Mon Sep 17 00:00:00 2001 From: hariharandev1 Date: Sun, 29 Sep 2024 23:01:08 -0700 Subject: [PATCH] multithreading support --- src/dftracer/df_logger.cpp | 7 ++- src/dftracer/df_logger.h | 78 +++++++++++++++------------ src/dftracer/writer/chrome_writer.cpp | 7 ++- src/dftracer/writer/chrome_writer.h | 22 ++++---- 4 files changed, 64 insertions(+), 50 deletions(-) diff --git a/src/dftracer/df_logger.cpp b/src/dftracer/df_logger.cpp index bc318e58..1476d503 100644 --- a/src/dftracer/df_logger.cpp +++ b/src/dftracer/df_logger.cpp @@ -2,4 +2,9 @@ template <> std::shared_ptr dftracer::Singleton::instance = nullptr; template <> -bool dftracer::Singleton::stop_creating_instances = false; \ No newline at end of file +bool dftracer::Singleton::stop_creating_instances = false; + +thread_local uint32_t DFTLogger::level = 0; +thread_local std::vector DFTLogger::index_stack = std::vector(); +thread_local std::unordered_map + DFTLogger::computed_hash = std::unordered_map(); \ No newline at end of file diff --git a/src/dftracer/df_logger.h b/src/dftracer/df_logger.h index d52998f9..a2b944b2 100644 --- a/src/dftracer/df_logger.h +++ b/src/dftracer/df_logger.h @@ -13,6 +13,7 @@ #include #include #include +#include #include #include @@ -40,11 +41,11 @@ class DFTLogger { bool is_init, dftracer_tid; ProcessID process_id; std::shared_ptr writer; - uint32_t level; - std::vector index_stack; - std::unordered_map computed_hash; std::atomic_int index; bool has_entry; + thread_local static uint32_t level; + thread_local static std::vector index_stack; + thread_local static std::unordered_map computed_hash; #ifdef DFTRACER_MPI_ENABLE bool mpi_event; #endif @@ -74,9 +75,6 @@ class DFTLogger { DFTLogger(bool init_log = false) : is_init(false), dftracer_tid(false), - level(0), - index_stack(), - computed_hash(), index(0), has_entry(false), #ifdef DFTRACER_MPI_ENABLE @@ -99,7 +97,7 @@ class DFTLogger { } this->is_init = true; } - ~DFTLogger() { index_stack.clear(); } + ~DFTLogger() {} inline void update_log_file(std::string log_file, std::string exec_name, std::string cmd, ProcessID process_id = -1) { DFTRACER_LOG_DEBUG("DFTLogger.update_log_file %s", log_file.c_str()); @@ -122,18 +120,16 @@ class DFTLogger { char thread_name[128]; auto size = sprintf(thread_name, "%lu", this->process_id); thread_name[size] = '\0'; - this->enter_event(); + auto current_index = this->enter_event(); this->writer->log_metadata( - index_stack[level - 1], thread_name, METADATA_NAME_THREAD_NAME, + current_index, thread_name, METADATA_NAME_THREAD_NAME, METADATA_NAME_THREAD_NAME, this->process_id, tid); this->exit_event(); - std::unordered_map* meta = nullptr; + std::unordered_map *meta = nullptr; if (include_metadata) { meta = new std::unordered_map(); - cmd_hash = - hash_and_store(cmd.data(), METADATA_NAME_STRING_HASH); - exec_hash = - hash_and_store(exec_name.data(), METADATA_NAME_STRING_HASH); + cmd_hash = hash_and_store(cmd.data(), METADATA_NAME_STRING_HASH); + exec_hash = hash_and_store(exec_name.data(), METADATA_NAME_STRING_HASH); meta->insert_or_assign("version", DFTRACER_VERSION); meta->insert_or_assign("exec_hash", exec_hash); @@ -150,7 +146,7 @@ class DFTLogger { this->log("start", "dftracer", this->get_time(), 0, meta); this->exit_event(); if (include_metadata) { - delete(meta); + delete (meta); } if (enable_core_affinity) { #ifdef DFTRACER_HWLOC_ENABLE @@ -169,11 +165,11 @@ class DFTLogger { if (dftracer_tid) { tid = df_gettid() + this->process_id; } - this->enter_event(); - this->writer->log_metadata(index_stack[level - 1], "core_affinity", - all_stream.str().c_str(), - METADATA_NAME_PROCESS, this->process_id, - tid, false); + auto current_index = this->enter_event(); + + this->writer->log_metadata( + current_index, "core_affinity", all_stream.str().c_str(), + METADATA_NAME_PROCESS, this->process_id, tid, false); this->exit_event(); } } @@ -184,10 +180,12 @@ class DFTLogger { DFTRACER_LOG_INFO("Writing trace to %s", log_file.c_str()); } - inline void enter_event() { + inline int enter_event() { index++; level++; - index_stack.push_back(index.load()); + int current_index = index.load(); + index_stack.push_back(current_index); + return current_index; } inline void exit_event() { @@ -195,6 +193,20 @@ class DFTLogger { index_stack.pop_back(); } + inline int get_parent() { + if (level > 1 && index_stack.size() > 1) { + return index_stack[level - 2]; + } + return -1; + } + + inline int get_current() { + if (level > 0 && index_stack.size() > 0) { + return index_stack[level - 1]; + } + return -1; + } + inline TimeResolution get_time() { DFTRACER_LOG_DEBUG("DFTLogger.get_time", ""); struct timeval tv {}; @@ -217,10 +229,7 @@ class DFTLogger { } if (metadata != nullptr) { metadata->insert_or_assign("level", level); - int parent_index_value = -1; - if (level > 1) { - parent_index_value = index_stack[level - 2]; - } + int parent_index_value = get_parent(); metadata->insert_or_assign("p_idx", parent_index_value); } #ifdef DFTRACER_MPI_ENABLE @@ -231,17 +240,17 @@ class DFTLogger { this->writer != nullptr) { int rank = 0; MPI_Comm_rank(MPI_COMM_WORLD, &rank); - this->enter_event(); + auto current_index = this->enter_event(); this->writer->log_metadata( - index_stack[level - 1], "rank", std::to_string(rank).c_str(), + current_index, "rank", std::to_string(rank).c_str(), METADATA_NAME_PROCESS, this->process_id, tid); this->exit_event(); char process_name[1024]; auto size = sprintf(process_name, "Rank %d", rank); process_name[size] = '\0'; - this->enter_event(); + current_index = this->enter_event(); this->writer->log_metadata( - index_stack[level - 1], process_name, METADATA_NAME_PROCESS_NAME, + current_index, process_name, METADATA_NAME_PROCESS_NAME, METADATA_NAME_PROCESS_NAME, this->process_id, tid); this->exit_event(); @@ -252,9 +261,8 @@ class DFTLogger { if (this->writer != nullptr) { if (include_metadata) { - this->writer->log(index_stack[level - 1], event_name, category, - start_time, duration, metadata, this->process_id, - tid); + this->writer->log(get_current(), event_name, category, start_time, + duration, metadata, this->process_id, tid); } else { this->writer->log(local_index, event_name, category, start_time, duration, metadata, this->process_id, tid); @@ -286,8 +294,8 @@ class DFTLogger { if (dftracer_tid) { tid = df_gettid(); } - this->enter_event(); - this->writer->log_metadata(index_stack[level - 1], file, + auto current_index = this->enter_event(); + this->writer->log_metadata(current_index, file, std::to_string(hash).c_str(), name, this->process_id, tid, false); this->exit_event(); diff --git a/src/dftracer/writer/chrome_writer.cpp b/src/dftracer/writer/chrome_writer.cpp index 653e14e4..b2fdcdfd 100644 --- a/src/dftracer/writer/chrome_writer.cpp +++ b/src/dftracer/writer/chrome_writer.cpp @@ -154,7 +154,7 @@ void dftracer::ChromeWriter::convert_json( TimeResolution start_time, TimeResolution duration, std::unordered_map *metadata, ProcessID process_id, ThreadID thread_id) { - auto previous_index = current_index; + size_t previous_index; (void)previous_index; char is_first_char[3] = " "; @@ -218,6 +218,7 @@ void dftracer::ChromeWriter::convert_json( } { std::unique_lock lock(mtx); + previous_index = current_index; auto written_size = sprintf( buffer.data() + current_index, R"(%s{"id":%d,"name":"%s","cat":"%s","pid":%lu,"tid":%lu,"ts":%llu,"dur":%llu,"ph":"X","args":{"hhash":%d%s}})", @@ -230,6 +231,7 @@ void dftracer::ChromeWriter::convert_json( } else { { std::unique_lock lock(mtx); + previous_index = current_index; auto written_size = sprintf( buffer.data() + current_index, R"(%s{"id":%d,"name":"%s","cat":"%s","pid":%lu,"tid":%lu,"ts":%llu,"dur":%llu,"ph":"X"})", @@ -248,13 +250,14 @@ void dftracer::ChromeWriter::convert_json_metadata( int index, ConstEventNameType name, ConstEventNameType value, ConstEventNameType ph, ProcessID process_id, ThreadID thread_id, bool is_string) { - auto previous_index = current_index; + size_t previous_index = 0; (void)previous_index; char is_first_char[3] = " "; if (!is_first_write) is_first_char[0] = '\0'; { std::unique_lock lock(mtx); + previous_index = current_index; auto written_size = 0; if (is_string) { written_size = sprintf( diff --git a/src/dftracer/writer/chrome_writer.h b/src/dftracer/writer/chrome_writer.h index b98868fd..77c63cc0 100644 --- a/src/dftracer/writer/chrome_writer.h +++ b/src/dftracer/writer/chrome_writer.h @@ -37,7 +37,7 @@ class ChromeWriter { FILE *fh; uint16_t hostname_hash; - static const int MAX_LINE_SIZE = 16*1024L; + static const int MAX_LINE_SIZE = 16 * 1024L; size_t write_buffer_size; size_t current_index; @@ -55,22 +55,20 @@ class ChromeWriter { bool is_first_write; inline size_t write_buffer_op(bool force = false) { + std::unique_lock lock(mtx); if (current_index == 0 || (!force && current_index < write_buffer_size)) return 0; DFTRACER_LOG_DEBUG("ChromeWriter.write_buffer_op %s", this->filename.c_str()); size_t written_elements = 0; - { - std::unique_lock lock(mtx); - flockfile(fh); - written_elements = fwrite(buffer.data(), current_index, sizeof(char), fh); - current_index = 0; - funlockfile(fh); - } - + flockfile(fh); + written_elements = fwrite(buffer.data(), current_index, sizeof(char), fh); + current_index = 0; + funlockfile(fh); if (written_elements != 1) { // GCOVR_EXCL_START DFTRACER_LOG_ERROR( - "unable to log write only %ld of %d trying to write %d with error code " + "unable to log write only %ld of %d trying to write %zu with error " + "code " "%d", written_elements, 1, current_index, errno); } // GCOVR_EXCL_STOP @@ -111,8 +109,8 @@ class ChromeWriter { ProcessID process_id, ThreadID tid); void log_metadata(int index, ConstEventNameType name, - ConstEventNameType value, ConstEventNameType ph, ProcessID process_id, - ThreadID tid, bool is_string = true); + ConstEventNameType value, ConstEventNameType ph, + ProcessID process_id, ThreadID tid, bool is_string = true); void finalize(bool has_entry); };