feat(compress): call reset storage policy directly from Rust
The CCtx reset tail already delegated storage reservation and ordering policy to Rust, but crossed back into C through a redundant callback trampoline. Project the storage state directly through the existing pointer-sized ABI slot and invoke the Rust storage operation without the extra C hop. Keep private workspace/layout callbacks and match-state reset in C, preserve hash -> match -> storage ordering, and retain allocation-error propagation in Rust tests. Test Plan: - ulimit -v 41943040; CARGO_BUILD_JOBS=1 cargo check --manifest-path rust/Cargo.toml --tests - ulimit -v 41943040; CARGO_BUILD_JOBS=1 cargo clippy --manifest-path rust/cli/Cargo.toml --all-targets -- -D warnings - ulimit -v 41943040; make -j1 - ulimit -v 41943040; make -j1 -C tests test
This commit is contained in:
@@ -2304,7 +2304,7 @@ typedef struct {
|
|||||||
ZSTD_rust_resetCCtxStorageCallback_f resetHash;
|
ZSTD_rust_resetCCtxStorageCallback_f resetHash;
|
||||||
void* compressedBlockState;
|
void* compressedBlockState;
|
||||||
ZSTD_rust_resetCCtxTailCallback_f resetMatchState;
|
ZSTD_rust_resetCCtxTailCallback_f resetMatchState;
|
||||||
ZSTD_rust_resetCCtxTailCallback_f resetStorage;
|
const ZSTD_rust_resetCCtxStorageState* storageState;
|
||||||
ZSTD_compressionParameters* matchStateCParams;
|
ZSTD_compressionParameters* matchStateCParams;
|
||||||
int* matchStatePrefetchCDictTables;
|
int* matchStatePrefetchCDictTables;
|
||||||
unsigned long long* pledgedSrcSizePlusOne;
|
unsigned long long* pledgedSrcSizePlusOne;
|
||||||
@@ -2327,7 +2327,7 @@ typedef char ZSTD_rust_reset_cctx_tail_state_layout[
|
|||||||
== 2 * sizeof(void*)
|
== 2 * sizeof(void*)
|
||||||
&& offsetof(ZSTD_rust_resetCCtxTailState, resetMatchState)
|
&& offsetof(ZSTD_rust_resetCCtxTailState, resetMatchState)
|
||||||
== 3 * sizeof(void*)
|
== 3 * sizeof(void*)
|
||||||
&& offsetof(ZSTD_rust_resetCCtxTailState, resetStorage)
|
&& offsetof(ZSTD_rust_resetCCtxTailState, storageState)
|
||||||
== 4 * sizeof(void*)
|
== 4 * sizeof(void*)
|
||||||
&& offsetof(ZSTD_rust_resetCCtxTailState, matchStateCParams)
|
&& offsetof(ZSTD_rust_resetCCtxTailState, matchStateCParams)
|
||||||
== 5 * sizeof(void*)
|
== 5 * sizeof(void*)
|
||||||
@@ -5389,13 +5389,6 @@ static size_t ZSTD_rust_resetCCtxTail_resetMatchState(void* opaque)
|
|||||||
ZSTD_resetTarget_CCtx);
|
ZSTD_resetTarget_CCtx);
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t ZSTD_rust_resetCCtxTail_resetStorage(void* opaque)
|
|
||||||
{
|
|
||||||
ZSTD_rust_resetCCtxTailContext* const context =
|
|
||||||
(ZSTD_rust_resetCCtxTailContext*)opaque;
|
|
||||||
return ZSTD_rust_resetCCtxStorage(context->storageState);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*! ZSTD_resetCCtx_internal() :
|
/*! ZSTD_resetCCtx_internal() :
|
||||||
* @param loadedDictSize The size of the dictionary to be loaded
|
* @param loadedDictSize The size of the dictionary to be loaded
|
||||||
* into the context, if any. If no dictionary is used, or the
|
* into the context, if any. If no dictionary is used, or the
|
||||||
@@ -5534,7 +5527,7 @@ static size_t ZSTD_resetCCtx_internal(ZSTD_CCtx* zc,
|
|||||||
tailState.resetHash = ZSTD_rust_resetCCtxTail_resetHash;
|
tailState.resetHash = ZSTD_rust_resetCCtxTail_resetHash;
|
||||||
tailState.compressedBlockState = NULL;
|
tailState.compressedBlockState = NULL;
|
||||||
tailState.resetMatchState = ZSTD_rust_resetCCtxTail_resetMatchState;
|
tailState.resetMatchState = ZSTD_rust_resetCCtxTail_resetMatchState;
|
||||||
tailState.resetStorage = ZSTD_rust_resetCCtxTail_resetStorage;
|
tailState.storageState = &storageState;
|
||||||
tailState.matchStateCParams = &zc->blockState.matchState.cParams;
|
tailState.matchStateCParams = &zc->blockState.matchState.cParams;
|
||||||
tailState.matchStatePrefetchCDictTables =
|
tailState.matchStatePrefetchCDictTables =
|
||||||
&zc->blockState.matchState.prefetchCDictTables;
|
&zc->blockState.matchState.prefetchCDictTables;
|
||||||
|
|||||||
+108
-14
@@ -9930,15 +9930,15 @@ const _: () = {
|
|||||||
/// C-owned operations used by the post-workspace CCtx reset tail.
|
/// C-owned operations used by the post-workspace CCtx reset tail.
|
||||||
///
|
///
|
||||||
/// Rust owns the operation order, compressed-block reset, and error
|
/// Rust owns the operation order, compressed-block reset, and error
|
||||||
/// propagation. C retains the private context initialization, match-state
|
/// propagation. C retains the private context initialization and match-state
|
||||||
/// reset, and storage publication operations.
|
/// reset; the storage policy is called directly through its projected state.
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct ZSTD_rust_resetCCtxTailState {
|
pub struct ZSTD_rust_resetCCtxTailState {
|
||||||
callbackContext: *mut c_void,
|
callbackContext: *mut c_void,
|
||||||
resetHash: Option<ResetCCtxStorageCallback>,
|
resetHash: Option<ResetCCtxStorageCallback>,
|
||||||
compressedBlockState: *mut ZSTD_compressedBlockState_t,
|
compressedBlockState: *mut ZSTD_compressedBlockState_t,
|
||||||
resetMatchState: Option<ResetCCtxTailCallback>,
|
resetMatchState: Option<ResetCCtxTailCallback>,
|
||||||
resetStorage: Option<ResetCCtxTailCallback>,
|
storageState: *const ZSTD_rust_resetCCtxStorageState,
|
||||||
matchStateCParams: *mut ZSTD_compressionParameters,
|
matchStateCParams: *mut ZSTD_compressionParameters,
|
||||||
matchStatePrefetchCDictTables: *mut c_int,
|
matchStatePrefetchCDictTables: *mut c_int,
|
||||||
pledgedSrcSizePlusOne: *mut u64,
|
pledgedSrcSizePlusOne: *mut u64,
|
||||||
@@ -9962,7 +9962,7 @@ const _: () = {
|
|||||||
offset_of!(ZSTD_rust_resetCCtxTailState, compressedBlockState) == 2 * size_of::<usize>()
|
offset_of!(ZSTD_rust_resetCCtxTailState, compressedBlockState) == 2 * size_of::<usize>()
|
||||||
);
|
);
|
||||||
assert!(offset_of!(ZSTD_rust_resetCCtxTailState, resetMatchState) == 3 * size_of::<usize>());
|
assert!(offset_of!(ZSTD_rust_resetCCtxTailState, resetMatchState) == 3 * size_of::<usize>());
|
||||||
assert!(offset_of!(ZSTD_rust_resetCCtxTailState, resetStorage) == 4 * size_of::<usize>());
|
assert!(offset_of!(ZSTD_rust_resetCCtxTailState, storageState) == 4 * size_of::<usize>());
|
||||||
assert!(
|
assert!(
|
||||||
offset_of!(ZSTD_rust_resetCCtxTailState, matchStateCParams) == 5 * size_of::<usize>()
|
offset_of!(ZSTD_rust_resetCCtxTailState, matchStateCParams) == 5 * size_of::<usize>()
|
||||||
);
|
);
|
||||||
@@ -10462,9 +10462,9 @@ pub unsafe extern "C" fn ZSTD_rust_resetCCtxTail(
|
|||||||
let Some(reset_match_state) = state.resetMatchState else {
|
let Some(reset_match_state) = state.resetMatchState else {
|
||||||
return ERROR(ZstdErrorCode::Generic);
|
return ERROR(ZstdErrorCode::Generic);
|
||||||
};
|
};
|
||||||
let Some(reset_storage) = state.resetStorage else {
|
if state.storageState.is_null() {
|
||||||
return ERROR(ZstdErrorCode::Generic);
|
return ERROR(ZstdErrorCode::Generic);
|
||||||
};
|
}
|
||||||
if state.compressedBlockState.is_null() {
|
if state.compressedBlockState.is_null() {
|
||||||
return ERROR(ZstdErrorCode::Generic);
|
return ERROR(ZstdErrorCode::Generic);
|
||||||
}
|
}
|
||||||
@@ -10502,7 +10502,7 @@ pub unsafe extern "C" fn ZSTD_rust_resetCCtxTail(
|
|||||||
if ERR_isError(result) {
|
if ERR_isError(result) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
let result = reset_storage(state.callbackContext);
|
let result = ZSTD_rust_resetCCtxStorage(state.storageState);
|
||||||
if ERR_isError(result) {
|
if ERR_isError(result) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -23436,6 +23436,8 @@ mod tests {
|
|||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
struct ResetCCtxTailTestContext {
|
struct ResetCCtxTailTestContext {
|
||||||
events: Vec<&'static str>,
|
events: Vec<&'static str>,
|
||||||
|
storage_allocations: Vec<Box<[u8]>>,
|
||||||
|
storage_error_armed: bool,
|
||||||
match_result: usize,
|
match_result: usize,
|
||||||
storage_result: usize,
|
storage_result: usize,
|
||||||
c_params: ZSTD_compressionParameters,
|
c_params: ZSTD_compressionParameters,
|
||||||
@@ -23471,22 +23473,110 @@ mod tests {
|
|||||||
context.match_result
|
context.match_result
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe extern "C" fn reset_cctx_tail_test_reset_storage(context: *mut c_void) -> usize {
|
unsafe extern "C" fn reset_cctx_tail_storage_set_pointer(
|
||||||
|
_context: *mut c_void,
|
||||||
|
_pointer_kind: c_int,
|
||||||
|
_pointer: *mut c_void,
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe extern "C" fn reset_cctx_tail_storage_set_size(
|
||||||
|
_context: *mut c_void,
|
||||||
|
_size_kind: c_int,
|
||||||
|
_value: usize,
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe extern "C" fn reset_cctx_tail_storage_set_int(
|
||||||
|
_context: *mut c_void,
|
||||||
|
_int_kind: c_int,
|
||||||
|
_value: c_int,
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe extern "C" fn reset_cctx_tail_storage_reserve(
|
||||||
|
context: *mut c_void,
|
||||||
|
_reserve_kind: c_int,
|
||||||
|
size: usize,
|
||||||
|
) -> *mut c_void {
|
||||||
|
let context = unsafe { reset_cctx_tail_test_context(context) };
|
||||||
|
let allocation = vec![0u8; size.max(1)].into_boxed_slice();
|
||||||
|
let pointer = allocation.as_ptr() as *mut c_void;
|
||||||
|
context.storage_allocations.push(allocation);
|
||||||
|
pointer
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe extern "C" fn reset_cctx_tail_storage_reserve_failed(
|
||||||
|
context: *mut c_void,
|
||||||
|
) -> c_int {
|
||||||
|
let context = unsafe { reset_cctx_tail_test_context(context) };
|
||||||
|
c_int::from(context.storage_error_armed)
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe extern "C" fn reset_cctx_tail_storage_zero(
|
||||||
|
_context: *mut c_void,
|
||||||
|
pointer: *mut c_void,
|
||||||
|
size: usize,
|
||||||
|
) {
|
||||||
|
if !pointer.is_null() {
|
||||||
|
unsafe { ptr::write_bytes(pointer.cast::<u8>(), 0, size) };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe extern "C" fn reset_cctx_tail_storage_window_init(_context: *mut c_void) {}
|
||||||
|
|
||||||
|
unsafe extern "C" fn reset_cctx_tail_storage_reset_external_sequences(
|
||||||
|
context: *mut c_void,
|
||||||
|
) {
|
||||||
let context = unsafe { reset_cctx_tail_test_context(context) };
|
let context = unsafe { reset_cctx_tail_test_context(context) };
|
||||||
context.events.push("reset-storage");
|
context.events.push("reset-storage");
|
||||||
context.storage_result
|
context.storage_error_armed = context.storage_result != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn reset_cctx_tail_test_storage_state(
|
||||||
|
context: &mut ResetCCtxTailTestContext,
|
||||||
|
) -> ZSTD_rust_resetCCtxStorageState {
|
||||||
|
ZSTD_rust_resetCCtxStorageState {
|
||||||
|
callbackContext: (context as *mut ResetCCtxTailTestContext).cast(),
|
||||||
|
ldmEnable: ZSTD_RUST_PS_DISABLE,
|
||||||
|
hasExtSeqProd: 0,
|
||||||
|
hashLog: 0,
|
||||||
|
bucketSizeLog: 0,
|
||||||
|
blockSize: 1,
|
||||||
|
maxNbSeq: 1,
|
||||||
|
maxNbLdmSeq: 0,
|
||||||
|
maxNbExternalSeq: 0,
|
||||||
|
buffInSize: 0,
|
||||||
|
buffOutSize: 0,
|
||||||
|
seqDefSize: 1,
|
||||||
|
ldmEntrySize: 1,
|
||||||
|
rawSeqSize: 1,
|
||||||
|
externalSequenceSize: 1,
|
||||||
|
byteSize: 1,
|
||||||
|
wildcopyOverlength: 0,
|
||||||
|
bufferedPolicy: 0,
|
||||||
|
setPointer: Some(reset_cctx_tail_storage_set_pointer),
|
||||||
|
setSize: Some(reset_cctx_tail_storage_set_size),
|
||||||
|
setInt: Some(reset_cctx_tail_storage_set_int),
|
||||||
|
reserve: Some(reset_cctx_tail_storage_reserve),
|
||||||
|
reserveFailed: Some(reset_cctx_tail_storage_reserve_failed),
|
||||||
|
zero: Some(reset_cctx_tail_storage_zero),
|
||||||
|
windowInit: Some(reset_cctx_tail_storage_window_init),
|
||||||
|
resetExternalSequences: Some(reset_cctx_tail_storage_reset_external_sequences),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn reset_cctx_tail_test_state(
|
fn reset_cctx_tail_test_state(
|
||||||
context: &mut ResetCCtxTailTestContext,
|
context: &mut ResetCCtxTailTestContext,
|
||||||
compressed_block_state: *mut ZSTD_compressedBlockState_t,
|
compressed_block_state: *mut ZSTD_compressedBlockState_t,
|
||||||
|
storage_state: &mut ZSTD_rust_resetCCtxStorageState,
|
||||||
) -> ZSTD_rust_resetCCtxTailState {
|
) -> ZSTD_rust_resetCCtxTailState {
|
||||||
ZSTD_rust_resetCCtxTailState {
|
ZSTD_rust_resetCCtxTailState {
|
||||||
callbackContext: (context as *mut ResetCCtxTailTestContext).cast(),
|
callbackContext: (context as *mut ResetCCtxTailTestContext).cast(),
|
||||||
resetHash: Some(reset_cctx_tail_test_reset_hash),
|
resetHash: Some(reset_cctx_tail_test_reset_hash),
|
||||||
compressedBlockState: compressed_block_state,
|
compressedBlockState: compressed_block_state,
|
||||||
resetMatchState: Some(reset_cctx_tail_test_reset_match_state),
|
resetMatchState: Some(reset_cctx_tail_test_reset_match_state),
|
||||||
resetStorage: Some(reset_cctx_tail_test_reset_storage),
|
storageState: storage_state,
|
||||||
matchStateCParams: ptr::addr_of_mut!(context.match_state_cparams),
|
matchStateCParams: ptr::addr_of_mut!(context.match_state_cparams),
|
||||||
matchStatePrefetchCDictTables: ptr::addr_of_mut!(
|
matchStatePrefetchCDictTables: ptr::addr_of_mut!(
|
||||||
context.match_state_prefetch_cdict_tables
|
context.match_state_prefetch_cdict_tables
|
||||||
@@ -23511,7 +23601,8 @@ mod tests {
|
|||||||
let mut context = ResetCCtxTailTestContext::default();
|
let mut context = ResetCCtxTailTestContext::default();
|
||||||
let mut block_state =
|
let mut block_state =
|
||||||
unsafe { MaybeUninit::<ZSTD_compressedBlockState_t>::zeroed().assume_init() };
|
unsafe { MaybeUninit::<ZSTD_compressedBlockState_t>::zeroed().assume_init() };
|
||||||
let state = reset_cctx_tail_test_state(&mut context, &mut block_state);
|
let mut storage_state = reset_cctx_tail_test_storage_state(&mut context);
|
||||||
|
let state = reset_cctx_tail_test_state(&mut context, &mut block_state, &mut storage_state);
|
||||||
|
|
||||||
assert_eq!(unsafe { ZSTD_rust_resetCCtxTail(&state) }, 0);
|
assert_eq!(unsafe { ZSTD_rust_resetCCtxTail(&state) }, 0);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
@@ -23551,7 +23642,8 @@ mod tests {
|
|||||||
};
|
};
|
||||||
let mut block_state =
|
let mut block_state =
|
||||||
unsafe { MaybeUninit::<ZSTD_compressedBlockState_t>::zeroed().assume_init() };
|
unsafe { MaybeUninit::<ZSTD_compressedBlockState_t>::zeroed().assume_init() };
|
||||||
let state = reset_cctx_tail_test_state(&mut context, &mut block_state);
|
let mut storage_state = reset_cctx_tail_test_storage_state(&mut context);
|
||||||
|
let state = reset_cctx_tail_test_state(&mut context, &mut block_state, &mut storage_state);
|
||||||
|
|
||||||
assert_eq!(unsafe { ZSTD_rust_resetCCtxTail(&state) }, 0);
|
assert_eq!(unsafe { ZSTD_rust_resetCCtxTail(&state) }, 0);
|
||||||
assert_eq!(context.match_state_cparams, c_params);
|
assert_eq!(context.match_state_cparams, c_params);
|
||||||
@@ -23574,7 +23666,8 @@ mod tests {
|
|||||||
};
|
};
|
||||||
let mut block_state =
|
let mut block_state =
|
||||||
unsafe { MaybeUninit::<ZSTD_compressedBlockState_t>::zeroed().assume_init() };
|
unsafe { MaybeUninit::<ZSTD_compressedBlockState_t>::zeroed().assume_init() };
|
||||||
let state = reset_cctx_tail_test_state(&mut context, &mut block_state);
|
let mut storage_state = reset_cctx_tail_test_storage_state(&mut context);
|
||||||
|
let state = reset_cctx_tail_test_state(&mut context, &mut block_state, &mut storage_state);
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
unsafe { ZSTD_rust_resetCCtxTail(&state) },
|
unsafe { ZSTD_rust_resetCCtxTail(&state) },
|
||||||
@@ -23591,7 +23684,8 @@ mod tests {
|
|||||||
};
|
};
|
||||||
let mut block_state =
|
let mut block_state =
|
||||||
unsafe { MaybeUninit::<ZSTD_compressedBlockState_t>::zeroed().assume_init() };
|
unsafe { MaybeUninit::<ZSTD_compressedBlockState_t>::zeroed().assume_init() };
|
||||||
let state = reset_cctx_tail_test_state(&mut context, &mut block_state);
|
let mut storage_state = reset_cctx_tail_test_storage_state(&mut context);
|
||||||
|
let state = reset_cctx_tail_test_state(&mut context, &mut block_state, &mut storage_state);
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
unsafe { ZSTD_rust_resetCCtxTail(&state) },
|
unsafe { ZSTD_rust_resetCCtxTail(&state) },
|
||||||
|
|||||||
Reference in New Issue
Block a user