Застрял в понимании, используя объект local_thread_storage (std :: align_storage) для ведения журнала - PullRequest
1 голос
/ 02 марта 2020

Я недавно читаю код 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?)

...