feat(mt): split serial LDM callback operations

The MT serial turn already belongs to Rust for turn selection, checksum
placement, and advance. The remaining LDM callback still bundled the private
window update, sequence generation, and ldmWindow publication behind one C
operation, which hid that ordering from Rust.

Expose those three private operations as separate C callbacks and invoke them
from Rust in the original order. The first callback retains the original
RawSeqStore and job-size assertions before updating the LDM window; sequence
generation keeps its error assertion; and publication keeps the
ldmWindowMutex lock, copy, signal, and unlock sequence. The serial mutex
remains held until the existing advance callback, and disabled-LDM, empty
input, and skipped-turn behavior remain unchanged.

Test Plan:
- `git diff --cached --check` -- passed.
- Cargo, make, and full tests were not run per request; run the capped serial
  verification suite before relying on runtime coverage.
This commit is contained in:
2026-07-21 20:02:55 +02:00
parent 09abf02049
commit 7cc25be2a8
2 changed files with 109 additions and 21 deletions
+28 -5
View File
@@ -602,9 +602,13 @@ typedef char ZSTDMT_rust_raw_seq_store_layout[
ZSTDMT_RustRawSeqStore ZSTDMT_rust_bufferToSeq(ZSTDMT_RustBuffer buffer);
ZSTDMT_RustBuffer ZSTDMT_rust_seqToBuffer(ZSTDMT_RustRawSeqStore seq);
typedef int (*ZSTDMT_serialWaitForTurnFn)(void* opaque, unsigned jobID);
typedef void (*ZSTDMT_serialGenerateLdmFn)(
typedef void (*ZSTDMT_serialLdmWindowUpdateFn)(
void* opaque, ZSTDMT_RustRawSeqStore* seqStore,
const void* src, size_t srcSize);
typedef void (*ZSTDMT_serialLdmGenerateSequencesFn)(
void* opaque, ZSTDMT_RustRawSeqStore* seqStore,
const void* src, size_t srcSize);
typedef void (*ZSTDMT_serialLdmPublishWindowFn)(void* opaque);
typedef void (*ZSTDMT_serialUpdateChecksumFn)(
void* opaque, const void* src, size_t srcSize);
typedef void (*ZSTDMT_serialAdvanceFn)(void* opaque);
@@ -645,7 +649,9 @@ void ZSTDMT_rust_serialStateGenSequences(
ZSTDMT_RustRawSeqStore* seqStore, const void* src, size_t srcSize,
unsigned jobID, int ldmEnabled, int checksumEnabled, void* opaque,
ZSTDMT_serialWaitForTurnFn waitForTurn,
ZSTDMT_serialGenerateLdmFn generateLdm,
ZSTDMT_serialLdmWindowUpdateFn updateLdmWindow,
ZSTDMT_serialLdmGenerateSequencesFn generateLdmSequences,
ZSTDMT_serialLdmPublishWindowFn publishLdmWindow,
ZSTDMT_serialUpdateChecksumFn updateChecksum,
ZSTDMT_serialAdvanceFn advance);
typedef struct {
@@ -1740,13 +1746,12 @@ static int ZSTDMT_serialState_waitForTurn(void* opaque, unsigned jobID)
return ZSTDMT_rust_serialStateWaitForTurn(&state);
}
static void ZSTDMT_serialState_generateLdm(
static void ZSTDMT_serialState_updateLdmWindow(
void* opaque, ZSTDMT_RustRawSeqStore* seqStore,
const void* src, size_t srcSize)
{
SerialState* const serialState = (SerialState*)opaque;
RawSeqStore_t* const cSeqStore = (RawSeqStore_t*)seqStore;
size_t error;
DEBUGLOG(6, "ZSTDMT_serialState_genSequences: LDM update");
assert(cSeqStore->seq != NULL && cSeqStore->pos == 0 &&
@@ -1754,11 +1759,27 @@ static void ZSTDMT_serialState_generateLdm(
assert(srcSize <= serialState->params.jobSize);
ZSTD_window_update(&serialState->ldmState.window, src, srcSize,
/* forceNonContiguous */ 0);
}
static void ZSTDMT_serialState_generateLdmSequences(
void* opaque, ZSTDMT_RustRawSeqStore* seqStore,
const void* src, size_t srcSize)
{
SerialState* const serialState = (SerialState*)opaque;
RawSeqStore_t* const cSeqStore = (RawSeqStore_t*)seqStore;
size_t error;
error = ZSTD_ldm_generateSequences(
&serialState->ldmState, cSeqStore,
&serialState->params.ldmParams, src, srcSize);
/* We provide a large enough buffer to never fail. */
assert(!ZSTD_isError(error)); (void)error;
}
static void ZSTDMT_serialState_publishLdmWindow(void* opaque)
{
SerialState* const serialState = (SerialState*)opaque;
/* Update ldmWindow to match the ldmState.window and signal the main
* thread if it is waiting for a buffer. */
ZSTD_PTHREAD_MUTEX_LOCK(&serialState->ldmWindowMutex);
@@ -2002,7 +2023,9 @@ static void ZSTDMT_compressionJobGenerateSequences(void* opaque)
job->serial->params.fParams.checksumFlag,
job->serial,
ZSTDMT_serialState_waitForTurn,
ZSTDMT_serialState_generateLdm,
ZSTDMT_serialState_updateLdmWindow,
ZSTDMT_serialState_generateLdmSequences,
ZSTDMT_serialState_publishLdmWindow,
ZSTDMT_serialState_updateChecksum,
ZSTDMT_serialState_advance);
}