Avril 3 years ago
parent 0bf9a43c54
commit 706bacd26a
Signed by: flanchan
GPG Key ID: 284488987C31F630

@ -7,6 +7,7 @@ OPT_FLAGS_RUST?= -C target-cpu=native
OPT_FLAGS?= -march=native -fgraphite -fopenmp -floop-parallelize-all -ftree-parallelize-loops=4 \
-floop-interchange -ftree-loop-distribution -floop-strip-mine -floop-block
FEAT_RUST?= threads
FEAT_CFLAGS?= -D_RUN_THREADED=0
FEAT_LDFLAGS?= -lpthread
@ -40,6 +41,9 @@ debug: | dirs $(PROJECT)-debug
.PHONY: pgo
pgo: | dirs $(PROJECT)-pgo
.PHONY: rs
rs: | $(PROJECT)-rs
dirs:
@mkdir -p {obj,prof}/src
@ -60,6 +64,11 @@ $(PROJECT)-debug: LDFLAGS := $(DEBUG_LDFLAGS) $(LDFLAGS)
$(PROJECT)-debug: $(OBJ)
$(CC) $^ $(CFLAGS) -o $@ $(LDFLAGS)
$(PROJECT)-rs:
cd fcmprs && OPT_FLAGS="$(OPT_FLAGS_RUST)" CARGO_FEATURES="$(FEAT_RUST)" $(MAKE)
cp -f ./fcmprs/target/release/fcmprs $@
pgo-generate: CFLAGS := $(RELEASE_CFLAGS) $(CFLAGS)
pgo-generate: LDFLAGS := $(RELEASE_LDFLAGS) $(LDFLAGS)
pgo-generate: $(PGO_OBJ)
@ -107,6 +116,9 @@ $(PROJECT)-pgo: pgo-profile
mv pgo-use $@
strip $@
clean:
cd fcmp && make clean
rm -rf {obj,prof}
rm -f $(PROJECT)-{release,debug,pgo}
rm -f $(PROJECT)-{release,debug,pgo,rs}

@ -20,5 +20,6 @@ panic = "abort"
[dependencies]
cfg-if = "1.0.0"
memmap = "0.7.0"
once_cell = "1.5.2"
rayon = {version = "1.5.0", optional = true}
smallvec = "1.5.0"

@ -1,3 +1,6 @@
#![allow(dead_code)]
#[cfg(feature="threads")] use rayon::prelude::*;
use std::{
path::Path,
@ -18,9 +21,25 @@ mod error;
use error::ResultPrintExt as _;
mod map;
use map::MappedFile as _;
#[derive(Debug)]
/// There was a non-matching file
struct UnmatchError;
const _:() = {
use std::{fmt,error};
impl error::Error for UnmatchError{}
impl fmt::Display for UnmatchError
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
{
write!(f, "files did not match")
}
}
()
};
fn main() {
let (map1, rest) = {
let mut args = std::env::args().skip(1);
@ -39,10 +58,9 @@ fn main() {
let path = Path::new(&filename);
if path.exists() && path.is_file() {
map::map(path).discard_msg(format!("Failed to map file {}", filename))
.or_else(|| { ok = false; None })
} else {
eprintln!("File {} does not exist or is not a normal file", filename);
ok = false;
ok=false;
None
}
}).collect();
@ -57,7 +75,7 @@ fn main() {
.map(|map| {
if slice == map.as_slice() {
Ok(())
}else{
} else {
Err(UnmatchError)
}
})

@ -1,5 +1,26 @@
use super::*;
use once_cell::sync::OnceCell;
pub trait MappedFile
{
#[inline] fn as_slice(&self) -> &[u8]
{
&self.as_map()[..]
}
fn as_map(&self) -> &memmap::Mmap;
fn as_file(&self) -> &fs::File;
}
pub trait MappedFileNew: MappedFile + Sized
{
fn try_map(file: fs::File) -> io::Result<Self>;
#[inline] fn map(file: fs::File) -> Self
{
Self::try_map(file).unwrap()
}
}
/// Represents an open and memory mapped file
#[derive(Debug)]
pub struct MemMap
@ -8,23 +29,107 @@ pub struct MemMap
file: fs::File,
}
impl MemMap
impl MappedFile for MemMap
{
/// Get the memory mapped portion as a slice
#[inline] pub fn as_slice(&self) -> &[u8]
{
fn as_slice(&self) -> &[u8] {
&self.map[..]
}
fn as_map(&self) -> &memmap::Mmap {
&self.map
}
#[inline] fn as_file(&self) -> &fs::File {
&self.file
}
}
impl MappedFileNew for MemMap
{
#[inline] fn try_map(file: fs::File) -> io::Result<Self>
{
Ok(MemMap {
map: unsafe { memmap::Mmap::map(&file)? },
file,
})
}
}
/// Attempt to map this file
pub fn map(file: impl AsRef<Path>) -> io::Result<MemMap>
pub fn map_with<M: MappedFileNew>(file: &Path) -> io::Result<M>
{
let file = OpenOptions::new()
.read(true)
.open(file)?;
Ok(MemMap {
map: unsafe { memmap::Mmap::map(&file)? },
file,
})
M::try_map(file)
}
/// Type container for memory map
pub type DefaultMapType = LazyMap;
/// Attempt to map this file to the `DefaultMapType`
pub fn map(file: impl AsRef<Path>) -> io::Result<DefaultMapType>
{
map_with(file.as_ref())
}
/// An open and maybe mapped file
#[derive(Debug)]
pub struct LazyMap
{
map: OnceCell<memmap::Mmap>,
file: fs::File,
}
impl LazyMap
{
#[inline(always)] fn get_map(&self) -> &memmap::Mmap
{
self.map.get_or_init(|| unsafe {memmap::Mmap::map(&self.file).expect("Lazy map failed")})
}
#[inline(always)] fn try_get_map(&self) -> io::Result<&memmap::Mmap>
{
self.map.get_or_try_init(|| unsafe {memmap::Mmap::map(&self.file)})
}
/// Is the memory mapped already?
#[inline] pub fn is_mapped(&self) -> bool
{
self.map.get().is_some()
}
/// Get the mapped portion if it is mapped, attempting a map if not
#[inline] pub fn try_as_slice(&self) -> io::Result<&[u8]>
{
Ok(&self.try_get_map()?[..])
}
}
impl MappedFile for LazyMap
{
/// Get the memory mapped portion as a slice
///
/// Returns blank slice if mapping fails
#[inline] fn as_slice(&self) -> &[u8]
{
self.try_get_map()
.map(|x| &x[..])
.unwrap_or(&[])
}
fn as_map(&self) -> &memmap::Mmap {
self.map.get().unwrap()
}
#[inline] fn as_file(&self) -> &fs::File {
&self.file
}
}
impl MappedFileNew for LazyMap
{
#[inline] fn try_map(file: fs::File) -> io::Result<Self>
{
Ok(LazyMap {
map: OnceCell::new(),
file,
})
}
}

Loading…
Cancel
Save