blob: 76fb694d86aef4f15d162f2bc0f045cb2f77a3c6 [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
4#include "aos/configuration.h"
5#include "aos/configuration_generated.h"
6#include "flatbuffers/flatbuffers.h"
7
8namespace aos {
9
10class ChannelPreallocatedAllocator : public flatbuffers::Allocator {
11 public:
12 ChannelPreallocatedAllocator(uint8_t *data, size_t size,
13 const Channel *channel)
14 : data_(data), size_(size), channel_(channel) {}
15
16 ChannelPreallocatedAllocator(const ChannelPreallocatedAllocator &) = delete;
17 ChannelPreallocatedAllocator(ChannelPreallocatedAllocator &&other)
18 : data_(other.data_), size_(other.size_), channel_(other.channel_) {
Brian Silverman341b57e2020-06-23 16:23:18 -070019 CHECK(!is_allocated()) << ": May not overwrite in-use allocator";
Austin Schuh1af273d2020-03-07 20:11:34 -080020 CHECK(!other.is_allocated());
21 }
22
23 ChannelPreallocatedAllocator &operator=(
24 const ChannelPreallocatedAllocator &) = delete;
25 ChannelPreallocatedAllocator &operator=(
26 ChannelPreallocatedAllocator &&other) {
Brian Silverman341b57e2020-06-23 16:23:18 -070027 CHECK(!is_allocated()) << ": May not overwrite in-use allocator";
Austin Schuh1af273d2020-03-07 20:11:34 -080028 CHECK(!other.is_allocated());
29 data_ = other.data_;
30 size_ = other.size_;
31 channel_ = other.channel_;
32 return *this;
33 }
34 ~ChannelPreallocatedAllocator() override { CHECK(!is_allocated_); }
35
36 // TODO(austin): Read the contract for these.
Austin Schuhd54780b2020-10-03 16:26:02 -070037 uint8_t *allocate(size_t size) override {
Austin Schuh1af273d2020-03-07 20:11:34 -080038 if (is_allocated_) {
Austin Schuhd54780b2020-10-03 16:26:02 -070039 LOG(FATAL) << "Can't allocate more memory with a fixed size allocator on "
40 "channel "
41 << configuration::CleanedChannelToString(channel_);
Austin Schuh1af273d2020-03-07 20:11:34 -080042 }
43
Austin Schuhd54780b2020-10-03 16:26:02 -070044 CHECK_LE(size, size_)
45 << ": Tried to allocate more space than available on channel "
46 << configuration::CleanedChannelToString(channel_);
47
Austin Schuh1af273d2020-03-07 20:11:34 -080048 is_allocated_ = true;
49 return data_;
50 }
51
Austin Schuhd54780b2020-10-03 16:26:02 -070052 void deallocate(uint8_t *data, size_t size) override {
53 CHECK_EQ(data, data_)
54 << ": Deallocating data not allocated here on channel "
55 << configuration::CleanedChannelToString(channel_);
56 CHECK_LE(size, size_)
57 << ": Tried to deallocate more space than available on channel "
58 << configuration::CleanedChannelToString(channel_);
59 is_allocated_ = false;
60 }
Austin Schuh1af273d2020-03-07 20:11:34 -080061
62 uint8_t *reallocate_downward(uint8_t * /*old_p*/, size_t /*old_size*/,
63 size_t new_size, size_t /*in_use_back*/,
64 size_t /*in_use_front*/) override {
Austin Schuha27efb72021-07-21 15:27:04 -070065 LOG(FATAL)
66 << "Requested " << new_size
67 << " bytes (includes extra for room to grow even more), max size "
68 << channel_->max_size() << " for channel "
69 << configuration::CleanedChannelToString(channel_)
70 << ". Increase the memory reserved to at least " << new_size << ".";
Austin Schuh1af273d2020-03-07 20:11:34 -080071 return nullptr;
72 }
73
74 void Reset() { is_allocated_ = false; }
75 bool is_allocated() const { return is_allocated_; }
76
77 bool allocated() { return is_allocated_; }
78
79 size_t size() const { return size_; }
80 const uint8_t *data() const { return data_; }
81
82 private:
83 bool is_allocated_ = false;
84 uint8_t *data_;
85 size_t size_;
86 const Channel *channel_;
87};
88
89} // namespace aos
90
91#endif // AOS_EVENTS_CHANNEL_PREALLOCATED_ALLOCATOR_