fix(fxrt): chan out ring overflow trong bridge (backpressure, het pointer collision)
This commit is contained in:
@@ -205,7 +205,7 @@ int run_realtime_fx_loop(const std::string& jobPath, const std::string& shmName,
|
||||
uint64_t processed = 0;
|
||||
uint64_t lastGen = 0; // chain generation đã báo latency
|
||||
// ---- FXRT_PERF instrumentation (tạm, đo crackle) ----
|
||||
uint64_t perfIter = 0, perfProc = 0, perfIdle = 0;
|
||||
uint64_t perfIter = 0, perfProc = 0, perfIdle = 0, perfOutFull = 0;
|
||||
double perfProcSum = 0.0, perfProcMax = 0.0, perfProcMin = 1e9;
|
||||
double perfLoopSum = 0.0, perfLoopMax = 0.0;
|
||||
uint32_t perfTakeSum = 0;
|
||||
@@ -264,6 +264,21 @@ int run_realtime_fx_loop(const std::string& jobPath, const std::string& shmName,
|
||||
std::cerr << "[RealtimeFxLoop] latency reported: " << lats.size()
|
||||
<< " slot(s)" << std::endl;
|
||||
}
|
||||
// OUT-ring backpressure (fix crackle "wobble" — pointer collision):
|
||||
// kiểm tra chỗ trống TRƯỚC khi consume input. Nếu out ring đầy (engine
|
||||
// pump chậm/stall: WS send bị block khi main-thread browser busy) mà
|
||||
// bridge vẫn ghi → ghi đè slot engine đang đọc = read/write pointer
|
||||
// giẫm nhau → mẫu torn → méo "wobble" kéo dài tới khi reset. Khi đầy:
|
||||
// KHÔNG xử lí batch này (nhường engine drain), input backlog dồn về
|
||||
// engine → engine drop batch cũ nhất (drop sạch, worklet hold+fade che
|
||||
// gap) — không bao giờ ghi đè out slot chưa đọc.
|
||||
const uint32_t outFree = ipc->h.outSlots - (ipc->h.outWrite - ipc->h.outRead);
|
||||
if (outFree < std::min<uint32_t>(ipc->h.inWrite - ipc->h.inRead, FXRT_IN_SLOTS)) {
|
||||
++perfOutFull;
|
||||
std::this_thread::sleep_until(std::chrono::steady_clock::now() +
|
||||
std::chrono::milliseconds(1));
|
||||
continue;
|
||||
}
|
||||
uint32_t avail = ipc->h.inWrite - ipc->h.inRead;
|
||||
if (avail == 0) {
|
||||
++perfIdle;
|
||||
@@ -315,12 +330,13 @@ int run_realtime_fx_loop(const std::string& jobPath, const std::string& shmName,
|
||||
<< " loopAvg=" << (perfIter ? perfLoopSum / perfIter : 0.0) << "ms"
|
||||
<< " loopMax=" << perfLoopMax << "ms"
|
||||
<< " idle=" << perfIdle
|
||||
<< " outFull=" << perfOutFull
|
||||
<< " takeAvg=" << (perfProc ? (double)perfTakeSum / perfProc : 0.0)
|
||||
<< " procBlocks=" << processed
|
||||
<< " rate=" << (runSec > 0 ? processed / runSec : 0.0) << "blk/s"
|
||||
<< " outDepth=" << (ipc->h.outWrite - ipc->h.outRead)
|
||||
<< std::endl;
|
||||
perfProc = 0; perfProcSum = 0.0; perfTakeSum = 0; perfIdle = 0;
|
||||
perfProc = 0; perfProcSum = 0.0; perfTakeSum = 0; perfIdle = 0; perfOutFull = 0;
|
||||
}
|
||||
}
|
||||
ipc->h.state = FXRT_STATE_STARTING; // đã dừng
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user