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 : : #include <hpactor/sched/a2ws.hpp>
16 : :
17 : : namespace hpactor::sched {
18 : :
19 : 107 : A2WS::A2WS(uint32_t num_workers, uint32_t pool_size)
20 : 214 : : num_workers_(num_workers), pool_size_(pool_size), workers_(num_workers),
21 : 214 : victim_hints_(num_workers) {
22 : : // Initialize victim hints to point to self + 1 (start scanning from next
23 : : // worker)
24 : 215 : for (uint32_t i = 0; i < num_workers; ++i) {
25 : 108 : victim_hints_[i].store((i + 1) % num_workers, std::memory_order_relaxed);
26 : : }
27 : 107 : }
28 : :
29 : 63033 : uint32_t A2WS::get_victim(uint32_t thief_index) {
30 : : // Simple round-robin with hint
31 : 63033 : uint32_t hint = victim_hints_[thief_index].load(std::memory_order_relaxed);
32 : 63033 : return hint;
33 : : }
34 : :
35 : 63020 : void A2WS::record_attempt(uint32_t thief, uint32_t victim, bool success) {
36 : 63020 : workers_[thief].steal_attempts.fetch_add(1, std::memory_order_relaxed);
37 : :
38 : 63020 : if (success) {
39 : 1 : workers_[thief].steal_successes.fetch_add(1, std::memory_order_relaxed);
40 : : }
41 : :
42 : : // Update victim hint based on result
43 : : // If steal failed, advance to next potential victim
44 : 63020 : uint32_t current_hint = victim_hints_[thief].load(std::memory_order_relaxed);
45 : 63020 : uint32_t next_hint = (victim + 1) % num_workers_;
46 : :
47 : 63020 : if (!success) {
48 : : // Failed steal - try next victim
49 : 63019 : victim_hints_[thief].store(next_hint, std::memory_order_relaxed);
50 : : } else {
51 : : // Success - stick with current victim for now
52 : : // Could also use adaptive logic to prefer victims with history of
53 : : // success
54 : : }
55 : :
56 : : (void)thief; // Currently unused in victim selection
57 : : (void)current_hint; // Currently unused
58 : 63020 : }
59 : :
60 : 16 : void A2WS::record_steal(uint32_t thief, uint32_t victim) {
61 : 16 : if (same_pool(thief, victim)) {
62 : 15 : workers_[thief].local_steals.fetch_add(1, std::memory_order_relaxed);
63 : : } else {
64 : 1 : workers_[thief].remote_steals.fetch_add(1, std::memory_order_relaxed);
65 : : }
66 : 16 : }
67 : :
68 : 4 : void A2WS::get_victim_pool(uint32_t worker, uint32_t& start, uint32_t& end) const {
69 : 4 : uint32_t pool_id = worker / pool_size_;
70 : 4 : start = pool_id * pool_size_;
71 : 4 : end = std::min(start + pool_size_, num_workers_);
72 : 4 : }
73 : :
74 : 21 : bool A2WS::same_pool(uint32_t a, uint32_t b) const {
75 : 21 : return (a / pool_size_) == (b / pool_size_);
76 : : }
77 : :
78 : : } // namespace hpactor::sched
|