Removing copy to temp buffer in log flush.

This commit is contained in:
Ben Vanik 2015-09-06 10:28:17 -07:00
parent 9ae807e56e
commit e48c3534cc
3 changed files with 47 additions and 3 deletions

View File

@ -104,9 +104,10 @@ class Logger {
bool did_write = false;
while (!ring_buffer_.empty()) {
did_write = true;
// Read line header and write out the line prefix.
LogLine line;
ring_buffer_.Read(&line, sizeof(line));
ring_buffer_.Read(log_format_buffer_.data(), line.buffer_length);
char prefix[] = {
line.level_char,
'>',
@ -125,11 +126,23 @@ class Logger {
std::snprintf(prefix + 3, sizeof(prefix) - 3, "%08" PRIX32 " ",
line.thread_id);
fwrite(prefix, 1, sizeof(prefix) - 1, file_);
fwrite(log_format_buffer_.data(), 1, line.buffer_length, file_);
if (log_format_buffer_[line.buffer_length - 1] != '\n') {
// Get access to the line data - which may be split in the ring buffer -
// and write it out in parts.
auto line_range = ring_buffer_.BeginRead(line.buffer_length);
fwrite(line_range.first, 1, line_range.first_length, file_);
if (line_range.second_length) {
fwrite(line_range.second, 1, line_range.second_length, file_);
}
// Always ensure there is a newline.
char last_char = line_range.second
? line_range.second[line_range.second_length - 1]
: line_range.first[line_range.first_length - 1];
if (last_char != '\n') {
const char suffix[1] = {'\n'};
fwrite(suffix, 1, sizeof(suffix), file_);
}
ring_buffer_.EndRead(std::move(line_range));
}
mutex_.unlock();
if (did_write) {

View File

@ -17,6 +17,28 @@ namespace xe {
RingBuffer::RingBuffer(uint8_t* buffer, size_t capacity)
: buffer_(buffer), capacity_(capacity) {}
RingBuffer::ReadRange RingBuffer::BeginRead(size_t count) {
count = std::min(count, capacity_);
if (!count) {
return {0};
}
if (read_offset_ + count < capacity_) {
return {buffer_ + read_offset_, count, nullptr, 0};
} else {
size_t left_half = capacity_ - read_offset_;
size_t right_half = count - left_half;
return {buffer_ + read_offset_, left_half, buffer_, right_half};
}
}
void RingBuffer::EndRead(ReadRange read_range) {
if (read_range.second_length) {
read_offset_ = read_range.second_length;
} else {
read_offset_ += read_range.first_length;
}
}
size_t RingBuffer::Read(uint8_t* buffer, size_t count) {
count = std::min(count, capacity_);
if (!count) {

View File

@ -48,6 +48,15 @@ class RingBuffer {
}
}
struct ReadRange {
const uint8_t* first;
size_t first_length;
const uint8_t* second;
size_t second_length;
};
ReadRange BeginRead(size_t count);
void EndRead(ReadRange read_range);
size_t Read(uint8_t* buffer, size_t count);
template <typename T>
size_t Read(T* buffer, size_t count) {