feat(mt): move serial advance orchestration into Rust
Move the serial turn increment, broadcast, and unlock ordering into a Rust entry point. C retains the pthread condition variable and mutex operations behind callbacks, while Rust preserves wrapping unsigned job-counter semantics and the required broadcast-before-unlock contract. Add ABI layout checks and focused tests for ordinary and wrapping advancement. Test Plan: - cargo fmt --manifest-path rust/Cargo.toml -- --check - ulimit -v 41943040 && CARGO_BUILD_JOBS=1 cargo test --manifest-path rust/Cargo.toml zstdmt_compress::tests::serial_ -- --nocapture - ulimit -v 41943040 && make -j1
This commit is contained in:
@@ -379,6 +379,21 @@ typedef char ZSTDMT_rust_serial_wait_for_turn_state_layout[
|
||||
&& sizeof(ZSTDMT_RustSerialWaitForTurnState) == 5 * sizeof(void*)) ? 1 : -1];
|
||||
int ZSTDMT_rust_serialStateWaitForTurn(
|
||||
const ZSTDMT_RustSerialWaitForTurnState* state);
|
||||
typedef void (*ZSTDMT_serialStateBroadcastFn)(void* opaque);
|
||||
typedef void (*ZSTDMT_serialStateUnlockFn)(void* opaque);
|
||||
typedef struct {
|
||||
void* callbackContext;
|
||||
unsigned* nextJobID;
|
||||
ZSTDMT_serialStateBroadcastFn broadcast;
|
||||
ZSTDMT_serialStateUnlockFn unlock;
|
||||
} ZSTDMT_RustSerialAdvanceState;
|
||||
typedef char ZSTDMT_rust_serial_advance_state_layout[
|
||||
(offsetof(ZSTDMT_RustSerialAdvanceState, callbackContext) == 0
|
||||
&& offsetof(ZSTDMT_RustSerialAdvanceState, nextJobID) == sizeof(void*)
|
||||
&& offsetof(ZSTDMT_RustSerialAdvanceState, broadcast) == 2 * sizeof(void*)
|
||||
&& offsetof(ZSTDMT_RustSerialAdvanceState, unlock) == 3 * sizeof(void*)
|
||||
&& sizeof(ZSTDMT_RustSerialAdvanceState) == 4 * sizeof(void*)) ? 1 : -1];
|
||||
void ZSTDMT_rust_serialStateAdvance(const ZSTDMT_RustSerialAdvanceState* state);
|
||||
void ZSTDMT_rust_serialStateGenSequences(
|
||||
ZSTDMT_RustRawSeqStore* seqStore, const void* src, size_t srcSize,
|
||||
unsigned jobID, int ldmEnabled, int checksumEnabled, void* opaque,
|
||||
@@ -1120,6 +1135,18 @@ static void ZSTDMT_serialState_wait(void* opaque)
|
||||
ZSTD_pthread_cond_wait(&serialState->cond, &serialState->mutex);
|
||||
}
|
||||
|
||||
static void ZSTDMT_serialState_broadcast(void* opaque)
|
||||
{
|
||||
SerialState* const serialState = (SerialState*)opaque;
|
||||
ZSTD_pthread_cond_broadcast(&serialState->cond);
|
||||
}
|
||||
|
||||
static void ZSTDMT_serialState_unlock(void* opaque)
|
||||
{
|
||||
SerialState* const serialState = (SerialState*)opaque;
|
||||
ZSTD_pthread_mutex_unlock(&serialState->mutex);
|
||||
}
|
||||
|
||||
/* Rust owns the serial turn/skip decision and operation ordering. The wait
|
||||
* callback intentionally leaves the main serial mutex locked; the advance
|
||||
* callback releases it after Rust has performed the current turn's work. */
|
||||
@@ -1172,9 +1199,12 @@ static void ZSTDMT_serialState_updateChecksum(
|
||||
static void ZSTDMT_serialState_advance(void* opaque)
|
||||
{
|
||||
SerialState* const serialState = (SerialState*)opaque;
|
||||
serialState->nextJobID++;
|
||||
ZSTD_pthread_cond_broadcast(&serialState->cond);
|
||||
ZSTD_pthread_mutex_unlock(&serialState->mutex);
|
||||
ZSTDMT_RustSerialAdvanceState state;
|
||||
state.callbackContext = serialState;
|
||||
state.nextJobID = &serialState->nextJobID;
|
||||
state.broadcast = ZSTDMT_serialState_broadcast;
|
||||
state.unlock = ZSTDMT_serialState_unlock;
|
||||
ZSTDMT_rust_serialStateAdvance(&state);
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
Reference in New Issue
Block a user