diff --git a/src/VecSim/algorithms/svs/svs_utils.h b/src/VecSim/algorithms/svs/svs_utils.h index 2bb4eaf57..8dfa23d53 100644 --- a/src/VecSim/algorithms/svs/svs_utils.h +++ b/src/VecSim/algorithms/svs/svs_utils.h @@ -462,15 +462,25 @@ class VecSimSVSThreadPoolImpl { // outside of the pool, nor per-index wrapper state. size_t getAllocationSize() const { return allocator_->getAllocationSize(); } - // Bytes allocated by the shared pool singleton. Returns 0 if the singleton has - // never been constructed (e.g., no SVS index was ever created and - // VecSim_UpdateThreadPoolSize was never called). Safe to call from any context; - // does not force singleton construction. + // Bytes allocated by the shared pool singleton. Returns 0 until the first SVS index + // attaches, for either reason: + // * the singleton was never constructed (no SVS index created and + // VecSim_UpdateThreadPoolSize never called), or + // * it was constructed to record a requested size (VecSim_UpdateThreadPoolSize at + // module init) but no SVS index has attached yet. + // This keeps process-wide vector memory reported as 0 on deployments that only use + // non-SVS indexes (or none at all). Safe to call from any context; does not force + // singleton construction. static size_t getSharedAllocationSize() { if (!isInitialized()) { return 0; } - return instance()->getAllocationSize(); + auto pool = instance(); + std::lock_guard lock{pool->pool_mutex_}; + if (!pool->has_attached_index_) { + return 0; + } + return pool->getAllocationSize(); } // Resize the shared pool. in all cases the requested size is stored in diff --git a/tests/unit/test_svs.cpp b/tests/unit/test_svs.cpp index 5256d2bdb..415add1fc 100644 --- a/tests/unit/test_svs.cpp +++ b/tests/unit/test_svs.cpp @@ -3445,12 +3445,13 @@ TYPED_TEST(SVSTest, sharedMemoryTracksThreadPoolResize) { // --------------------------------------------------------------------------- TEST(SVSTest, ThreadPoolLazyInit) { // Reset the shared singleton to a clean state — earlier tests may have - // attached indexes and resized the pool. After reset, getAllocationSize() - // still reports sizeof(VecSimAllocator) (the allocator's self-accounting, - // see VecSimAllocator() ctor); assertions below compare against this - // baseline rather than absolute zero. + // attached indexes and resized the pool. resetForTest() clears + // has_attached_index_, so VecSim_GetSharedMemory() reports 0 even though the + // singleton object (and its self-accounting allocator) still exist: shared + // memory is only attributed once an SVS index attaches. VecSimSVSThreadPoolImpl::instance()->resetForTest(); const size_t baseline_mem = VecSim_GetSharedMemory(); + EXPECT_EQ(baseline_mem, 0u) << "shared memory must be 0 before any SVS index attaches"; // Recording a non-trivial requested size before any SVS index exists must // not allocate any worker slots.