Я недавно читаю код glog для последующей сборки пользовательского модуля журнала.
В основном, использование выглядит следующим образом:
#define LOG(SERVERITY) LogMessage(SERVERITY).stream()
const char* log;
...
LOG(INFO)<<log<<endl;
Я извлек некоторые ключи строк кода следующим образом:
class LogStream : public std::ostream {
...
}
class LogMessage{
...
public:
LogMessage() : allocated_(NULL) {
Init(...);
}
ostream& LogMessage::stream() {
return data_->stream_;
}
struct LogMessageData;
...
private:
void Init(...);
LogMessageData* allocated_;
LogMessageData* data_;
...
};
struct LogMessage::LogMessageData{
...
LogStream stream_;
...
};
static __thread bool thread_data_available = true;
static __thread std::aligned_storage<sizeof(LogMessageData),
alignof(LogMessageData)>::type thread_msg_data;
void LogMessage::Init(...){
if (thread_data_available) {
thread_data_available = false;
data_ = new (&thread_msg_data) LogMessageData;
}else {
allocated_ = new LogMessageData();
data_ = allocated_;
}
//initialize each field of LogMessageData
...
}
LogMessage::~LogMessage() {
...
if (data_ == static_cast<void*>(&thread_msg_data)) {
data_->~LogMessageData();
thread_data_available = true;
}
else {
delete allocated_;
}
}
Насколько я понимаю thread_msg_data
используется в качестве предварительно выделенного буфера, чтобы избежать частого выделения и освобождения памяти в локальном потоке, так для чего используется allocated_
? Кажется, что allocated_
будет использоваться только тогда, когда последняя задача регистрации не будет завершена в том же потоке (возможно, огромная порция данных все еще находится в буфере потока и ожидает записи в место назначения, что блокирует thread_msg_data
?)