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 processed = 0;
|
||||||
uint64_t lastGen = 0; // chain generation đã báo latency
|
uint64_t lastGen = 0; // chain generation đã báo latency
|
||||||
// ---- FXRT_PERF instrumentation (tạm, đo crackle) ----
|
// ---- 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 perfProcSum = 0.0, perfProcMax = 0.0, perfProcMin = 1e9;
|
||||||
double perfLoopSum = 0.0, perfLoopMax = 0.0;
|
double perfLoopSum = 0.0, perfLoopMax = 0.0;
|
||||||
uint32_t perfTakeSum = 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()
|
std::cerr << "[RealtimeFxLoop] latency reported: " << lats.size()
|
||||||
<< " slot(s)" << std::endl;
|
<< " 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;
|
uint32_t avail = ipc->h.inWrite - ipc->h.inRead;
|
||||||
if (avail == 0) {
|
if (avail == 0) {
|
||||||
++perfIdle;
|
++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"
|
<< " loopAvg=" << (perfIter ? perfLoopSum / perfIter : 0.0) << "ms"
|
||||||
<< " loopMax=" << perfLoopMax << "ms"
|
<< " loopMax=" << perfLoopMax << "ms"
|
||||||
<< " idle=" << perfIdle
|
<< " idle=" << perfIdle
|
||||||
|
<< " outFull=" << perfOutFull
|
||||||
<< " takeAvg=" << (perfProc ? (double)perfTakeSum / perfProc : 0.0)
|
<< " takeAvg=" << (perfProc ? (double)perfTakeSum / perfProc : 0.0)
|
||||||
<< " procBlocks=" << processed
|
<< " procBlocks=" << processed
|
||||||
<< " rate=" << (runSec > 0 ? processed / runSec : 0.0) << "blk/s"
|
<< " rate=" << (runSec > 0 ? processed / runSec : 0.0) << "blk/s"
|
||||||
<< " outDepth=" << (ipc->h.outWrite - ipc->h.outRead)
|
<< " outDepth=" << (ipc->h.outWrite - ipc->h.outRead)
|
||||||
<< std::endl;
|
<< 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
|
ipc->h.state = FXRT_STATE_STARTING; // đã dừng
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user