WPILibC++ 2025.1.1
Loading...
Searching...
No Matches
memory_stack.hpp
Go to the documentation of this file.
1// Copyright (C) 2015-2023 Jonathan Müller and foonathan/memory contributors
2// SPDX-License-Identifier: Zlib
3
4#ifndef WPI_MEMORY_DETAIL_MEMORY_STACK_HPP_INCLUDED
5#define WPI_MEMORY_DETAIL_MEMORY_STACK_HPP_INCLUDED
6
7#include <cstddef>
8
9#include "../config.hpp"
10#include "align.hpp"
11#include "debug_helpers.hpp"
12#include "../debugging.hpp"
13
14namespace wpi
15{
16 namespace memory
17 {
18 namespace detail
19 {
20 // simple memory stack implementation that does not support growing
22 {
23 public:
24 fixed_memory_stack() noexcept : fixed_memory_stack(nullptr) {}
25
26 // gives it the current pointer, the end pointer must be maintained seperataly
27 explicit fixed_memory_stack(void* memory) noexcept
28 : cur_(static_cast<char*>(memory))
29 {
30 }
31
32 fixed_memory_stack(fixed_memory_stack&& other) noexcept : cur_(other.cur_)
33 {
34 other.cur_ = nullptr;
35 }
36
37 ~fixed_memory_stack() noexcept = default;
38
39 fixed_memory_stack& operator=(fixed_memory_stack&& other) noexcept
40 {
41 cur_ = other.cur_;
42 other.cur_ = nullptr;
43 return *this;
44 }
45
46 // bumps the top pointer without filling it
47 void bump(std::size_t offset) noexcept
48 {
49 cur_ += offset;
50 }
51
52 // bumps the top pointer by offset and fills
53 void bump(std::size_t offset, debug_magic m) noexcept
54 {
55 detail::debug_fill(cur_, offset, m);
56 bump(offset);
57 }
58
59 // same as bump(offset, m) but returns old value
60 void* bump_return(std::size_t offset,
62 {
63 auto memory = cur_;
64 detail::debug_fill(memory, offset, m);
65 cur_ += offset;
66 return memory;
67 }
68
69 // allocates memory by advancing the stack, returns nullptr if insufficient
70 // debug: mark memory as new_memory, put fence in front and back
71 void* allocate(const char* end, std::size_t size, std::size_t alignment,
72 std::size_t fence_size = debug_fence_size) noexcept
73 {
74 if (cur_ == nullptr)
75 return nullptr;
76
77 auto remaining = std::size_t(end - cur_);
78 auto offset = align_offset(cur_ + fence_size, alignment);
79 if (fence_size + offset + size + fence_size > remaining)
80 return nullptr;
81
82 return allocate_unchecked(size, offset, fence_size);
83 }
84
85 // same as allocate() but does not check the size
86 // note: pass it the align OFFSET, not the alignment
87 void* allocate_unchecked(std::size_t size, std::size_t align_offset,
88 std::size_t fence_size = debug_fence_size) noexcept
89 {
92 auto mem = bump_return(size);
94 return mem;
95 }
96
97 // unwindws the stack to a certain older position
98 // debug: marks memory from new top to old top as freed
99 // doesn't check for invalid pointer
100 void unwind(char* top) noexcept
101 {
102 debug_fill(top, std::size_t(cur_ - top), debug_magic::freed_memory);
103 cur_ = top;
104 }
105
106 // returns the current top
107 char* top() const noexcept
108 {
109 return cur_;
110 }
111
112 private:
113 char* cur_;
114 };
115 } // namespace detail
116 } // namespace memory
117} // namespace wpi
118
119#endif // WPI_MEMORY_DETAIL_MEMORY_STACK_HPP_INCLUDED
Definition memory_stack.hpp:22
fixed_memory_stack(fixed_memory_stack &&other) noexcept
Definition memory_stack.hpp:32
void unwind(char *top) noexcept
Definition memory_stack.hpp:100
void * allocate_unchecked(std::size_t size, std::size_t align_offset, std::size_t fence_size=debug_fence_size) noexcept
Definition memory_stack.hpp:87
fixed_memory_stack(void *memory) noexcept
Definition memory_stack.hpp:27
void bump(std::size_t offset) noexcept
Definition memory_stack.hpp:47
void bump(std::size_t offset, debug_magic m) noexcept
Definition memory_stack.hpp:53
void * allocate(const char *end, std::size_t size, std::size_t alignment, std::size_t fence_size=debug_fence_size) noexcept
Definition memory_stack.hpp:71
void * bump_return(std::size_t offset, debug_magic m=debug_magic::new_memory) noexcept
Definition memory_stack.hpp:60
char * top() const noexcept
Definition memory_stack.hpp:107
fixed_memory_stack() noexcept
Definition memory_stack.hpp:24
Configuration macros.
debug_magic
The magic values that are used for debug filling.
Definition debugging.hpp:23
@ freed_memory
Marks freed memory - "dead memory".
@ alignment_memory
Marks buffer memory used to ensure proper alignment.
@ fence_memory
Marks buffer memory used to protect against overflow - "fence memory".
@ new_memory
Marks allocated, but not yet used memory - "clean memory".
Debugging facilities.
detail namespace with internal helper functions
Definition input_adapters.h:32
std::size_t align_offset(std::uintptr_t address, std::size_t alignment) noexcept
Definition align.hpp:26
void debug_fill(void *, std::size_t, debug_magic) noexcept
Definition debug_helpers.hpp:45
constexpr std::size_t debug_fence_size
Definition debug_helpers.hpp:22
Memory namespace.
Definition heap_allocator.hpp:20
Foonathan namespace.
Definition ntcore_cpp.h:26