feat(mt): move job completion wait loop into Rust
Move MT job-ring completion progression into Rust, including ring-slot selection, termination, and wrapping done-job advancement. C retains the per-job mutex and condition wait over private consumed/source counters through a callback. Test Plan: - ulimit -v 41943040; CARGO_BUILD_JOBS=1; cargo test --manifest-path rust/Cargo.toml - ulimit -v 41943040; CARGO_BUILD_JOBS=1; cargo clippy --manifest-path rust/Cargo.toml --all-targets -- -D warnings - ulimit -v 41943040; make -B -C programs -j1 zstd - ulimit -v 41943040; make -C tests -j1 test-zstream ZSTREAM_TESTTIME=-T1s
This commit is contained in:
@@ -374,6 +374,11 @@ typedef struct {
|
||||
} ZSTDMT_RustSerialEnsureFinishedResult;
|
||||
ZSTDMT_RustSerialEnsureFinishedResult ZSTDMT_rust_serialStateEnsureFinished(
|
||||
unsigned nextJobID, unsigned jobID);
|
||||
typedef void (*ZSTDMT_waitForJobCompleteFn)(
|
||||
void* opaque, unsigned jobID, unsigned doneJobID);
|
||||
unsigned ZSTDMT_rust_waitForAllJobsCompleted(
|
||||
unsigned doneJobID, unsigned nextJobID, unsigned jobIDMask,
|
||||
void* opaque, ZSTDMT_waitForJobCompleteFn waitForJob);
|
||||
typedef void (*ZSTDMT_waitForLdmLockFn)(void* opaque);
|
||||
typedef int (*ZSTDMT_waitForLdmOverlapFn)(
|
||||
void* opaque, void* bufferStart, size_t bufferCapacity);
|
||||
@@ -1502,19 +1507,26 @@ static void ZSTDMT_releaseAllJobResources(ZSTDMT_CCtx* mtctx)
|
||||
mtctx->allJobsCompleted = 1;
|
||||
}
|
||||
|
||||
static void ZSTDMT_waitForJobComplete(
|
||||
void* opaque, unsigned jobID, unsigned doneJobID)
|
||||
{
|
||||
ZSTDMT_CCtx* const mtctx = (ZSTDMT_CCtx*)opaque;
|
||||
ZSTDMT_jobDescription* const job = &mtctx->jobs[jobID];
|
||||
(void)doneJobID;
|
||||
ZSTD_PTHREAD_MUTEX_LOCK(&job->job_mutex);
|
||||
while (job->consumed < job->src.size) {
|
||||
DEBUGLOG(4, "waiting for jobCompleted signal from job %u", doneJobID);
|
||||
ZSTD_pthread_cond_wait(&job->job_cond, &job->job_mutex);
|
||||
}
|
||||
ZSTD_pthread_mutex_unlock(&job->job_mutex);
|
||||
}
|
||||
|
||||
static void ZSTDMT_waitForAllJobsCompleted(ZSTDMT_CCtx* mtctx)
|
||||
{
|
||||
DEBUGLOG(4, "ZSTDMT_waitForAllJobsCompleted");
|
||||
while (mtctx->doneJobID < mtctx->nextJobID) {
|
||||
unsigned const jobID = mtctx->doneJobID & mtctx->jobIDMask;
|
||||
ZSTD_PTHREAD_MUTEX_LOCK(&mtctx->jobs[jobID].job_mutex);
|
||||
while (mtctx->jobs[jobID].consumed < mtctx->jobs[jobID].src.size) {
|
||||
DEBUGLOG(4, "waiting for jobCompleted signal from job %u", mtctx->doneJobID); /* we want to block when waiting for data to flush */
|
||||
ZSTD_pthread_cond_wait(&mtctx->jobs[jobID].job_cond, &mtctx->jobs[jobID].job_mutex);
|
||||
}
|
||||
ZSTD_pthread_mutex_unlock(&mtctx->jobs[jobID].job_mutex);
|
||||
mtctx->doneJobID++;
|
||||
}
|
||||
mtctx->doneJobID = ZSTDMT_rust_waitForAllJobsCompleted(
|
||||
mtctx->doneJobID, mtctx->nextJobID, mtctx->jobIDMask,
|
||||
mtctx, ZSTDMT_waitForJobComplete);
|
||||
}
|
||||
|
||||
size_t ZSTDMT_freeCCtx(ZSTDMT_CCtx* mtctx)
|
||||
|
||||
Reference in New Issue
Block a user