Branch data Line data Source code
1 : : // Copyright 2026 HPActor Contributors
2 : : //
3 : : // Licensed under the Apache License, Version 2.0 (the "License");
4 : : // you may not use this file except in compliance with the License.
5 : : // You may obtain a copy of the License at
6 : : //
7 : : // http://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,
11 : : // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 : : // See the License for the specific language governing permissions and
13 : : // limitations under the License.
14 : :
15 : : #pragma once
16 : :
17 : : #include <hpactor/hpactor_config.hpp>
18 : : #include <hpactor/log/log_field.hpp>
19 : : #include <hpactor/log/logger.hpp>
20 : : #include <hpactor/mem/memory_region.hpp>
21 : : #include <hpactor/mem/size_class.hpp>
22 : : #include <hpactor/mem/thread_local_allocator.hpp>
23 : :
24 : : #include <cstddef>
25 : : #include <cstdlib>
26 : :
27 : : namespace hpactor::mem {
28 : :
29 : : // =========================================================================
30 : : // Compile-time configuration
31 : : // =========================================================================
32 : :
33 : : #if HPACTOR_ENABLE_MEMORY_TRACKING
34 : : inline constexpr bool kMemoryTrackingEnabled = true;
35 : : #else
36 : : inline constexpr bool kMemoryTrackingEnabled = false;
37 : : #endif
38 : :
39 : : #if HPACTOR_ENABLE_MEMORY_DEBUG
40 : : inline constexpr bool kMemoryDebugEnabled = true;
41 : : #else
42 : : inline constexpr bool kMemoryDebugEnabled = false;
43 : : #endif
44 : :
45 : : inline constexpr uint32_t kDefaultSampleRate = 128;
46 : :
47 : : // =========================================================================
48 : : // Thread-local allocator pointer
49 : : // =========================================================================
50 : :
51 : : // Set by WorkerThread during init, used by global convenience functions.
52 : : extern thread_local ThreadLocalAllocator* t_tla;
53 : :
54 : : // Current actor ID — set by the scheduler before dispatching actor work.
55 : : // Used by SlabAllocated::operator new to attribute allocations correctly.
56 : : extern thread_local ActorId t_current_actor_id;
57 : :
58 : 3 : inline void set_thread_allocator(ThreadLocalAllocator* tla) {
59 : 3 : t_tla = tla;
60 : 3 : }
61 : :
62 : : inline ThreadLocalAllocator* thread_allocator() {
63 : : return t_tla;
64 : : }
65 : :
66 : 353 : inline void set_current_actor_id(ActorId id) {
67 : 353 : t_current_actor_id = id;
68 : 353 : }
69 : :
70 : 1 : inline ActorId current_actor_id() {
71 : 1 : return t_current_actor_id;
72 : : }
73 : :
74 : : // =========================================================================
75 : : // Global convenience API
76 : : // =========================================================================
77 : :
78 : : // Allocate memory from a typed region, auto-selecting size class.
79 : 1448 : inline void* allocate(RegionType /*region*/, size_t user_bytes, ActorId owner) {
80 : 1448 : if (t_tla) {
81 : 0 : return t_tla->allocate_bytes(user_bytes, owner);
82 : : }
83 : 1448 : HPACTOR_LOG_WARNING(log::LogCategory::kMemory, ActorId{0},
84 : : static_cast<uint32_t>(log::LogEventId::kMemoryAlloc),
85 : : "allocation fallback to malloc",
86 : : log::field("size", static_cast<uint64_t>(user_bytes)));
87 : 1448 : return std::malloc(user_bytes); // NOLINT: intentional fallback
88 : : }
89 : :
90 : : // Allocate from a specific size class.
91 : : inline void* allocate_class(SizeClass sc, ActorId owner) {
92 : : if (t_tla) {
93 : : return t_tla->allocate(sc, owner);
94 : : }
95 : : HPACTOR_LOG_WARNING(
96 : : log::LogCategory::kMemory, ActorId{0},
97 : : static_cast<uint32_t>(log::LogEventId::kMemoryAlloc),
98 : : "allocation fallback to malloc",
99 : : log::field("size", static_cast<uint64_t>(size_for_class(sc))));
100 : : return std::malloc(size_for_class(sc)); // NOLINT: intentional fallback
101 : : }
102 : :
103 : : // Deallocate memory previously allocated via allocate() or allocate_class().
104 : 1155 : inline void deallocate(void* user_ptr) {
105 : 1155 : if (!user_ptr)
106 : 0 : return;
107 : 1155 : if (t_tla) {
108 : 0 : t_tla->deallocate(user_ptr);
109 : 0 : return;
110 : : }
111 : 1155 : std::free(user_ptr); // NOLINT: intentional fallback
112 : : }
113 : :
114 : : } // namespace hpactor::mem
|