xref: /aosp_15_r20/system/logging/logd/SerializedLogChunk.h (revision 598139dc91b21518d67c408eaea2644226490971)
1*598139dcSAndroid Build Coastguard Worker /*
2*598139dcSAndroid Build Coastguard Worker  * Copyright (C) 2020 The Android Open Source Project
3*598139dcSAndroid Build Coastguard Worker  *
4*598139dcSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*598139dcSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*598139dcSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*598139dcSAndroid Build Coastguard Worker  *
8*598139dcSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*598139dcSAndroid Build Coastguard Worker  *
10*598139dcSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*598139dcSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*598139dcSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*598139dcSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*598139dcSAndroid Build Coastguard Worker  * limitations under the License.
15*598139dcSAndroid Build Coastguard Worker  */
16*598139dcSAndroid Build Coastguard Worker 
17*598139dcSAndroid Build Coastguard Worker #pragma once
18*598139dcSAndroid Build Coastguard Worker 
19*598139dcSAndroid Build Coastguard Worker #include <sys/types.h>
20*598139dcSAndroid Build Coastguard Worker 
21*598139dcSAndroid Build Coastguard Worker #include <list>
22*598139dcSAndroid Build Coastguard Worker #include <vector>
23*598139dcSAndroid Build Coastguard Worker 
24*598139dcSAndroid Build Coastguard Worker #include <android-base/logging.h>
25*598139dcSAndroid Build Coastguard Worker 
26*598139dcSAndroid Build Coastguard Worker #include "LogWriter.h"
27*598139dcSAndroid Build Coastguard Worker #include "LogdLock.h"
28*598139dcSAndroid Build Coastguard Worker #include "SerializedData.h"
29*598139dcSAndroid Build Coastguard Worker #include "SerializedLogEntry.h"
30*598139dcSAndroid Build Coastguard Worker 
31*598139dcSAndroid Build Coastguard Worker class SerializedFlushToState;
32*598139dcSAndroid Build Coastguard Worker 
33*598139dcSAndroid Build Coastguard Worker class SerializedLogChunk {
34*598139dcSAndroid Build Coastguard Worker   public:
35*598139dcSAndroid Build Coastguard Worker     friend void VerifyChunks(const std::list<SerializedLogChunk>& expected,
36*598139dcSAndroid Build Coastguard Worker                              const std::list<SerializedLogChunk>& chunks);
37*598139dcSAndroid Build Coastguard Worker 
38*598139dcSAndroid Build Coastguard Worker     class LogEntryIterator {
39*598139dcSAndroid Build Coastguard Worker       public:
LogEntryIterator(SerializedLogChunk & chunk,int read_offset_)40*598139dcSAndroid Build Coastguard Worker         LogEntryIterator(SerializedLogChunk& chunk, int read_offset_)
41*598139dcSAndroid Build Coastguard Worker             : chunk_(chunk), read_offset_(read_offset_) {}
42*598139dcSAndroid Build Coastguard Worker 
43*598139dcSAndroid Build Coastguard Worker         LogEntryIterator& operator++() {
44*598139dcSAndroid Build Coastguard Worker             read_offset_ += chunk_.log_entry(read_offset_)->total_len();
45*598139dcSAndroid Build Coastguard Worker             return *this;
46*598139dcSAndroid Build Coastguard Worker         }
47*598139dcSAndroid Build Coastguard Worker 
48*598139dcSAndroid Build Coastguard Worker         bool operator!=(const LogEntryIterator& other) const {
49*598139dcSAndroid Build Coastguard Worker             return read_offset_ != other.read_offset_;
50*598139dcSAndroid Build Coastguard Worker         }
51*598139dcSAndroid Build Coastguard Worker         const SerializedLogEntry& operator*() const { return *chunk_.log_entry(read_offset_); }
52*598139dcSAndroid Build Coastguard Worker 
53*598139dcSAndroid Build Coastguard Worker       private:
54*598139dcSAndroid Build Coastguard Worker         SerializedLogChunk& chunk_;
55*598139dcSAndroid Build Coastguard Worker         int read_offset_;
56*598139dcSAndroid Build Coastguard Worker     };
57*598139dcSAndroid Build Coastguard Worker 
SerializedLogChunk(size_t size)58*598139dcSAndroid Build Coastguard Worker     explicit SerializedLogChunk(size_t size) : contents_(size) {}
59*598139dcSAndroid Build Coastguard Worker     SerializedLogChunk(SerializedLogChunk&& other) noexcept = default;
60*598139dcSAndroid Build Coastguard Worker     ~SerializedLogChunk();
61*598139dcSAndroid Build Coastguard Worker 
62*598139dcSAndroid Build Coastguard Worker     void FinishWriting();
63*598139dcSAndroid Build Coastguard Worker     void IncReaderRefCount();
64*598139dcSAndroid Build Coastguard Worker     void DecReaderRefCount();
65*598139dcSAndroid Build Coastguard Worker     void AttachReader(SerializedFlushToState* reader);
66*598139dcSAndroid Build Coastguard Worker     void DetachReader(SerializedFlushToState* reader);
67*598139dcSAndroid Build Coastguard Worker 
68*598139dcSAndroid Build Coastguard Worker     void NotifyReadersOfPrune(log_id_t log_id) REQUIRES(logd_lock);
69*598139dcSAndroid Build Coastguard Worker 
70*598139dcSAndroid Build Coastguard Worker     bool CanLog(size_t len);
71*598139dcSAndroid Build Coastguard Worker     SerializedLogEntry* Log(uint64_t sequence, log_time realtime, uid_t uid, pid_t pid, pid_t tid,
72*598139dcSAndroid Build Coastguard Worker                             const char* msg, uint16_t len);
73*598139dcSAndroid Build Coastguard Worker 
74*598139dcSAndroid Build Coastguard Worker     // If this buffer has been compressed, we only consider its compressed size when accounting for
75*598139dcSAndroid Build Coastguard Worker     // memory consumption for pruning.  This is since the uncompressed log is only by used by
76*598139dcSAndroid Build Coastguard Worker     // readers, and thus not a representation of how much these logs cost to keep in memory.
PruneSize()77*598139dcSAndroid Build Coastguard Worker     size_t PruneSize() const {
78*598139dcSAndroid Build Coastguard Worker         return sizeof(*this) + (compressed_log_.size() ?: contents_.size());
79*598139dcSAndroid Build Coastguard Worker     }
80*598139dcSAndroid Build Coastguard Worker 
log_entry(int offset)81*598139dcSAndroid Build Coastguard Worker     const SerializedLogEntry* log_entry(int offset) const {
82*598139dcSAndroid Build Coastguard Worker         CHECK(writer_active_ || reader_ref_count_ > 0);
83*598139dcSAndroid Build Coastguard Worker         return reinterpret_cast<const SerializedLogEntry*>(data() + offset);
84*598139dcSAndroid Build Coastguard Worker     }
data()85*598139dcSAndroid Build Coastguard Worker     const uint8_t* data() const { return contents_.data(); }
write_offset()86*598139dcSAndroid Build Coastguard Worker     int write_offset() const { return write_offset_; }
highest_sequence_number()87*598139dcSAndroid Build Coastguard Worker     uint64_t highest_sequence_number() const { return highest_sequence_number_; }
88*598139dcSAndroid Build Coastguard Worker 
begin()89*598139dcSAndroid Build Coastguard Worker     LogEntryIterator begin() { return LogEntryIterator(*this, 0); }
90*598139dcSAndroid Build Coastguard Worker 
end()91*598139dcSAndroid Build Coastguard Worker     LogEntryIterator end() { return LogEntryIterator(*this, write_offset_); }
92*598139dcSAndroid Build Coastguard Worker 
93*598139dcSAndroid Build Coastguard Worker     // Exposed for testing
reader_ref_count()94*598139dcSAndroid Build Coastguard Worker     uint32_t reader_ref_count() const { return reader_ref_count_; }
95*598139dcSAndroid Build Coastguard Worker 
96*598139dcSAndroid Build Coastguard Worker   private:
97*598139dcSAndroid Build Coastguard Worker     // The decompressed contents of this log buffer.  Deallocated when the ref_count reaches 0 and
98*598139dcSAndroid Build Coastguard Worker     // writer_active_ is false.
99*598139dcSAndroid Build Coastguard Worker     SerializedData contents_;
100*598139dcSAndroid Build Coastguard Worker     int write_offset_ = 0;
101*598139dcSAndroid Build Coastguard Worker     uint32_t reader_ref_count_ = 0;
102*598139dcSAndroid Build Coastguard Worker     bool writer_active_ = true;
103*598139dcSAndroid Build Coastguard Worker     uint64_t highest_sequence_number_ = 1;
104*598139dcSAndroid Build Coastguard Worker     SerializedData compressed_log_;
105*598139dcSAndroid Build Coastguard Worker     std::vector<SerializedFlushToState*> readers_;
106*598139dcSAndroid Build Coastguard Worker };
107