diff --git a/logging.h b/logging.h index ceb1620..2857165 100644 --- a/logging.h +++ b/logging.h @@ -3,92 +3,98 @@ #pragma once -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include #include "config/config.h" #include "utils.h" + using namespace config; + enum class LogLevel { LOG_NONE = 0, LOG_INFO = 1, LOG_ERROR = 2 }; #if defined(DEBUG_LOG) || defined(ENABLE_STATISTICS) -inline FILE* log_file_stream = nullptr; +inline std::unique_ptr log_file_stream = nullptr; -inline static void CreateLogFile(const char* file_name) { - log_file_stream = fopen(file_name, "a"); +inline void CreateLogFile(const char* file_name) { + log_file_stream = std::make_unique(file_name, std::ios::app); } -inline static void CloseLogFile() { - if (log_file_stream != nullptr) { - fclose(log_file_stream); +inline void CloseLogFile() { log_file_stream.reset(); } + +inline std::ostream& GetLogStream() { + if (log_file_stream && log_file_stream->is_open()) { + return *log_file_stream; } + return std::cout; +} + +inline void LogImpl(std::ostream& stream) { stream << std::endl; } + +template +inline void LogImpl(std::ostream& stream, T&& first, Args&&... rest) { + stream << std::forward(first); + LogImpl(stream, std::forward(rest)...); } #endif #ifdef DEBUG_LOG -static inline void Log(LogLevel level, const char* format, ...) { +template +inline void Log(LogLevel level, Args&&... args) { if (static_cast(level) < configs[LOG_LEVEL]) { return; } - - FILE* stream = stdout; - if (log_file_stream != nullptr) { - stream = log_file_stream; - } - + auto& stream = GetLogStream(); switch (level) { case LogLevel::LOG_ERROR: - fprintf(stream, "Error: "); + stream << "Error: "; break; case LogLevel::LOG_INFO: - fprintf(stream, "Info: "); + stream << "Info: "; break; case LogLevel::LOG_NONE: return; } - va_list args; - va_start(args, format); - vfprintf(stream, format, args); - va_end(args); + LogImpl(stream, std::forward(args)...); } #else -#define Log(...) +template +inline void Log(LogLevel, Args&&...) {} #endif #ifdef ENABLE_STATISTICS -static inline void LogStats(const char* stats_str) { - FILE* stream = stdout; - if (log_file_stream != nullptr) { - stream = log_file_stream; - } - - fprintf(stream, "Stats:\n"); - fprintf(stream, "%s", stats_str); +template +inline void LogStats(Args&&... args) { + auto& stream = GetLogStream(); + stream << "Stats:\n"; + LogImpl(stream, std::forward(args)...); } #else -#define LogStats(...) +template +inline void LogStats(Args&&...) {} #endif #ifdef DEBUG_LOG -static inline void PrintDeflateBlockHeader(LogLevel level, uint8_t* data, - uint32_t len, int window_bits) { +template +inline void PrintDeflateBlockHeader(LogLevel level, uint8_t* data, uint32_t len, + int window_bits, Args&&... args) { if (static_cast(level) < configs[LOG_LEVEL]) { return; } - CompressedFormat format = GetCompressedFormat(window_bits); uint32_t header_length = GetHeaderLength(format); if (len >= (header_length + 1)) { - Log(level, "Deflate block header bfinal=%d, btype=%d\n", - data[header_length] & 0b00000001, - (data[header_length] & 0b00000110) >> 1); + Log(level, "Deflate block header bfinal=", + static_cast(data[header_length] & 0b00000001), + ", btype=", static_cast((data[header_length] & 0b00000110) >> 1), + "\n", std::forward(args)...); } } #else -#define PrintDeflateBlockHeader(...) +template +inline void PrintDeflateBlockHeader(LogLevel, uint8_t*, uint32_t, int, + Args&&...) {} #endif diff --git a/statistics.cpp b/statistics.cpp index 4430aaf..5d359a1 100644 --- a/statistics.cpp +++ b/statistics.cpp @@ -4,75 +4,37 @@ #include "statistics.h" #ifdef ENABLE_STATISTICS +#include +#include #include #include #include "config/config.h" #include "logging.h" -using namespace config; - -// clang-format off -const std::string stat_names[STATS_COUNT] { - "deflate_count", - "deflate_error_count", - "deflate_qat_count", - "deflate_qat_error_count", - "deflate_iaa_count", - "deflate_iaa_error_count", - "deflate_zlib_count", - - "inflate_count", - "inflate_error_count", - "inflate_qat_count", - "inflate_qat_error_count", - "inflate_iaa_count", - "inflate_iaa_error_count", - "inflate_zlib_count" -}; -// clang-format on - -thread_local uint64_t stats[STATS_COUNT]; -#endif -bool AreStatsEnabled() { -#ifdef ENABLE_STATISTICS - return true; -#else - return false; -#endif -} +using namespace config; -void ResetStats() { -#ifdef ENABLE_STATISTICS - for (int i = 0; i < STATS_COUNT; i++) { - stats[i] = 0; - } -#endif -} +const std::array stat_names{ + {"deflate_count", "deflate_error_count", "deflate_qat_count", + "deflate_qat_error_count", "deflate_iaa_count", "deflate_iaa_error_count", + "deflate_zlib_count", "inflate_count", "inflate_error_count", + "inflate_qat_count", "inflate_qat_error_count", "inflate_iaa_count", + "inflate_iaa_error_count", "inflate_zlib_count"}}; -uint64_t GetStat(Statistic stat) { -#ifdef ENABLE_STATISTICS - return stats[stat]; -#else - (void)stat; - return 0; -#endif -} +thread_local std::array stats{}; -#ifdef ENABLE_STATISTICS void PrintStats() { - if ((stats[DEFLATE_COUNT] + stats[INFLATE_COUNT]) % - configs[LOG_STATS_SAMPLES] != - 0) { + auto total_operations = stats[static_cast(Statistic::DEFLATE_COUNT)] + + stats[static_cast(Statistic::INFLATE_COUNT)]; + + if (total_operations % configs[LOG_STATS_SAMPLES] != 0) { return; } - std::stringstream printed_stats; - printed_stats << "Thread: " << std::this_thread::get_id() << std::endl; - for (int i = 0; i < STATS_COUNT; i++) { - printed_stats << stat_names[i] << " = " << stats[i] << std::endl; - } + LogStats("Thread: ", std::this_thread::get_id(), "\n"); - LogStats(printed_stats.str().c_str()); + for (size_t i = 0; i < stats.size(); ++i) { + LogStats(stat_names[i], " = ", stats[i], "\n"); + } } #endif diff --git a/statistics.h b/statistics.h index 387e555..8cee404 100644 --- a/statistics.h +++ b/statistics.h @@ -3,19 +3,14 @@ #pragma once -#define VISIBLE_FOR_TESTING __attribute__((visibility("default"))) -#include +#include +#include +#include +#include -#ifdef ENABLE_STATISTICS -#define INCREMENT_STAT(stat) stats[stat]++ -#define INCREMENT_STAT_COND(cond, stat) \ - if (cond) stats[stat]++ -#else -#define INCREMENT_STAT(stat) -#define INCREMENT_STAT_COND(cond, stat) -#endif +#define VISIBLE_FOR_TESTING __attribute__((visibility("default"))) -enum Statistic { +enum class Statistic : size_t { DEFLATE_COUNT = 0, DEFLATE_ERROR_COUNT, DEFLATE_QAT_COUNT, @@ -23,7 +18,6 @@ enum Statistic { DEFLATE_IAA_COUNT, DEFLATE_IAA_ERROR_COUNT, DEFLATE_ZLIB_COUNT, - INFLATE_COUNT, INFLATE_ERROR_COUNT, INFLATE_QAT_COUNT, @@ -31,17 +25,51 @@ enum Statistic { INFLATE_IAA_COUNT, INFLATE_IAA_ERROR_COUNT, INFLATE_ZLIB_COUNT, - STATS_COUNT }; +constexpr size_t STATS_COUNT = static_cast(Statistic::STATS_COUNT); + +inline std::ostream& operator<<(std::ostream& os, const Statistic& stat) { + return os << static_cast(stat); +} + #ifdef ENABLE_STATISTICS -extern thread_local uint64_t stats[STATS_COUNT]; +#define INCREMENT_STAT(stat) stats[static_cast(Statistic::stat)]++ +#define INCREMENT_STAT_COND(cond, stat) \ + if (cond) stats[static_cast(Statistic::stat)]++ +#else +#define INCREMENT_STAT(stat) +#define INCREMENT_STAT_COND(cond, stat) +#endif + +#ifdef ENABLE_STATISTICS +extern thread_local std::array stats; +extern const std::array stat_names; +#endif + +VISIBLE_FOR_TESTING constexpr bool AreStatsEnabled() { +#ifdef ENABLE_STATISTICS + return true; +#else + return false; +#endif +} + +VISIBLE_FOR_TESTING inline void ResetStats() { +#ifdef ENABLE_STATISTICS + stats.fill(0); #endif +} -VISIBLE_FOR_TESTING bool AreStatsEnabled(); -VISIBLE_FOR_TESTING void ResetStats(); -VISIBLE_FOR_TESTING uint64_t GetStat(Statistic stat); +VISIBLE_FOR_TESTING inline uint64_t GetStat(Statistic stat) { +#ifdef ENABLE_STATISTICS + return stats[static_cast(stat)]; +#else + (void)stat; + return 0; +#endif +} #ifdef ENABLE_STATISTICS void PrintStats(); diff --git a/tests/zlib_accel_test.cpp b/tests/zlib_accel_test.cpp index 6d66f9c..4964130 100644 --- a/tests/zlib_accel_test.cpp +++ b/tests/zlib_accel_test.cpp @@ -598,28 +598,28 @@ TEST_P(ZlibTest, CompressDecompress) { int ret = ZlibCompress( input, input_length, &compressed, test_param.window_bits_compress, test_param.flush_compress, &output_upper_bound, &execution_path); - VerifyStatIncremented(DEFLATE_COUNT); + VerifyStatIncremented(Statistic::DEFLATE_COUNT); bool compress_fallback_expected = ZlibCompressExpectFallback(test_param, input_length, output_upper_bound); if (compress_fallback_expected && !test_param.zlib_fallback_compress) { ASSERT_EQ(ret, Z_DATA_ERROR); - VerifyStatIncremented(DEFLATE_ERROR_COUNT); + VerifyStatIncremented(Statistic::DEFLATE_ERROR_COUNT); DestroyBlock(input); return; } else { ASSERT_EQ(ret, Z_STREAM_END); if (compress_fallback_expected) { ASSERT_EQ(execution_path, ZLIB); - VerifyStatIncremented(DEFLATE_ZLIB_COUNT); + VerifyStatIncremented(Statistic::DEFLATE_ZLIB_COUNT); } else { ASSERT_EQ(execution_path, test_param.execution_path_compress); if (test_param.execution_path_compress == QAT) { - VerifyStatIncremented(DEFLATE_QAT_COUNT); + VerifyStatIncremented(Statistic::DEFLATE_QAT_COUNT); } else if (test_param.execution_path_compress == IAA) { - VerifyStatIncremented(DEFLATE_IAA_COUNT); + VerifyStatIncremented(Statistic::DEFLATE_IAA_COUNT); } else if (test_param.execution_path_compress == ZLIB) { - VerifyStatIncremented(DEFLATE_ZLIB_COUNT); + VerifyStatIncremented(Statistic::DEFLATE_ZLIB_COUNT); } } } @@ -640,7 +640,8 @@ TEST_P(ZlibTest, CompressDecompress) { &uncompressed, &uncompressed_length, &input_consumed, window_bits_uncompress, test_param.flush_uncompress, test_param.input_chunks_uncompress, &execution_path); - VerifyStatIncrementedUpTo(INFLATE_COUNT, test_param.input_chunks_uncompress); + VerifyStatIncrementedUpTo(Statistic::INFLATE_COUNT, + test_param.input_chunks_uncompress); bool error_expected = false; bool accelerator_tried = false; @@ -649,12 +650,12 @@ TEST_P(ZlibTest, CompressDecompress) { window_bits_uncompress, compress_fallback_expected, &accelerator_tried); if (uncompress_fallback_expected && !test_param.zlib_fallback_uncompress) { ASSERT_EQ(ret, Z_DATA_ERROR); - VerifyStatIncremented(INFLATE_ERROR_COUNT); + VerifyStatIncremented(Statistic::INFLATE_ERROR_COUNT); if (accelerator_tried) { if (test_param.execution_path_uncompress == QAT) { - VerifyStatIncremented(INFLATE_QAT_ERROR_COUNT); + VerifyStatIncremented(Statistic::INFLATE_QAT_ERROR_COUNT); } else if (test_param.execution_path_uncompress == IAA) { - VerifyStatIncremented(INFLATE_IAA_ERROR_COUNT); + VerifyStatIncremented(Statistic::INFLATE_IAA_ERROR_COUNT); } } error_expected = true; @@ -662,16 +663,16 @@ TEST_P(ZlibTest, CompressDecompress) { ASSERT_EQ(ret, Z_STREAM_END); if (uncompress_fallback_expected) { ASSERT_EQ(execution_path, ZLIB); - VerifyStatIncrementedUpTo(INFLATE_ZLIB_COUNT, + VerifyStatIncrementedUpTo(Statistic::INFLATE_ZLIB_COUNT, test_param.input_chunks_uncompress); } else { ASSERT_EQ(execution_path, test_param.execution_path_uncompress); if (test_param.execution_path_uncompress == QAT) { - VerifyStatIncremented(INFLATE_QAT_COUNT); + VerifyStatIncremented(Statistic::INFLATE_QAT_COUNT); } else if (test_param.execution_path_uncompress == IAA) { - VerifyStatIncremented(INFLATE_IAA_COUNT); + VerifyStatIncremented(Statistic::INFLATE_IAA_COUNT); } else if (test_param.execution_path_uncompress == ZLIB) { - VerifyStatIncrementedUpTo(INFLATE_ZLIB_COUNT, + VerifyStatIncrementedUpTo(Statistic::INFLATE_ZLIB_COUNT, test_param.input_chunks_uncompress); } }