Merge "logd: don't use a thread for deleting log chunks"

This commit is contained in:
Tom Cherry 2020-07-15 22:57:50 +00:00 committed by Gerrit Code Review
commit 7c95de7591
2 changed files with 12 additions and 66 deletions

View file

@ -32,12 +32,6 @@ SerializedLogBuffer::SerializedLogBuffer(LogReaderList* reader_list, LogTags* ta
Init();
}
SerializedLogBuffer::~SerializedLogBuffer() {
if (deleter_thread_.joinable()) {
deleter_thread_.join();
}
}
void SerializedLogBuffer::Init() {
log_id_for_each(i) {
if (SetSize(i, __android_logger_get_buffer_size(i))) {
@ -121,54 +115,15 @@ void SerializedLogBuffer::MaybePrune(log_id_t log_id) {
stats_->set_overhead(log_id, after_size);
}
void SerializedLogBuffer::StartDeleterThread() {
if (deleter_thread_running_) {
return;
}
if (deleter_thread_.joinable()) {
deleter_thread_.join();
}
auto new_thread = std::thread([this] { DeleterThread(); });
deleter_thread_.swap(new_thread);
deleter_thread_running_ = true;
}
// Decompresses the chunks, call LogStatistics::Subtract() on each entry, then delete the chunks and
// the list. Note that the SerializedLogChunk objects have been removed from logs_ and their
// references have been deleted from any SerializedFlushToState objects, so this can be safely done
// without holding lock_. It is done in a separate thread to avoid delaying the writer thread.
void SerializedLogBuffer::DeleterThread() {
prctl(PR_SET_NAME, "logd.deleter");
while (true) {
std::list<SerializedLogChunk> local_chunks_to_delete;
log_id_t log_id;
{
auto lock = std::lock_guard{lock_};
log_id_for_each(i) {
if (!chunks_to_delete_[i].empty()) {
local_chunks_to_delete = std::move(chunks_to_delete_[i]);
chunks_to_delete_[i].clear();
log_id = i;
break;
}
}
if (local_chunks_to_delete.empty()) {
deleter_thread_running_ = false;
return;
}
}
for (auto& chunk : local_chunks_to_delete) {
chunk.IncReaderRefCount();
int read_offset = 0;
while (read_offset < chunk.write_offset()) {
auto* entry = chunk.log_entry(read_offset);
stats_->Subtract(entry->ToLogStatisticsElement(log_id));
read_offset += entry->total_len();
}
chunk.DecReaderRefCount(false);
}
void SerializedLogBuffer::RemoveChunkFromStats(log_id_t log_id, SerializedLogChunk& chunk) {
chunk.IncReaderRefCount();
int read_offset = 0;
while (read_offset < chunk.write_offset()) {
auto* entry = chunk.log_entry(read_offset);
stats_->Subtract(entry->ToLogStatisticsElement(log_id));
read_offset += entry->total_len();
}
chunk.DecReaderRefCount(false);
}
void SerializedLogBuffer::NotifyReadersOfPrune(
@ -194,8 +149,6 @@ bool SerializedLogBuffer::Prune(log_id_t log_id, size_t bytes_to_free, uid_t uid
}
}
StartDeleterThread();
auto& log_buffer = logs_[log_id];
auto it = log_buffer.begin();
while (it != log_buffer.end()) {
@ -203,7 +156,7 @@ bool SerializedLogBuffer::Prune(log_id_t log_id, size_t bytes_to_free, uid_t uid
break;
}
// Increment ahead of time since we're going to splice this iterator from the list.
// Increment ahead of time since we're going to erase this iterator from the list.
auto it_to_prune = it++;
// The sequence number check ensures that all readers have read all logs in this chunk, but
@ -219,8 +172,8 @@ bool SerializedLogBuffer::Prune(log_id_t log_id, size_t bytes_to_free, uid_t uid
}
} else {
size_t buffer_size = it_to_prune->PruneSize();
chunks_to_delete_[log_id].splice(chunks_to_delete_[log_id].end(), log_buffer,
it_to_prune);
RemoveChunkFromStats(log_id, *it_to_prune);
log_buffer.erase(it_to_prune);
if (buffer_size >= bytes_to_free) {
return true;
}

View file

@ -37,7 +37,6 @@
class SerializedLogBuffer final : public LogBuffer {
public:
SerializedLogBuffer(LogReaderList* reader_list, LogTags* tags, LogStatistics* stats);
~SerializedLogBuffer();
void Init() override;
int Log(log_id_t log_id, log_time realtime, uid_t uid, pid_t pid, pid_t tid, const char* msg,
@ -61,11 +60,9 @@ class SerializedLogBuffer final : public LogBuffer {
REQUIRES_SHARED(lock_);
void NotifyReadersOfPrune(log_id_t log_id, const std::list<SerializedLogChunk>::iterator& chunk)
REQUIRES(reader_list_->reader_threads_lock());
void RemoveChunkFromStats(log_id_t log_id, SerializedLogChunk& chunk);
unsigned long GetSizeUsed(log_id_t id) REQUIRES(lock_);
void StartDeleterThread() REQUIRES(lock_);
void DeleterThread();
LogReaderList* reader_list_;
LogTags* tags_;
LogStatistics* stats_;
@ -74,9 +71,5 @@ class SerializedLogBuffer final : public LogBuffer {
std::list<SerializedLogChunk> logs_[LOG_ID_MAX] GUARDED_BY(lock_);
RwLock lock_;
std::list<SerializedLogChunk> chunks_to_delete_[LOG_ID_MAX] GUARDED_BY(lock_);
std::thread deleter_thread_ GUARDED_BY(lock_);
bool deleter_thread_running_ GUARDED_BY(lock_) = false;
std::atomic<uint64_t> sequence_ = 1;
};