[Pal] Simplify memset and clean up other string ops

This commit is contained in:
Michał Kowalczyk
2020-07-23 19:48:15 +02:00
parent 13bd8c6e85
commit bdcf29ba33
6 changed files with 69 additions and 167 deletions
-5
View File
@@ -19,10 +19,6 @@ cJSON - MIT
uthash - BSD revised
A number of files taken from other C libraries:
* musl - MIT
** Pal/lib/string/memcmp.c
** Pal/lib/string/memcpy.c
** Pal/lib/string/strcmp.c
* glibc - LGPL
** clone, sysdeps.h (and variants) used in code
** Pal/src/host/Linux/clone-x86_64.S
@@ -33,7 +29,6 @@ A number of files taken from other C libraries:
** Pal/include/sysdeps/generic/sysdep.h
** Pal/lib/network/hton.c
** Pal/lib/string/atoi.c
** Pal/lib/string/memset.c
** Pal/lib/string/strchr.c
** Pal/lib/string/strlen.c
** Pal/src/dynamic_link.h, do-rel.h , dl-machine-x86_64.h
+12 -12
View File
@@ -103,28 +103,28 @@ typedef ptrdiff_t ssize_t;
#define __UNUSED(x) do { (void)(x); } while (0)
#define static_strlen(str) (ARRAY_SIZE(FORCE_LITERAL_CSTR(str)) - 1)
/* Libc functions */
/* LibC functions */
/* Libc String functions string.h/stdlib.h */
size_t strnlen (const char *str, size_t maxlen);
size_t strlen (const char *str);
/* LibC string functions */
size_t strnlen(const char* str, size_t maxlen);
size_t strlen(const char* str);
int strcmp(const char* a, const char* b);
long strtol (const char *s, char **endptr, int base);
int atoi (const char *nptr);
long int atol (const char *nptr);
long strtol(const char* s, char** endptr, int base);
int atoi(const char* nptr);
long int atol(const char* nptr);
char* strchr(const char* s, int c_in);
char* strstr(const char* haystack, const char* needle);
void * memcpy (void *dstpp, const void *srcpp, size_t len);
void * memmove (void *dstpp, const void *srcpp, size_t len);
void * memset (void *dstpp, int c, size_t len);
int memcmp (const void *s1, const void *s2, size_t len);
void* memcpy(void* restrict dest, const void* restrict src, size_t count);
void* memmove(void* dest, const void* src, size_t count);
void* memset(void* dest, int ch, size_t count);
int memcmp(const void* lhs, const void* rhs, size_t count);
bool strendswith(const char* haystack, const char* needle);
/* Libc memory allocation functions. stdlib.h. */
/* Libc memory allocation functions */
void *malloc(size_t size);
void free(void *ptr);
void *calloc(size_t nmemb, size_t size);
+13 -21
View File
@@ -1,24 +1,16 @@
/* SPDX-License-Identifier: LGPL-3.0-or-later */
#include <stdint.h>
#include "api.h"
/* Copyright © 2005-2014 Rich Felker, et al. */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* musl 1.1.24 */
int memcmp(const void* vl, const void* vr, size_t n) {
const unsigned char* l=vl;
const unsigned char* r=vr;
for (; n && *l == *r; n--, l++, r++)
/*nop*/;
return n ? *l - *r : 0;
int memcmp(const void* lhs, const void* rhs, size_t count) {
const unsigned char* l = lhs;
const unsigned char* r = rhs;
while (count && *l == *r) {
count--;
l++;
r++;
}
return count ? *l - *r : 0;
}
+17 -30
View File
@@ -1,22 +1,11 @@
/* SPDX-License-Identifier: LGPL-3.0-or-later */
#include <stdint.h>
#include "api.h"
/* Copyright © 2005-2014 Rich Felker, et al. */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* heavily based on musl 1.1.15/1.1.24 */
void* memcpy(void* restrict dst, const void* restrict src, size_t n) {
char* d = dst;
void* memcpy(void* restrict dest, const void* restrict src, size_t count) {
char* d = dest;
#if defined(__x86_64__)
/* "Beginning with processors based on Intel microarchitecture code name Ivy Bridge, REP string
* operation using MOVSB and STOSB can provide both flexible and high-performance REP string
@@ -26,33 +15,31 @@ void* memcpy(void* restrict dst, const void* restrict src, size_t n) {
* memcpy() is heavily used in Linux-SGX PAL to copy data in/out of SGX enclave. Experiments
* with Redis 5.0 show perf improvement of using "rep movsb" at 3-5% for 4KB payloads over
* previous implementation taken from Glibc 2.23. */
__asm__ volatile("rep movsb" : "+D" (d) : "c"(n), "S"(src) : "cc", "memory");
__asm__ volatile("rep movsb" : "+&D"(d), "+&c"(count) : "S"(src) : "cc", "memory");
#else
const char* s = src;
for (; n; n--)
while (count--)
*d++ = *s++;
#endif
return dst;
return dest;
}
void* memmove(void* dst, const void* src, size_t n) {
char* d = dst;
void* memmove(void* dest, const void* src, size_t count) {
char* d = dest;
const char* s = src;
if (d == s)
return d;
if (s + n <= d || d + n <= s)
return memcpy(d, s, n);
if (s + count <= d || d + count <= s)
return memcpy(d, s, count);
if (d < s) {
for (; n; n--)
while (count--)
*d++ = *s++;
} else {
while (n) {
n--;
d[n] = s[n];
}
while (count--)
d[count] = s[count];
}
return dst;
return dest;
}
+19 -80
View File
@@ -1,85 +1,24 @@
/* Copyright (C) 1991,1993,1995,1997,1998,2003,2004
Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Torbjorn Granlund (tege@sics.se).
/* SPDX-License-Identifier: LGPL-3.0-or-later */
/* Copyright (C) 2020 Invisible Things Lab
* Michał Kowalczyk <mkow@invisiblethingslab.com>
*/
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
#include <stdint.h>
#include "api.h"
#define op_t unsigned long int
#define OPSIZ (sizeof(op_t))
typedef unsigned char byte;
void* memset(void* dstpp, int c, size_t len) {
long int dstp = (long int)dstpp;
if (len >= 8) {
int xlen;
op_t cccc;
cccc = (unsigned char)c;
cccc |= cccc << 8;
cccc |= cccc << 16;
if (OPSIZ > 4) {
/* Do the shift in two steps to avoid warning if long has 32 bits. */
cccc |= (cccc << 16) << 16;
}
/* There are at least some bytes to set.
No need to test for LEN == 0 in this alignment loop. */
while (dstp % OPSIZ != 0) {
((byte*)dstp)[0] = c;
dstp += 1;
len -= 1;
}
/* Write 8 `op_t' per iteration until less than 8 `op_t' remain. */
xlen = len / (OPSIZ * 8);
while (xlen > 0) {
((op_t*)dstp)[0] = cccc;
((op_t*)dstp)[1] = cccc;
((op_t*)dstp)[2] = cccc;
((op_t*)dstp)[3] = cccc;
((op_t*)dstp)[4] = cccc;
((op_t*)dstp)[5] = cccc;
((op_t*)dstp)[6] = cccc;
((op_t*)dstp)[7] = cccc;
dstp += 8 * OPSIZ;
xlen -= 1;
}
len %= OPSIZ * 8;
/* Write 1 `op_t' per iteration until less than OPSIZ bytes remain. */
xlen = len / OPSIZ;
while (xlen > 0) {
((op_t*)dstp)[0] = cccc;
dstp += OPSIZ;
xlen -= 1;
}
len %= OPSIZ;
}
/* Write the last few bytes. */
while (len > 0) {
((byte*)dstp)[0] = c;
dstp += 1;
len -= 1;
}
return dstpp;
void* memset(void* dest, int ch, size_t count) {
char* d = dest;
#if defined(__x86_64__)
/* "Beginning with processors based on Intel microarchitecture code name Ivy Bridge, REP string
* operation using MOVSB and STOSB can provide both flexible and high-performance REP string
* operations for software in common situations like memory copy and set operations"
* Intel 64 and IA-32 Architectures Optimization Reference Manual
*/
__asm__ volatile("rep stosb" : "+&D"(d), "+&c"(count) : "a"((uint8_t)ch) : "cc", "memory");
#else
while (count--)
*d++ = ch;
#endif
return dest;
}
+8 -19
View File
@@ -1,22 +1,11 @@
/* SPDX-License-Identifier: LGPL-3.0-or-later */
#include "api.h"
/* Copyright © 2005-2014 Rich Felker, et al. */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* musl 1.1.24 */
int strcmp(const char* l, const char* r) {
for (; *l == *r && *l; l++, r++)
;
return *(unsigned char*)l - *(unsigned char*)r;
int strcmp(const char* lhs, const char* rhs) {
while (*lhs == *rhs && *lhs) {
lhs++;
rhs++;
}
return *(unsigned char*)lhs - *(unsigned char*)rhs;
}