Merge pull request #116 from matijaskala/patch-1

Add optimized version of memchr
This commit is contained in:
Jeremy Soller
2018-05-15 18:33:31 -06:00
committed by GitHub
+35 -8
View File
@@ -11,6 +11,7 @@ use errno::*;
use core::cmp;
use core::usize;
use core::ptr;
use core::mem;
#[no_mangle]
pub unsafe extern "C" fn memccpy(
@@ -32,12 +33,42 @@ pub unsafe extern "C" fn memccpy(
#[no_mangle]
pub unsafe extern "C" fn memchr(s: *const c_void, c: c_int, n: usize) -> *mut c_void {
let s = s as *mut u8;
let mut s = s as *const u8;
let c = c as u8;
for i in 0..n {
if *s.offset(i as isize) == c {
return s.offset(i as isize) as *mut c_void;
let mut n = n;
// read one byte at a time until s is aligned
while s as usize % mem::size_of::<usize>() != 0 {
if n == 0 {
return ptr::null_mut();
}
if *s == c {
return s as *mut c_void;
}
n -= 1;
s = s.offset(1);
}
let mut s = s as *const usize;
let lowbits = !0 as usize / 255;
let highbits = lowbits * 0x80;
let repeated_c = lowbits * c as usize;
while n >= mem::size_of::<usize>() {
// read multiple bytes at a time
// turn the requested byte into 8 zero bits
let m = *s ^ repeated_c;
// subtracting one from zero flips high bit from 0 to 1
if (m.wrapping_sub(lowbits) & !m & highbits) != 0 {
break;
}
n -= mem::size_of::<usize>();
s = s.offset(1);
}
let mut s = s as *const u8;
while n > 0 {
if *s == c {
return s as *mut c_void;
}
n -= 1;
s = s.offset(1);
}
ptr::null_mut()
}
@@ -126,8 +157,6 @@ pub unsafe extern "C" fn strcpy(s1: *mut c_char, s2: *const c_char) -> *mut c_ch
#[no_mangle]
pub unsafe extern "C" fn strcspn(s1: *const c_char, s2: *const c_char) -> size_t {
use core::mem;
let s1 = s1 as *const u8;
let s2 = s2 as *const u8;
@@ -283,8 +312,6 @@ pub unsafe extern "C" fn strrchr(s: *const c_char, c: c_int) -> *mut c_char {
#[no_mangle]
pub unsafe extern "C" fn strspn(s1: *const c_char, s2: *const c_char) -> size_t {
use core::mem;
let s1 = s1 as *const u8;
let s2 = s2 as *const u8;