Auto merge of #114016 - krtab:delete_sys_memchr, r=workingjubilee

Delete architecture-specific memchr code in std::sys

Currently all architecture-specific memchr code is only used in `std::io`. Most of the actual `memchr` capacity exposed to the user through the slice API is instead implemented in `core::slice::memchr`.

Hence this commit deletes `memchr` from `std::sys[_common]` and replace calls to it by calls to `core::slice::memchr` functions. This deletes `(r)memchr` from the list of symbols linked to libc.

The interest of putting architecture specific code back in core is linked to the discussion to be had in #113654
This commit is contained in:
bors 2024-03-01 00:45:47 +00:00
commit 6f435eb0eb
23 changed files with 8 additions and 231 deletions

View File

@ -1,5 +1,5 @@
use crate::io::{self, BufWriter, IoSlice, Write};
use crate::sys_common::memchr;
use core::slice::memchr;
/// Private helper struct for implementing the line-buffered writing logic.
/// This shim temporarily wraps a BufWriter, and uses its internals to

View File

@ -304,7 +304,7 @@
use crate::slice;
use crate::str;
use crate::sys;
use crate::sys_common::memchr;
use core::slice::memchr;
#[stable(feature = "bufwriter_into_parts", since = "1.56.0")]
pub use self::buffered::WriterPanicked;

View File

@ -1 +0,0 @@
pub use core::slice::memchr::{memchr, memrchr};

View File

@ -25,7 +25,6 @@
pub mod futex;
#[path = "../unsupported/io.rs"]
pub mod io;
pub mod memchr;
pub mod net;
pub mod os;
#[path = "../unsupported/pipe.rs"]

View File

@ -9,9 +9,9 @@
use crate::path::{self, PathBuf};
use crate::str;
use crate::sync::Mutex;
use crate::sys::memchr;
use crate::sys::unsupported;
use crate::vec;
use core::slice::memchr;
pub fn errno() -> i32 {
unsafe { abi::get_errno() }

View File

@ -1 +0,0 @@
pub use core::slice::memchr::{memchr, memrchr};

View File

@ -17,7 +17,6 @@
pub mod fs;
#[path = "../unsupported/io.rs"]
pub mod io;
pub mod memchr;
pub mod net;
pub mod os;
#[path = "../unsupported/pipe.rs"]

View File

@ -1,21 +0,0 @@
pub fn memchr(needle: u8, haystack: &[u8]) -> Option<usize> {
let p = unsafe {
libc::memchr(
haystack.as_ptr() as *const libc::c_void,
needle as libc::c_int,
haystack.len(),
)
};
if p.is_null() { None } else { Some(p as usize - (haystack.as_ptr() as usize)) }
}
pub fn memrchr(needle: u8, haystack: &[u8]) -> Option<usize> {
let p = unsafe {
libc::memrchr(
haystack.as_ptr() as *const libc::c_void,
needle as libc::c_int,
haystack.len(),
)
};
if p.is_null() { None } else { Some(p as usize - (haystack.as_ptr() as usize)) }
}

View File

@ -33,7 +33,6 @@ pub mod itron {
pub mod process;
pub mod stdio;
pub use self::itron::thread;
pub mod memchr;
pub mod thread_local_dtor;
pub mod thread_local_key;
pub use self::itron::thread_parking;

View File

@ -12,7 +12,9 @@
use crate::sys::common::small_c_string::run_with_cstr;
use crate::vec;
use super::{error, itron, memchr};
use super::{error, itron};
use core::slice::memchr;
// `solid` directly maps `errno`s to μITRON error codes.
impl itron::error::ItronError {

View File

@ -18,8 +18,6 @@
pub mod fs;
#[path = "../unsupported/io.rs"]
pub mod io;
#[path = "../unix/memchr.rs"]
pub mod memchr;
pub mod net;
#[path = "../unsupported/once.rs"]
pub mod once;

View File

@ -48,10 +48,6 @@
use crate::ptr::NonNull;
use crate::sync::atomic::{AtomicPtr, Ordering};
pub mod memchr {
pub use core::slice::memchr::{memchr, memrchr};
}
static EXIT_BOOT_SERVICE_EVENT: AtomicPtr<crate::ffi::c_void> =
AtomicPtr::new(crate::ptr::null_mut());

View File

@ -1,40 +0,0 @@
// Original implementation taken from rust-memchr.
// Copyright 2015 Andrew Gallant, bluss and Nicolas Koch
pub fn memchr(needle: u8, haystack: &[u8]) -> Option<usize> {
let p = unsafe {
libc::memchr(
haystack.as_ptr() as *const libc::c_void,
needle as libc::c_int,
haystack.len(),
)
};
if p.is_null() { None } else { Some(p.addr() - haystack.as_ptr().addr()) }
}
pub fn memrchr(needle: u8, haystack: &[u8]) -> Option<usize> {
#[cfg(target_os = "linux")]
fn memrchr_specific(needle: u8, haystack: &[u8]) -> Option<usize> {
// GNU's memrchr() will - unlike memchr() - error if haystack is empty.
if haystack.is_empty() {
return None;
}
let p = unsafe {
libc::memrchr(
haystack.as_ptr() as *const libc::c_void,
needle as libc::c_int,
haystack.len(),
)
};
// FIXME: this should *likely* use `offset_from`, but more
// investigation is needed (including running tests in miri).
if p.is_null() { None } else { Some(p.addr() - haystack.as_ptr().addr()) }
}
#[cfg(not(target_os = "linux"))]
fn memrchr_specific(needle: u8, haystack: &[u8]) -> Option<usize> {
core::slice::memchr::memrchr(needle, haystack)
}
memrchr_specific(needle, haystack)
}

View File

@ -20,7 +20,6 @@
pub mod kernel_copy;
#[cfg(target_os = "l4re")]
mod l4re;
pub mod memchr;
#[cfg(not(target_os = "l4re"))]
pub mod net;
#[cfg(target_os = "l4re")]

View File

@ -21,8 +21,8 @@
use crate::sys::common::small_c_string::{run_path_with_cstr, run_with_cstr};
use crate::sys::cvt;
use crate::sys::fd;
use crate::sys::memchr;
use crate::vec;
use core::slice::memchr;
#[cfg(all(target_env = "gnu", not(target_os = "vxworks")))]
use crate::sys::weak::weak;

View File

@ -1,9 +1,5 @@
use crate::io as std_io;
pub mod memchr {
pub use core::slice::memchr::{memchr, memrchr};
}
// SAFETY: must be called only once during runtime initialization.
// NOTE: this is not guaranteed to run, for example when Rust code is called externally.
pub unsafe fn init(_argc: isize, _argv: *const *const u8, _sigpipe: u8) {}

View File

@ -10,9 +10,9 @@
use crate::path::{self, PathBuf};
use crate::str;
use crate::sys::common::small_c_string::{run_path_with_cstr, run_with_cstr};
use crate::sys::memchr;
use crate::sys::unsupported;
use crate::vec;
use core::slice::memchr;
// Add a few symbols not in upstream `libc` just yet.
mod libc {

View File

@ -1,5 +0,0 @@
// Original implementation taken from rust-memchr.
// Copyright 2015 Andrew Gallant, bluss and Nicolas Koch
// Fallback memchr is fastest on Windows.
pub use core::slice::memchr::{memchr, memrchr};

View File

@ -19,7 +19,6 @@
pub mod fs;
pub mod handle;
pub mod io;
pub mod memchr;
pub mod net;
pub mod os;
pub mod pipe;

View File

@ -43,10 +43,6 @@
use crate::io as std_io;
pub mod memchr {
pub use core::slice::memchr::{memchr, memrchr};
}
// SAFETY: must be called only once during runtime initialization.
// NOTE: this is not guaranteed to run, for example when Rust code is called externally.
pub unsafe fn init(_argc: isize, _argv: *const *const u8, _sigpipe: u8) {}

View File

@ -1,51 +0,0 @@
// Original implementation taken from rust-memchr.
// Copyright 2015 Andrew Gallant, bluss and Nicolas Koch
use crate::sys::memchr as sys;
#[cfg(test)]
mod tests;
/// A safe interface to `memchr`.
///
/// Returns the index corresponding to the first occurrence of `needle` in
/// `haystack`, or `None` if one is not found.
///
/// memchr reduces to super-optimized machine code at around an order of
/// magnitude faster than `haystack.iter().position(|&b| b == needle)`.
/// (See benchmarks.)
///
/// # Examples
///
/// This shows how to find the first position of a byte in a byte string.
///
/// ```ignore (cannot-doctest-private-modules)
/// use memchr::memchr;
///
/// let haystack = b"the quick brown fox";
/// assert_eq!(memchr(b'k', haystack), Some(8));
/// ```
#[inline]
pub fn memchr(needle: u8, haystack: &[u8]) -> Option<usize> {
sys::memchr(needle, haystack)
}
/// A safe interface to `memrchr`.
///
/// Returns the index corresponding to the last occurrence of `needle` in
/// `haystack`, or `None` if one is not found.
///
/// # Examples
///
/// This shows how to find the last position of a byte in a byte string.
///
/// ```ignore (cannot-doctest-private-modules)
/// use memchr::memrchr;
///
/// let haystack = b"the quick brown fox";
/// assert_eq!(memrchr(b'o', haystack), Some(17));
/// ```
#[inline]
pub fn memrchr(needle: u8, haystack: &[u8]) -> Option<usize> {
sys::memrchr(needle, haystack)
}

View File

@ -1,86 +0,0 @@
// Original implementation taken from rust-memchr.
// Copyright 2015 Andrew Gallant, bluss and Nicolas Koch
// test the implementations for the current platform
use super::{memchr, memrchr};
#[test]
fn matches_one() {
assert_eq!(Some(0), memchr(b'a', b"a"));
}
#[test]
fn matches_begin() {
assert_eq!(Some(0), memchr(b'a', b"aaaa"));
}
#[test]
fn matches_end() {
assert_eq!(Some(4), memchr(b'z', b"aaaaz"));
}
#[test]
fn matches_nul() {
assert_eq!(Some(4), memchr(b'\x00', b"aaaa\x00"));
}
#[test]
fn matches_past_nul() {
assert_eq!(Some(5), memchr(b'z', b"aaaa\x00z"));
}
#[test]
fn no_match_empty() {
assert_eq!(None, memchr(b'a', b""));
}
#[test]
fn no_match() {
assert_eq!(None, memchr(b'a', b"xyz"));
}
#[test]
fn matches_one_reversed() {
assert_eq!(Some(0), memrchr(b'a', b"a"));
}
#[test]
fn matches_begin_reversed() {
assert_eq!(Some(3), memrchr(b'a', b"aaaa"));
}
#[test]
fn matches_end_reversed() {
assert_eq!(Some(0), memrchr(b'z', b"zaaaa"));
}
#[test]
fn matches_nul_reversed() {
assert_eq!(Some(4), memrchr(b'\x00', b"aaaa\x00"));
}
#[test]
fn matches_past_nul_reversed() {
assert_eq!(Some(0), memrchr(b'z', b"z\x00aaaa"));
}
#[test]
fn no_match_empty_reversed() {
assert_eq!(None, memrchr(b'a', b""));
}
#[test]
fn no_match_reversed() {
assert_eq!(None, memrchr(b'a', b"xyz"));
}
#[test]
fn each_alignment() {
let mut data = [1u8; 64];
let needle = 2;
let pos = 40;
data[pos] = needle;
for start in 0..16 {
assert_eq!(Some(pos - start), memchr(needle, &data[start..]));
}
}

View File

@ -24,7 +24,6 @@
pub mod fs;
pub mod io;
pub mod lazy_box;
pub mod memchr;
pub mod once;
pub mod process;
pub mod thread;