Pigweed
 
Loading...
Searching...
No Matches
single_chunk_region_tracker.h
1// Copyright 2024 The Pigweed Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License"); you may not
4// use this file except in compliance with the License. You may obtain a copy of
5// the License at
6//
7// https://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12// License for the specific language governing permissions and limitations under
13// the License.
14#pragma once
15
16#include <array>
17#include <atomic>
18#include <cstring>
19#include <optional>
20
21#include "pw_assert/assert.h"
22#include "pw_bytes/span.h"
23#include "pw_multibuf/chunk.h"
24
25namespace pw::multibuf {
26
31 public:
34 explicit SingleChunkRegionTracker(ByteSpan region) : region_(region) {}
35 ~SingleChunkRegionTracker() override { Destroy(); }
36
43 std::optional<OwnedChunk> GetChunk(size_t size) {
44 PW_DASSERT(size <= region_.size());
45 // Since this is a single `Chunk` region, re-create the first `Chunk` is
46 // allowed if freed.
47 std::optional<OwnedChunk> chunk = CreateFirstChunk();
48 if (chunk.has_value() && size < region_.size()) {
49 (*chunk)->Truncate(size);
50 }
51 return chunk;
52 }
53
54 void Destroy() final {
55 // Nothing to release here.
56 PW_ASSERT(!chunk_in_use_);
57 }
58
59 ByteSpan Region() const final { return region_; }
60
61 void* AllocateChunkClass() final {
62 bool in_use = false;
63 if (!chunk_in_use_.compare_exchange_strong(in_use, true)) {
64 return nullptr;
65 }
66 return &chunk_storage_;
67 }
68
69 void DeallocateChunkClass(void* chunk) final {
70 PW_ASSERT(chunk == chunk_storage_.data());
71 // Mark the `Chunk` as not in use and zero-out the region and chunk storage.
72 std::memset(chunk_storage_.data(), 0, chunk_storage_.size());
73 std::memset(region_.data(), 0, region_.size());
74 chunk_in_use_ = false;
75 }
76
77 private:
78 ByteSpan region_;
79 std::atomic<bool> chunk_in_use_ = false;
80 alignas(Chunk) std::array<std::byte, sizeof(Chunk)> chunk_storage_;
81};
82
83} // namespace pw::multibuf
Definition: chunk.h:47
Definition: chunk.h:271
std::optional< OwnedChunk > CreateFirstChunk()
Definition: single_chunk_region_tracker.h:30
void DeallocateChunkClass(void *chunk) final
Deallocates a pointer returned by AllocateChunkClass.
Definition: single_chunk_region_tracker.h:69
ByteSpan Region() const final
Definition: single_chunk_region_tracker.h:59
SingleChunkRegionTracker(ByteSpan region)
Definition: single_chunk_region_tracker.h:34
void Destroy() final
Definition: single_chunk_region_tracker.h:54
void * AllocateChunkClass() final
Definition: single_chunk_region_tracker.h:61
std::optional< OwnedChunk > GetChunk(size_t size)
Definition: single_chunk_region_tracker.h:43