diff options
author | behlendo <behlendo@7e1ea52c-4ff2-0310-8f11-9dd32ca42a1c> | 2008-08-11 22:42:04 +0000 |
---|---|---|
committer | behlendo <behlendo@7e1ea52c-4ff2-0310-8f11-9dd32ca42a1c> | 2008-08-11 22:42:04 +0000 |
commit | b61a6e8bdc5ca52a09ff02a6ce2e92742725f8cc (patch) | |
tree | 5848193e57d72b0287a019e3b2f1734aa4fa7c3c | |
parent | 3d061e9d1092364be132fc3f6c478add94b4e482 (diff) |
Pull in initial 32-bit support patches.
git-svn-id: https://outreach.scidac.gov/svn/spl/trunk@156 7e1ea52c-4ff2-0310-8f11-9dd32ca42a1c
-rw-r--r-- | autoconf/spl-build.m4 | 18 | ||||
-rw-r--r-- | configure.ac | 1 | ||||
-rw-r--r-- | include/sys/atomic.h | 26 | ||||
-rw-r--r-- | include/sys/div64.h | 44 | ||||
-rw-r--r-- | modules/spl/spl-generic.c | 24 |
5 files changed, 112 insertions, 1 deletions
diff --git a/autoconf/spl-build.m4 b/autoconf/spl-build.m4 index e12a2e3eb..33465b6bb 100644 --- a/autoconf/spl-build.m4 +++ b/autoconf/spl-build.m4 @@ -665,3 +665,21 @@ AC_DEFUN([SPL_AC_INODE_I_MUTEX], [ AC_MSG_RESULT(no) ]) ]) + +dnl # +dnl # 2.6.14 API change, +dnl # check whether 'div64_64()' is available +dnl # +AC_DEFUN([SPL_AC_DIV64_64], [ + AC_MSG_CHECKING([whether div64_64() is available]) + SPL_LINUX_TRY_COMPILE([ + #include <asm/div64.h> + ],[ + uint64_t i = div64_64(1ULL, 1ULL); + ],[ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_DIV64_64, 1, [div64_64() is available]) + ],[ + AC_MSG_RESULT(no) + ]) +]) diff --git a/configure.ac b/configure.ac index 74b043b32..f32db79da 100644 --- a/configure.ac +++ b/configure.ac @@ -64,6 +64,7 @@ SPL_AC_UACCESS_HEADER SPL_AC_KMALLOC_NODE SPL_AC_MONOTONIC_CLOCK SPL_AC_INODE_I_MUTEX +SPL_AC_DIV64_64 TOPDIR=`/bin/pwd` diff --git a/include/sys/atomic.h b/include/sys/atomic.h index 7bb915611..cd0eb3b0a 100644 --- a/include/sys/atomic.h +++ b/include/sys/atomic.h @@ -33,6 +33,7 @@ extern "C" { #include <linux/module.h> #include <linux/spinlock.h> +#include <sys/isa_defs.h> /* XXX: Serialize everything through global locks. This is * going to be bad for performance, but for now it's the easiest @@ -133,7 +134,23 @@ atomic_cas_64(volatile uint64_t *target, uint64_t cmp, return rc; } -#if defined(__x86_64__) +static __inline__ uint32_t +atomic_cas_32(volatile uint32_t *target, uint32_t cmp, + uint32_t newval) +{ + uint32_t rc; + + spin_lock(&atomic32_lock); + rc = *target; + if (*target == cmp) + *target = newval; + + spin_unlock(&atomic32_lock); + + return rc; +} + +#ifdef _LP64 /* XXX: Implement atomic_cas_ptr() in terms of uint64'ts. This * is of course only safe and correct for 64 bit arches... but * for now I'm OK with that. @@ -144,6 +161,13 @@ atomic_cas_ptr(volatile void *target, void *cmp, void *newval) return (void *)atomic_cas_64((volatile uint64_t *)target, (uint64_t)cmp, (uint64_t)newval); } +#else +static __inline__ void * +atomic_cas_ptr(volatile void *target, void *cmp, void *newval) +{ + return (void *)atomic_cas_32((volatile uint32_t *)target, + (uint32_t)cmp, (uint32_t)newval); +} #endif #ifdef __cplusplus diff --git a/include/sys/div64.h b/include/sys/div64.h new file mode 100644 index 000000000..cb62cd3c5 --- /dev/null +++ b/include/sys/div64.h @@ -0,0 +1,44 @@ +/* + * This file is part of the SPL: Solaris Porting Layer. + * + * Copyright (c) 2008 Sun Microsystems, Inc. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This 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 General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef _SPL_DIV64_H +#define _SPL_DIV64_H + +#include <asm/div64.h> + +#ifndef HAVE_DIV64_64 +#if BITS_PER_LONG == 32 + +extern uint64_t spl_div64_64(uint64_t dividend, uint64_t divisor); +#define div64_64(a,b) spl_div64_64(a,b) + +#else /* BITS_PER_LONG == 32 */ + +static inline uint64_t div64_64(uint64_t dividend, uint64_t divisor) +{ + return dividend / divisor; +} + +#endif /* BITS_PER_LONG == 32 */ +#endif /* HAVE_DIV64_64 */ + +#define roundup64(x, y) (div64_64((x) + ((y) - 1), (y)) * (y)) + +#endif /* _SPL_DIV64_H */ diff --git a/modules/spl/spl-generic.c b/modules/spl/spl-generic.c index 7a818add8..afaefb6b4 100644 --- a/modules/spl/spl-generic.c +++ b/modules/spl/spl-generic.c @@ -87,6 +87,30 @@ highbit(unsigned long i) } EXPORT_SYMBOL(highbit); +/* + * Implementation of div64_64(), for kernels that don't have it. + * + * Taken from a 2.6.24 kernel. + */ +uint64_t spl_div64_64(uint64_t dividend, uint64_t divisor) +{ + uint32_t high, d; + + high = divisor >> 32; + if (high) { + unsigned int shift = fls(high); + + d = divisor >> shift; + dividend >>= shift; + } else + d = divisor; + + do_div(dividend, d); + + return dividend; +} +EXPORT_SYMBOL(spl_div64_64); + int ddi_strtoul(const char *str, char **nptr, int base, unsigned long *result) { |