Loading logd/SerializedLogBuffer.cpp +11 −58 Original line number Original line Diff line number Diff line Loading @@ -32,12 +32,6 @@ SerializedLogBuffer::SerializedLogBuffer(LogReaderList* reader_list, LogTags* ta Init(); Init(); } } SerializedLogBuffer::~SerializedLogBuffer() { if (deleter_thread_.joinable()) { deleter_thread_.join(); } } void SerializedLogBuffer::Init() { void SerializedLogBuffer::Init() { log_id_for_each(i) { log_id_for_each(i) { if (SetSize(i, __android_logger_get_buffer_size(i))) { if (SetSize(i, __android_logger_get_buffer_size(i))) { Loading Loading @@ -121,44 +115,7 @@ void SerializedLogBuffer::MaybePrune(log_id_t log_id) { stats_->set_overhead(log_id, after_size); stats_->set_overhead(log_id, after_size); } } void SerializedLogBuffer::StartDeleterThread() { void SerializedLogBuffer::RemoveChunkFromStats(log_id_t log_id, SerializedLogChunk& chunk) { 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(); chunk.IncReaderRefCount(); int read_offset = 0; int read_offset = 0; while (read_offset < chunk.write_offset()) { while (read_offset < chunk.write_offset()) { Loading @@ -168,8 +125,6 @@ void SerializedLogBuffer::DeleterThread() { } } chunk.DecReaderRefCount(false); chunk.DecReaderRefCount(false); } } } } void SerializedLogBuffer::NotifyReadersOfPrune( void SerializedLogBuffer::NotifyReadersOfPrune( log_id_t log_id, const std::list<SerializedLogChunk>::iterator& chunk) { log_id_t log_id, const std::list<SerializedLogChunk>::iterator& chunk) { Loading @@ -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& log_buffer = logs_[log_id]; auto it = log_buffer.begin(); auto it = log_buffer.begin(); while (it != log_buffer.end()) { while (it != log_buffer.end()) { Loading @@ -203,7 +156,7 @@ bool SerializedLogBuffer::Prune(log_id_t log_id, size_t bytes_to_free, uid_t uid break; 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++; auto it_to_prune = it++; // The sequence number check ensures that all readers have read all logs in this chunk, but // The sequence number check ensures that all readers have read all logs in this chunk, but Loading @@ -219,8 +172,8 @@ bool SerializedLogBuffer::Prune(log_id_t log_id, size_t bytes_to_free, uid_t uid } } } else { } else { size_t buffer_size = it_to_prune->PruneSize(); size_t buffer_size = it_to_prune->PruneSize(); chunks_to_delete_[log_id].splice(chunks_to_delete_[log_id].end(), log_buffer, RemoveChunkFromStats(log_id, *it_to_prune); it_to_prune); log_buffer.erase(it_to_prune); if (buffer_size >= bytes_to_free) { if (buffer_size >= bytes_to_free) { return true; return true; } } Loading logd/SerializedLogBuffer.h +1 −8 Original line number Original line Diff line number Diff line Loading @@ -37,7 +37,6 @@ class SerializedLogBuffer final : public LogBuffer { class SerializedLogBuffer final : public LogBuffer { public: public: SerializedLogBuffer(LogReaderList* reader_list, LogTags* tags, LogStatistics* stats); SerializedLogBuffer(LogReaderList* reader_list, LogTags* tags, LogStatistics* stats); ~SerializedLogBuffer(); void Init() override; 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, int Log(log_id_t log_id, log_time realtime, uid_t uid, pid_t pid, pid_t tid, const char* msg, Loading @@ -61,11 +60,9 @@ class SerializedLogBuffer final : public LogBuffer { REQUIRES_SHARED(lock_); REQUIRES_SHARED(lock_); void NotifyReadersOfPrune(log_id_t log_id, const std::list<SerializedLogChunk>::iterator& chunk) void NotifyReadersOfPrune(log_id_t log_id, const std::list<SerializedLogChunk>::iterator& chunk) REQUIRES(reader_list_->reader_threads_lock()); REQUIRES(reader_list_->reader_threads_lock()); void RemoveChunkFromStats(log_id_t log_id, SerializedLogChunk& chunk); unsigned long GetSizeUsed(log_id_t id) REQUIRES(lock_); unsigned long GetSizeUsed(log_id_t id) REQUIRES(lock_); void StartDeleterThread() REQUIRES(lock_); void DeleterThread(); LogReaderList* reader_list_; LogReaderList* reader_list_; LogTags* tags_; LogTags* tags_; LogStatistics* stats_; LogStatistics* stats_; Loading @@ -74,9 +71,5 @@ class SerializedLogBuffer final : public LogBuffer { std::list<SerializedLogChunk> logs_[LOG_ID_MAX] GUARDED_BY(lock_); std::list<SerializedLogChunk> logs_[LOG_ID_MAX] GUARDED_BY(lock_); RwLock 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; std::atomic<uint64_t> sequence_ = 1; }; }; Loading
logd/SerializedLogBuffer.cpp +11 −58 Original line number Original line Diff line number Diff line Loading @@ -32,12 +32,6 @@ SerializedLogBuffer::SerializedLogBuffer(LogReaderList* reader_list, LogTags* ta Init(); Init(); } } SerializedLogBuffer::~SerializedLogBuffer() { if (deleter_thread_.joinable()) { deleter_thread_.join(); } } void SerializedLogBuffer::Init() { void SerializedLogBuffer::Init() { log_id_for_each(i) { log_id_for_each(i) { if (SetSize(i, __android_logger_get_buffer_size(i))) { if (SetSize(i, __android_logger_get_buffer_size(i))) { Loading Loading @@ -121,44 +115,7 @@ void SerializedLogBuffer::MaybePrune(log_id_t log_id) { stats_->set_overhead(log_id, after_size); stats_->set_overhead(log_id, after_size); } } void SerializedLogBuffer::StartDeleterThread() { void SerializedLogBuffer::RemoveChunkFromStats(log_id_t log_id, SerializedLogChunk& chunk) { 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(); chunk.IncReaderRefCount(); int read_offset = 0; int read_offset = 0; while (read_offset < chunk.write_offset()) { while (read_offset < chunk.write_offset()) { Loading @@ -168,8 +125,6 @@ void SerializedLogBuffer::DeleterThread() { } } chunk.DecReaderRefCount(false); chunk.DecReaderRefCount(false); } } } } void SerializedLogBuffer::NotifyReadersOfPrune( void SerializedLogBuffer::NotifyReadersOfPrune( log_id_t log_id, const std::list<SerializedLogChunk>::iterator& chunk) { log_id_t log_id, const std::list<SerializedLogChunk>::iterator& chunk) { Loading @@ -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& log_buffer = logs_[log_id]; auto it = log_buffer.begin(); auto it = log_buffer.begin(); while (it != log_buffer.end()) { while (it != log_buffer.end()) { Loading @@ -203,7 +156,7 @@ bool SerializedLogBuffer::Prune(log_id_t log_id, size_t bytes_to_free, uid_t uid break; 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++; auto it_to_prune = it++; // The sequence number check ensures that all readers have read all logs in this chunk, but // The sequence number check ensures that all readers have read all logs in this chunk, but Loading @@ -219,8 +172,8 @@ bool SerializedLogBuffer::Prune(log_id_t log_id, size_t bytes_to_free, uid_t uid } } } else { } else { size_t buffer_size = it_to_prune->PruneSize(); size_t buffer_size = it_to_prune->PruneSize(); chunks_to_delete_[log_id].splice(chunks_to_delete_[log_id].end(), log_buffer, RemoveChunkFromStats(log_id, *it_to_prune); it_to_prune); log_buffer.erase(it_to_prune); if (buffer_size >= bytes_to_free) { if (buffer_size >= bytes_to_free) { return true; return true; } } Loading
logd/SerializedLogBuffer.h +1 −8 Original line number Original line Diff line number Diff line Loading @@ -37,7 +37,6 @@ class SerializedLogBuffer final : public LogBuffer { class SerializedLogBuffer final : public LogBuffer { public: public: SerializedLogBuffer(LogReaderList* reader_list, LogTags* tags, LogStatistics* stats); SerializedLogBuffer(LogReaderList* reader_list, LogTags* tags, LogStatistics* stats); ~SerializedLogBuffer(); void Init() override; 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, int Log(log_id_t log_id, log_time realtime, uid_t uid, pid_t pid, pid_t tid, const char* msg, Loading @@ -61,11 +60,9 @@ class SerializedLogBuffer final : public LogBuffer { REQUIRES_SHARED(lock_); REQUIRES_SHARED(lock_); void NotifyReadersOfPrune(log_id_t log_id, const std::list<SerializedLogChunk>::iterator& chunk) void NotifyReadersOfPrune(log_id_t log_id, const std::list<SerializedLogChunk>::iterator& chunk) REQUIRES(reader_list_->reader_threads_lock()); REQUIRES(reader_list_->reader_threads_lock()); void RemoveChunkFromStats(log_id_t log_id, SerializedLogChunk& chunk); unsigned long GetSizeUsed(log_id_t id) REQUIRES(lock_); unsigned long GetSizeUsed(log_id_t id) REQUIRES(lock_); void StartDeleterThread() REQUIRES(lock_); void DeleterThread(); LogReaderList* reader_list_; LogReaderList* reader_list_; LogTags* tags_; LogTags* tags_; LogStatistics* stats_; LogStatistics* stats_; Loading @@ -74,9 +71,5 @@ class SerializedLogBuffer final : public LogBuffer { std::list<SerializedLogChunk> logs_[LOG_ID_MAX] GUARDED_BY(lock_); std::list<SerializedLogChunk> logs_[LOG_ID_MAX] GUARDED_BY(lock_); RwLock 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; std::atomic<uint64_t> sequence_ = 1; }; };