Skip to content

Commit ff431c3

Browse files
committed
Track remote inflight.
snmalloc::RemoteDeallocCache::remote_inflight tracks the amount of bytes that are inbetween threads.
1 parent af80ccc commit ff431c3

File tree

4 files changed

+33
-22
lines changed

4 files changed

+33
-22
lines changed

src/snmalloc/mem/corealloc.h

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -478,14 +478,18 @@ namespace snmalloc
478478
SNMALLOC_FAST_PATH_LAMBDA {
479479
return capptr_domesticate<Config>(local_state, p);
480480
};
481-
auto cb = [this,
482-
&need_post](freelist::HeadPtr msg) SNMALLOC_FAST_PATH_LAMBDA {
481+
482+
size_t received_bytes = 0;
483+
484+
auto cb = [this, &need_post, &received_bytes](
485+
freelist::HeadPtr msg) SNMALLOC_FAST_PATH_LAMBDA {
483486
#ifdef SNMALLOC_TRACING
484487
message<1024>("Handling remote");
485488
#endif
486489

487490
auto& entry =
488491
Config::Backend::template get_metaentry(snmalloc::address_cast(msg));
492+
received_bytes += sizeclass_full_to_size(entry.get_sizeclass());
489493

490494
handle_dealloc_remote(entry, msg.as_void(), need_post);
491495

@@ -514,6 +518,9 @@ namespace snmalloc
514518
post();
515519
}
516520

521+
// Push size to global statistics
522+
RemoteDeallocCache::remote_inflight -= received_bytes;
523+
517524
return action(args...);
518525
}
519526

@@ -542,10 +549,7 @@ namespace snmalloc
542549
}
543550
else
544551
{
545-
if (
546-
!need_post &&
547-
!attached_cache->remote_dealloc_cache.reserve_space(entry))
548-
need_post = true;
552+
need_post = attached_cache->remote_dealloc_cache.reserve_space(entry);
549553
attached_cache->remote_dealloc_cache
550554
.template dealloc<sizeof(CoreAllocator)>(
551555
entry.get_remote()->trunc_id(), p.as_void());
@@ -834,17 +838,19 @@ namespace snmalloc
834838
{
835839
auto p_wild = message_queue().destroy();
836840
auto p_tame = domesticate(p_wild);
837-
841+
size_t received_bytes = 0;
838842
while (p_tame != nullptr)
839843
{
840844
bool need_post = true; // Always going to post, so ignore.
841845
auto n_tame =
842846
p_tame->atomic_read_next(RemoteAllocator::key_global, domesticate);
843847
const PagemapEntry& entry =
844848
Config::Backend::get_metaentry(snmalloc::address_cast(p_tame));
849+
received_bytes += sizeclass_full_to_size(entry.get_sizeclass());
845850
handle_dealloc_remote(entry, p_tame.as_void(), need_post);
846851
p_tame = n_tame;
847852
}
853+
RemoteDeallocCache::remote_inflight -= received_bytes;
848854
}
849855
else
850856
{

src/snmalloc/mem/globalalloc.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,9 @@ namespace snmalloc
8787
}
8888
}
8989

90+
if (result == nullptr && RemoteDeallocCache::remote_inflight.load() != 0)
91+
error("ERROR: RemoteDeallocCache::remote_inflight != 0");
92+
9093
if (result != nullptr)
9194
{
9295
*result = okay;

src/snmalloc/mem/localalloc.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -418,7 +418,7 @@ namespace snmalloc
418418
message<1024>("flush(): core_alloc={}", core_alloc);
419419
#endif
420420
local_cache.remote_allocator = &Config::unused_remote;
421-
local_cache.remote_dealloc_cache.capacity = 0;
421+
local_cache.remote_dealloc_cache.cache_bytes = REMOTE_CACHE;
422422
}
423423
}
424424

src/snmalloc/mem/remotecache.h

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,17 @@ namespace snmalloc
1919
{
2020
std::array<freelist::Builder<false>, REMOTE_SLOTS> list;
2121

22+
static inline std::atomic<size_t> remote_inflight{0};
23+
2224
/**
23-
* The total amount of memory we are waiting for before we will dispatch
24-
* to other allocators. Zero can mean we have not initialised the allocator
25-
* yet. This is initialised to the 0 so that we always hit a slow path to
26-
* start with, when we hit the slow path and need to dispatch everything, we
27-
* can check if we are a real allocator and lazily provide a real allocator.
25+
* The total amount of bytes of memory in the cache.
26+
*
27+
* REMOTE_CACHE is used as the initial value, so that we always hit a slow
28+
* path to start with, when we hit the slow path and need to dispatch
29+
* everything, we can check if we are a real allocator and lazily provide a
30+
* real allocator.
2831
*/
29-
int64_t capacity{0};
32+
size_t cache_bytes{REMOTE_CACHE};
3033

3134
#ifndef NDEBUG
3235
bool initialised = false;
@@ -56,13 +59,10 @@ namespace snmalloc
5659
template<typename Entry>
5760
SNMALLOC_FAST_PATH bool reserve_space(const Entry& entry)
5861
{
59-
auto size =
60-
static_cast<int64_t>(sizeclass_full_to_size(entry.get_sizeclass()));
62+
auto size = sizeclass_full_to_size(entry.get_sizeclass());
6163

62-
bool result = capacity > size;
63-
if (result)
64-
capacity -= size;
65-
return result;
64+
cache_bytes += size;
65+
return cache_bytes < REMOTE_CACHE;
6666
}
6767

6868
template<size_t allocator_size>
@@ -91,6 +91,8 @@ namespace snmalloc
9191
return capptr_domesticate<Config>(local_state, p);
9292
};
9393

94+
// We are about to post cache_bytes bytes to other allocators.
95+
remote_inflight += cache_bytes;
9496
while (true)
9597
{
9698
auto my_slot = get_slot<allocator_size>(id, post_round);
@@ -152,7 +154,7 @@ namespace snmalloc
152154
}
153155

154156
// Reset capacity as we have empty everything
155-
capacity = REMOTE_CACHE;
157+
cache_bytes = 0;
156158

157159
return sent_something;
158160
}
@@ -177,7 +179,7 @@ namespace snmalloc
177179
// a null address.
178180
l.init(0, RemoteAllocator::key_global);
179181
}
180-
capacity = REMOTE_CACHE;
182+
cache_bytes = 0;
181183
}
182184
};
183185
} // namespace snmalloc

0 commit comments

Comments
 (0)