mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-11-07 01:53:24 +09:00
[MG_Remote, MG_Test] (Disaggregated): P5f fs - keep applier diagnostics within each role
This commit is contained in:
@@ -292,7 +292,7 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
}
|
||||
|
||||
// P4a (D-F3, [correction]). THE RAW-DEPTH-FETCH SUBSTITUTION STAYS ON THE SERVER, and it
|
||||
// keeps constructing a frontend SamplerObject inside MG_Backend to do it. That is
|
||||
// keeps constructing a frontend SamplerObject inside MG_Backend on MONOLITH to do it. That is
|
||||
// deliberate and it is not this phase's to change: ARCHITECTURE.md assigns the two
|
||||
// backend-specific post-processings of the resolved sampler set - this one and Magma's
|
||||
// feedback-loop detection - to the server, acting ON the already-resolved set, and the
|
||||
@@ -305,6 +305,8 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
// MG_State-type usage anywhere under MG_Backend/DirectGLES, and its owner is P3b/P4b - so
|
||||
// the include-graph gate at P13 meets a known item rather than a surprise. The purity
|
||||
// gates are unaffected either way: they grep MG_Backend for the pull arm's live-GLContext
|
||||
// P5f fs's transport arm below uses only a native sampler with fixed values. The legacy
|
||||
// pair is not constructed or consulted by the server. The purity gate's live-context
|
||||
// pointer token (G13 - deliberately not spelled here, because that grep is a BARE TOKEN
|
||||
// grep and a comment naming it is a hit) and for an MG_State type inside
|
||||
// MGPipeResourceOps, and this is neither.
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include "WireTables.h"
|
||||
|
||||
#include <MGGitHash.h>
|
||||
#include <MG_Backend/MGPipe/PipeInputs.h>
|
||||
#include <MG_Impl/GLImpl/Framebuffer/GL_Framebuffer.h>
|
||||
#include <MG_Impl/Pipe/ResourceTracker.h>
|
||||
#include <MG_Pipe/MGPipeCallbacks.h>
|
||||
@@ -116,6 +117,10 @@ namespace MobileGL::MG_Remote::Client {
|
||||
// thread inside the applier" - see ClientSession::InBarrierWait's note.
|
||||
thread_local Bool g_inBarrierWait = false;
|
||||
std::atomic<Bool> g_applyThreadInsideApplier{false};
|
||||
// A split client cannot observe a server's process-local diagnostic. The
|
||||
// role-local value remains useful to the applier itself; ordering between
|
||||
// roles is carried by the ring watermarks, not by this instrumentation.
|
||||
thread_local Bool g_roleInsideApplier = false;
|
||||
|
||||
struct BarrierWaitScope {
|
||||
BarrierWaitScope() { g_inBarrierWait = true; }
|
||||
@@ -1280,10 +1285,11 @@ namespace MobileGL::MG_Remote::Client {
|
||||
// THE CLIENT'S FLAG IS THREAD-LOCAL AND THE SERVER'S IS NOT, and the asymmetry is the
|
||||
// point: "am I inside a barrier wait" is a question about the calling thread, while "is the
|
||||
// apply thread inside the applier" is a question the GL thread asks about a DIFFERENT
|
||||
// thread - so the second has to be a shared atomic and the first must not be, or a second
|
||||
// GL thread would see the first one's wait as its own.
|
||||
// thread in the shared-block control. Under role split each thread instead observes only
|
||||
// its own diagnostic; the client writes a different block and waits through appliedSeq.
|
||||
Bool ClientSession::InBarrierWait() { return g_inBarrierWait; }
|
||||
Bool ClientSession::ApplyThreadIsInsideApplier() {
|
||||
if (MG_Pipe::MGPipeRoleSplitActive()) return g_roleInsideApplier;
|
||||
return g_applyThreadInsideApplier.load(std::memory_order_acquire);
|
||||
}
|
||||
|
||||
@@ -1379,10 +1385,14 @@ namespace MobileGL::MG_Remote::Client {
|
||||
std::abort();
|
||||
}
|
||||
void ClientSession::NoteApplyThreadEnteredApplier() {
|
||||
g_applyThreadInsideApplier.store(true, std::memory_order_release);
|
||||
g_roleInsideApplier = true;
|
||||
if (!MG_Pipe::MGPipeRoleSplitActive())
|
||||
g_applyThreadInsideApplier.store(true, std::memory_order_release);
|
||||
}
|
||||
void ClientSession::NoteApplyThreadLeftApplier() {
|
||||
g_applyThreadInsideApplier.store(false, std::memory_order_release);
|
||||
g_roleInsideApplier = false;
|
||||
if (!MG_Pipe::MGPipeRoleSplitActive())
|
||||
g_applyThreadInsideApplier.store(false, std::memory_order_release);
|
||||
}
|
||||
|
||||
Uint32 ClientSession::PumpControlPlane() {
|
||||
|
||||
@@ -7,6 +7,9 @@
|
||||
#include <MG_Backend/MGPipe/PipeInputs.h>
|
||||
#include <MG_Pipe/PipeApply.h>
|
||||
#include <MG_State/GLState/Core.h>
|
||||
#include <MG_Remote/Client/ClientSession.h>
|
||||
#include <thread>
|
||||
#include <atomic>
|
||||
|
||||
namespace MobileGL::MG_Backend::DirectGLES {
|
||||
SamplerImpl::BackendSamplerObject* GetRawDepthFetchSampler();
|
||||
@@ -149,3 +152,35 @@ TEST(ContextEpochTest, ServerLivenessDoesNotFollowTheClientContextOrAVerbStamp)
|
||||
GTEST_SKIP() << "server liveness exists only in the disaggregated build";
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST(ContextEpochTest, DualBlockApplierDiagnosticIsRoleLocalWhileSharedControlRemainsArmed) {
|
||||
#if MOBILEGL_BUILD_DISAGGREGATED
|
||||
DriverScope scope;
|
||||
const Bool previous = MG_Config::Ipc.RoleSplitState;
|
||||
using Session = MG_Remote::Client::ClientSession;
|
||||
const auto observe = [&](Bool split) {
|
||||
MG_Config::Ipc.RoleSplitState = split;
|
||||
std::atomic<Bool> entered{false}, leave{false};
|
||||
Bool serverSawItself = false;
|
||||
std::thread server([&] {
|
||||
Session::NoteApplyThreadEnteredApplier();
|
||||
serverSawItself = Session::ApplyThreadIsInsideApplier();
|
||||
entered.store(true, std::memory_order_release);
|
||||
while (!leave.load(std::memory_order_acquire)) std::this_thread::yield();
|
||||
Session::NoteApplyThreadLeftApplier();
|
||||
});
|
||||
while (!entered.load(std::memory_order_acquire)) std::this_thread::yield();
|
||||
const Bool clientSawServer = Session::ApplyThreadIsInsideApplier();
|
||||
leave.store(true, std::memory_order_release);
|
||||
server.join();
|
||||
EXPECT_TRUE(serverSawItself);
|
||||
EXPECT_EQ(clientSawServer, !split);
|
||||
EXPECT_FALSE(Session::ApplyThreadIsInsideApplier());
|
||||
};
|
||||
observe(false);
|
||||
observe(true);
|
||||
MG_Config::Ipc.RoleSplitState = previous;
|
||||
#else
|
||||
GTEST_SKIP() << "role-local observer requires the disaggregated build";
|
||||
#endif
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user