summaryrefslogtreecommitdiff
path: root/src/logging.cc
diff options
context:
space:
mode:
authorShinichiro Hamaji <shinichiro.hamaji@gmail.com>2017-07-06 14:58:37 +0900
committerGitHub <noreply@github.com>2017-07-06 14:58:37 +0900
commita835da8e088273066c32c3cb0e8ff69d54071217 (patch)
treeb6ef48802055eae672126cf914a15522dfad53c3 /src/logging.cc
parent96f6656551860c40c746c1946a4e4cb131e1f4a4 (diff)
parent2df0ca34aa3000dadf76633ca700abf0bf50756d (diff)
downloadglog-a835da8e088273066c32c3cb0e8ff69d54071217.tar.gz
glog-a835da8e088273066c32c3cb0e8ff69d54071217.tar.bz2
glog-a835da8e088273066c32c3cb0e8ff69d54071217.zip
Merge pull request #158 from sergiud/zero-allocation
[RFC] reduce heap memory allocations to zero
Diffstat (limited to 'src/logging.cc')
-rw-r--r--src/logging.cc31
1 files changed, 31 insertions, 0 deletions
diff --git a/src/logging.cc b/src/logging.cc
index 46a0f5a..0d9aad8 100644
--- a/src/logging.cc
+++ b/src/logging.cc
@@ -331,6 +331,7 @@ const size_t LogMessage::kMaxLogMessageLen = 30000;
struct LogMessage::LogMessageData {
LogMessageData();
+ void reset();
int preserved_errno_; // preserved errno
// Buffer space; contains complete message text.
@@ -1145,10 +1146,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) {
@@ -1201,8 +1214,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);
@@ -1271,6 +1298,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_;
}