reduce memory allocations to zero
This commit is contained in:
parent
f176cc8454
commit
2df0ca34aa
@ -28,6 +28,7 @@ set (CPACK_PACKAGE_VERSION ${GLOG_VERSION})
|
||||
|
||||
option (WITH_GFLAGS "Use gflags" ON)
|
||||
option (WITH_THREADS "Enable multithreading support" ON)
|
||||
option (WITH_TLS "Enable Thread Local Storage (TLS) support" ON)
|
||||
|
||||
list (APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
|
||||
|
||||
@ -183,6 +184,31 @@ using namespace Outer::Inner;;
|
||||
int main() { return i; }
|
||||
" HAVE_NAMESPACES)
|
||||
|
||||
check_cxx_source_compiles ("
|
||||
__declspec(thread) int tls;
|
||||
int main() { }
|
||||
" HAVE_MSVC_TLS)
|
||||
|
||||
check_cxx_source_compiles ("
|
||||
thread_local int tls;
|
||||
int main() { }
|
||||
" HAVE_CXX11_TLS)
|
||||
|
||||
check_cxx_source_compiles ("
|
||||
__attribute__((thread)) int tls;
|
||||
int main() { }
|
||||
" HAVE_CYGWIN_TLS)
|
||||
|
||||
if (WITH_TLS)
|
||||
if (HAVE_CYGWIN_TLS)
|
||||
set (GLOG_THREAD_LOCAL_STORAGE "__attribute__((thread))")
|
||||
elseif (HAVE_MSVC_TLS)
|
||||
set (GLOG_THREAD_LOCAL_STORAGE "__declspec(thread)")
|
||||
elseif (HAVE_CXX11_TLS)
|
||||
set (GLOG_THREAD_LOCAL_STORAGE thread_local)
|
||||
endif (HAVE_CYGWIN_TLS)
|
||||
endif (WITH_TLS)
|
||||
|
||||
set (_PC_FIELDS
|
||||
"gregs[REG_PC]"
|
||||
"gregs[REG_EIP]"
|
||||
|
||||
@ -174,6 +174,9 @@
|
||||
/* location of source code */
|
||||
#cmakedefine TEST_SRC_DIR ${TEST_SRC_DIR}
|
||||
|
||||
/* Define to necessary thread-local storage attribute. */
|
||||
#cmakedefine GLOG_THREAD_LOCAL_STORAGE ${GLOG_THREAD_LOCAL_STORAGE}
|
||||
|
||||
/* Version number of package */
|
||||
#cmakedefine VERSION
|
||||
|
||||
|
||||
@ -1107,6 +1107,12 @@ class GOOGLE_GLOG_DLL_DECL LogStreamBuf : public std::streambuf {
|
||||
LogStreamBuf(char *buf, int len) {
|
||||
setp(buf, buf + len - 2);
|
||||
}
|
||||
|
||||
// Resets the buffer. Useful if we reuse it by means of TLS.
|
||||
void reset() {
|
||||
setp(pbase(), epptr());
|
||||
}
|
||||
|
||||
// This effectively ignores overflow.
|
||||
virtual int_type overflow(int_type ch) {
|
||||
return ch;
|
||||
@ -1169,6 +1175,7 @@ public:
|
||||
size_t pcount() const { return streambuf_.pcount(); }
|
||||
char* pbase() const { return streambuf_.pbase(); }
|
||||
char* str() const { return pbase(); }
|
||||
void reset() { streambuf_.reset(); }
|
||||
|
||||
private:
|
||||
LogStream(const LogStream&);
|
||||
|
||||
@ -336,6 +336,7 @@ const size_t LogMessage::kMaxLogMessageLen = 30000;
|
||||
|
||||
struct LogMessage::LogMessageData {
|
||||
LogMessageData();
|
||||
void reset();
|
||||
|
||||
int preserved_errno_; // preserved errno
|
||||
// Buffer space; contains complete message text.
|
||||
@ -1141,10 +1142,22 @@ static bool fatal_msg_exclusive = true;
|
||||
static LogMessage::LogMessageData fatal_msg_data_exclusive;
|
||||
static LogMessage::LogMessageData fatal_msg_data_shared;
|
||||
|
||||
#ifdef GLOG_THREAD_LOCAL_STORAGE
|
||||
// Static thread-local log data space to use, because typically at most one
|
||||
// LogMessageData object exists (in this case glog makes zero heap memory
|
||||
// allocations).
|
||||
static GLOG_THREAD_LOCAL_STORAGE bool thread_data_available = true;
|
||||
static GLOG_THREAD_LOCAL_STORAGE LogMessage::LogMessageData thread_msg_data;
|
||||
#endif // defined(GLOG_THREAD_LOCAL_STORAGE)
|
||||
|
||||
LogMessage::LogMessageData::LogMessageData()
|
||||
: stream_(message_text_, LogMessage::kMaxLogMessageLen, 0) {
|
||||
}
|
||||
|
||||
void LogMessage::LogMessageData::reset() {
|
||||
stream_.reset();
|
||||
}
|
||||
|
||||
LogMessage::LogMessage(const char* file, int line, LogSeverity severity,
|
||||
int ctr, void (LogMessage::*send_method)())
|
||||
: allocated_(NULL) {
|
||||
@ -1197,8 +1210,22 @@ void LogMessage::Init(const char* file,
|
||||
void (LogMessage::*send_method)()) {
|
||||
allocated_ = NULL;
|
||||
if (severity != GLOG_FATAL || !exit_on_dfatal) {
|
||||
#ifdef GLOG_THREAD_LOCAL_STORAGE
|
||||
// No need for locking, because this is thread local.
|
||||
if (thread_data_available) {
|
||||
thread_data_available = false;
|
||||
data_ = &thread_msg_data;
|
||||
// Make sure to clear log data since it may have been used and filled with
|
||||
// data. We do not want to append the new message to the previous one.
|
||||
data_->reset();
|
||||
} else {
|
||||
allocated_ = new LogMessageData();
|
||||
data_ = allocated_;
|
||||
}
|
||||
#else // !defined(GLOG_THREAD_LOCAL_STORAGE)
|
||||
allocated_ = new LogMessageData();
|
||||
data_ = allocated_;
|
||||
#endif // defined(GLOG_THREAD_LOCAL_STORAGE)
|
||||
data_->first_fatal_ = false;
|
||||
} else {
|
||||
MutexLock l(&fatal_msg_lock);
|
||||
@ -1267,6 +1294,10 @@ void LogMessage::Init(const char* file,
|
||||
|
||||
LogMessage::~LogMessage() {
|
||||
Flush();
|
||||
#ifdef GLOG_THREAD_LOCAL_STORAGE
|
||||
if (data_ == &thread_msg_data)
|
||||
thread_data_available = true;
|
||||
#endif // defined(GLOG_THREAD_LOCAL_STORAGE)
|
||||
delete allocated_;
|
||||
}
|
||||
|
||||
|
||||
@ -272,12 +272,14 @@ void TestLogging(bool check_counts) {
|
||||
LOG(ERROR) << string("foo") << ' '<< j << ' ' << setw(10) << j << " "
|
||||
<< setw(1) << hex << j;
|
||||
|
||||
LOG(ERROR) << (&LOG(ERROR) && 0) << " nested LOG";
|
||||
|
||||
LogMessage("foo", LogMessage::kNoLogPrefix, GLOG_INFO).stream() << "no prefix";
|
||||
|
||||
if (check_counts) {
|
||||
CHECK_EQ(base_num_infos + 14, LogMessage::num_messages(GLOG_INFO));
|
||||
CHECK_EQ(base_num_warning + 3, LogMessage::num_messages(GLOG_WARNING));
|
||||
CHECK_EQ(base_num_errors + 15, LogMessage::num_messages(GLOG_ERROR));
|
||||
CHECK_EQ(base_num_errors + 17, LogMessage::num_messages(GLOG_ERROR));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -74,6 +74,8 @@ WDATE TIME__ THREADID logging_unittest.cc:LINE] log_if this
|
||||
IDATE TIME__ THREADID logging_unittest.cc:LINE] array
|
||||
IDATE TIME__ THREADID logging_unittest.cc:LINE] const array
|
||||
EDATE TIME__ THREADID logging_unittest.cc:LINE] foo 1000 0000001000 3e8
|
||||
EDATE TIME__ THREADID logging_unittest.cc:LINE] 0 nested LOG
|
||||
EDATE TIME__ THREADID logging_unittest.cc:LINE]
|
||||
no prefix
|
||||
IDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: foo bar 10 3.400000
|
||||
WDATE TIME__ THREADID logging_unittest.cc:LINE] RAW: array
|
||||
|
||||
Loading…
Reference in New Issue
Block a user