blob: 5ca370b6e6117d63790f961532ebeb12b63a6d37 [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.
37 uint8_t *allocate(size_t /*size*/) override {
38 if (is_allocated_) {
39 LOG(FATAL) << "Can't allocate more memory with a fixed size allocator. "
40 "Increase the memory reserved.";
41 }
42
43 is_allocated_ = true;
44 return data_;
45 }
46
47 void deallocate(uint8_t *, size_t) override { is_allocated_ = false; }
48
49 uint8_t *reallocate_downward(uint8_t * /*old_p*/, size_t /*old_size*/,
50 size_t new_size, size_t /*in_use_back*/,
51 size_t /*in_use_front*/) override {
52 LOG(FATAL) << "Requested " << new_size << " bytes, max size "
53 << channel_->max_size() << " for channel "
54 << configuration::CleanedChannelToString(channel_)
55 << ". Increase the memory reserved to at least " << new_size
56 << ".";
57 return nullptr;
58 }
59
60 void Reset() { is_allocated_ = false; }
61 bool is_allocated() const { return is_allocated_; }
62
63 bool allocated() { return is_allocated_; }
64
65 size_t size() const { return size_; }
66 const uint8_t *data() const { return data_; }
67
68 private:
69 bool is_allocated_ = false;
70 uint8_t *data_;
71 size_t size_;
72 const Channel *channel_;
73};
74
75} // namespace aos
76
77#endif // AOS_EVENTS_CHANNEL_PREALLOCATED_ALLOCATOR_