.. _program_listing_file_src_flamegpu_simulation_detail_SimLogger.cu: Program Listing for File SimLogger.cu ===================================== |exhale_lsh| :ref:`Return to documentation for file ` (``src/flamegpu/simulation/detail/SimLogger.cu``) .. |exhale_lsh| unicode:: U+021B0 .. UPWARDS ARROW WITH TIP LEFTWARDS .. code-block:: cpp #include "flamegpu/simulation/detail/SimLogger.h" #include #include "flamegpu/io/LoggerFactory.h" #include "flamegpu/simulation/RunPlanVector.h" #ifdef _MSC_VER #include #else #include #endif namespace flamegpu { namespace detail { SimLogger::SimLogger(const std::map &_run_logs, const RunPlanVector &_run_plans, const std::string &_out_directory, const std::string &_out_format, std::queue &_log_export_queue, std::mutex &_log_export_queue_mutex, std::condition_variable &_log_export_queue_cdn, bool _export_step, bool _export_exit, bool _export_step_time, bool _export_exit_time) : run_logs(_run_logs) , run_plans(_run_plans) , out_directory(_out_directory) , out_format(_out_format) , log_export_queue(_log_export_queue) , log_export_queue_mutex(_log_export_queue_mutex) , log_export_queue_cdn(_log_export_queue_cdn) , export_step(_export_step) , export_exit(_export_exit) , export_step_time(_export_step_time) , export_exit_time(_export_exit_time) { this->thread = std::thread(&SimLogger::start, this); // Attempt to name the thread #ifdef _MSC_VER std::wstringstream thread_name; thread_name << L"SimLogger"; // HRESULT hr = SetThreadDescription(this->thread.native_handle(), thread_name.str().c_str()); // if (FAILED(hr)) { // fprintf(stderr, "Failed to name thread 'SimLogger'\n"); // } #else std::stringstream thread_name; thread_name << "SimLogger"; // int hr = pthread_setname_np(this->thread.native_handle(), thread_name.str().c_str()); // if (hr) { // fprintf(stderr, "Failed to name thread 'SimLogger'\n"); // } #endif } void SimLogger::start() { const std::filesystem::path p_out_directory = out_directory; unsigned int logs_processed = 0; while (logs_processed < run_plans.size()) { std::unique_lock lock(log_export_queue_mutex); log_export_queue_cdn.wait(lock, [this]{ return !log_export_queue.empty(); }); do { // Pop item to be logged from queue const unsigned int target_log = log_export_queue.front(); log_export_queue.pop(); lock.unlock(); // Check item isn't telling us to exit early if (target_log == UINT_MAX) { logs_processed = UINT_MAX; break; } // Log items if (export_exit) { const std::filesystem::path exit_path = p_out_directory / std::filesystem::path(run_plans[target_log].getOutputSubdirectory()) / std::filesystem::path("exit." + out_format); const auto exit_logger = io::LoggerFactory::createLogger(exit_path.generic_string(), false, false); exit_logger->log(run_logs.at(target_log), run_plans[target_log], false, true, false, export_exit_time); } if (export_step) { const std::filesystem::path step_path = p_out_directory/std::filesystem::path(run_plans[target_log].getOutputSubdirectory())/std::filesystem::path(std::to_string(target_log)+"."+out_format); const auto step_logger = io::LoggerFactory::createLogger(step_path.generic_string(), false, true); step_logger->log(run_logs.at(target_log), run_plans[target_log], true, false, export_step_time, false); } // Continue ++logs_processed; lock.lock(); } while (!log_export_queue.empty()); } } } // namespace detail } // namespace flamegpu