// ---------------------------------------------------------------------- // File: Macros.hh // Author: Georgios Bitzes - CERN // ---------------------------------------------------------------------- /************************************************************************ * quarkdb - a redis-like highly available key-value store * * Copyright (C) 2016 CERN/Switzerland * * * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see .* ************************************************************************/ #ifndef QUARKDB_MACROS_HH #define QUARKDB_MACROS_HH #include #include #include namespace quarkdb { class FatalException : public std::exception { public: FatalException(const std::string &m) : msg(m) {} virtual ~FatalException() {} virtual const char* what() const noexcept { return msg.c_str(); } private: std::string msg; }; // Returns a stacktrace if 'stacktrace-on-error' is enabled, empty otherwise. std::string errorStacktrace(bool crash); #define DISALLOW_COPY_AND_ASSIGN(TypeName) \ TypeName(const TypeName&) = delete; \ void operator=(const TypeName&) = delete #define SSTR(message) static_cast(std::ostringstream().flush() << message).str() #define quotes(message) SSTR("'" << message << "'") extern std::mutex logMutex; #define TIME_NOW std::chrono::duration_cast(std::chrono::high_resolution_clock::now().time_since_epoch()).count() #define ___log(message) { std::scoped_lock logLock(quarkdb::logMutex); \ std::cerr << "[" << TIME_NOW << "] " << message << std::endl; } #define DBG(message) ___log(__FILE__ << ":" << __LINE__ << " -- " << #message << " = " << message) // temporary solution for now #define qdb_log(message) ___log(message) #define qdb_event(message) ___log("EVENT: " << message) #define qdb_critical(message) ___log("CRITICAL: " << message << quarkdb::errorStacktrace(false)) #define qdb_misconfig(message) ___log("MISCONFIGURATION: " << message) #define qdb_fatal(message) { ___log(quarkdb::errorStacktrace(true) << std::endl << std::endl); ___log("FATAL: " << message); std::quick_exit(1); } #define qdb_warn(message) ___log("WARNING: " << message) #define qdb_error(message) ___log("ERROR: " << message) #define qdb_info(message) ___log("INFO: " << message) #define qdb_debug(message) if(false) { ___log(message); } #define QDB_LIKELY(x) __builtin_expect((x),1) #define QDB_UNLIKELY(x) __builtin_expect((x),0) // a serious error has occured signifying a bug in the program logic #define qdb_throw(message) throw quarkdb::FatalException(SSTR(message << quarkdb::errorStacktrace(true))) #define qdb_assert(condition) if(QDB_UNLIKELY(!((condition)))) throw quarkdb::FatalException(SSTR("assertion violation, condition is not true: " << #condition << quarkdb::errorStacktrace(true))) // Always inline this function. #define QDB_ALWAYS_INLINE __attribute__((always_inline)) } #endif