diff options
Diffstat (limited to 'lib/libc/string/strlen.c')
-rw-r--r-- | lib/libc/string/strlen.c | 130 |
1 files changed, 0 insertions, 130 deletions
diff --git a/lib/libc/string/strlen.c b/lib/libc/string/strlen.c deleted file mode 100644 index 2bc1f2b..0000000 --- a/lib/libc/string/strlen.c +++ /dev/null @@ -1,130 +0,0 @@ -/*- - * Copyright (c) 2009, 2010 Xin LI <delphij@FreeBSD.org> - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <sys/limits.h> -#include <sys/types.h> -#include <string.h> - -/* - * Portable strlen() for 32-bit and 64-bit systems. - * - * Rationale: it is generally much more efficient to do word length - * operations and avoid branches on modern computer systems, as - * compared to byte-length operations with a lot of branches. - * - * The expression: - * - * ((x - 0x01....01) & ~x & 0x80....80) - * - * would evaluate to a non-zero value iff any of the bytes in the - * original word is zero. - * - * On multi-issue processors, we can divide the above expression into: - * a) (x - 0x01....01) - * b) (~x & 0x80....80) - * c) a & b - * - * Where, a) and b) can be partially computed in parallel. - * - * The algorithm above is found on "Hacker's Delight" by - * Henry S. Warren, Jr. - */ - -/* Magic numbers for the algorithm */ -#if LONG_BIT == 32 -static const unsigned long mask01 = 0x01010101; -static const unsigned long mask80 = 0x80808080; -#elif LONG_BIT == 64 -static const unsigned long mask01 = 0x0101010101010101; -static const unsigned long mask80 = 0x8080808080808080; -#else -#error Unsupported word size -#endif - -#define LONGPTR_MASK (sizeof(long) - 1) - -/* - * Helper macro to return string length if we caught the zero - * byte. - */ -#define testbyte(x) \ - do { \ - if (p[x] == '\0') \ - return (p - str + x); \ - } while (0) - -size_t -strlen(const char *str) -{ - const char *p; - const unsigned long *lp; - long va, vb; - - /* - * Before trying the hard (unaligned byte-by-byte access) way - * to figure out whether there is a nul character, try to see - * if there is a nul character is within this accessible word - * first. - * - * p and (p & ~LONGPTR_MASK) must be equally accessible since - * they always fall in the same memory page, as long as page - * boundaries is integral multiple of word size. - */ - lp = (const unsigned long *)((uintptr_t)str & ~LONGPTR_MASK); - va = (*lp - mask01); - vb = ((~*lp) & mask80); - lp++; - if (va & vb) - /* Check if we have \0 in the first part */ - for (p = str; p < (const char *)lp; p++) - if (*p == '\0') - return (p - str); - - /* Scan the rest of the string using word sized operation */ - for (; ; lp++) { - va = (*lp - mask01); - vb = ((~*lp) & mask80); - if (va & vb) { - p = (const char *)(lp); - testbyte(0); - testbyte(1); - testbyte(2); - testbyte(3); -#if (LONG_BIT >= 64) - testbyte(4); - testbyte(5); - testbyte(6); - testbyte(7); -#endif - } - } - - /* NOTREACHED */ - return (0); -} |