Skip to content

Commit 72844a5

Browse files
committed
Add memory::MemoryAllocator class with weak Allocate/Free.
Use final and override for classes.
1 parent 0b2eed0 commit 72844a5

39 files changed

Lines changed: 495 additions & 518 deletions

build/test/eclipse/blockpool/.project

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,11 @@
135135
<type>1</type>
136136
<locationURI>PARENT-4-PROJECT_LOC/stk/include/memory/stk_memory.h</locationURI>
137137
</link>
138+
<link>
139+
<name>deps/stk/include/memory/stk_memory_allocator.h</name>
140+
<type>1</type>
141+
<locationURI>PARENT-4-PROJECT_LOC/stk/include/memory/stk_memory_allocator.h</locationURI>
142+
</link>
138143
<link>
139144
<name>deps/stk/include/memory/stk_memory_blockpool.h</name>
140145
<type>1</type>

build/test/eclipse/timerhost-stm32f407g-disc1/.project

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2010,11 +2010,6 @@
20102010
<type>1</type>
20112011
<locationURI>PARENT-4-PROJECT_LOC/stk/include/arch/x86/win32/stk_arch_x86-win32.h</locationURI>
20122012
</link>
2013-
<link>
2014-
<name>deps/stk/src/arch/arm/cortex-m/stk_arch_arm-cortex-m (5).cpp</name>
2015-
<type>1</type>
2016-
<locationURI>PARENT-4-PROJECT_LOC/stk/src/arch/arm/cortex-m/stk_arch_arm-cortex-m%20(5).cpp</locationURI>
2017-
</link>
20182013
<link>
20192014
<name>deps/stk/src/arch/arm/cortex-m/stk_arch_arm-cortex-m.cpp</name>
20202015
<type>1</type>

interop/c/include/stk_c.h

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -371,12 +371,6 @@ void stk_task_set_weight(stk_task_t *task, uint32_t weight);
371371
*/
372372
void stk_task_set_priority(stk_task_t *task, uint8_t priority);
373373

374-
/*! \brief Assign application-defined task ID (for tracing/debugging).
375-
\param[in] task: Task handle.
376-
\param[in] tid: Arbitrary 32-bit task identifier.
377-
*/
378-
void stk_task_set_id(stk_task_t *task, uint32_t tid);
379-
380374
/*! \brief Assign human-readable task name (for tracing/debugging).
381375
\param[in] task: Task handle.
382376
\param[in] tname: Null-terminated string (may be NULL).

interop/c/src/stk_c.cpp

Lines changed: 1 addition & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -9,21 +9,16 @@
99

1010
#include <cstddef> // for std::size_t
1111

12-
#include <stk_config.h>
1312
#include <stk.h>
1413
#include <sync/stk_sync.h>
14+
#include <memory/stk_memory.h>
1515

1616
#include "stk_c.h"
1717

1818
using namespace stk;
1919

2020
#define STK_C_TASKS_MAX (STK_C_KERNEL_MAX_TASKS)
2121

22-
#ifndef _NEW
23-
inline void *operator new(std::size_t, void *ptr) noexcept { return ptr; }
24-
inline void operator delete(void *, void *) noexcept { /* nothing for placement delete */ }
25-
#endif
26-
2722
static void FreeTask(const stk_task_t *task);
2823

2924
// Forward decl.
@@ -36,7 +31,6 @@ class TaskWrapper : public ITask
3631
EAccessMode GetAccessMode() const override { return m_mode; }
3732
void OnDeadlineMissed(uint32_t duration) override { (void)duration; }
3833
int32_t GetWeight() const override { return m_weight; }
39-
stk_tid_t GetId() const override { return m_tid; }
4034
const char *GetTraceName() const override { return m_tname; }
4135

4236
// IStackMemory
@@ -59,7 +53,6 @@ class TaskWrapper : public ITask
5953
}
6054

6155
void SetWeight(int32_t weight) { m_weight = weight; }
62-
void SetId(stk_tid_t tid) { m_tid = tid; }
6356
void SetName(const char *tname) { m_tname = tname; }
6457

6558
private:
@@ -75,7 +68,6 @@ class TaskWrapper : public ITask
7568
size_t m_stack_size;
7669
EAccessMode m_mode;
7770
int32_t m_weight;
78-
stk_tid_t m_tid;
7971
const char *m_tname;
8072
};
8173

@@ -359,13 +351,6 @@ void stk_task_set_priority(stk_task_t *task, uint8_t priority)
359351
stk_task_set_weight(task, priority);
360352
}
361353

362-
void stk_task_set_id(stk_task_t *task, uint32_t tid)
363-
{
364-
STK_ASSERT(task != nullptr);
365-
366-
task->handle.SetId(tid);
367-
}
368-
369354
void stk_task_set_name(stk_task_t *task, const char *tname)
370355
{
371356
STK_ASSERT(task != nullptr);

interop/c/src/stk_c_memory.cpp

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
*/
99

1010
#include <cstddef> // for std::size_t
11+
#include <cstdlib> // for malloc, free
1112

1213
#include <stk_config.h>
1314
#include <stk.h>
@@ -16,11 +17,6 @@
1617
#include "stk_c.h"
1718
#include "stk_c_memory.h"
1819

19-
#ifndef _NEW
20-
inline void *operator new(std::size_t, void *ptr) noexcept { return ptr; }
21-
inline void operator delete(void *, void *) noexcept { /* nothing for placement delete */ }
22-
#endif
23-
2420
using namespace stk;
2521
using namespace stk::memory;
2622

@@ -30,6 +26,16 @@ template <typename T> static constexpr size_t StkGetWordCountForType()
3026
return ((sizeof(T) + sizeof(stk::Word) - 1) / sizeof(stk::Word));
3127
}
3228

29+
// Private memory allocators.
30+
void *stk::memory::MemoryAllocator::Allocate(size_t size)
31+
{
32+
return malloc(size);
33+
}
34+
void stk::memory::MemoryAllocator::Free(void *ptr)
35+
{
36+
free(ptr);
37+
}
38+
3339
// ---------------------------------------------------------------------------
3440
// stk_blockpool_t — wraps a BlockMemoryPool instance
3541
//

interop/c/src/stk_c_sync.cpp

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,16 +12,13 @@
1212
#include <stk_config.h>
1313
#include <stk.h>
1414
#include <sync/stk_sync.h>
15+
#include <memory/stk_memory.h>
16+
1517
#include "stk_c.h"
1618

1719
using namespace stk;
1820
using namespace stk::sync;
1921

20-
#ifndef _NEW
21-
inline void *operator new(std::size_t, void *ptr) noexcept { return ptr; }
22-
inline void operator delete(void *, void *) noexcept { /* nothing for placement delete */ }
23-
#endif
24-
2522
// ---------------------------------------------------------------------------
2623
// C-interface
2724
// ---------------------------------------------------------------------------

interop/c/src/stk_c_time.cpp

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,9 @@
99

1010
#include <cstddef> // for std::size_t
1111

12-
#include <stk_config.h>
1312
#include <stk.h>
13+
#include <memory/stk_memory.h>
14+
1415
#include "stk_c.h"
1516
#include "stk_c_time.h"
1617

@@ -25,11 +26,6 @@
2526
#include <time/stk_time_timer.h>
2627
#include <time/stk_time_util.h>
2728

28-
#ifndef _NEW
29-
inline void *operator new(std::size_t, void *ptr) noexcept { return ptr; }
30-
inline void operator delete(void *, void *) noexcept { /* nothing for placement delete */ }
31-
#endif
32-
3329
using namespace stk;
3430
using namespace stk::time;
3531

interop/cmsis/rtos2/src/cmsis_os2_stk.cpp

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,16 @@ template <typename T> static constexpr size_t StkGetWordCountForType()
9090
return ((sizeof(T) + sizeof(stk::Word) - 1) / sizeof(stk::Word));
9191
}
9292

93+
// Private memory allocators.
94+
void *stk::memory::MemoryAllocator::Allocate(size_t size)
95+
{
96+
return malloc(size);
97+
}
98+
void stk::memory::MemoryAllocator::Free(void *ptr)
99+
{
100+
free(ptr);
101+
}
102+
93103
// ---------------------------------------------------------------------------
94104
// Priority mapping:
95105
// CMSIS range: osPriorityIdle(1) .. osPriorityISR(56) -> 57 levels
@@ -222,7 +232,6 @@ struct StkThread : public stk::ITask
222232
stk::EAccessMode GetAccessMode() const override { return stk::ACCESS_PRIVILEGED; }
223233
void OnDeadlineMissed(uint32_t) override {}
224234
int32_t GetWeight() const override { return m_stk_priority; }
225-
stk::TId GetId() const override { return stk::hw::PtrToWord(this); }
226235
const char *GetTraceName() const override { return m_name; }
227236

228237
// ---- Members ----

stk/include/memory/stk_memory.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ namespace memory {
2222
} // namespace memory
2323
} // namespace stk
2424

25+
#include "stk_memory_allocator.h"
2526
#include "stk_memory_blockpool.h"
2627

2728
#endif /* STK_MEMORY_H_ */
Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
/*
2+
* SuperTinyKernel(TM) RTOS: Lightweight High-Performance Deterministic C++ RTOS for Embedded Systems.
3+
*
4+
* Source: https://github.com/SuperTinyKernel-RTOS
5+
*
6+
* Copyright (c) 2022-2026 Neutron Code Limited <stk@neutroncode.com>. All Rights Reserved.
7+
* License: MIT License, see LICENSE for a full text.
8+
*/
9+
10+
#ifndef STK_MEMORY_ALLOCATOR_H_
11+
#define STK_MEMORY_ALLOCATOR_H_
12+
13+
#include "stk_defs.h"
14+
15+
/*! \def STK_MEMORY_PLACEMENTNEW
16+
\brief When defined as 1, placement new C++ operator is enabled for memory::MemoryAllocator.
17+
\see memory::MemoryAllocator::AllocateOneT, memory::MemoryAllocator::AllocateArrayT
18+
*/
19+
#ifndef STK_MEMORY_PLACEMENT_NEW
20+
#define STK_MEMORY_PLACEMENT_NEW 1
21+
#endif
22+
23+
#if STK_MEMORY_PLACEMENT_NEW
24+
#include <type_traits>
25+
#include <new>
26+
#endif
27+
28+
/*! \file stk_memory_allocator.h
29+
\brief Weak declaration of memory allocator: stk::memory::MemoryAllocator.
30+
*/
31+
32+
namespace stk {
33+
namespace memory {
34+
35+
/*! \class MemoryAllocator
36+
\brief Memory allocator for allocating dynamic memory.
37+
\note STK does not use dynamic memory allocation but some auxiliary classes may provide such
38+
functionality for convenience. In this case you must provide your own implementation
39+
of MemoryAllocator::Allocate() and MemoryAllocator::Free(). By default STK does not
40+
provide any implementation, therefore you will get a linker error if these two functions
41+
are left unimplemented.
42+
43+
Example of your trivial implementation:
44+
\code
45+
void *MemoryAllocator::Allocate(size_t size)
46+
{
47+
return malloc(size);
48+
}
49+
void MemoryAllocator::Free(void *ptr)
50+
{
51+
free(ptr);
52+
}
53+
\endcode
54+
*/
55+
struct MemoryAllocator
56+
{
57+
/*! \brief Allocate the memory chunk.
58+
\param[in] size: Size of the memory chunk.
59+
\return Pointer to the allocated memory chunk, nullptr if allocator failed to allocate it.
60+
*/
61+
static void *Allocate(size_t size) __stk_weak;
62+
63+
/*! \brief Free the memory chunk.
64+
\param[in] ptr: Pointer to the memory chunk. nullptr is allowed and results in noop.
65+
*/
66+
static void Free(void *ptr) __stk_weak;
67+
68+
#if STK_MEMORY_PLACEMENT_NEW
69+
70+
/*! \brief Allocate a single element and construct it in-place.
71+
\param[in] args: Constructor arguments forwarded to TElement.
72+
\return Pointer to the constructed element, nullptr if allocation failed.
73+
\note Pair with FreeOneT<TElement>() to properly invoke the destructor.
74+
*/
75+
template <typename TElement, typename... TArgs>
76+
static inline TElement *AllocateOneT(TArgs &&...args)
77+
{
78+
STK_ASSERT(Allocate != nullptr);
79+
80+
TElement *ptr = reinterpret_cast<TElement *>(Allocate(sizeof(TElement)));
81+
if (ptr != nullptr)
82+
{
83+
if (!std::is_trivially_constructible<TElement, TArgs...>())
84+
new (ptr) TElement(static_cast<TArgs &&>(args)...);
85+
}
86+
87+
return ptr;
88+
}
89+
90+
/*! \brief Allocate an array of elements and default/copy-construct each one.
91+
\param[in] count: Number of elements to allocate.
92+
\param[in] args: Constructor arguments forwarded to every element.
93+
\return Pointer to the first element, nullptr if allocation failed or count is 0.
94+
\note Pair with FreeArrayT<TElement>() passing the same count to properly invoke destructors.
95+
*/
96+
template <typename TElement, typename... TArgs>
97+
static inline TElement *AllocateArrayT(size_t count, TArgs &&...args)
98+
{
99+
if (count == 0)
100+
return nullptr;
101+
102+
STK_ASSERT(Allocate != nullptr);
103+
104+
TElement *ptr = reinterpret_cast<TElement *>(Allocate(count * sizeof(TElement)));
105+
if (ptr != nullptr)
106+
{
107+
if (!std::is_trivially_constructible<TElement, TArgs...>())
108+
{
109+
for (size_t i = 0; i < count; ++i)
110+
new (&ptr[i]) TElement(static_cast<TArgs &&>(args)...);
111+
}
112+
}
113+
114+
return ptr;
115+
}
116+
117+
/*! \brief Destroy and free a single element allocated via AllocateOne().
118+
\param[in] ptr: Pointer to the element. nullptr is allowed and results in noop.
119+
*/
120+
template <typename TElement>
121+
static inline void FreeOneT(TElement *ptr)
122+
{
123+
STK_ASSERT(Free != nullptr);
124+
125+
if (ptr != nullptr)
126+
{
127+
if (!std::is_trivially_destructible<TElement>())
128+
ptr->~TElement();
129+
130+
Free(ptr);
131+
}
132+
}
133+
134+
/*! \brief Destroy and free an array allocated via AllocateT().
135+
\param[in] ptr: Pointer to the first element. nullptr is allowed and results in noop.
136+
\param[in] count: Number of elements (must match the count passed to AllocateT()).
137+
*/
138+
template <typename TElement>
139+
static inline void FreeArrayT(TElement *ptr, size_t count)
140+
{
141+
STK_ASSERT(Free != nullptr);
142+
143+
if (ptr != nullptr)
144+
{
145+
if (!std::is_trivially_destructible<TElement>())
146+
{
147+
// destroy in reverse order (mirrors stack unwinding)
148+
for (size_t i = count; i > 0; --i)
149+
ptr[i - 1].~TElement();
150+
}
151+
152+
Free(ptr);
153+
}
154+
}
155+
156+
#endif // STK_MEMORY_PLACEMENT_NEW
157+
};
158+
159+
} // namespace memory
160+
} // namespace stk
161+
162+
#endif /* STK_MEMORY_ALLOCATOR_H_ */

0 commit comments

Comments
 (0)