Merge pull request #116 from matijaskala/patch-1
Add optimized version of memchr
This commit is contained in:
+35
-8
@@ -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;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user