Pigweed
C/C++ API Reference
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
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#include "pw_multibuf/config.h"
25
26namespace pw::multibuf {
27
31class PW_MULTIBUF_DEPRECATED SingleChunkRegionTracker
32 : public ChunkRegionTracker {
33 public:
36 explicit SingleChunkRegionTracker(ByteSpan region) : region_(region) {}
37 ~SingleChunkRegionTracker() override { Destroy(); }
38
45 std::optional<OwnedChunk> GetChunk(size_t size) {
46 PW_DASSERT(size <= region_.size());
47 // Since this is a single `Chunk` region, re-create the first `Chunk` is
48 // allowed if freed.
49 std::optional<OwnedChunk> chunk = CreateFirstChunk();
50 if (chunk.has_value() && size < region_.size()) {
51 (*chunk)->Truncate(size);
52 }
53 return chunk;
54 }
55
56 void Destroy() final {
57 // Nothing to release here.
58 PW_ASSERT(!chunk_in_use_);
59 }
60
61 ByteSpan Region() const final { return region_; }
62
63 void* AllocateChunkClass() final {
64 bool in_use = false;
65 if (!chunk_in_use_.compare_exchange_strong(in_use, true)) {
66 return nullptr;
67 }
68 return &chunk_storage_;
69 }
70
71 void DeallocateChunkClass(void* chunk) final {
72 PW_ASSERT(chunk == chunk_storage_.data());
73 // Mark the `Chunk` as not in use and zero-out the region and chunk storage.
74 std::memset(chunk_storage_.data(), 0, chunk_storage_.size());
75 std::memset(region_.data(), 0, region_.size());
76 chunk_in_use_ = false;
77 }
78
79 private:
80 ByteSpan region_;
81 std::atomic<bool> chunk_in_use_ = false;
82 alignas(Chunk) std::array<std::byte, sizeof(Chunk)> chunk_storage_;
83};
84
85} // namespace pw::multibuf
Definition: chunk.h:48
Definition: chunk.h:272
Definition: single_chunk_region_tracker.h:32
void DeallocateChunkClass(void *chunk) final
Deallocates a pointer returned by AllocateChunkClass.
Definition: single_chunk_region_tracker.h:71
ByteSpan Region() const final
Definition: single_chunk_region_tracker.h:61
SingleChunkRegionTracker(ByteSpan region)
Definition: single_chunk_region_tracker.h:36
void Destroy() final
Definition: single_chunk_region_tracker.h:56
void * AllocateChunkClass() final
Definition: single_chunk_region_tracker.h:63
std::optional< OwnedChunk > GetChunk(size_t size)
Definition: single_chunk_region_tracker.h:45