Removing copy to temp buffer in log flush.
This commit is contained in:
parent
9ae807e56e
commit
e48c3534cc
|
@ -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) {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Reference in New Issue