Search
j0ke.net Open Build Service
>
Projects
>
server:database
:
mongodb
:
2.4
>
mongodb
> mongodb-2.4.11-ppc_patch_based_on_mongo_ibmsoe.patch
Sign Up
|
Log In
Username
Password
Cancel
Overview
Repositories
Revisions
Requests
Users
Advanced
Attributes
Meta
File mongodb-2.4.11-ppc_patch_based_on_mongo_ibmsoe.patch of Package mongodb
From: Michel Normand <normand@linux.vnet.ibm.com> Subject: mongodb_2_4_10_ppc_patch_based_on_mongo_ibmsoe Date: Fri, 06 Feb 2015 17:28:47 +0100 This is a step1 patch (without step2 related to src/third_party/v8-3.14) mongodb_2_4_10_ppc_patch_based_on_mongo_ibmsoe.patch is the git merge of all commits of r2.4.9-ppc branch applied to r2.4.10-ppc branch It has been created as detailed below. TODO: need to check who is pushing upstream the related change of mongo_ibmsoe note: gbr, gco and gta are aliases of git commands * details of actions to create this patch: 1_ clone mongo ibmsoe git tree 2_ identify the commit id 08da87a as base of r2.4.9-ppc branch 3_ update git tree with last changes of mongodb git tree with remote add and fetch commands 4_ identify the commit id e3d7895 associated to 2.4.10 release create a local r2.4.10-ppc on this same id e3d7895 5_ do the git merge of r2.4.9-ppc to r2.4.10-ppc ultimately use git diff command to create the patch === 1_ $git clone https://github.com/ibmsoe/mongo ... === 2_ $gco r2.4.9-ppc $gbr |grep \^\* * r2.4.9-ppc $git rev-list --boundary $(git rev-parse --abbrev-ref HEAD)...master | grep ^- | cut -c2- 08da87aa68a489dab7f24e059916b1ba2aa33452 ... $gta ... | * 3201046 (HEAD, origin/r2.4.9-ppc, origin/HEAD, r2.4.9-ppc) Updated buildin.md ... | * | | 3018a05 SERVER-8914: rename document.scanned metric |/ / / * | | 08da87a SERVER-8880 Visual Studio -- remove /OPT:REF and /OPT:ICF ... | | * 52fe0d2 (tag: r2.4.9) BUMP 2.4.9 | | * 3e3734c post 2.4.9-rc0 === 3_ $git remote add mongodb https://github.com/mongodb/mongo.git $git fetch mongodb $gco v2.4 $gbr | grep \^\* * v2.4 $git merge mongodb/v2.4 === 4_ $gta |grep 2.4.10 | | | * d218cd5 post 2.4.10 | | | * e3d7895 (HEAD, tag: r2.4.10) BUMP 2.4.10 | | | * e8d714a post 2.4.10-rc0 | | | * 6c3b955 (tag: r2.4.10-rc0) BUMP 2.4.10-rc0 | * | | 2e4f101 defensive $gco -b r2.4.10-ppc e3d7895 Switched to a new branch 'r2.4.10-ppc' $gbr |grep 2.4 * r2.4.10-ppc r2.4.9-aixppc r2.4.9-ppc v2.4 v2.4.1 $gta |grep r2.4.10.ppc | | | * e3d7895 (HEAD, tag: r2.4.10, r2.4.10-ppc) BUMP 2.4.10 === 5_ $git merge r2.4.9-ppc $git diff -u --stat r2.4.10 r2.4.10-ppc | grep -v '^[a-z]' \ > /tmp/mongodb_2_4_10_ppc_patch_based_on_mongo_ibmsoe.patch === diff --git a/README b/README index 1d059c6..6e7f5b9 100755 --- a/README +++ b/README @@ -1,3 +1,5 @@ +Porting 2.4.9 for Power Linux + MongoDB README Welcome to MongoDB! diff --git a/SConstruct b/SConstruct index ab01a71..548ce8d 100644 --- a/SConstruct +++ b/SConstruct @@ -149,6 +149,7 @@ add_option( "static-libstdc++" , "statically link libstdc++" , 0 , False ) # base compile flags add_option( "64" , "whether to force 64 bit" , 0 , True , "force64" ) add_option( "32" , "whether to force 32 bit" , 0 , True , "force32" ) +add_option( "31" , "whether to force 31 bit for s390x" , 0 , True , "force31" ) add_option( "cxx", "compiler to use" , 1 , True ) add_option( "cc", "compiler to use for c" , 1 , True ) @@ -259,6 +260,8 @@ windows = False freebsd = False openbsd = False solaris = False +bigendian = True # For snappy +force31 = has_option( "force31" ) force32 = has_option( "force32" ) force64 = has_option( "force64" ) if not force64 and not force32 and os.getcwd().endswith( "mongo-64" ): @@ -551,6 +554,10 @@ elif os.sys.platform.startswith("linux"): if has_option( "static-libstdc++" ): env.Append( LINKFLAGS=" -static-libstdc++ " ) + if os.uname()[4] == "s390x": + env.Prepend(CPPDEFINES=[ "_BIG_ENDIAN=1" ] ) + env.Prepend(CPPDEFINES=[ "__BIG_ENDIAN__=1" ] ) + elif "sunos5" == os.sys.platform: nix = True solaris = True @@ -706,7 +713,6 @@ if nix: "-fno-strict-aliasing", "-ggdb", "-pthread", - "-Wall", "-Wsign-compare", "-Wno-unknown-pragmas", "-Winvalid-pch"] ) @@ -751,6 +757,10 @@ if nix: env.Append( CCFLAGS="-m32" ) env.Append( LINKFLAGS="-m32" ) + if force31: + env.Append( CCFLAGS="-m31" ) + env.Append( LINKFLAGS="-m31" ) + if has_option( "gdbserver" ): env.Append( CPPDEFINES=["USE_GDBSERVER"] ) @@ -872,6 +882,9 @@ def doConfigure(myenv): if not conf.CheckLib("execinfo"): Exit(1) + #hcj added for snappy + Export( "bigendian" ) + # 'tcmalloc' needs to be the last library linked. Please, add new libraries before this # point. if get_option('allocator') == 'tcmalloc': diff --git a/docs/building.md b/docs/building.md index 13aa4f9..db9db93 100644 --- a/docs/building.md +++ b/docs/building.md @@ -36,6 +36,13 @@ COMPILER VERSIONS Mongo has been tested with GCC 4.x and Visual Studio 2008 and 2010. Older versions of GCC may not be happy. +LINUX ON POWER +-------------- + +To build MongoDB for Linux on IBM Power Systems, you need to install v8 separately (it can be downloaded from https://github.com/andrewlow/v8ppc ). Then run the following: + + $ scons all -j4 --sharedclient=SHAREDCLIENT --use-system-tcmalloc --use-system-v8 --prefix=/usr/lib --extrapath=/lib --usev8 --nostrip --ssl --full + WINDOWS -------------- diff --git a/src/mongo/bson/bson-inl.h b/src/mongo/bson/bson-inl.h index dfe7568..fac190b 100644 --- a/src/mongo/bson/bson-inl.h +++ b/src/mongo/bson/bson-inl.h @@ -186,7 +186,7 @@ dodouble: inline BSONObj BSONElement::codeWScopeObject() const { verify( type() == CodeWScope ); - int strSizeWNull = *(int *)( value() + 4 ); + int strSizeWNull = little<int>::ref( value() + 4 ); return BSONObj( value() + 4 + 4 + strSizeWNull ); } @@ -511,15 +511,15 @@ dodouble: break; } case CodeWScope: { - int totalSize = *( int * )( value() ); + int totalSize = little<int>::ref( value() ); massert( 10322 , "Invalid CodeWScope size", totalSize >= 8 ); - int strSizeWNull = *( int * )( value() + 4 ); + int strSizeWNull = little<int>::ref( value() + 4 ); massert( 10323 , "Invalid CodeWScope string size", totalSize >= strSizeWNull + 4 + 4 ); massert( 10324 , "Invalid CodeWScope string size", strSizeWNull > 0 && (strSizeWNull - 1) == mongo::strnlen( codeWScopeCode(), strSizeWNull ) ); massert( 10325 , "Invalid CodeWScope size", totalSize >= strSizeWNull + 4 + 4 + 4 ); - int objSize = *( int * )( value() + 4 + 4 + strSizeWNull ); + int objSize = little<int>::ref( value() + 4 + 4 + strSizeWNull ); massert( 10326 , "Invalid CodeWScope object size", totalSize == 4 + 4 + strSizeWNull + objSize ); // Subobject validation handled elsewhere. } diff --git a/src/mongo/bson/bson_db.h b/src/mongo/bson/bson_db.h index c421816..2cecd5a 100644 --- a/src/mongo/bson/bson_db.h +++ b/src/mongo/bson/bson_db.h @@ -49,7 +49,7 @@ namespace mongo { inline OpTime BSONElement::_opTime() const { if( type() == mongo::Date || type() == Timestamp ) - return OpTime( *reinterpret_cast< const unsigned long long* >( value() ) ); + return OpTime( little<unsigned long long>::ref( value() ) ); return OpTime(); } @@ -59,7 +59,7 @@ namespace mongo { case Code: return std::string(valuestr(), valuestrsize()-1); case CodeWScope: - return std::string(codeWScopeCode(), *(int*)(valuestr())-1); + return std::string(codeWScopeCode(), little<int>::ref(valuestr()) - 1 ); default: log() << "can't convert type: " << (int)(type()) << " to code" << std::endl; } diff --git a/src/mongo/bson/bson_validate.cpp b/src/mongo/bson/bson_validate.cpp index cd88190..3ed02f4 100644 --- a/src/mongo/bson/bson_validate.cpp +++ b/src/mongo/bson/bson_validate.cpp @@ -36,8 +36,11 @@ namespace mongo { if ( ( _position + sizeof(N) ) > _maxLength ) return false; if ( out ) { - const N* temp = reinterpret_cast<const N*>(_buffer + _position); - *out = *temp; +//hcj for little + //const N* temp = reinterpret_cast<const N*>(_buffer + _position); + + const N* temp = (const N*)(_buffer + _position); + *out = little<int>::ref(temp); } _position += sizeof(N); return true; @@ -136,8 +139,8 @@ namespace mongo { Status validateElementInfo(Buffer* buffer, ValidationState::State* nextState) { Status status = Status::OK(); - char type; - if ( !buffer->readNumber<char>(&type) ) + signed char type; + if ( !buffer->readNumber<signed char>(&type) ) return Status( ErrorCodes::InvalidBSON, "invalid bson" ); if ( type == EOO ) { diff --git a/src/mongo/bson/bsonelement.h b/src/mongo/bson/bsonelement.h index f094ab9..f02619d 100644 --- a/src/mongo/bson/bsonelement.h +++ b/src/mongo/bson/bsonelement.h @@ -20,7 +20,7 @@ #include <string.h> // strlen #include <string> #include <vector> - +#include "util/bswap.h" #include "mongo/bson/bsontypes.h" #include "mongo/bson/oid.h" #include "mongo/platform/cstdint.h" @@ -176,7 +176,7 @@ namespace mongo { @see Bool(), trueValue() */ Date_t date() const { - return *reinterpret_cast< const Date_t* >( value() ); + return Date_t( little<unsigned long long>::ref( value() ) ); } /** Convert the value to boolean, regardless of its type, in a javascript-like fashion @@ -191,11 +191,11 @@ namespace mongo { bool isNumber() const; /** Return double value for this field. MUST be NumberDouble type. */ - double _numberDouble() const {return (reinterpret_cast< const PackedDouble* >( value() ))->d; } + double _numberDouble() const {return little<double>::ref( value() ); } /** Return int value for this field. MUST be NumberInt type. */ - int _numberInt() const {return *reinterpret_cast< const int* >( value() ); } + int _numberInt() const {return little<int>::ref( value() ); } /** Return long long value for this field. MUST be NumberLong type. */ - long long _numberLong() const {return *reinterpret_cast< const long long* >( value() ); } + long long _numberLong() const {return little<long long>::ref( value() ); } /** Retrieve int value for the element safely. Zero returned if not a number. */ int numberInt() const; @@ -234,12 +234,12 @@ namespace mongo { @return string size including terminating null */ int valuestrsize() const { - return *reinterpret_cast< const int* >( value() ); + return little<int>::ref( value() ); } // for objects the size *includes* the size of the size field size_t objsize() const { - return static_cast< const size_t >( *reinterpret_cast< const uint32_t* >( value() ) ); + return little<size_t>::ref( value() ); } /** Get a string's value. Also gives you start of the real data for an embedded object. @@ -268,7 +268,7 @@ namespace mongo { * This INCLUDES the null char at the end */ int codeWScopeCodeLen() const { massert( 16178 , "not codeWScope" , type() == CodeWScope ); - return *(int *)( value() + 4 ); + return little<int>::ref( value() + 4); } /** Get the scope SavedContext of a CodeWScope data element. @@ -396,11 +396,11 @@ namespace mongo { } Date_t timestampTime() const { - unsigned long long t = ((unsigned int*)(value() + 4 ))[0]; + unsigned long long t = little<unsigned int>::ref( value() + 4 ); return t * 1000; } unsigned int timestampInc() const { - return ((unsigned int*)(value() ))[0]; + return little<unsigned int>::ref( value() ); } const char * dbrefNS() const { @@ -411,7 +411,7 @@ namespace mongo { const mongo::OID& dbrefOID() const { uassert( 10064 , "not a dbref" , type() == DBRef ); const char * start = value(); - start += 4 + *reinterpret_cast< const int* >( start ); + start += 4 + little<int>::ref( start ); return *reinterpret_cast< const mongo::OID* >( start ); } @@ -483,11 +483,11 @@ namespace mongo { // NOTE Behavior changes must be replicated in Value::coerceToBool(). switch( type() ) { case NumberLong: - return *reinterpret_cast< const long long* >( value() ) != 0; + return little<long long>::ref( value() ) != 0; case NumberDouble: - return (reinterpret_cast < const PackedDouble* >(value ()))->d != 0; + return little<double>::ref( value() ) != 0; case NumberInt: - return *reinterpret_cast< const int* >( value() ) != 0; + return little<int>::ref( value() ) != 0; case mongo::Bool: return boolean(); case EOO: @@ -533,9 +533,9 @@ namespace mongo { case NumberDouble: return _numberDouble(); case NumberInt: - return *reinterpret_cast< const int* >( value() ); + return little<int>::ref( value() ); case NumberLong: - return (double) *reinterpret_cast< const long long* >( value() ); + return little<long long>::ref( value() ); default: return 0; } diff --git a/src/mongo/bson/bsonobj.h b/src/mongo/bson/bsonobj.h index ecf172a..d7b48b4 100644 --- a/src/mongo/bson/bsonobj.h +++ b/src/mongo/bson/bsonobj.h @@ -277,7 +277,7 @@ namespace mongo { return _objdata; } /** @return total size of the BSON object in bytes */ - int objsize() const { return *(reinterpret_cast<const int*>(objdata())); } + int objsize() const { return little<int>::ref(objdata()); } /** performs a cursory check on the object's size only. */ bool isValid() const; @@ -376,8 +376,8 @@ namespace mongo { /** @return A hash code for the object */ int hash() const { unsigned x = 0; - const char *p = objdata(); - for ( int i = 0; i < objsize(); i++ ) + const signed char *p = (signed char*)objdata(); + for ( int i = 0, n = objsize(); i < n; i++ ) x = x * 131 + p[i]; return (x & 0x7fffffff) | 0x8000000; // must be > 0 } diff --git a/src/mongo/bson/bsonobjbuilder.h b/src/mongo/bson/bsonobjbuilder.h index c0c3d0b..2b7aba5 100644 --- a/src/mongo/bson/bsonobjbuilder.h +++ b/src/mongo/bson/bsonobjbuilder.h @@ -108,7 +108,7 @@ namespace mongo { BSONObjBuilder& appendObject(const StringData& fieldName, const char * objdata , int size = 0 ) { verify( objdata ); if ( size == 0 ) { - size = *((int*)objdata); + size = little<int>::ref( objdata ); } verify( size > 4 && size < 100000000 ); @@ -666,7 +666,7 @@ namespace mongo { _b.appendNum((char) EOO); char *data = _b.buf() + _offset; int size = _b.len() - _offset; - *((int*)data) = size; + little<int>::ref( data ) = size; if ( _tracker ) _tracker->got( size ); return data; diff --git a/src/mongo/bson/oid.cpp b/src/mongo/bson/oid.cpp index e96b076..2643212 100644 --- a/src/mongo/bson/oid.cpp +++ b/src/mongo/bson/oid.cpp @@ -58,7 +58,7 @@ namespace mongo { unsigned p = ourPid(); x._pid ^= (unsigned short) p; // when the pid is greater than 16 bits, let the high bits modulate the machine id field. - unsigned short& rest = (unsigned short &) x._machineNumber[1]; + little<unsigned short>& rest = little<unsigned short>::ref (&x._machineNumber[1]); rest ^= p >> 16; } @@ -68,7 +68,7 @@ namespace mongo { // we only call this once per process scoped_ptr<SecureRandom> sr( SecureRandom::create() ); int64_t n = sr->nextInt64(); - OID::MachineAndPid x = ourMachine = reinterpret_cast<OID::MachineAndPid&>(n); + OID::MachineAndPid x = ourMachine = (OID::MachineAndPid&) n; foldInPid(x); return x; } @@ -90,7 +90,7 @@ namespace mongo { x[1] = ourMachineAndPid._machineNumber[1]; x[2] = ourMachineAndPid._machineNumber[2]; x[3] = 0; - return (unsigned&) x[0]; + return little<unsigned>::ref( x ); } void OID::justForked() { @@ -107,37 +107,23 @@ namespace mongo { static AtomicUInt inc = static_cast<unsigned>( scoped_ptr<SecureRandom>(SecureRandom::create())->nextInt64()); - { - unsigned t = (unsigned) time(0); - unsigned char *T = (unsigned char *) &t; - _time[0] = T[3]; // big endian order because we use memcmp() to compare OID's - _time[1] = T[2]; - _time[2] = T[1]; - _time[3] = T[0]; - } + big<unsigned>::ref( _time ) = time( 0 ); _machineAndPid = ourMachineAndPid; { - int new_inc = inc++; - unsigned char *T = (unsigned char *) &new_inc; - _inc[0] = T[2]; - _inc[1] = T[1]; - _inc[2] = T[0]; + // 24 bits big endian + unsigned int new_inc = inc++; + _inc[0] = new_inc >> 16; + _inc[1] = new_inc >> 8; + _inc[2] = new_inc; } } static AtomicUInt64 _initSequential_sequence; void OID::initSequential() { - { - unsigned t = (unsigned) time(0); - unsigned char *T = (unsigned char *) &t; - _time[0] = T[3]; // big endian order because we use memcmp() to compare OID's - _time[1] = T[2]; - _time[2] = T[1]; - _time[3] = T[0]; - } + big<unsigned>::ref( _time ) = time( 0 ); { unsigned long long nextNumber = _initSequential_sequence.fetchAndAdd(1); @@ -159,26 +145,16 @@ namespace mongo { void OID::init(Date_t date, bool max) { int time = (int) (date / 1000); - char* T = (char *) &time; - data[0] = T[3]; - data[1] = T[2]; - data[2] = T[1]; - data[3] = T[0]; - + big<unsigned>::ref( data ) = time; + if (max) - *(long long*)(data + 4) = 0xFFFFFFFFFFFFFFFFll; + little<long long>::ref(data + 4) = 0xFFFFFFFFFFFFFFFFll; else - *(long long*)(data + 4) = 0x0000000000000000ll; + little<long long>::ref(data + 4) = 0x0000000000000000ll; } time_t OID::asTimeT() { - int time; - char* T = (char *) &time; - T[0] = data[3]; - T[1] = data[2]; - T[2] = data[1]; - T[3] = data[0]; - return time; + return big<int>::ref( data ); } const string BSONObjBuilder::numStrs[] = { diff --git a/src/mongo/bson/util/bswap.h b/src/mongo/bson/util/bswap.h new file mode 100644 index 0000000..b372def --- /dev/null +++ b/src/mongo/bson/util/bswap.h @@ -0,0 +1,522 @@ + +#pragma once + +#ifndef MONGO_BSWAP_H +#define MONGO_BSWAP_H + +#include "boost/detail/endian.hpp" +#include "boost/static_assert.hpp" +#include <string.h> + +#ifdef __APPLE__ +# include <libkern/OSByteOrder.h> +#endif + +namespace mongo { + class Nullstream; + + // Generic (portable) byte swap function + template<class T> T byteSwap( T j ) { + +#ifdef HAVE_BSWAP32 + if ( sizeof( T ) == 4 ) { + return __builtin_bswap32( j ); + } +#endif +#ifdef HAVE_BSWAP64 + if ( sizeof( T ) == 8 ) { + return __builtin_bswap64( j ); + } +#endif + + T retVal = 0; + for ( unsigned i = 0; i < sizeof( T ); ++i ) { + + // 7 5 3 1 -1 -3 -5 -7 + int shiftamount = sizeof(T) - 2 * i - 1; + // 56 40 24 8 -8 -24 -40 -56 + shiftamount *= 8; + + // See to it that the masks can be re-used + if ( shiftamount > 0 ) { + T mask = T( 0xff ) << ( 8 * i ); + retVal |= ( (j & mask ) << shiftamount ); + } else { + T mask = T( 0xff ) << ( 8 * (sizeof(T) - i - 1) ); + retVal |= ( j >> -shiftamount ) & mask; + } + } + return retVal; + } + + template<> inline double byteSwap( double j ) { + union { + double d; + unsigned long long l; + } u; + u.d = j; + u.l = byteSwap<unsigned long long>( u.l ); + return u.d; + } + + + // Here we assume that double is big endian if ints are big endian + // and also that the format is the same as for x86 when swapped. + template<class T> inline T littleEndian( T j ) { +#ifdef BOOST_LITTLE_ENDIAN + return j; +#else + return byteSwap<T>(j); +#endif + } + + template<class T> inline T bigEndian( T j ) { +#ifdef BOOST_BIG_ENDIAN + return j; +#else + return byteSwap<T>(j); +#endif + } + +#if defined(__arm__) +# if defined(__MAVERICK__) +# define MONGO_ARM_SPECIAL_ENDIAN + // Floating point is always little endian + template<> inline double littleEndian( double j ) { + return j; + } +# elif defined(__VFP_FP__) || defined( BOOST_BIG_ENDIAN ) + // Native endian floating points even if FPA is used +# else +# define MONGO_ARM_SPECIAL_ENDIAN + // FPA mixed endian floating point format 456701234 + template<> inline double littleEndian( double j ) { + union { double d; unsigned u[2]; } u; + u.d = j; + std::swap( u.u[0], u.u[1] ); + return u.d; + } +# endif +# if defined(MONGO_ARM_SPECIAL_ENDIAN) + template<> inline double bigEndian( double j ) { + return byteSwap<double>( littleEndian<double>( j ) ); + } +# endif +#endif + + + BOOST_STATIC_ASSERT( sizeof( double ) == sizeof( unsigned long long ) ); + + template<class S, class D> inline D convert( S src ) + { + union { S s; D d; } u; + u.s = src; + return u.d; + } + + template<> inline char convert<bool,char>( bool src ) { + return src; + } + + template<> inline bool convert<char, bool>( char src ) { + return src; + } + + +#define MONGO_ENDIAN_BODY( MYTYPE, BASE_TYPE, T ) \ + MYTYPE& operator=( const T& val ) { \ + BASE_TYPE::_val = val; \ + return *this; \ + } \ + \ + operator const T() const { \ + return BASE_TYPE::_val; \ + } \ + \ + MYTYPE& operator+=( T other ) { \ + (*this) = T(*this) + other; \ + return *this; \ + } \ + \ + MYTYPE& operator-=( T other ) { \ + (*this) = T(*this) - other; \ + return *this; \ + } \ + \ + MYTYPE& operator&=( T other ) { \ + (*this) = T(*this) & other; \ + return *this; \ + } \ + \ + MYTYPE& operator|=( T other ) { \ + (*this) = T(*this) | other; \ + return *this; \ + } \ + \ + MYTYPE& operator^=( T other ) { \ + (*this) = T(*this) ^ other; \ + return *this; \ + } \ + \ + MYTYPE& operator++() { \ + return (*this) += 1; \ + } \ + \ + MYTYPE operator++(int) { \ + MYTYPE old = *this; \ + ++(*this); \ + return old; \ + } \ + \ + MYTYPE& operator--() { \ + return (*this) -= 1; \ + } \ + \ + MYTYPE operator--(int) { \ + MYTYPE old = *this; \ + --(*this); \ + return old; \ + } \ + \ + friend std::ostream& operator<<( std::ostream& ost, MYTYPE val ) { \ + return ost << T(val); \ + } \ + \ + friend Nullstream& operator<<( Nullstream& ost, MYTYPE val ) { \ + return ost << T(val); \ + } + + + template<class T, class D> void storeLE( D* dest, T src ) { +#if defined(BOOST_LITTLE_ENDIAN) || !defined( ALIGNMENT_IMPORTANT ) + // This also assumes no alignment issues + *dest = littleEndian<T>( src ); +#else + unsigned char* u_dest = reinterpret_cast<unsigned char*>( dest ); + for ( unsigned i = 0; i < sizeof( T ); ++i ) { + u_dest[i] = src >> ( 8 * i ); + } +#endif + } + + template<class T, class S> T loadLE( const S* data ) { +#ifdef __APPLE__ + switch ( sizeof( T ) ) { + case 8: + return OSReadLittleInt64( data, 0 ); + case 4: + return OSReadLittleInt32( data, 0 ); + case 2: + return OSReadLittleInt16( data, 0 ); + } +#endif + +#if defined(BOOST_LITTLE_ENDIAN) || !defined( ALIGNMENT_IMPORTANT ) +#if defined(__powerpc__) + // Without this trick gcc (4.4.5) compiles 64 bit load to 8 byte loads. + if ( sizeof( T ) == 8 ) { + const unsigned * x = reinterpret_cast<const unsigned*>( data ); + unsigned long long a = loadLE<unsigned, unsigned>( x ); + unsigned long long b = loadLE<unsigned, unsigned>( x + 1 ); + return a | ( b << 32 ); + } +#endif + return littleEndian<T>( *data ); +#else + T retval = 0; + const unsigned char* u_data = reinterpret_cast<const unsigned char*>( data ); + for( unsigned i = 0; i < sizeof( T ); ++i ) { + retval |= T( u_data[i] ) << ( 8 * i ); + } + return retval; +#endif + } + + template<class T, class D> void store_big( D* dest, T src ) { +#if defined(BOOST_BIG_ENDIAN) || !defined( ALIGNMENT_IMPORTANT ) + // This also assumes no alignment issues + *dest = bigEndian<T>( src ); +#else + unsigned char* u_dest = reinterpret_cast<unsigned char*>( dest ); + for ( unsigned i = 0; i < sizeof( T ); ++i ) { + u_dest[ sizeof(T) - 1 - i ] = src >> ( 8 * i ); + } +#endif + } + + template<class T, class S> T load_big( const S* data ) { + + if ( sizeof( T ) == 8 && sizeof( void* ) == 4 ) { + const unsigned * x = reinterpret_cast<const unsigned*>( data ); + unsigned long long a = load_big<unsigned, unsigned>( x ); + unsigned long long b = load_big<unsigned, unsigned>( x + 1 ); + return a << 32 | b; + } + +#if defined(BOOST_BIG_ENDIAN) || !defined( ALIGNMENT_IMPORTANT ) + return bigEndian<T>( *data ); +#else + T retval = 0; + const unsigned char* u_data = reinterpret_cast<const unsigned char*>( data ); + for( unsigned i = 0; i < sizeof( T ); ++i ) { + retval |= T( u_data[ sizeof(T) - 1 - i ] ) << ( 8 * i ); + } + return retval; +#endif + } + + + /** Converts the type to the type to actually store */ + template<typename T> class storage_type { + public: + typedef T t; + + static inline t toStorage( T src ) { return src; } + static inline T fromStorage( t src ) { return src; } + + }; + + template<> class storage_type<bool> { + public: + typedef unsigned char t; + + static inline t toStorage( bool src ) { return src; } + static inline bool fromStorage( t src ) { return src; } + + }; + + template<> class storage_type<double> { + public: + typedef unsigned long long t; + + static inline t toStorage( double src ) { return convert<double,t>( src ); } + static inline double fromStorage( t src ) { + return convert<t,double>( src ); + } + }; + +#pragma pack(1) + +#ifdef __GNUC__ + #define ATTRIB_PACKED __attribute__((packed)) +#else + #define ATTRIB_PACKED +#endif + +#pragma pack(1) + template<class T> struct packed_little_storage { + protected: + typedef storage_type<T> STORAGE; + typedef typename STORAGE::t S; + S _val; + + void store( S val ) { +#ifdef __APPLE__ + switch ( sizeof( S ) ) { + case 8: + return OSWriteLittleInt64( &_val, 0, val ); + case 4: + return OSWriteLittleInt32( &_val, 0, val ); + case 2: + return OSWriteLittleInt16( &_val, 0, val ); + } +#endif + +#if defined(BOOST_LITTLE_ENDIAN) || !defined( ALIGNMENT_IMPORTANT ) + _val = littleEndian<S>( val ); +#else + unsigned char* u_dest = reinterpret_cast<unsigned char*>( &_val ); + for ( unsigned i = 0; i < sizeof( T ); ++i ) { + u_dest[i] = val >> ( 8 * i ); + } +#endif + } + + S load() const { + // Here S should always be an integer type +#ifdef __APPLE__ + switch ( sizeof( S ) ) { + case 8: + return OSReadLittleInt64( &_val, 0 ); + case 4: + return OSReadLittleInt32( &_val, 0 ); + case 2: + return OSReadLittleInt16( &_val, 0 ); + } +#endif + // Without this trick gcc (4.4.5) compiles 64 bit load to 8 byte loads. + // (ppc) + if ( sizeof( S ) == 8 && sizeof( void* ) == 4 ) { + const packed_little_storage<unsigned>* x = + reinterpret_cast<const packed_little_storage<unsigned>* >(this); + + unsigned long long a = x[0]; + unsigned long long b = x[1]; + return a | ( b << 32 ); + } + + +#if defined(BOOST_LITTLE_ENDIAN) || !defined( ALIGNMENT_IMPORTANT ) + return littleEndian<S>( _val ); +#else + S retval = 0; + const unsigned char* u_data = + reinterpret_cast<const unsigned char*>( &_val ); + for( unsigned i = 0; i < sizeof( T ); ++i ) { + retval |= S( u_data[i] ) << ( 8 * i ); + } + return retval; +#endif + } + public: + inline packed_little_storage& operator=( T val ) { + store( STORAGE::toStorage( val ) ); + return *this; + } + + inline operator T() const { + return STORAGE::fromStorage( load() ); + } + + + } ATTRIB_PACKED ; + +#ifdef MONGO_ARM_SPECIAL_ENDIAN + template<> struct packed_little_storage<double> { + private: + double _val; + public: + inline packed_little_storage<double>& operator=( double val ) { + _val = littleEndian<double>( val ); + return *this; + } + + inline operator double() const { + return littleEndian<double>( _val ); + } + } ATTRIB_PACKED ; +#endif + + template<class T> struct packed_big_storage { + private: + typedef typename storage_type<T>::t S; + S _val; + public: + + packed_big_storage& operator=( T val ) { + store_big<S>( &_val, convert<T,S>( val ) ); + return *this; + } + + operator T() const { + return convert<S,T>( load_big<S>( &_val ) ); + } + } ATTRIB_PACKED ; + +#ifdef MONGO_ARM_SPECIAL_ENDIAN + template<> struct packed_big_storage<double> { + private: + double _val; + public: + inline packed_big_storage<double>& operator=( double val ) { + _val = bigEndian<double>( val ); + return *this; + } + + inline operator double() const { + return bigEndian<double>( _val ); + } + } ATTRIB_PACKED; +#endif + + +#pragma pack() + + +#define MONGO_ENDIAN_REF_FUNCS( TYPE ) \ + static TYPE& ref( char* src ) { \ + return *reinterpret_cast<TYPE*>( src ); \ + } \ + \ + static const TYPE& ref( const char* src ) { \ + return *reinterpret_cast<const TYPE*>( src ); \ + } \ + \ + static TYPE& ref( void* src ) { \ + return ref( reinterpret_cast<char*>( src ) ); \ + } \ + \ + static const TYPE& ref( const void* src ) { \ + return ref( reinterpret_cast<const char*>( src ) ); \ + } + + template<class T> class little_pod { + protected: + packed_little_storage<T> _val; + public: + MONGO_ENDIAN_REF_FUNCS( little_pod ); + MONGO_ENDIAN_BODY( little_pod, little_pod<T>, T ); + } ATTRIB_PACKED; + + template<class T> class little : public little_pod<T> { + public: + inline little( T x ) { + *this = x; + } + + inline little() {} + MONGO_ENDIAN_REF_FUNCS( little ); + MONGO_ENDIAN_BODY( little, little_pod<T>, T ); + } ATTRIB_PACKED; + + template<class T> class big_pod { + protected: + packed_big_storage<T> _val; + public: + MONGO_ENDIAN_REF_FUNCS( big_pod ); + MONGO_ENDIAN_BODY( big_pod, big_pod<T>, T ); + } ATTRIB_PACKED; + + template<class T> class big : public big_pod<T> { + public: + inline big( T x ) { + *this = x; + } + + inline big() {} + MONGO_ENDIAN_REF_FUNCS( big ); + MONGO_ENDIAN_BODY( big, big_pod<T>, T ); + } ATTRIB_PACKED; + + // Helper functions + template<class T> T readLE( const void* data ) { + return little<T>::ref( data ); + } + + template<class T> T readBE( const void* data ) { + return big<T>::ref( data ); + } + + template<class T> void copyLE( void* dest, T src ) { + little<T>::ref( dest ) = src; + } + + template<class T> void copyBE( void* dest, T src ) { + big<T>::ref( dest ) = src; + } + + + BOOST_STATIC_ASSERT( sizeof( little_pod<double> ) == 8 ); + BOOST_STATIC_ASSERT( sizeof( little<double> ) == 8 ); + BOOST_STATIC_ASSERT( sizeof( big<bool> ) == 1 ); + BOOST_STATIC_ASSERT( sizeof( little<bool> ) == 1 ); + + /** Marker class to inherit from to mark that endianess has been taken care of */ + struct endian_aware { typedef int endian_aware_t; }; + + /** To assert that a class has the endian aware marker */ + #define STATIC_ASSERT_HAS_ENDIAN_AWARE_MARKER( T ) BOOST_STATIC_ASSERT( sizeof( typename T::endian_aware_t ) > 0 ) + +} + +#endif diff --git a/src/mongo/bson/util/builder.h b/src/mongo/bson/util/builder.h index a66a736..e9a319d 100644 --- a/src/mongo/bson/util/builder.h +++ b/src/mongo/bson/util/builder.h @@ -23,6 +23,7 @@ #include <stdio.h> #include <string> #include <string.h> +#include "bswap.h" #include "mongo/bson/inline_decls.h" #include "mongo/base/string_data.h" @@ -148,35 +149,43 @@ namespace mongo { /* assume ownership of the buffer - you must then free() it */ void decouple() { data = 0; } + private: + /* + * Wrap all primitive types in an endian/alignment insensitive way. + */ + template<class T> void append( T j ) { + little<T>::ref( grow( sizeof( T ) ) ) = j; + } + public: void appendUChar(unsigned char j) { - *((unsigned char*)grow(sizeof(unsigned char))) = j; + append<unsigned char>( j ); } void appendChar(char j) { - *((char*)grow(sizeof(char))) = j; + append<char>( j ); } void appendNum(char j) { - *((char*)grow(sizeof(char))) = j; + append<char>( j ); } void appendNum(short j) { - *((short*)grow(sizeof(short))) = j; + append<short>( j ); } void appendNum(int j) { - *((int*)grow(sizeof(int))) = j; + append<int>( j ); } void appendNum(unsigned j) { - *((unsigned*)grow(sizeof(unsigned))) = j; + append<unsigned>( j ); } void appendNum(bool j) { - *((bool*)grow(sizeof(bool))) = j; + append<char>( j ); } void appendNum(double j) { - (reinterpret_cast< PackedDouble* >(grow(sizeof(double))))->d = j; + append<double>( j ); } void appendNum(long long j) { - *((long long*)grow(sizeof(long long))) = j; + append<long long>( j ); } void appendNum(unsigned long long j) { - *((unsigned long long*)grow(sizeof(unsigned long long))) = j; + append<unsigned long long>( j ); } void appendBuf(const void *src, size_t len) { diff --git a/src/mongo/db/auth/privilege_set.cpp b/src/mongo/db/auth/privilege_set.cpp index c641b65..94d27a1 100644 --- a/src/mongo/db/auth/privilege_set.cpp +++ b/src/mongo/db/auth/privilege_set.cpp @@ -79,7 +79,7 @@ namespace mongo { resourceSearchList[1] = nsToDatabaseSubstring(desiredPrivilege.getResource()); ActionSet unmetRequirements = desiredPrivilege.getActions(); - for (int i = 0; i < boost::size(resourceSearchList); ++i) { + for (unsigned int i = 0; i < boost::size(resourceSearchList); ++i) { ResourcePrivilegeCacheEntry* entry = _lookupEntry(resourceSearchList[i]); if (NULL == entry) continue; diff --git a/src/mongo/db/btree.h b/src/mongo/db/btree.h index 32e0e23..5162152 100644 --- a/src/mongo/db/btree.h +++ b/src/mongo/db/btree.h @@ -88,7 +88,7 @@ namespace mongo { short keyDataOfs() const { return (short) _kdo; } /** Offset within current bucket of the variable width bson key for this _KeyNode. */ - unsigned short _kdo; + little<unsigned short> _kdo; void setKeyDataOfs(short s) { _kdo = s; verify(s>=0); @@ -148,10 +148,10 @@ namespace mongo { /** Given that there are n keys, this is the n index child. */ DiskLoc nextChild; /** can be reused, value is 8192 in current pdfile version Apr2010 */ - unsigned short _wasSize; + little<unsigned short> _wasSize; /** zero */ - unsigned short _reserved1; - int flags; + little<unsigned short> _reserved1; + little<int> flags; void _init() { _reserved1 = 0; @@ -162,13 +162,13 @@ namespace mongo { /** basicInsert() assumes the next three members are consecutive and in this order: */ /** Size of the empty region. */ - int emptySize; + little<int> emptySize; /** Size used for bson storage, including storage of old keys. */ - int topSize; + little<int> topSize; /* Number of keys in the bucket. */ - int n; + little<int> n; - int reserved; + little<int> reserved; /* Beginning of the bucket's body */ char data[4]; @@ -182,16 +182,16 @@ namespace mongo { // largest key size we allow. note we very much need to support bigger keys (somehow) in the future. static const int KeyMax = OldBucketSize / 10; // A sentinel value sometimes used to identify a deallocated bucket. - static const int INVALID_N_SENTINEL = -1; + enum { INVALID_N_SENTINEL = -1 }; }; // a a a ofs ofs ofs ofs class DiskLoc56Bit { - int ofs; + little<int> ofs; unsigned char _a[3]; unsigned long long Z() const { // endian - return *((unsigned long long*)this) & 0x00ffffffffffffffULL; + return little<unsigned long long>::ref(this) & 0x00ffffffffffffffULL; } enum { // first bit of offsets used in _KeyNode we don't use -1 here. @@ -209,10 +209,10 @@ namespace mongo { operator const DiskLoc() const { // endian if( isNull() ) return DiskLoc(); - unsigned a = *((unsigned *) (_a-1)); + unsigned a = little<unsigned>::ref( _a - 1 ); return DiskLoc(a >> 8, ofs); } - int& GETOFS() { return ofs; } + little<int>& GETOFS() { return ofs; } int getOfs() const { return ofs; } bool operator<(const DiskLoc56Bit& rhs) const { // the orderering of dup keys in btrees isn't too critical, but we'd like to put items that are @@ -250,7 +250,8 @@ namespace mongo { la = 0; ofs = OurNullOfs; } - memcpy(_a, &la, 3); // endian + little<int> lila = la; + memcpy(_a, &lila, 3); // endian } DiskLoc56Bit& writing() const { return *((DiskLoc56Bit*) getDur().writingPtr((void*)this, 7)); @@ -275,14 +276,14 @@ namespace mongo { /** Given that there are n keys, this is the n index child. */ Loc nextChild; - unsigned short flags; + little<unsigned short> flags; /** basicInsert() assumes the next three members are consecutive and in this order: */ /** Size of the empty region. */ - unsigned short emptySize; + little<unsigned short> emptySize; /** Size used for bson storage, including storage of old keys. */ - unsigned short topSize; + little<unsigned short> topSize; /* Number of keys in the bucket. */ unsigned short n; diff --git a/src/mongo/db/commands/storage_details.cpp b/src/mongo/db/commands/storage_details.cpp index 9197ce2..3165973 100644 --- a/src/mongo/db/commands/storage_details.cpp +++ b/src/mongo/db/commands/storage_details.cpp @@ -49,12 +49,12 @@ namespace { */ struct AnalyzeParams { // startOfs and endOfs are extent-relative - int startOfs; - int endOfs; - int length; - int numberOfSlices; - int granularity; - int lastSliceLength; + little<int> startOfs; + little<int> endOfs; + little<int> length; + little<int> numberOfSlices; + little<int> granularity; + little<int> lastSliceLength; string characteristicField; bool processDeletedRecords; bool showRecords; @@ -676,7 +676,7 @@ namespace { bool analyzeExtent(const NamespaceDetails* nsd, const Extent* ex, SubCommand subCommand, AnalyzeParams& params, string& errmsg, BSONObjBuilder& outputBuilder) { - params.startOfs = max(0, params.startOfs); + params.startOfs = max((little<int>)0, params.startOfs); params.endOfs = min(params.endOfs, ex->length); params.length = params.endOfs - params.startOfs; if (params.numberOfSlices != 0) { diff --git a/src/mongo/db/curop.h b/src/mongo/db/curop.h index 30d94d2..2d50fe9 100644 --- a/src/mongo/db/curop.h +++ b/src/mongo/db/curop.h @@ -109,7 +109,7 @@ namespace mongo { static BSONObj _tooBig; // { $msg : "query not recording (too large)" } CachedBSONObj() { - _size = (int*)_buf; + _size = &little<int>::ref( _buf ); reset(); } @@ -159,7 +159,7 @@ namespace mongo { void _reset( int sz ) { _size[0] = sz; } mutable SpinLock _lock; - int * _size; + little<int> * _size; char _buf[512]; }; diff --git a/src/mongo/db/db.cpp b/src/mongo/db/db.cpp index 046101a..b4fec43 100644 --- a/src/mongo/db/db.cpp +++ b/src/mongo/db/db.cpp @@ -1289,7 +1289,7 @@ static int mongoDbMain(int argc, char* argv[], char **envp) { { unsigned x = 0x12345678; unsigned char& b = (unsigned char&) x; - if ( b != 0x78 ) { + if ( 0 && b != 0x78 ) { out() << "big endian cpus not yet supported" << endl; return 33; } diff --git a/src/mongo/db/dbmessage.h b/src/mongo/db/dbmessage.h index 50658dd..089efc3 100644 --- a/src/mongo/db/dbmessage.h +++ b/src/mongo/db/dbmessage.h @@ -82,16 +82,16 @@ namespace mongo { #pragma pack(1) struct QueryResult : public MsgData { - long long cursorId; - int startingFrom; - int nReturned; + little<long long> cursorId; + little<int> startingFrom; + little<int> nReturned; const char *data() { - return (char *) (((int *)&nReturned)+1); + return reinterpret_cast<char*>( &nReturned ) + 4; } int resultFlags() { return dataAsInt(); } - int& _resultFlags() { + little<int>& _resultFlags() { return dataAsInt(); } void setResultFlagsToOk() { diff --git a/src/mongo/db/diskloc.h b/src/mongo/db/diskloc.h index 70acc97..d192841 100644 --- a/src/mongo/db/diskloc.h +++ b/src/mongo/db/diskloc.h @@ -42,8 +42,8 @@ namespace mongo { (such as adding a virtual function) */ class DiskLoc { - int _a; // this will be volume, file #, etc. but is a logical value could be anything depending on storage engine - int ofs; + little<int> _a; // this will be volume, file #, etsc. but is a logical value could be anything depending on storage engine + little<int> ofs; public: @@ -94,7 +94,7 @@ namespace mongo { int a() const { return _a; } - int& GETOFS() { return ofs; } + little<int>& GETOFS() { return ofs; } int getOfs() const { return ofs; } void set(int a, int b) { _a=a; diff --git a/src/mongo/db/dur.h b/src/mongo/db/dur.h index 604ed2e..b5ba774 100644 --- a/src/mongo/db/dur.h +++ b/src/mongo/db/dur.h @@ -126,7 +126,7 @@ namespace mongo { inline DiskLoc& writingDiskLoc(DiskLoc& d) { return *((DiskLoc*) writingPtr(&d, sizeof(d))); } /** Declare write intent for an int */ - inline int& writingInt(int& d) { return *static_cast<int*>(writingPtr( &d, sizeof(d))); } + inline little<int>& writingInt( little<int>& d) { return *static_cast<little<int>*>(writingPtr( &d, sizeof(d))); } /** "assume i've already indicated write intent, let me write" redeclaration is fine too, but this is faster. diff --git a/src/mongo/db/dur_journalformat.h b/src/mongo/db/dur_journalformat.h index 10ed848..da9e35c 100644 --- a/src/mongo/db/dur_journalformat.h +++ b/src/mongo/db/dur_journalformat.h @@ -41,7 +41,7 @@ namespace mongo { #else enum { CurrentVersion = 0x4149 }; #endif - unsigned short _version; + little<unsigned short> _version; // these are just for diagnostic ease (make header more useful as plain text) char n1; // '\n' @@ -50,7 +50,7 @@ namespace mongo { char dbpath[128]; // path/filename of this file for human reading and diagnostics. not used by code. char n3, n4; // '\n', '\n' - unsigned long long fileId; // unique identifier that will be in each JSectHeader. important as we recycle prealloced files + little<unsigned long long> fileId; // unique identifier that will be in each JSectHeader. important as we recycle prealloced files char reserved3[8026]; // 8KB total for the file header char txt2[2]; // "\n\n" at the end @@ -65,10 +65,10 @@ namespace mongo { */ struct JSectHeader { private: - unsigned _sectionLen; // unpadded length in bytes of the whole section + little<unsigned> _sectionLen; // unpadded length in bytes of the whole section public: - unsigned long long seqNumber; // sequence number that can be used on recovery to not do too much work - unsigned long long fileId; // matches JHeader::fileId + little<unsigned long long> seqNumber; // sequence number that can be used on recovery to not do too much work + little<unsigned long long> fileId; // matches JHeader::fileId unsigned sectionLen() const { return _sectionLen; } // we store the unpadded length so we can use that when we uncompress. to @@ -94,22 +94,22 @@ namespace mongo { OpCode_Min = 0xfffff000 }; union { - unsigned len; // length in bytes of the data of the JEntry. does not include the JEntry header - OpCodes opcode; + little_pod<unsigned> len; // length in bytes of the data of the JEntry. does not include the JEntry header + little_pod<OpCodes> opcode; }; - unsigned ofs; // offset in file + little<unsigned> ofs; // offset in file // sentinel and masks for _fileNo enum { DotNsSuffix = 0x7fffffff, // ".ns" file LocalDbBit = 0x80000000 // assuming "local" db instead of using the JDbContext }; - int _fileNo; // high bit is set to indicate it should be the <dbpath>/local database + little<int> _fileNo; // high bit is set to indicate it should be the <dbpath>/local database // char data[len] follows const char * srcData() const { - const int *i = &_fileNo; + const little<int> *i = &_fileNo; return (const char *) (i+1); } @@ -133,9 +133,9 @@ namespace mongo { struct JSectFooter { JSectFooter(); JSectFooter(const void* begin, int len); // needs buffer to compute hash - unsigned sentinel; + little<unsigned> sentinel; unsigned char hash[16]; - unsigned long long reserved; + little<unsigned long long> reserved; char magic[4]; // "\n\n\n\n" /** used by recovery to see if buffer is valid @@ -145,23 +145,23 @@ namespace mongo { */ bool checkHash(const void* begin, int len) const; - bool magicOk() const { return *((unsigned*)magic) == 0x0a0a0a0a; } + bool magicOk() const { return little<unsigned>::ref( magic ) == 0x0a0a0a0a; } }; /** declares "the next entry(s) are for this database / file path prefix" */ struct JDbContext { JDbContext() : sentinel(JEntry::OpCode_DbContext) { } - const unsigned sentinel; // compare to JEntry::len -- zero is our sentinel + const little<unsigned> sentinel; // compare to JEntry::len -- zero is our sentinel //char dbname[]; }; /** "last sequence number" */ struct LSNFile { - unsigned ver; - unsigned reserved2; - unsigned long long lsn; - unsigned long long checkbytes; - unsigned long long reserved[8]; + little<unsigned> ver; + little<unsigned> reserved2; + little<unsigned long long> lsn; + little<unsigned long long> checkbytes; + little<unsigned long long> reserved[8]; void set(unsigned long long lsn); unsigned long long get(); diff --git a/src/mongo/db/dur_recover.cpp b/src/mongo/db/dur_recover.cpp index 58dacff..42a7b87 100644 --- a/src/mongo/db/dur_recover.cpp +++ b/src/mongo/db/dur_recover.cpp @@ -593,7 +593,7 @@ namespace mongo { _recover(); // throws on interruption } - struct BufReaderY { int a,b; }; + struct BufReaderY { little<int> a,b; }; class BufReaderUnitTest : public StartupTest { public: void run() { diff --git a/src/mongo/db/extsort.cpp b/src/mongo/db/extsort.cpp index d955acb..3326c38 100644 --- a/src/mongo/db/extsort.cpp +++ b/src/mongo/db/extsort.cpp @@ -329,7 +329,7 @@ namespace mongo { BSONObjExternalSorter::Data BSONObjExternalSorter::FileIterator::next() { // read BSONObj - int size; + little<int> size; verify( _read( reinterpret_cast<char*>(&size), 4 ) ); char* buf = reinterpret_cast<char*>( malloc( sizeof(unsigned) + size ) ); verify( buf ); diff --git a/src/mongo/db/geo/2d.cpp b/src/mongo/db/geo/2d.cpp index e1e21ee..c8d68cc 100644 --- a/src/mongo/db/geo/2d.cpp +++ b/src/mongo/db/geo/2d.cpp @@ -2508,7 +2508,7 @@ namespace mongo { cout << "\t" << h.toString() << "\t" << c.current()[g->_geo] << "\t" << hex << h.getHash() - << "\t" << hex << ((long long*)c.currKey().firstElement().binData(len))[0] + << "\t" << hex << little<long long>::ref( c.currKey().firstElement().binData(len) ) << "\t" << c.current()["_id"] << endl; c.advance(); @@ -2540,6 +2540,7 @@ namespace mongo { BSONObj in = BSON("x" << x << "y" << y); GeoHash h = conv.hash(in); BSONObj out = conv.unhashToBSONObj(h); + verify(round(x) == round(out["x"].number())); verify(round(y) == round(out["y"].number())); verify(round(in["x"].number()) == round(out["x"].number())); diff --git a/src/mongo/db/geo/hash.h b/src/mongo/db/geo/hash.h index ba6a9b3..4a55421 100644 --- a/src/mongo/db/geo/hash.h +++ b/src/mongo/db/geo/hash.h @@ -116,7 +116,7 @@ namespace mongo { void unhash_fast(unsigned *x, unsigned *y) const; void unhash_slow(unsigned *x, unsigned *y) const; - long long _hash; + little<long long> _hash; // Bits per field. Our hash is 64 bits, and we have an X and a Y field, // so this is 1 to 32. unsigned _bits; diff --git a/src/mongo/db/hasher.cpp b/src/mongo/db/hasher.cpp index ae51d87..e7f49bb 100644 --- a/src/mongo/db/hasher.cpp +++ b/src/mongo/db/hasher.cpp @@ -53,7 +53,7 @@ namespace mongo { const BSONElement& e , bool includeFieldName ) { - int canonicalType = e.canonicalType(); + little<int> canonicalType = e.canonicalType(); h->addData( &canonicalType , sizeof( canonicalType ) ); if ( includeFieldName ){ @@ -64,7 +64,7 @@ namespace mongo { //if there are no embedded objects (subobjects or arrays), //compute the hash, squashing numeric types to 64-bit ints if ( e.isNumber() ){ - long long int i = e.safeNumberLong(); //well-defined for troublesome doubles + little<long long int> i = e.safeNumberLong(); //well-defined for troublesome doubles h->addData( &i , sizeof( i ) ); } else { @@ -96,7 +96,15 @@ namespace mongo { void run() { // Hard-coded check to ensure the hash function is consistent across platforms BSONObj o = BSON( "check" << 42 ); - verify( BSONElementHasher::hash64( o.firstElement(), 0 ) == -944302157085130861LL ); + +#ifdef __BIG_ENDIAN__ + long long expected_hash = 0x933f4ef6302ae5f2LL; +#else + long long expected_hash = 0xf2e52a30f64e3f93LL; +#endif + long long result = BSONElementHasher::hash64(o.firstElement(), 0); + + verify( result == expected_hash); } } hasherUnitTest; } diff --git a/src/mongo/db/instance.cpp b/src/mongo/db/instance.cpp index c4fb9f7..1e0e358 100644 --- a/src/mongo/db/instance.cpp +++ b/src/mongo/db/instance.cpp @@ -118,8 +118,8 @@ namespace mongo { // OpTime::now() uses mutex, thus it is in this file not in the cpp files used by drivers and such void BSONElementManipulator::initTimestamp() { - massert( 10332 , "Expected CurrentTime type", _element.type() == Timestamp ); - unsigned long long ×tamp = *( reinterpret_cast< unsigned long long* >( value() ) ); + massert( 10332 , "Expected CurrentTime type", _element.type() == Timestamp ); + little<unsigned long long> ×tamp = little< unsigned long long >::ref( value() ); if ( timestamp == 0 ) { mutex::scoped_lock lk(OpTime::m); timestamp = OpTime::now(lk).asDate(); @@ -127,18 +127,18 @@ namespace mongo { } void BSONElementManipulator::SetNumber(double d) { if ( _element.type() == NumberDouble ) - *getDur().writing( reinterpret_cast< double * >( value() ) ) = d; + *getDur().writing( &little< double >::ref( value() ) ) = d; else if ( _element.type() == NumberInt ) - *getDur().writing( reinterpret_cast< int * >( value() ) ) = (int) d; + *getDur().writing( &little< int >::ref( value() ) ) = (int) d; else verify(0); } void BSONElementManipulator::SetLong(long long n) { verify( _element.type() == NumberLong ); - *getDur().writing( reinterpret_cast< long long * >(value()) ) = n; + *getDur().writing( &little< long long >::ref( value() ) ) = n; } void BSONElementManipulator::SetInt(int n) { verify( _element.type() == NumberInt ); - getDur().writingInt( *reinterpret_cast< int * >( value() ) ) = n; + getDur().writingInt( little< int >::ref( value() ) ) = n; } /* dur:: version */ void BSONElementManipulator::ReplaceTypeAndValue( const BSONElement &e ) { @@ -1039,7 +1039,7 @@ namespace mongo { // uh - oh, not sure there is anything else we can do... } - static void shutdownServer() { + void shutdownServer() { log() << "shutdown: going to close listening sockets..." << endl; ListeningSockets::get()->closeAll(); diff --git a/src/mongo/db/jsobj.cpp b/src/mongo/db/jsobj.cpp index ea3248e..972adaf 100644 --- a/src/mongo/db/jsobj.cpp +++ b/src/mongo/db/jsobj.cpp @@ -179,11 +179,10 @@ namespace mongo { } break; case BinData: { - const int len = *( reinterpret_cast<const int*>( value() ) ); - BinDataType type = BinDataType( *( reinterpret_cast<const unsigned char*>( value() ) + - sizeof( int ) ) ); + int len = little<int>::ref( value() ); + BinDataType type = BinDataType( *reinterpret_cast<const signed char*>( value() + 4 ) ); s << "{ \"$binary\" : \""; - const char *start = reinterpret_cast<const char*>( value() ) + sizeof( int ) + 1; + char *start = ( char * )( value() ) + sizeof( int ) + 1; base64::encode( s , start , len ); s << "\", \"$type\" : \"" << hex; s.width( 2 ); @@ -967,7 +966,7 @@ namespace mongo { name=0; eoo=EOO; } - int totsize; + little<int> totsize; char maxkey; char name; char eoo; @@ -981,7 +980,7 @@ namespace mongo { name=0; eoo=EOO; } - int totsize; + little<int> totsize; char minkey; char name; char eoo; @@ -994,7 +993,7 @@ namespace mongo { totsize = 5; eoo = EOO; } - int totsize; + little<int> totsize; char eoo; } js0; */ diff --git a/src/mongo/db/jsobjmanipulator.h b/src/mongo/db/jsobjmanipulator.h index 0566640..ac605cf 100644 --- a/src/mongo/db/jsobjmanipulator.h +++ b/src/mongo/db/jsobjmanipulator.h @@ -41,19 +41,19 @@ namespace mongo { /** Change the value, in place, of the number. */ void setNumber(double d) { - if ( _element.type() == NumberDouble ) *reinterpret_cast< double * >( value() ) = d; - else if ( _element.type() == NumberInt ) *reinterpret_cast< int * >( value() ) = (int) d; + if ( _element.type() == NumberDouble ) little< double >::ref( value() ) = d; + else if ( _element.type() == NumberInt ) little< int >::ref( value() ) = (int) d; else verify(0); } void SetNumber(double d); void setLong(long long n) { verify( _element.type() == NumberLong ); - *reinterpret_cast< long long * >( value() ) = n; + little< long long >::ref( value() ) = n; } void SetLong(long long n); void setInt(int n) { verify( _element.type() == NumberInt ); - *reinterpret_cast< int * >( value() ) = n; + little< int >::ref( value() ) = n; } void SetInt(int n); diff --git a/src/mongo/db/key.cpp b/src/mongo/db/key.cpp index 3d9eaa7..7a197e2 100644 --- a/src/mongo/db/key.cpp +++ b/src/mongo/db/key.cpp @@ -294,7 +294,7 @@ namespace mongo { } case Date: b.appendUChar(cdate|bits); - b.appendStruct(e.date()); + b.appendNum( ( unsigned long long) e.date()); break; case String: { @@ -402,19 +402,19 @@ namespace mongo { break; } case cdate: - b.appendDate("", (Date_t&) *p); + b.appendDate("", Date_t( little<unsigned long long>::ref( p ) )); p += 8; break; case cdouble: - b.append("", (double&) *p); + b.append("", little<double>::ref( p )); p += sizeof(double); break; case cint: - b.append("", static_cast< int >((reinterpret_cast< const PackedDouble& >(*p)).d)); + b.append("", static_cast< int >( little<double>::ref( p ) ) ); p += sizeof(double); break; case clong: - b.append("", static_cast< long long>((reinterpret_cast< const PackedDouble& >(*p)).d)); + b.append("", static_cast< long long>( little<double>::ref( p ) ) ); p += sizeof(double); break; default: @@ -440,8 +440,8 @@ namespace mongo { switch( lt ) { case cdouble: { - double L = (reinterpret_cast< const PackedDouble* >(l))->d; - double R = (reinterpret_cast< const PackedDouble* >(r))->d; + double L = little<double>::ref( l ); + double R = little<double>::ref( r ); if( L < R ) return -1; if( L != R ) @@ -489,8 +489,8 @@ namespace mongo { } case cdate: { - long long L = *((long long *) l); - long long R = *((long long *) r); + long long L = little<long long>::ref( l ); + long long R = little<long long>::ref( r ); if( L < R ) return -1; if( L > R ) @@ -620,16 +620,16 @@ namespace mongo { l++; r++; switch( lval&cCANONTYPEMASK ) { case coid: - if( *((unsigned*) l) != *((unsigned*) r) ) + if ( little<unsigned>::ref( l ) != little<unsigned>::ref( r ) ) return false; l += 4; r += 4; case cdate: - if( *((unsigned long long *) l) != *((unsigned long long *) r) ) + if ( little<unsigned long long>::ref( l ) != little<unsigned long long>::ref( r ) ) return false; l += 8; r += 8; break; case cdouble: - if( (reinterpret_cast< const PackedDouble* > (l))->d != (reinterpret_cast< const PackedDouble* >(r))->d ) + if ( little<double>::ref( l ) != little<double>::ref( r ) ) return false; l += 8; r += 8; break; diff --git a/src/mongo/db/matcher.cpp b/src/mongo/db/matcher.cpp index 532c18e..c116ccc 100644 --- a/src/mongo/db/matcher.cpp +++ b/src/mongo/db/matcher.cpp @@ -1267,15 +1267,15 @@ namespace mongo { strcpy_s(sval, 10, "123456789"); eoo = EOO; } - unsigned totsize; + little<unsigned> totsize; char n; char nname[5]; - double N; + little<double> N; char s; char sname[7]; - unsigned slen; + little<unsigned> slen; char sval[10]; char eoo; @@ -1294,10 +1294,10 @@ namespace mongo { strcpy_s(sval, 10, "123456789"); eoo = EOO; } - unsigned totsize; + little<unsigned> totsize; char s; char sname[7]; - unsigned slen; + little<unsigned> slen; char sval[10]; char eoo; } js2; diff --git a/src/mongo/db/namespace_details.cpp b/src/mongo/db/namespace_details.cpp index 360e3dd..a113530 100644 --- a/src/mongo/db/namespace_details.cpp +++ b/src/mongo/db/namespace_details.cpp @@ -254,7 +254,7 @@ namespace mongo { Record *r = (Record *) getDur().writingPtr(d, sizeof(Record)); d = &r->asDeleted(); // defensive code: try to make us notice if we reference a deleted record - reinterpret_cast<unsigned*>( r->data() )[0] = 0xeeeeeeee; + little<unsigned>::ref( r->data() ) = 0xeeeeeeee; } DEBUGGING log() << "TEMP: add deleted rec " << dloc.toString() << ' ' << hex << d->extentOfs() << endl; if ( isCapped() ) { @@ -355,7 +355,8 @@ namespace mongo { if ( !isCapped() && NamespaceString::normal( ns ) ) { // we quantize here so that it only impacts newly sized records // this prevents oddities with older records and space re-use SERVER-8435 - lenToAlloc = std::min( r->lengthWithHeaders(), + // hcj have to cast the first one from little<int> to int + lenToAlloc = std::min( (int)r->lengthWithHeaders(), NamespaceDetails::quantizeAllocationSpace( lenToAlloc ) ); left = regionlen - lenToAlloc; diff --git a/src/mongo/db/namespace_details.h b/src/mongo/db/namespace_details.h index 3f38160..debe233 100644 --- a/src/mongo/db/namespace_details.h +++ b/src/mongo/db/namespace_details.h @@ -71,48 +71,48 @@ namespace mongo { // ofs 168 (8 byte aligned) struct Stats { // datasize and nrecords MUST Be adjacent code assumes! - long long datasize; // this includes padding, but not record headers - long long nrecords; + little<long long> datasize; // this includes padding, but not record headers + little<long long> nrecords; } stats; - int lastExtentSize; - int nIndexes; + little<int> lastExtentSize; + little<int> nIndexes; private: // ofs 192 IndexDetails _indexes[NIndexesBase]; // ofs 352 (16 byte aligned) - int _isCapped; // there is wasted space here if I'm right (ERH) - int _maxDocsInCapped; // max # of objects for a capped table, -1 for inf. + little<int> _isCapped; // there is wasted space here if I'm right (ERH) + little<int> _maxDocsInCapped; // max # of objects for a capped table. TODO: should this be 64 bit? - double _paddingFactor; // 1.0 = no padding. + little<double> _paddingFactor; // 1.0 = no padding. // ofs 386 (16) - int _systemFlags; // things that the system sets/cares about + little<int> _systemFlags; // things that the system sets/cares about public: DiskLoc capExtent; // the "current" extent we're writing too for a capped collection DiskLoc capFirstNewRecord; - unsigned short dataFileVersion; // NamespaceDetails version. So we can do backward compatibility in the future. See filever.h - unsigned short indexFileVersion; - unsigned long long multiKeyIndexBits; + little<unsigned short> dataFileVersion; // NamespaceDetails version. So we can do backward compatibility in the future. See filever.h + little<unsigned short> indexFileVersion; + little<unsigned long long> multiKeyIndexBits; private: // ofs 400 (16) - unsigned long long reservedA; - long long extraOffset; // where the $extra info is located (bytes relative to this) + little<unsigned long long> reservedA; + little<long long> extraOffset; // where the $extra info is located (bytes relative to this) public: - int indexBuildsInProgress; // Number of indexes currently being built + little<int> indexBuildsInProgress; // 1 if in prog private: - int _userFlags; + little<int> _userFlags; char reserved[72]; /*-------- end data 496 bytes */ public: explicit NamespaceDetails( const DiskLoc &loc, bool _capped ); class Extra { - long long _next; + little<long long> _next; public: IndexDetails details[NIndexesExtra]; private: - unsigned reserved2; - unsigned reserved3; + little<unsigned> reserved2; + little<unsigned> reserved3; Extra(const Extra&) { verify(false); } Extra& operator=(const Extra& r) { verify(false); return *this; } public: @@ -183,7 +183,7 @@ namespace mongo { /* when a background index build is in progress, we don't count the index in nIndexes until complete, yet need to still use it in _indexRecord() - thus we use this function for that. */ - int getTotalIndexCount() const { return nIndexes + indexBuildsInProgress; } + little<int> getTotalIndexCount() const { return nIndexes + indexBuildsInProgress; } /* NOTE: be careful with flags. are we manipulating them in read locks? if so, this isn't thread safe. TODO @@ -282,7 +282,7 @@ namespace mongo { can pushes this down considerably. further tweaking will be a good idea but this should be an adequate starting point. */ - double N = min(nIndexes,7) + 3; + double N = min( nIndexes + 0, 7 ) + 3; double x = _paddingFactor + (0.001 * N); if ( x <= 2.0 ) { setPaddingFactor( x ); diff --git a/src/mongo/db/oplog.cpp b/src/mongo/db/oplog.cpp index 3399036..14e887d 100644 --- a/src/mongo/db/oplog.cpp +++ b/src/mongo/db/oplog.cpp @@ -132,7 +132,7 @@ namespace mongo { memcpy(p, partial.objdata(), size1); // adjust overall bson object size for the o: field - *(static_cast<unsigned*>(p)) += o.objsize() + 1/*fieldtype byte*/ + 2/*"o" fieldname*/; + little<unsigned>::ref( p ) += o.objsize() + 1/*fieldtype byte*/ + 2/*"o" fieldname*/; char *b = static_cast<char *>(p); b += size1; diff --git a/src/mongo/db/ops/query.cpp b/src/mongo/db/ops/query.cpp index 48a191b..04fcda0 100644 --- a/src/mongo/db/ops/query.cpp +++ b/src/mongo/db/ops/query.cpp @@ -825,7 +825,7 @@ namespace mongo { QueryResult *qr = (QueryResult *) result.header(); qr->cursorId = cursorid; - curop.debug().cursorid = ( cursorid == 0 ? -1 : qr->cursorId ); + curop.debug().cursorid = ( cursorid == 0 ?(little<long long int>)-1 : qr->cursorId ); qr->setResultFlagsToOk(); // qr->len is updated automatically by appendData() curop.debug().responseLength = qr->len; diff --git a/src/mongo/db/pdfile.cpp b/src/mongo/db/pdfile.cpp index aa49b15..0e26041 100644 --- a/src/mongo/db/pdfile.cpp +++ b/src/mongo/db/pdfile.cpp @@ -536,7 +536,7 @@ namespace mongo { massert( 10357 , "shutdown in progress", ! inShutdown() ); massert( 10358 , "bad new extent size", approxSize >= Extent::minSize() && approxSize <= Extent::maxSize() ); massert( 10359 , "header==0 on new extent: 32 bit mmap space exceeded?", header() ); // null if file open failed - int ExtentSize = min(header()->unusedLength, approxSize); + int ExtentSize = min( header()->unusedLength + 0, approxSize ); DiskLoc loc; if ( ExtentSize < Extent::minSize() ) { /* note there could be a lot of looping here is db just started and @@ -672,7 +672,7 @@ namespace mongo { delRecLength = extentLength - Extent::HeaderSize(); if( delRecLength >= 32*1024 && str::contains(ns, '$') && !capped ) { // probably an index. so skip forward to keep its records page aligned - int& ofs = emptyLoc.GETOFS(); + little<int>& ofs = emptyLoc.GETOFS(); int newOfs = (ofs + 0xfff) & ~0xfff; delRecLength -= (newOfs-ofs); dassert( delRecLength > 0 ); @@ -1087,7 +1087,7 @@ namespace mongo { } else { DEV { - unsigned long long *p = reinterpret_cast<unsigned long long *>( todelete->data() ); + little<unsigned long long> *p = &little<unsigned long long >::ref( todelete->data() ); *getDur().writing(p) = 0; //DEV memset(todelete->data, 0, todelete->netLength()); // attempt to notice invalid reuse. } @@ -1657,9 +1657,8 @@ namespace mongo { len = fixedIndexObject.objsize(); } } - IDToInsert idToInsert; // only initialized if needed - + // int addID = 0; // 0 if not adding _id; if adding, the length of that new element if( !god ) { /* Check if we have an _id field. If we don't, we'll add it. Note that btree buckets which we insert aren't BSONObj's, but in that case god==true. @@ -1682,7 +1681,6 @@ namespace mongo { BSONElementManipulator::lookForTimestamps( io ); } - int lenWHdr = d->getRecordAllocationSize( len + Record::HeaderSize ); fassert( 16440, lenWHdr >= ( len + Record::HeaderSize ) ); @@ -1734,26 +1732,23 @@ namespace mongo { DiskLoc real = allocateSpaceForANewRecord(ns, d, lenWHdr, god); verify( real == loc ); } - Record *r = loc.rec(); { verify( r->lengthWithHeaders() >= lenWHdr ); r = (Record*) getDur().writingPtr(r, lenWHdr); if( idToInsert.needed() ) { /* a little effort was made here to avoid a double copy when we add an ID */ - int originalSize = *((int*) obuf); - ((int&)*r->data()) = originalSize + idToInsert.size(); +// int originalSize = *((int*) obuf); + little<int>::ref( r->data() ) = little<int>::ref( obuf ) + idToInsert.size(); memcpy(r->data()+4, idToInsert.rawdata(), idToInsert.size()); - memcpy(r->data()+4+idToInsert.size(), ((char*)obuf)+4, originalSize-4); + memcpy(r->data()+4+idToInsert.size(), ((char *)obuf)+4, little<int>::ref( obuf )-4); } else { if( obuf ) // obuf can be null from internal callers memcpy(r->data(), obuf, len); } } - addRecordToRecListInExtent(r, loc); - /* durability todo : this could be a bit annoying / slow to record constantly */ { NamespaceDetails::Stats *s = getDur().writing(&d->stats); diff --git a/src/mongo/db/pdfile.h b/src/mongo/db/pdfile.h index 67343b6..d84f2e8 100644 --- a/src/mongo/db/pdfile.h +++ b/src/mongo/db/pdfile.h @@ -205,10 +205,10 @@ namespace mongo { public: int lengthWithHeaders() const { _accessing(); return _lengthWithHeaders; } - int& lengthWithHeaders() { _accessing(); return _lengthWithHeaders; } + little<int>& lengthWithHeaders() { _accessing(); return _lengthWithHeaders; } int extentOfs() const { _accessing(); return _extentOfs; } - int& extentOfs() { _accessing(); return _extentOfs; } + little<int>& extentOfs() { _accessing(); return _extentOfs; } // TODO: we need to not const_cast here but problem is DiskLoc::writing DiskLoc& nextDeleted() const { _accessing(); return const_cast<DiskLoc&>(_nextDeleted); } @@ -225,8 +225,8 @@ namespace mongo { void _accessing() const; - int _lengthWithHeaders; - int _extentOfs; + little<int> _lengthWithHeaders; + little<int> _extentOfs; DiskLoc _nextDeleted; }; @@ -246,16 +246,16 @@ namespace mongo { enum HeaderSizeValue { HeaderSize = 16 }; int lengthWithHeaders() const { _accessing(); return _lengthWithHeaders; } - int& lengthWithHeaders() { _accessing(); return _lengthWithHeaders; } + little<int>& lengthWithHeaders() { _accessing(); return _lengthWithHeaders; } int extentOfs() const { _accessing(); return _extentOfs; } - int& extentOfs() { _accessing(); return _extentOfs; } + little<int>& extentOfs() { _accessing(); return _extentOfs; } int nextOfs() const { _accessing(); return _nextOfs; } - int& nextOfs() { _accessing(); return _nextOfs; } + little<int>& nextOfs() { _accessing(); return _nextOfs; } int prevOfs() const { _accessing(); return _prevOfs; } - int& prevOfs() { _accessing(); return _prevOfs; } + little<int>& prevOfs() { _accessing(); return _prevOfs; } const char * data() const { _accessing(); return _data; } char * data() { _accessing(); return _data; } @@ -280,8 +280,8 @@ namespace mongo { } struct NP { - int nextOfs; - int prevOfs; + little<int> nextOfs; + little<int> prevOfs; }; NP* np() { return (NP*) &_nextOfs; } @@ -327,10 +327,10 @@ namespace mongo { */ void _accessing() const; - int _lengthWithHeaders; - int _extentOfs; - int _nextOfs; - int _prevOfs; + little<int> _lengthWithHeaders; + little<int> _extentOfs; + little<int> _nextOfs; + little<int> _prevOfs; /** be careful when referencing this that your write intent was correct */ char _data[4]; @@ -349,7 +349,7 @@ namespace mongo { class Extent { public: enum { extentSignature = 0x41424344 }; - unsigned magic; + little<unsigned> magic; DiskLoc myLoc; DiskLoc xnext, xprev; /* next/prev extent for this namespace */ @@ -358,7 +358,7 @@ namespace mongo { */ Namespace nsDiagnostic; - int length; /* size of the extent, including these fields */ + little<int> length; /* size of the extent, including these fields */ DiskLoc firstRecord; DiskLoc lastRecord; char _extentData[4]; @@ -447,11 +447,11 @@ namespace mongo { */ class DataFileHeader { public: - int version; - int versionMinor; - int fileLength; + little<int> version; + little<int> versionMinor; + little<int> fileLength; DiskLoc unused; /* unused is the portion of the file that doesn't belong to any allocated extents. -1 = no more */ - int unusedLength; + little<int> unusedLength; char reserved[8192 - 4*4 - 8]; char data[4]; // first extent starts here diff --git a/src/mongo/dbtests/basictests.cpp b/src/mongo/dbtests/basictests.cpp index ad3e5db..9ce0427 100644 --- a/src/mongo/dbtests/basictests.cpp +++ b/src/mongo/dbtests/basictests.cpp @@ -28,6 +28,7 @@ #include "../util/stringutils.h" #include "../util/compress.h" #include "../util/time_support.h" +#include "../bson/util/bswap.h" #include "../db/db.h" namespace BasicTests { @@ -311,6 +312,50 @@ namespace BasicTests { } }; + class bswaptest { + public: + + void run() { + { + unsigned long long a = 0x123456789abcdef0ULL; + ASSERT_EQUALS( 0xf0debc9a78563412ULL, byteSwap<unsigned long long>( a ) ); + } + { + const char* a = "0123456789abcdefghijkl"; + ASSERT_EQUALS( 0x3031323334353637ULL, readBE<unsigned long long>( a ) ); + ASSERT_EQUALS( 0x3736353433323130ULL, readLE<unsigned long long>( a ) ); + ASSERT_EQUALS( 0x3132333435363738ULL, readBE<unsigned long long>( a + 1 ) ); + ASSERT_EQUALS( 0x3837363534333231ULL, readLE<unsigned long long>( a + 1 ) ); + ASSERT_EQUALS( 0x30313233U, readBE<unsigned int>( a ) ); + ASSERT_EQUALS( 0x34333231U, readLE<unsigned int>( a + 1 ) ); + ASSERT_EQUALS( 0x34333231U, little<unsigned int>::ref( a + 1 ) ); + } + { + unsigned char a [] = { 0, 0, 0, 0, 0, 0, 0xf0, 0x3f }; + ASSERT_EQUALS( 1.0, readLE<double>( a ) ); + ASSERT_EQUALS( 1.0, little<double>::ref( a ) ); + char b[8]; + copyLE<double>( b, 1.0 ); + ASSERT_EQUALS( 0, memcmp( a, b, 8 ) ); + memset( b, 0xff, 8 ); + little<double>::ref( b ) = 1.0; + ASSERT_EQUALS( 0, memcmp( a, b, 8 ) ); + } + { + unsigned char a [] = { 0x3f, 0xf0, 0, 0, 0, 0, 0, 0 }; + ASSERT_EQUALS( 1.0, readBE<double>( a ) ); + ASSERT_EQUALS( 1.0, big<double>::ref( a ) ); + char b[8]; + copyBE<double>( b, 1.0 ); + ASSERT_EQUALS( 0, memcmp( a, b, 8 ) ); + memset( b, 0xff, 8 ); + big<double>::ref( b ) = 1.0; + ASSERT_EQUALS( 0, memcmp( a, b, 8 ) ); + } + } + + }; + class AssertTests { public: @@ -662,7 +707,7 @@ namespace BasicTests { add< sleeptest >(); add< SleepBackoffTest >(); add< AssertTests >(); - + add< bswaptest >(); add< ArrayTests::basic1 >(); add< DatabaseOwnsNS >(); diff --git a/src/mongo/dbtests/jsobjtests.cpp b/src/mongo/dbtests/jsobjtests.cpp index bb2c582..1e8e155 100644 --- a/src/mongo/dbtests/jsobjtests.cpp +++ b/src/mongo/dbtests/jsobjtests.cpp @@ -1885,7 +1885,7 @@ namespace JsobjTests { { char * crap = (char*)malloc( x.objsize() ); memcpy( crap , x.objdata() , x.objsize() ); - int * foo = (int*)crap; + little<int> * foo = &little<int>::ref( crap ); foo[0] = 123123123; int state = 0; try { diff --git a/src/mongo/dbtests/perftests.cpp b/src/mongo/dbtests/perftests.cpp index 3c7c95c..d76e0f4 100644 --- a/src/mongo/dbtests/perftests.cpp +++ b/src/mongo/dbtests/perftests.cpp @@ -915,7 +915,7 @@ namespace PerfTests { void prep() { { // the checksum code assumes 'standard' rollover on addition overflows. let's check that: - unsigned long long x = 0xffffffffffffffffULL; + little<unsigned long long> x = 0xffffffffffffffffULL; ASSERT( x+2 == 1 ); } diff --git a/src/mongo/platform/atomic_intrinsics_gcc.h b/src/mongo/platform/atomic_intrinsics_gcc.h index f8f96f0..fc415e4 100644 --- a/src/mongo/platform/atomic_intrinsics_gcc.h +++ b/src/mongo/platform/atomic_intrinsics_gcc.h @@ -17,7 +17,7 @@ * Implementation of the AtomicIntrinsics<T>::* operations for IA-32 and AMD64 systems using a * GCC-compatible compiler toolchain. */ - +/* re-implement it on Powerpc--hcj */ #pragma once #include <boost/utility.hpp> @@ -33,36 +33,40 @@ namespace mongo { template <typename T, typename IsTLarge=void> class AtomicIntrinsics { public: - +#if 0 static T compareAndSwap(volatile T* dest, T expected, T newValue) { - - T result; - asm volatile ("lock cmpxchg %[src], %[dest]" - : [dest] "+m" (*dest), - "=a" (result) - : [src] "r" (newValue), - "a" (expected) - : "memory", "cc"); - return result; + T result; + __asm__ __volatile__ ( + "0: lwarx %0, 0, %1\n\t" + " xor. %0, %3, %0\n\t" + " bne 1f\n\t" + " stwcx. %2, 0, %1\n\t" + " bne- 0b\n\t" + " isync\n\t" + "1: " + : "=&r"(result) + : "r"(dest), "r"(newValue), "r"(expected) + : "cr0"); + return result; } - +#else + static T compareAndSwap(volatile T* dest, T expected, T newValue) { + return __sync_val_compare_and_swap(dest, expected, newValue); + } +#endif static T swap(volatile T* dest, T newValue) { - T result = newValue; - // No need for "lock" prefix on "xchg". - asm volatile ("xchg %[r], %[dest]" - : [dest] "+m" (*dest), - [r] "+r" (result) - : - : "memory"); - return result; + T expected; + T actual; + do { + expected = *dest; + actual = compareAndSwap(dest, expected, newValue); + } while (actual != expected); + return actual; } static T load(volatile const T* value) { - asm volatile ("mfence" ::: "memory"); - T result = *value; - asm volatile ("mfence" ::: "memory"); - return result; + return compareAndSwap(const_cast<volatile T*>(value), T(0), T(0)); } static T loadRelaxed(volatile const T* value) { @@ -70,25 +74,29 @@ namespace mongo { } static void store(volatile T* dest, T newValue) { - asm volatile ("mfence" ::: "memory"); - *dest = newValue; - asm volatile ("mfence" ::: "memory"); + swap(dest, newValue); } - +#if 0 static T fetchAndAdd(volatile T* dest, T increment) { - T result = increment; - asm volatile ("lock xadd %[src], %[dest]" - : [dest] "+m" (*dest), - [src] "+r" (result) - : - : "memory", "cc"); - return result; + T expected; + T actual; + do { + expected = load(dest); + actual = compareAndSwap(dest, expected, expected + increment); + } while (actual != expected); + return actual; } +#else + static T fetchAndAdd(volatile T* dest, T increment) { + return __sync_fetch_and_add(dest, increment); + } +#endif private: AtomicIntrinsics(); ~AtomicIntrinsics(); + }; /** @@ -103,31 +111,28 @@ namespace mongo { template <typename T> class AtomicIntrinsics<T, typename boost::disable_if_c<sizeof(T) <= sizeof(void*)>::type> { public: +#if 0 static T compareAndSwap(volatile T* dest, T expected, T newValue) { - T result = expected; - asm volatile ("push %%eax\n" - "push %%ebx\n" - "push %%ecx\n" - "push %%edx\n" - "mov (%%edx), %%ebx\n" - "mov 4(%%edx), %%ecx\n" - "mov (%%edi), %%eax\n" - "mov 4(%%edi), %%edx\n" - "lock cmpxchg8b (%%esi)\n" - "mov %%eax, (%%edi)\n" - "mov %%edx, 4(%%edi)\n" - "pop %%edx\n" - "pop %%ecx\n" - "pop %%ebx\n" - "pop %%eax\n" - : - : "S" (dest), - "D" (&result), - "d" (&newValue) - : "memory", "cc"); - return result; + T result; + __asm__ __volatile__ ( + "0: lwarx %0, 0, %1\n\t" + " xor. %0, %3, %0\n\t" + " bne 1f\n\t" + " stwcx. %2, 0, %1\n\t" + " bne- 0b\n\t" + " isync\n\t" + "1: " + : "=&r"(result) + : "r"(dest), "r"(newValue), "r"(expected) + : "cr0"); + return result; } - +#else + static T compareAndSwap(volatile T* dest, T expected, T newValue) { + T result; + return __sync_val_compare_and_swap(dest, expected, newValue); + } +#endif static T swap(volatile T* dest, T newValue) { T expected; @@ -147,6 +152,7 @@ namespace mongo { swap(dest, newValue); } +#if 0 static T fetchAndAdd(volatile T* dest, T increment) { T expected; @@ -157,6 +163,12 @@ namespace mongo { } while (actual != expected); return actual; } +#else + static T fetchAndAdd(volatile T* dest, T increment) { + + return __sync_fetch_and_add(dest, increment); + } +#endif private: AtomicIntrinsics(); diff --git a/src/mongo/platform/bits.h b/src/mongo/platform/bits.h index 7afc428..b28f186 100644 --- a/src/mongo/platform/bits.h +++ b/src/mongo/platform/bits.h @@ -18,13 +18,14 @@ #pragma once // figure out if we're on a 64 or 32 bit system - +//hcj in else, just make it MONGO_PLATFORM_64 as default since dont know ppc64's true typedef #if defined(__x86_64__) || defined(__amd64__) || defined(_WIN64) #define MONGO_PLATFORM_64 #elif defined(__i386__) || defined(_WIN32) #define MONGO_PLATFORM_32 #else -#error "unknown platform" +//#error "unknown platform" +#define MONGO_PLATFORM_64 #endif namespace mongo { diff --git a/src/mongo/s/chunk.cpp b/src/mongo/s/chunk.cpp index fc58bbc..aa0c111 100644 --- a/src/mongo/s/chunk.cpp +++ b/src/mongo/s/chunk.cpp @@ -1432,6 +1432,7 @@ namespace mongo { for ( unsigned i=0; i<all.size(); i++ ) { for ( unsigned j=i+1; j<all.size(); j++ ) { + //hcj: failed with this assertion, for trial, we comment it out temporarily verify( all[i] < all[j] ); } } diff --git a/src/mongo/s/chunk_version.h b/src/mongo/s/chunk_version.h index 36d5ac1..65655be 100644 --- a/src/mongo/s/chunk_version.h +++ b/src/mongo/s/chunk_version.h @@ -26,8 +26,13 @@ namespace mongo { struct ChunkVersion { union { struct { +#ifdef BOOST_LITTLE_ENDIAN int _minor; int _major; +#else + int _major; + int _minor; +#endif }; unsigned long long _combined; }; diff --git a/src/mongo/tools/tool.cpp b/src/mongo/tools/tool.cpp index 2539e5c..012cf2b 100644 --- a/src/mongo/tools/tool.cpp +++ b/src/mongo/tools/tool.cpp @@ -501,7 +501,7 @@ namespace mongo { size_t amt = fread(buf, 1, 4, file); verify( amt == 4 ); - int size = ((int*)buf)[0]; + int size = little<int>::ref( buf ); uassert( 10264 , str::stream() << "invalid object size: " << size , size < BUF_SIZE ); amt = fread(buf+4, 1, size-4, file); diff --git a/src/mongo/util/alignedbuilder.h b/src/mongo/util/alignedbuilder.h index fb180e5..3e42921 100644 --- a/src/mongo/util/alignedbuilder.h +++ b/src/mongo/util/alignedbuilder.h @@ -52,32 +52,40 @@ namespace mongo { /** if buffer grows pointer no longer valid */ char* cur() { return _p._data + _len; } + private: + /* + * Wrap all primitive types in an endian/alignment insensitive way. + */ + template<class T> void append( T j ) { + little<T>::ref( grow( sizeof( T ) ) ) = j; + } + public: void appendChar(char j) { - *((char*)grow(sizeof(char))) = j; + append<char>( j ); } void appendNum(char j) { - *((char*)grow(sizeof(char))) = j; + append<char>( j ); } void appendNum(short j) { - *((short*)grow(sizeof(short))) = j; + append<short>( j ); } void appendNum(int j) { - *((int*)grow(sizeof(int))) = j; + append<int>( j ); } void appendNum(unsigned j) { - *((unsigned*)grow(sizeof(unsigned))) = j; + append<unsigned>( j ); } void appendNum(bool j) { - *((bool*)grow(sizeof(bool))) = j; + append<char>( j ); } void appendNum(double j) { - *((double*)grow(sizeof(double))) = j; + append<double>( j ); } void appendNum(long long j) { - *((long long*)grow(sizeof(long long))) = j; + append<long long>( j ); } void appendNum(unsigned long long j) { - *((unsigned long long*)grow(sizeof(unsigned long long))) = j; + append<unsigned long long>( j ); } void appendBuf(const void *src, size_t len) { memcpy(grow((unsigned) len), src, len); } diff --git a/src/mongo/util/bufreader.h b/src/mongo/util/bufreader.h index 4cb34f4..573502e 100644 --- a/src/mongo/util/bufreader.h +++ b/src/mongo/util/bufreader.h @@ -18,6 +18,8 @@ #pragma once +#include<boost/type_traits/is_compound.hpp> + namespace mongo { /** helper to read and parse a block of memory @@ -25,7 +27,26 @@ namespace mongo { buffer with which we are working. */ class BufReader : boost::noncopyable { + private: + /** Helper class to determine if the values read should be copied or byteswapped */ + template< typename T, + bool C = boost::is_compound<T>::value > class TypeToRead { + }; + + /** Specialization for reading structs */ + template< typename T > class TypeToRead<T, true> { + public: + typedef T t; + }; + + /** Specialization for reading pods */ + template< typename T> class TypeToRead<T, false> { + public: + typedef little<T> t; + }; public: + + class eof : public std::exception { public: eof() { } @@ -37,9 +58,10 @@ namespace mongo { bool atEof() const { return _pos == _end; } /** read in the object specified, and advance buffer pointer */ - template <typename T> - void read(T &t) { - T* cur = (T*) _pos; + template <typename R> + void read(R &t) { + typedef typename TypeToRead<R>::t T; + T* cur = (T*)_pos; T *next = cur + 1; if( _end < next ) throw eof(); t = *cur; @@ -47,8 +69,9 @@ namespace mongo { } /** verify we can look at t, but do not advance */ - template <typename T> - void peek(T &t) { + template <typename R> + void peek(R &t) { + typedef typename TypeToRead<R>::t T; T* cur = (T*) _pos; T *next = cur + 1; if( _end < next ) throw eof(); diff --git a/src/mongo/util/checksum.h b/src/mongo/util/checksum.h index f8c61d7..4f57537 100644 --- a/src/mongo/util/checksum.h +++ b/src/mongo/util/checksum.h @@ -23,14 +23,14 @@ namespace mongo { struct Checksum { union { unsigned char bytes[16]; - unsigned long long words[2]; + little_pod<unsigned long long> words[2]; }; // if you change this you must bump dur::CurrentVersion void gen(const void *buf, unsigned len) { wassert( ((size_t)buf) % 8 == 0 ); // performance warning unsigned n = len / 8 / 2; - const unsigned long long *p = (const unsigned long long *) buf; + const little<unsigned long long> *p = &little<unsigned long long>::ref( buf ); unsigned long long a = 0; for( unsigned i = 0; i < n; i++ ) { a += (*p ^ i); diff --git a/src/mongo/util/hashtab.h b/src/mongo/util/hashtab.h index e23cf7f..a3470b0 100644 --- a/src/mongo/util/hashtab.h +++ b/src/mongo/util/hashtab.h @@ -40,7 +40,7 @@ namespace mongo { public: const char *name; struct Node { - int hash; + little<int> hash; Key k; Type value; bool inUse() { diff --git a/src/mongo/util/logfile.cpp b/src/mongo/util/logfile.cpp index 9ab57de..28562b2 100644 --- a/src/mongo/util/logfile.cpp +++ b/src/mongo/util/logfile.cpp @@ -26,6 +26,11 @@ #include "mongo/util/startup_test.h" #include "mongo/util/text.h" +#if defined(__powerpc64__) && defined(__BIG_ENDIAN__) +#define PAGESIZE 65536 +#else +#define PAGESIZE 4096 +#endif using namespace mongoutils; @@ -36,16 +41,16 @@ namespace mongo { if( 0 && debug ) { try { LogFile f("logfile_test"); - void *p = malloc(16384); + void *p = malloc(4*PAGESIZE); char *buf = (char*) p; - buf += 4095; + buf += PAGESIZE - 1; buf = (char*) (((size_t)buf)&(~0xfff)); memset(buf, 'z', 8192); - buf[8190] = '\n'; - buf[8191] = 'B'; + buf[2 * PAGESIZE - 2] = '\n'; + buf[2 * PAGESIZE - 1] = 'B'; buf[0] = 'A'; - f.synchronousAppend(buf, 8192); - f.synchronousAppend(buf, 8192); + f.synchronousAppend(buf, 2 * PAGESIZE); + f.synchronousAppend(buf, 2 * PAGESIZE); free(p); } catch(DBException& e ) { @@ -226,7 +231,11 @@ namespace mongo { fassert( 16144, charsToWrite >= 0 ); fassert( 16142, _fd >= 0 ); + +// Disabling alignment test on PPC64 due to a 64kB page size on PPC64 instead of 4kB on x86 +#ifndef __PPC64__ fassert( 16143, reinterpret_cast<ssize_t>( buf ) % g_minOSPageSizeBytes == 0 ); // aligned +#endif #ifdef POSIX_FADV_DONTNEED const off_t pos = lseek(_fd, 0, SEEK_CUR); // doesn't actually seek, just get current position diff --git a/src/mongo/util/net/message.h b/src/mongo/util/net/message.h index dee49f5..f420935 100644 --- a/src/mongo/util/net/message.h +++ b/src/mongo/util/net/message.h @@ -32,7 +32,7 @@ namespace mongo { class MessagingPort; class PiggyBackData; - typedef AtomicUInt MSGID; + typedef unsigned int MSGID; enum Operations { opReply = 1, /* reply. responseTo is set. */ @@ -93,11 +93,11 @@ namespace mongo { /* see http://dochub.mongodb.org/core/mongowireprotocol */ struct MSGHEADER { - int messageLength; // total message size, including this - int requestID; // identifier for this message - int responseTo; // requestID from the original request - // (used in responses from db) - int opCode; + little<int> messageLength; // total message size, including this + little<int> requestID; // identifier for this message + little<int> responseTo; // requestID from the original request + // (used in reponses from db) + little<int> opCode; }; #pragma pack() @@ -108,10 +108,10 @@ namespace mongo { friend class DbMessage; friend class MessagingPort; public: - int len; /* len of the msg, including this field */ - MSGID id; /* request/reply id's match... */ - MSGID responseTo; /* id of the message we are responding to */ - short _operation; + little<int> len; /* len of the msg, including this field */ + little<MSGID> id; /* request/reply id's match... */ + little<MSGID> responseTo; /* id of the message we are responding to */ + little<short> _operation; char _flags; char _version; @@ -124,8 +124,8 @@ namespace mongo { _operation = o; } - int& dataAsInt() { - return *((int *) _data); + little<int>& dataAsInt() { + return little<int>::ref( _data ); } bool valid() { @@ -139,8 +139,7 @@ namespace mongo { long long getCursor() { verify( responseTo > 0 ); verify( _operation == opReply ); - long long * l = (long long *)(_data + 4); - return l[0]; + return little<long long>::ref( _data + 4 ); } int dataLen(); // len without header @@ -282,7 +281,7 @@ namespace mongo { size_t dataLen = len + sizeof(MsgData) - 4; MsgData *d = (MsgData *) malloc(dataLen); memcpy(d->_data, msgdata, len); - d->len = fixEndian(dataLen); + d->len = dataLen; d->setOperation(operation); _setData( d, true ); } diff --git a/src/mongo/util/net/message_port.cpp b/src/mongo/util/net/message_port.cpp index f11b1d7..41ac4b7 100644 --- a/src/mongo/util/net/message_port.cpp +++ b/src/mongo/util/net/message_port.cpp @@ -159,11 +159,10 @@ namespace mongo { try { again: //mmm( log() << "* recv() sock:" << this->sock << endl; ) - int len = -1; - - char *lenbuf = (char *) &len; - int lft = 4; + const int lft = 4; + char lenbuf[lft]; psock->recv( lenbuf, lft ); + int len = little<int>::ref( lenbuf ); if ( len < 16 || len > MaxMessageSizeBytes ) { // messages must be large enough for headers if ( len == -1 ) { diff --git a/src/mongo/util/net/message_port.h b/src/mongo/util/net/message_port.h index 7f9681e..f24e1a1 100644 --- a/src/mongo/util/net/message_port.h +++ b/src/mongo/util/net/message_port.h @@ -24,9 +24,9 @@ namespace mongo { class MessagingPort; class PiggyBackData; - - typedef AtomicUInt MSGID; - +//hcj: for conflict with before +// typedef AtomicUInt MSGID; + typedef unsigned int MSGID; class AbstractMessagingPort : boost::noncopyable { public: AbstractMessagingPort() : tag(0), _connectionId(0) {} diff --git a/src/mongo/util/optime.h b/src/mongo/util/optime.h index 740e7cf..fb97570 100644 --- a/src/mongo/util/optime.h +++ b/src/mongo/util/optime.h @@ -35,8 +35,13 @@ namespace mongo { */ #pragma pack(4) class OpTime { +#ifdef __BIG_ENDIAN__ + unsigned secs; + unsigned i; // ordinal comes first so we can do a single 64 bit compare on little endian +#else unsigned i; // ordinal comes first so we can do a single 64 bit compare on little endian unsigned secs; +#endif static OpTime last; static OpTime skewed(); public: @@ -98,10 +103,18 @@ namespace mongo { bytes of overhead. */ unsigned long long asDate() const { +#ifdef __BIG_ENDIAN__ + return little<unsigned long long>(reinterpret_cast<const unsigned long long*>(&secs)[0]); +#else return reinterpret_cast<const unsigned long long*>(&i)[0]; +#endif } long long asLL() const { +#ifdef __BIG_ENDIAN__ + return little<long long>(reinterpret_cast<const long long*>(&secs)[0]); +#else return reinterpret_cast<const long long*>(&i)[0]; +#endif } bool isNull() const { return secs == 0; } diff --git a/src/mongo/util/processinfo_test.cpp b/src/mongo/util/processinfo_test.cpp index 263e7cc..3b88c57 100644 --- a/src/mongo/util/processinfo_test.cpp +++ b/src/mongo/util/processinfo_test.cpp @@ -19,6 +19,12 @@ #include "mongo/util/processinfo.h" #include "mongo/unittest/unittest.h" +#if defined(__powerpc64__) && defined(__BIG_ENDIAN__) +#define PAGESIZE 65536 +#else +#define PAGESIZE 4096 +#endif + using mongo::ProcessInfo; namespace mongo_test { @@ -39,14 +45,14 @@ namespace mongo_test { TEST(ProcessInfo, BlockInMemoryDoesNotThrowIfSupported) { if (ProcessInfo::blockCheckSupported()) { - static char ptr[4096 * PAGES] = "This needs data to not be in .bss"; + static char ptr[PAGESIZE * PAGES] = "This needs data to not be in .bss"; ProcessInfo::blockInMemory(ptr + ProcessInfo::getPageSize() * 2); } } TEST(ProcessInfo, PagesInMemoryIsSensible) { if (ProcessInfo::blockCheckSupported()) { - static char ptr[4096 * PAGES] = "This needs data to not be in .bss"; + static char ptr[PAGESIZE * PAGES] = "This needs data to not be in .bss"; ptr[(ProcessInfo::getPageSize() * 0) + 1] = 'a'; ptr[(ProcessInfo::getPageSize() * 8) + 1] = 'a'; std::vector<char> result; diff --git a/src/mongo/util/stacktrace.cpp b/src/mongo/util/stacktrace.cpp index c1348a0..f62a3d7 100644 --- a/src/mongo/util/stacktrace.cpp +++ b/src/mongo/util/stacktrace.cpp @@ -312,7 +312,10 @@ namespace mongo { char** backtraceStrings = backtrace_symbols(addresses, addressCount); if (backtraceStrings == NULL) { const int err = errno; - os << "Unable to collect backtrace symbols (" << errnoWithDescription(err) << ")" +/* hcj comment errnoWithDescription out */ +/* os << "Unable to collect backtrace symbols (" << errnoWithDescription(err) << ")" + << std::endl; */ + os << "Unable to collect backtrace symbols" << std::endl; return; } diff --git a/src/third_party/boost/boost/system/error_code.hpp b/src/third_party/boost/boost/system/error_code.hpp index b22775f..db5c833 100644 --- a/src/third_party/boost/boost/system/error_code.hpp +++ b/src/third_party/boost/boost/system/error_code.hpp @@ -211,9 +211,9 @@ namespace boost inline const error_category & get_system_category() { return system_category(); } inline const error_category & get_generic_category() { return generic_category(); } inline const error_category & get_posix_category() { return generic_category(); } - static const error_category & posix_category = generic_category(); - static const error_category & errno_ecat = generic_category(); - static const error_category & native_ecat = system_category(); + // static const error_category & posix_category = generic_category(); + // static const error_category & errno_ecat = generic_category(); + // static const error_category & native_ecat = system_category(); # endif // class error_condition -----------------------------------------------// diff --git a/src/third_party/snappy/SConscript b/src/third_party/snappy/SConscript index 0eb7487..364fa15 100644 --- a/src/third_party/snappy/SConscript +++ b/src/third_party/snappy/SConscript @@ -1,9 +1,13 @@ # -*- mode: python -*- Import("env windows") +Import("bigendian") if not windows: env = env.Clone() env.Append(CCFLAGS=['-Wno-sign-compare', '-Wno-unused-function']) +if bigendian: + env.Append(CPPDEFINES=[ 'WORDS_BIGENDIAN' ]) + env.StaticLibrary('snappy', ['snappy.cc', 'snappy-sinksource.cc']) diff --git a/src/third_party/snappy/snappy-stubs-internal.h b/src/third_party/snappy/snappy-stubs-internal.h index 355a06b..0c2eb1c 100755 --- a/src/third_party/snappy/snappy-stubs-internal.h +++ b/src/third_party/snappy/snappy-stubs-internal.h @@ -179,8 +179,8 @@ class LogMessageVoidify { // Potentially unaligned loads and stores. -#if 1 -//#if defined(__i386__) || defined(__x86_64__) || defined(__powerpc__) || defined(_WIN32) +//#if 1 +#if defined(__i386__) || defined(__x86_64__) || defined(__powerpc__) || defined(_WIN32) #define UNALIGNED_LOAD16(_p) (*reinterpret_cast<const uint16 *>(_p)) #define UNALIGNED_LOAD32(_p) (*reinterpret_cast<const uint32 *>(_p)) @@ -243,8 +243,24 @@ inline void UNALIGNED_STORE64(void *p, uint64 v) { #define bswap_32(x) OSSwapInt32(x) #define bswap_64(x) OSSwapInt64(x) -#else +#elif defined(__linux__) #include <byteswap.h> +#else +inline uint16 bswap_16(uint16 x) { + return (x << 8) | (x >> 8); +} + +inline uint32 bswap_32(uint32 x) { + x = ((x & 0xff00ff00UL) >> 8) | ((x & 0x00ff00ffUL) << 8); + return (x >> 16) | (x << 16); +} + +inline uint64 bswap_64(uint64 x) { + x = ((x & 0xff00ff00ff00ff00ULL) >> 8) | ((x & 0x00ff00ff00ff00ffULL) << 8); + x = ((x & 0xffff0000ffff0000ULL) >> 16) | ((x & 0x0000ffff0000ffffULL) << 16); + return (x >> 32) | (x << 32); +} + #endif #endif // WORDS_BIGENDIAN