Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7c95de75 authored by Tom Cherry's avatar Tom Cherry Committed by Gerrit Code Review
Browse files

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

parents ed99870f 4f8125af
Loading
Loading
Loading
Loading
+11 −58
Original line number Original line Diff line number Diff line
@@ -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))) {
@@ -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()) {
@@ -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) {
@@ -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()) {
@@ -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
@@ -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;
            }
            }
+1 −8
Original line number Original line Diff line number Diff line
@@ -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,
@@ -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_;
@@ -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;
};
};