blob: 49eafef8ff85778656baa439b3902237e90a8f8e [file] [log] [blame]
Austin Schuh1af273d2020-03-07 20:11:34 -08001#ifndef AOS_EVENTS_CHANNEL_PREALLOCATED_ALLOCATOR_
2#define AOS_EVENTS_CHANNEL_PREALLOCATED_ALLOCATOR_
3
Philipp Schrader790cb542023-07-05 21:06:52 -07004#include "flatbuffers/flatbuffers.h"
5
Austin Schuh1af273d2020-03-07 20:11:34 -08006#include "aos/configuration.h"
7#include "aos/configuration_generated.h"
Austin Schuh1af273d2020-03-07 20:11:34 -08008
9namespace aos {
10
11class ChannelPreallocatedAllocator : public flatbuffers::Allocator {
12 public:
13 ChannelPreallocatedAllocator(uint8_t *data, size_t size,
14 const Channel *channel)
15 : data_(data), size_(size), channel_(channel) {}
16
17 ChannelPreallocatedAllocator(const ChannelPreallocatedAllocator &) = delete;
18 ChannelPreallocatedAllocator(ChannelPreallocatedAllocator &&other)
19 : data_(other.data_), size_(other.size_), channel_(other.channel_) {
Brian Silverman341b57e2020-06-23 16:23:18 -070020 CHECK(!is_allocated()) << ": May not overwrite in-use allocator";
Austin Schuh1af273d2020-03-07 20:11:34 -080021 CHECK(!other.is_allocated());
22 }
23
24 ChannelPreallocatedAllocator &operator=(
25 const ChannelPreallocatedAllocator &) = delete;
26 ChannelPreallocatedAllocator &operator=(
27 ChannelPreallocatedAllocator &&other) {
Brian Silverman341b57e2020-06-23 16:23:18 -070028 CHECK(!is_allocated()) << ": May not overwrite in-use allocator";
Austin Schuh1af273d2020-03-07 20:11:34 -080029 CHECK(!other.is_allocated());
30 data_ = other.data_;
31 size_ = other.size_;
32 channel_ = other.channel_;
33 return *this;
34 }
35 ~ChannelPreallocatedAllocator() override { CHECK(!is_allocated_); }
36
37 // TODO(austin): Read the contract for these.
Austin Schuhd54780b2020-10-03 16:26:02 -070038 uint8_t *allocate(size_t size) override {
Austin Schuh1af273d2020-03-07 20:11:34 -080039 if (is_allocated_) {
Austin Schuhd54780b2020-10-03 16:26:02 -070040 LOG(FATAL) << "Can't allocate more memory with a fixed size allocator on "
41 "channel "
42 << configuration::CleanedChannelToString(channel_);
Austin Schuh1af273d2020-03-07 20:11:34 -080043 }
44
Austin Schuhd54780b2020-10-03 16:26:02 -070045 CHECK_LE(size, size_)
46 << ": Tried to allocate more space than available on channel "
47 << configuration::CleanedChannelToString(channel_);
48
Austin Schuh1af273d2020-03-07 20:11:34 -080049 is_allocated_ = true;
50 return data_;
51 }
52
Austin Schuhd54780b2020-10-03 16:26:02 -070053 void deallocate(uint8_t *data, size_t size) override {
54 CHECK_EQ(data, data_)
55 << ": Deallocating data not allocated here on channel "
56 << configuration::CleanedChannelToString(channel_);
57 CHECK_LE(size, size_)
58 << ": Tried to deallocate more space than available on channel "
59 << configuration::CleanedChannelToString(channel_);
60 is_allocated_ = false;
61 }
Austin Schuh1af273d2020-03-07 20:11:34 -080062
63 uint8_t *reallocate_downward(uint8_t * /*old_p*/, size_t /*old_size*/,
64 size_t new_size, size_t /*in_use_back*/,
65 size_t /*in_use_front*/) override {
Austin Schuha27efb72021-07-21 15:27:04 -070066 LOG(FATAL)
67 << "Requested " << new_size
68 << " bytes (includes extra for room to grow even more), max size "
69 << channel_->max_size() << " for channel "
70 << configuration::CleanedChannelToString(channel_)
71 << ". Increase the memory reserved to at least " << new_size << ".";
Austin Schuh1af273d2020-03-07 20:11:34 -080072 return nullptr;
73 }
74
75 void Reset() { is_allocated_ = false; }
76 bool is_allocated() const { return is_allocated_; }
77
78 bool allocated() { return is_allocated_; }
79
80 size_t size() const { return size_; }
81 const uint8_t *data() const { return data_; }
82
83 private:
84 bool is_allocated_ = false;
85 uint8_t *data_;
86 size_t size_;
87 const Channel *channel_;
88};
89
90} // namespace aos
91
92#endif // AOS_EVENTS_CHANNEL_PREALLOCATED_ALLOCATOR_