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/mem/size_class.hpp>
18 : : #include <hpactor/mem/alloc_header.hpp>
19 : : #include <hpactor/mem/freelist.hpp>
20 : : #include <hpactor/mem/segment_provider.hpp>
21 : :
22 : : #include <atomic>
23 : : #include <cstddef>
24 : : #include <cstdint>
25 : : #include <vector>
26 : :
27 : : namespace hpactor::mem {
28 : :
29 : : // Per-size-class slab cache. Manages one or more slabs of the same size class.
30 : : // Uses bump allocation for virgin memory + lock-free freelist for recycled blocks.
31 : : class SlabCache {
32 : : public:
33 : : struct Stats {
34 : : std::atomic<uint64_t> alloc_count{0};
35 : : std::atomic<uint64_t> free_count{0};
36 : : std::atomic<uint64_t> slab_acquire_count{0};
37 : : };
38 : :
39 : 229 : explicit SlabCache(SizeClass sc) : size_class_(sc) {}
40 : :
41 : : ~SlabCache();
42 : :
43 : : SlabCache(const SlabCache&) = delete;
44 : : SlabCache& operator=(const SlabCache&) = delete;
45 : : SlabCache(SlabCache&&) = delete;
46 : : SlabCache& operator=(SlabCache&&) = delete;
47 : :
48 : : // Allocate a block from this cache. Returns pointer to user data.
49 : : void* allocate(ActorId owner) noexcept;
50 : :
51 : : // Free a block back to this cache.
52 : : void deallocate(void* user_ptr) noexcept;
53 : :
54 : 4 : SizeClass size_class() const noexcept { return size_class_; }
55 : 22 : uint32_t live_count() const noexcept { return live_count_.load(); }
56 : 2 : const Stats& stats() const noexcept { return stats_; }
57 : :
58 : : private:
59 : : void refill();
60 : :
61 : : SizeClass size_class_;
62 : : uint8_t current_generation_{0};
63 : :
64 : : std::byte* current_slab_{nullptr};
65 : : size_t slab_size_{0};
66 : : size_t bump_offset_{0};
67 : :
68 : : FreeList<AllocHeader> freelist_;
69 : : std::atomic<uint32_t> live_count_{0};
70 : : Stats stats_;
71 : :
72 : : std::vector<std::byte*> slabs_;
73 : : };
74 : :
75 : : } // namespace hpactor::mem
|