use crate::AsmService;
pub(crate) const NAMESPACE: &str = "ZISK";
fn build_service_shmem_name(prefix: &str, asm_service: AsmService, suffix: &str) -> String {
format!("{}_{}_{}", prefix, asm_service.as_str(), suffix)
}
fn build_shmem_name(prefix: &str, suffix: &str) -> String {
format!("{}_{}", prefix, suffix)
}
fn build_sem_name(prefix: &str, asm_service: AsmService, suffix: &str) -> String {
format!("/{}_{}_{}", prefix, asm_service.as_str(), suffix)
}
pub(crate) fn shmem_input_name(shm_prefix: &str) -> String {
build_shmem_name(shm_prefix, "input")
}
pub(crate) fn sem_input_avail_name(prefix: &str, asm_service: AsmService) -> String {
build_sem_name(prefix, asm_service, "input_avail")
}
pub(crate) fn shmem_precompile_name(prefix: &str) -> String {
build_shmem_name(prefix, "precompile")
}
pub(crate) fn sem_prec_available_name(prefix: &str, asm_service: AsmService) -> String {
build_sem_name(prefix, asm_service, "prec_avail")
}
pub(crate) fn sem_prec_read_name(prefix: &str, asm_service: AsmService) -> String {
build_sem_name(prefix, asm_service, "prec_read")
}
pub(crate) fn shmem_control_input_name(prefix: &str) -> String {
build_shmem_name(prefix, "control_input")
}
pub(crate) fn shmem_control_output_name(prefix: &str, asm_service: AsmService) -> String {
build_service_shmem_name(prefix, asm_service, "control_output")
}
pub(crate) fn shmem_output_name(
prefix: &str,
asm_service: AsmService,
suffix: Option<isize>,
) -> String {
if let Some(n) = suffix {
build_service_shmem_name(prefix, asm_service, &format!("output_{n}"))
} else {
build_service_shmem_name(prefix, asm_service, "output")
}
}
pub(crate) fn sem_chunk_done_name(prefix: &str, asm_service: AsmService) -> String {
build_sem_name(prefix, asm_service, "chunk_done")
}
pub(crate) fn is_zisk_shmem_file(file_name: &str) -> bool {
file_name.strip_prefix(NAMESPACE).is_some_and(|rest| rest.starts_with('_'))
}
pub(crate) fn is_zisk_sem_file(file_name: &str) -> bool {
file_name.strip_prefix("sem.").is_some_and(is_zisk_shmem_file)
}
pub(crate) fn sem_file_to_posix_name(file_name: &str) -> Option<String> {
file_name.strip_prefix("sem.").map(|rest| format!("/{rest}"))
}
#[cfg(test)]
mod tests {
use super::*;
use crate::AsmService;
#[test]
fn shmem_names_match_dev_shm_suffixes() {
let p = "ZISK_42_0";
assert_eq!(shmem_input_name(p), "ZISK_42_0_input");
assert_eq!(shmem_precompile_name(p), "ZISK_42_0_precompile");
assert_eq!(shmem_control_input_name(p), "ZISK_42_0_control_input");
assert_eq!(shmem_control_output_name(p, AsmService::MO), "ZISK_42_0_MO_control_output");
assert_eq!(shmem_output_name(p, AsmService::MT, None), "ZISK_42_0_MT_output");
assert_eq!(shmem_output_name(p, AsmService::MT, Some(3)), "ZISK_42_0_MT_output_3");
}
#[test]
fn sem_names_are_posix_absolute_and_per_service() {
let p = "ZISK_42_h_0";
assert_eq!(sem_input_avail_name(p, AsmService::MO), "/ZISK_42_h_0_MO_input_avail");
assert_eq!(sem_prec_available_name(p, AsmService::RH), "/ZISK_42_h_0_RH_prec_avail");
assert_eq!(sem_prec_read_name(p, AsmService::RH), "/ZISK_42_h_0_RH_prec_read");
assert_eq!(sem_chunk_done_name(p, AsmService::MT), "/ZISK_42_h_0_MT_chunk_done");
}
#[test]
fn shmem_predicate_requires_namespace_and_underscore_boundary() {
assert!(is_zisk_shmem_file("ZISK_42_0_input"));
assert!(is_zisk_shmem_file(&format!("{NAMESPACE}_x")));
assert!(!is_zisk_shmem_file("ZISKX"));
assert!(!is_zisk_shmem_file("OTHER_42_0"));
assert!(!is_zisk_shmem_file("sem.ZISK_42_0"));
}
#[test]
fn sem_file_predicate_and_posix_conversion() {
assert!(is_zisk_sem_file("sem.ZISK_42_0_MO_chunk_done"));
assert!(!is_zisk_sem_file("ZISK_42_0_input")); assert_eq!(sem_file_to_posix_name("sem.ZISK_42_0_x").as_deref(), Some("/ZISK_42_0_x"));
assert_eq!(sem_file_to_posix_name("ZISK_42_0_x"), None);
}
#[test]
fn builder_output_is_recognized_by_the_cleanup_scanner() {
let p = format!("{NAMESPACE}_99_0");
assert!(is_zisk_shmem_file(&shmem_input_name(&p)));
assert!(is_zisk_shmem_file(&shmem_output_name(&p, AsmService::RH, Some(0))));
let posix = sem_chunk_done_name(&p, AsmService::MO); let backing = format!("sem.{}", &posix[1..]);
assert!(is_zisk_sem_file(&backing));
assert_eq!(sem_file_to_posix_name(&backing).as_deref(), Some(posix.as_str()));
}
}