At Tue, 15 Nov 2011 11:16:43 +0800, Liu Yuan wrote: > > From: Liu Yuan <tailai.ly at taobao.com> > > These are trivial helper wrappers around standard IO functions > and interger hash function. "stolen" from git and Linux kernel. > > Signed-off-by: Liu Yuan <tailai.ly at taobao.com> > --- > include/util.h | 63 +++++++++++++++++++++++ > sheep/util.c | 150 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > 2 files changed, 213 insertions(+), 0 deletions(-) > create mode 100644 sheep/util.c > > diff --git a/include/util.h b/include/util.h > index 2dccd16..c73a6d5 100644 > --- a/include/util.h > +++ b/include/util.h > @@ -2,6 +2,8 @@ > #define __UTIL_H__ > > #include <string.h> > +#include <limits.h> > +#include <stdint.h> > > #include "bitops.h" > > @@ -53,4 +55,65 @@ static inline void *zalloc(size_t size) > return calloc(1, size); > } > > +typedef void (*try_to_free_t)(size_t); > +extern try_to_free_t set_try_to_free_routine(try_to_free_t); > + > +extern void *xmalloc(size_t size); > +extern void *xzalloc(size_t size); > +extern void *xrealloc(void *ptr, size_t size); > +extern void *xcalloc(size_t nmemb, size_t size); > +extern ssize_t xread(int fd, void *buf, size_t len); > +extern ssize_t xwrite(int fd, const void *buf, size_t len); > + > +/* Integer hash functions, taken from Linux kernel. > + * Use hash_long() to get most out of your cpu. > + */ > + > +/* 2^31 + 2^29 - 2^25 + 2^22 - 2^19 - 2^16 + 1 */ > +#define GOLDEN_RATIO_PRIME_32 0x9e370001UL > +/* 2^63 + 2^61 - 2^57 + 2^54 - 2^51 - 2^18 + 1 */ > +#define GOLDEN_RATIO_PRIME_64 0x9e37fffffffc0001UL > + > +#if __SIZEOF_POINTER__ == 4 > +#define GOLDEN_RATIO_PRIME GOLDEN_RATIO_PRIME_32 > +#define hash_long(val, bits) hash_32(val, bits) > +#elif __SIZEOF_POINTER__ == 8 > +#define hash_long(val, bits) hash_64(val, bits) > +#define GOLDEN_RATIO_PRIME GOLDEN_RATIO_PRIME_64 > +#else > +#error Wordsize not 32 or 64 > +#endif > + > +static inline uint64_t hash_64(uint64_t val, unsigned int bits) > +{ > + uint64_t hash = val; > + > + /* Sigh, gcc can't optimise this alone like it does for 32 bits. */ > + uint64_t n = hash; > + n <<= 18; > + hash -= n; > + n <<= 33; > + hash -= n; > + n <<= 3; > + hash += n; > + n <<= 3; > + hash -= n; > + n <<= 4; > + hash += n; > + n <<= 2; > + hash += n; > + > + /* High bits are more random, so use them. */ > + return hash >> (64 - bits); > +} > + > +static inline uint32_t hash_32(uint32_t val, unsigned int bits) > +{ > + /* On some cpus multiply is faster, on others gcc will do shifts */ > + uint32_t hash = val * GOLDEN_RATIO_PRIME_32; > + > + /* High bits are more random, so use them. */ > + return hash >> (32 - bits); > +} We already have a hash function, fnv_64a_buf(). How about using it instead of introducing new one? Thanks, Kazutaka > + > #endif > diff --git a/sheep/util.c b/sheep/util.c > new file mode 100644 > index 0000000..ebcc1d8 > --- /dev/null > +++ b/sheep/util.c > @@ -0,0 +1,150 @@ > +/* > + * Taken from git and Linux kernel by Liu Yuan <namei.unix at gmail.com> > + * > + * This program is free software; you can redistribute it and/or > + * modify it under the terms of the GNU General Public License version > + * 2 as published by the Free Software Foundation. > + * > + * You should have received a copy of the GNU General Public License > + * along with this program. If not, see <http://www.gnu.org/licenses/>. > + */ > + > +#include <unistd.h> > +#include <errno.h> > +#include <stdlib.h> > + > +#include "util.h" > +#include "logger.h" > + > +static void do_nothing(size_t size) > +{ > +} > + > +static void (*try_to_free_routine)(size_t size) = do_nothing; > + > +try_to_free_t set_try_to_free_routine(try_to_free_t routine) > +{ > + try_to_free_t old = try_to_free_routine; > + if (!routine) > + routine = do_nothing; > + try_to_free_routine = routine; > + return old; > +} > + > +void *xmalloc(size_t size) > +{ > + void *ret = malloc(size); > + if (!ret && !size) > + ret = malloc(1); > + if (!ret) { > + try_to_free_routine(size); > + ret = malloc(size); > + if (!ret && !size) > + ret = malloc(1); > + if (!ret) > + panic("Out of memory"); > + } > + return ret; > +} > + > +void *xzalloc(size_t size) > +{ > + void *ret; > + ret = xmalloc(size); > + memset(ret, 0, size); > + return ret; > +} > + > +void *xrealloc(void *ptr, size_t size) > +{ > + void *ret = realloc(ptr, size); > + if (!ret && !size) > + ret = realloc(ptr, 1); > + if (!ret) { > + try_to_free_routine(size); > + ret = realloc(ptr, size); > + if (!ret && !size) > + ret = realloc(ptr, 1); > + if (!ret) > + panic("Out of memory"); > + } > + return ret; > +} > + > +void *xcalloc(size_t nmemb, size_t size) > +{ > + void *ret = calloc(nmemb, size); > + if (!ret && (!nmemb || !size)) > + ret = calloc(1, 1); > + if (!ret) { > + try_to_free_routine(nmemb * size); > + ret = calloc(nmemb, size); > + if (!ret && (!nmemb || !size)) > + ret = calloc(1, 1); > + if (!ret) > + panic("Out of memory"); > + } > + return ret; > +} > + > +static ssize_t _read(int fd, void *buf, size_t len) > +{ > + ssize_t nr; > + while (1) { > + nr = read(fd, buf, len); > + if ((nr < 0) && (errno == EAGAIN || errno == EINTR)) > + continue; > + return nr; > + } > +} > + > +static ssize_t _write(int fd, const void *buf, size_t len) > +{ > + ssize_t nr; > + while (1) { > + nr = write(fd, buf, len); > + if ((nr < 0) && (errno == EAGAIN || errno == EINTR)) > + continue; > + return nr; > + } > +} > + > +ssize_t xread(int fd, void *buf, size_t count) > +{ > + char *p = buf; > + ssize_t total = 0; > + > + while (count > 0) { > + ssize_t loaded = _read(fd, p, count); > + if (loaded < 0) > + return -1; > + if (loaded == 0) > + return total; > + count -= loaded; > + p += loaded; > + total += loaded; > + } > + > + return total; > +} > + > +ssize_t xwrite(int fd, const void *buf, size_t count) > +{ > + const char *p = buf; > + ssize_t total = 0; > + > + while (count > 0) { > + ssize_t written = _write(fd, p, count); > + if (written < 0) > + return -1; > + if (!written) { > + errno = ENOSPC; > + return -1; > + } > + count -= written; > + p += written; > + total += written; > + } > + > + return total; > +} > -- > 1.7.6.1 > > -- > sheepdog mailing list > sheepdog at lists.wpkg.org > http://lists.wpkg.org/mailman/listinfo/sheepdog |