/************************************************************************************************* * System-dependent configurations of Tokyo Cabinet * Copyright (C) 2006-2012 FAL Labs * Copyright (C) 2012-2015 Softmotions Ltd * This file is part of Tokyo Cabinet. * Tokyo Cabinet 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 any later version. Tokyo Cabinet 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 Tokyo * Cabinet; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307 USA. *************************************************************************************************/ #ifndef _MYCONF_H // duplication check #define _MYCONF_H #if ( (defined(__clang__) && ((__clang_major__ - 0) * 100 + (__clang_minor__ - 0)) < 302) || \ (!defined(__clang__) && defined(__GNUC__) && ((__GNUC__ - 0) * 100 + (__GNUC_MINOR__ - 0)) < 402) || \ (!defined(__GNUC__) && !defined(__clang__)) ) #error You are using an unsupported compiler! EJDB has only been tested with Clang >= 3.2 and GCC >= 4.2 #endif #include "basedefs.h" /************************************************************************************************* * system discrimination *************************************************************************************************/ #if defined(__linux__) #define _SYS_LINUX_ #define TCSYSNAME "Linux" #elif defined(__FreeBSD__) #define _SYS_FREEBSD_ #define TCSYSNAME "FreeBSD" #elif defined(__NetBSD__) #define _SYS_NETBSD_ #define TCSYSNAME "NetBSD" #elif defined(__OpenBSD__) #define _SYS_OPENBSD_ #define TCSYSNAME "OpenBSD" #elif defined(__sun__) || defined(__sun) #define _SYS_SUNOS_ #define TCSYSNAME "SunOS" #elif defined(__hpux) #define _SYS_HPUX_ #define TCSYSNAME "HP-UX" #elif defined(__osf) #define _SYS_TRU64_ #define TCSYSNAME "Tru64" #elif defined(_AIX) #define _SYS_AIX_ #define TCSYSNAME "AIX" #elif defined(__APPLE__) && defined(__MACH__) #define _SYS_MACOSX_ #define TCSYSNAME "Mac OS X" #elif defined(_MSC_VER) #define _SYS_MSVC_ #define TCSYSNAME "Windows (VC++)" #elif defined(_WIN32) #define _SYS_MINGW_ #define TCSYSNAME "Windows (MinGW)" #elif defined(__CYGWIN__) #define _SYS_CYGWIN_ #define TCSYSNAME "Windows (Cygwin)" #else #define _SYS_GENERIC_ #define TCSYSNAME "Generic" #endif /* String containing the version information. */ extern EJDB_EXPORT const char *tcversion; /************************************************************************************************* * common settings *************************************************************************************************/ #if defined(NDEBUG) #define TCDODEBUG(TC_expr) \ do { \ } while(false) #else #define TCDODEBUG(TC_expr) \ do { \ TC_expr; \ } while(false) #endif #define TCSWAB16(TC_num) \ ( \ ((TC_num & 0x00ffU) << 8) | \ ((TC_num & 0xff00U) >> 8) \ ) #define TCSWAB32(TC_num) \ ( \ ((TC_num & 0x000000ffUL) << 24) | \ ((TC_num & 0x0000ff00UL) << 8) | \ ((TC_num & 0x00ff0000UL) >> 8) | \ ((TC_num & 0xff000000UL) >> 24) \ ) #define TCSWAB64(TC_num) \ ( \ ((TC_num & 0x00000000000000ffULL) << 56) | \ ((TC_num & 0x000000000000ff00ULL) << 40) | \ ((TC_num & 0x0000000000ff0000ULL) << 24) | \ ((TC_num & 0x00000000ff000000ULL) << 8) | \ ((TC_num & 0x000000ff00000000ULL) >> 8) | \ ((TC_num & 0x0000ff0000000000ULL) >> 24) | \ ((TC_num & 0x00ff000000000000ULL) >> 40) | \ ((TC_num & 0xff00000000000000ULL) >> 56) \ ) #if defined(_MYBIGEND) || defined(_MYSWAB) #define TCBIGEND 1 #define TCHTOIS(TC_num) TCSWAB16(TC_num) #define TCHTOIL(TC_num) TCSWAB32(TC_num) #define TCHTOILL(TC_num) TCSWAB64(TC_num) #define TCITOHS(TC_num) TCSWAB16(TC_num) #define TCITOHL(TC_num) TCSWAB32(TC_num) #define TCITOHLL(TC_num) TCSWAB64(TC_num) #else #define TCBIGEND 0 #define TCHTOIS(TC_num) (TC_num) #define TCHTOIL(TC_num) (TC_num) #define TCHTOILL(TC_num) (TC_num) #define TCITOHS(TC_num) (TC_num) #define TCITOHL(TC_num) (TC_num) #define TCITOHLL(TC_num) (TC_num) #endif #if defined(_MYNOUBC) || defined(__hppa__) #define TCUBCACHE 0 #elif defined(_SYS_LINUX_) || defined(_SYS_FREEBSD_) || defined(_SYS_NETBSD_) || \ defined(_SYS_MACOSX_) || defined(_SYS_SUNOS_) || defined(_WIN32) #define TCUBCACHE 1 #else #define TCUBCACHE 0 #endif #if defined(_MYNOZLIB) #define TCUSEZLIB 0 #else #define TCUSEZLIB 1 #endif #if defined(_MYBZIP) #define TCUSEBZIP 1 #else #define TCUSEBZIP 0 #endif #if defined(_MYEXLZMA) #define TCUSEEXLZMA 1 #else #define TCUSEEXLZMA 0 #endif #if defined(_MYEXLZO) #define TCUSEEXLZO 1 #else #define TCUSEEXLZO 0 #endif #if defined(_MYMICROYIELD) #define TCMICROYIELD 1 #else #define TCMICROYIELD 0 #endif #define MYMALLOC malloc #define MYCALLOC calloc #define MYREALLOC realloc #define MYFREE free /************************************************************************************************* * general headers *************************************************************************************************/ #ifdef _WIN32 #include #include "win32/platform.h" #define GET_STDOUT_HANDLE() GetStdHandle(STD_OUTPUT_HANDLE) #define GET_STDERR_HANDLE() GetStdHandle(STD_ERROR_HANDLE) #define GET_STDIN_HANDLE() GetStdHandle(STD_INPUT_HANDLE) #define CLOSEFH(_fd) (CloseHandle(_fd)) #else #if defined(__unix) || defined(__APPLE__) #include "nix/platform.h" #endif #include #include #include #include #include #include #define GET_STDOUT_HANDLE() (1) #define GET_STDERR_HANDLE() (2) #define GET_STDIN_HANDLE() (0) #define CLOSEFH(_fd) (closefd(_fd)) #define sysconf_SC_CLK_TCK sysconf(_SC_CLK_TCK) #endif #define CLOSEFH2(_fd) \ do { \ CLOSEFH(_fd); \ (_fd) = INVALID_HANDLE_VALUE; \ } while(0) #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #if defined(_POSIX_PRIORITY_SCHEDULING) #include #endif /************************************************************************************************* * miscellaneous hacks *************************************************************************************************/ #if defined(__GNUC__) #define _alignof(TC_a) ((size_t)__alignof__(TC_a)) #else #define _alignof(TC_a) sizeof(TC_a) #endif #define _issigned(TC_a) ((TC_a)-1 < 1 ? true : false) #define _maxof(TC_a) \ ((TC_a)(sizeof(TC_a) == sizeof(int64_t) ? _issigned(TC_a) ? INT64_MAX : UINT64_MAX : \ sizeof(TC_a) == sizeof(int32_t) ? _issigned(TC_a) ? INT32_MAX : UINT32_MAX : \ sizeof(TC_a) == sizeof(int16_t) ? _issigned(TC_a) ? INT16_MAX : UINT16_MAX : \ _issigned(TC_a) ? INT8_MAX : UINT8_MAX)) #if defined(_SYS_FREEBSD_) || defined(_SYS_NETBSD_) || defined(_SYS_OPENBSD_) #define nan(TC_a) strtod("nan", NULL) #define nanl(TC_a) ((long double)strtod("nan", NULL)) #endif #if ! defined(PATH_MAX) #if defined(MAXPATHLEN) #define PATH_MAX MAXPATHLEN #else #define PATH_MAX 4096 #endif #endif #if ! defined(NAME_MAX) #define NAME_MAX 255 #endif extern int _tc_dummy_cnt; int _tc_dummyfunc(void); int _tc_dummyfuncv(int a, ...); /* MAX and MIN are defined in a really funky place in Solaris. */ #ifndef MIN #define MIN(a, b) ((a) < (b) ? (a) : (b)) #endif #ifndef MAX #define MAX(a, b) ((a) > (b) ? (a) : (b)) #endif /************************************************************************************************* * notation of filesystems *************************************************************************************************/ #ifdef _WIN32 #define MYPATHCHR '\\' #define MYPATHSTR "\\" #else #define MYPATHCHR '/' #define MYPATHSTR "/" #endif #define MYEXTCHR '.' #define MYEXTSTR "." #define MYCDIRSTR "." #define MYPDIRSTR ".." /************************************************************************************************* * for ZLIB *************************************************************************************************/ enum { _TCZMZLIB, _TCZMRAW, _TCZMGZIP }; EJDB_EXPORT extern char *(*_tc_deflate)(const char *, int, int *, int); EJDB_EXPORT extern char *(*_tc_inflate)(const char *, int, int *, int); EJDB_EXPORT extern unsigned int (*_tc_getcrc)(const char *, int); /************************************************************************************************* * for BZIP2 *************************************************************************************************/ EJDB_EXPORT extern char *(*_tc_bzcompress)(const char *, int, int *); EJDB_EXPORT extern char *(*_tc_bzdecompress)(const char *, int, int *); /************************************************************************************************* * for test of custom codec functions *************************************************************************************************/ EJDB_EXPORT void *_tc_recencode(const void *ptr, int size, int *sp, void *op); EJDB_EXPORT void *_tc_recdecode(const void *ptr, int size, int *sp, void *op); #if TCMICROYIELD #define TCTESTYIELD() \ do { \ if(((++_tc_dummy_cnt) & (0x20 - 1)) == 0){ \ sched_yield(); \ if(_tc_dummy_cnt > 0x1000) _tc_dummy_cnt = (uint32_t)time(NULL) % 0x1000; \ } \ } while(false) #undef assert #define assert(TC_expr) \ do { \ if(!(TC_expr)){ \ fprintf(stderr, "assertion failed: %s\n", #TC_expr); \ abort(); \ } \ TCTESTYIELD(); \ } while(false) #define if(TC_cond) \ if((((++_tc_dummy_cnt) & (0x100 - 1)) != 0 || (sched_yield() * 0) == 0) && (TC_cond)) #define while(TC_cond) \ while((((++_tc_dummy_cnt) & (0x100 - 1)) != 0 || (sched_yield() * 0) == 0) && (TC_cond)) #else #define TCTESTYIELD() \ do { \ } while(false) #endif #ifndef _POSIX_PRIORITY_SCHEDULING #define sched_yield() usleep(1000 * 20) #endif /************************************************************************************************* * utilities for implementation *************************************************************************************************/ #define TCNUMBUFSIZ 32 // size of a buffer for a number /* set a buffer for a variable length number */ #define TCSETVNUMBUF(TC_len, TC_buf, TC_num) \ do { \ int _TC_num = (TC_num); \ if(_TC_num == 0){ \ ((signed char *)(TC_buf))[0] = 0; \ (TC_len) = 1; \ } else { \ (TC_len) = 0; \ while(_TC_num > 0){ \ int _TC_rem = _TC_num & 0x7f; \ _TC_num >>= 7; \ if(_TC_num > 0){ \ ((signed char *)(TC_buf))[(TC_len)] = -_TC_rem - 1; \ } else { \ ((signed char *)(TC_buf))[(TC_len)] = _TC_rem; \ } \ (TC_len)++; \ } \ } \ } while(false) /* set a buffer for a variable length number of 64-bit */ #define TCSETVNUMBUF64(TC_len, TC_buf, TC_num) \ do { \ long long int _TC_num = (TC_num); \ if(_TC_num == 0){ \ ((signed char *)(TC_buf))[0] = 0; \ (TC_len) = 1; \ } else { \ (TC_len) = 0; \ while(_TC_num > 0){ \ int _TC_rem = _TC_num & 0x7f; \ _TC_num >>= 7; \ if(_TC_num > 0){ \ ((signed char *)(TC_buf))[(TC_len)] = -_TC_rem - 1; \ } else { \ ((signed char *)(TC_buf))[(TC_len)] = _TC_rem; \ } \ (TC_len)++; \ } \ } \ } while(false) /* read a variable length buffer */ #define TCREADVNUMBUF(TC_buf, TC_num, TC_step) \ do { \ TC_num = 0; \ int _TC_base = 1; \ int _TC_i = 0; \ while(true){ \ if(((signed char *)(TC_buf))[_TC_i] >= 0){ \ TC_num += ((signed char *)(TC_buf))[_TC_i] * _TC_base; \ break; \ } \ TC_num += _TC_base * (((signed char *)(TC_buf))[_TC_i] + 1) * -1; \ _TC_base <<= 7; \ _TC_i++; \ } \ (TC_step) = _TC_i + 1; \ } while(false) /* read a variable length buffer */ #define TCREADVNUMBUF64(TC_buf, TC_num, TC_step) \ do { \ TC_num = 0; \ long long int _TC_base = 1; \ int _TC_i = 0; \ while(true){ \ if(((signed char *)(TC_buf))[_TC_i] >= 0){ \ TC_num += ((signed char *)(TC_buf))[_TC_i] * _TC_base; \ break; \ } \ TC_num += _TC_base * (((signed char *)(TC_buf))[_TC_i] + 1) * -1; \ _TC_base <<= 7; \ _TC_i++; \ } \ (TC_step) = _TC_i + 1; \ } while(false) /* calculate the size of a buffer for a variable length number */ #define TCCALCVNUMSIZE(TC_num) \ ((TC_num) < 0x80 ? 1 : (TC_num) < 0x4000 ? 2 : (TC_num) < 0x200000 ? 3 : \ (TC_num) < 0x10000000 ? 4 : 5) #define TCCMPLEXICAL(TC_rv, TC_aptr, TC_asiz, TC_bptr, TC_bsiz) \ do { \ (TC_rv) = 0; \ int _TC_min = (TC_asiz) < (TC_bsiz) ? (TC_asiz) : (TC_bsiz); \ for(int _TC_i = 0; _TC_i < _TC_min; _TC_i++){ \ if(((unsigned char *)(TC_aptr))[_TC_i] != ((unsigned char *)(TC_bptr))[_TC_i]){ \ (TC_rv) = ((unsigned char *)(TC_aptr))[_TC_i] - ((unsigned char *)(TC_bptr))[_TC_i]; \ break; \ } \ } \ if((TC_rv) == 0) (TC_rv) = (TC_asiz) - (TC_bsiz); \ } while(false) /************************************************************************************************* * atomics *************************************************************************************************/ #ifndef __has_builtin #define __has_builtin(x) 0 #endif #define TCAS(ptr, expected, desired) __sync_bool_compare_and_swap(ptr, expected, desired) #if !defined(__GNUC__) || \ ((__GNUC__ - 0) * 100 + (__GNUC_MINOR__ - 0)) < 407 || \ defined(__INTEL_COMPILER) || defined(__clang__) #if !__has_builtin(__atomic_load_n) //todo review! #define _TC_HAVE_ATOMICS 0 #define __atomic_load_n(ptr,order) *(ptr) #else #define _TC_HAVE_ATOMICS 1 #endif #if !__has_builtin(__atomic_store_n) #define __atomic_store_n(ptr,val,order) (*(ptr) = (val), (void)0) #endif #if !__has_builtin(__atomic_exchange_n) #define __atomic_exchange_n(ptr,val,order) __sync_lock_test_and_set(ptr, val) #endif #if !__has_builtin(__atomic_compare_exchange_n) #define __atomic_compare_exchange_n(ptr,expected,desired,weak,order1,order2) \ __sync_bool_compare_and_swap(ptr, *(expected), desired) ? 1 : \ (*(expected) = *(ptr), 0) #endif #if !__has_builtin(__atomic_add_fetch) #define __atomic_add_fetch(ptr,val,order) __sync_add_and_fetch(ptr, val) #endif #if !__has_builtin(__atomic_sub_fetch) #define __atomic_sub_fetch(ptr,val,order) __sync_sub_and_fetch(ptr, val) #endif #if !__has_builtin(__atomic_or_fetch) #define __atomic_or_fetch(ptr,val,order) __sync_or_and_fetch(ptr, val) #endif #if !__has_builtin(__atomic_and_fetch) #define __atomic_and_fetch(ptr,val,order) __sync_and_and_fetch(ptr, val) #endif #if !__has_builtin(__atomic_xor_fetch) #define __atomic_xor_fetch(ptr,val,order) __sync_xor_and_fetch(ptr, val) #endif #if !__has_builtin(__atomic_nand_fetch) #define __atomic_nand_fetch(ptr,val,order) __sync_nand_and_fetch(ptr, val) #endif #if !__has_builtin(__atomic_fetch_add) #define __atomic_fetch_add(ptr,val,order) __sync_fetch_and_add(ptr, val) #endif #if !__has_builtin(__atomic_fetch_sub) #define __atomic_fetch_sub(ptr,val,order) __sync_fetch_and_sub(ptr, val) #endif #if !__has_builtin(__atomic_fetch_or) #define __atomic_fetch_or(ptr,val,order) __sync_fetch_and_or(ptr, val) #endif #if !__has_builtin(__atomic_fetch_and) #define __atomic_fetch_and(ptr,val,order) __sync_fetch_and_and(ptr, val) #endif #if !__has_builtin(__atomic_fetch_xor) #define __atomic_fetch_xor(ptr,val,order) __sync_fetch_and_xor(ptr, val) #endif #if !__has_builtin(__atomic_fetch_nand) #define __atomic_fetch_nand(ptr,val,order) __sync_fetch_and_nand(ptr, val) #endif #else // EOF !defined(__GNUC__) || ((__GNUC__ - 0) * 100 + (__GNUC_MINOR__ - 0)) < ... #define _TC_HAVE_ATOMICS 1 #endif #if (_TC_HAVE_ATOMICS == 1) //checking for 64bit atomics support #if defined(__mips__) #if (_MIPS_SIM == _ABIO32 || _MIPS_SIM == _ABIN32) #define _TC_HAVE_ATOMICS64 0 #else #define _TC_HAVE_ATOMICS64 1 #endif #elif (defined(_LP64) || defined(__LP64__)) //todo review? #define _TC_HAVE_ATOMICS64 1 #else #define _TC_HAVE_ATOMICS64 0 #endif #else #define _TC_HAVE_ATOMICS64 0 #endif #if (_TC_HAVE_ATOMICS64 == 0) #define __atomic_load_n64(ptr,order) *(ptr) #define __atomic_store_n64(ptr,val,order) (*(ptr) = (val), (void)0) #else #define __atomic_load_n64(ptr,order) __atomic_load_n(ptr,order) #define __atomic_store_n64(ptr,val,order) __atomic_store_n(ptr,val,order) #endif #endif // duplication check // END OF FILE