w_base.cpp

00001 /* -*- mode:C++; c-basic-offset:4 -*-
00002      Shore-MT -- Multi-threaded port of the SHORE storage manager
00003    
00004                        Copyright (c) 2007-2009
00005       Data Intensive Applications and Systems Labaratory (DIAS)
00006                Ecole Polytechnique Federale de Lausanne
00007    
00008                          All Rights Reserved.
00009    
00010    Permission to use, copy, modify and distribute this software and
00011    its documentation is hereby granted, provided that both the
00012    copyright notice and this permission notice appear in all copies of
00013    the software, derivative works or modified versions, and any
00014    portions thereof, and that both notices appear in supporting
00015    documentation.
00016    
00017    This code is distributed in the hope that it will be useful, but
00018    WITHOUT ANY WARRANTY; without even the implied warranty of
00019    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS
00020    DISCLAIM ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER
00021    RESULTING FROM THE USE OF THIS SOFTWARE.
00022 */
00023 
00024 /*<std-header orig-src='shore'>
00025 
00026  $Id: w_base.cpp,v 1.58 2012/01/02 17:02:13 nhall Exp $
00027 
00028 SHORE -- Scalable Heterogeneous Object REpository
00029 
00030 Copyright (c) 1994-99 Computer Sciences Department, University of
00031                       Wisconsin -- Madison
00032 All Rights Reserved.
00033 
00034 Permission to use, copy, modify and distribute this software and its
00035 documentation is hereby granted, provided that both the copyright
00036 notice and this permission notice appear in all copies of the
00037 software, derivative works or modified versions, and any portions
00038 thereof, and that both notices appear in supporting documentation.
00039 
00040 THE AUTHORS AND THE COMPUTER SCIENCES DEPARTMENT OF THE UNIVERSITY
00041 OF WISCONSIN - MADISON ALLOW FREE USE OF THIS SOFTWARE IN ITS
00042 "AS IS" CONDITION, AND THEY DISCLAIM ANY LIABILITY OF ANY KIND
00043 FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
00044 
00045 This software was developed with support by the Advanced Research
00046 Project Agency, ARPA order number 018 (formerly 8230), monitored by
00047 the U.S. Army Research Laboratory under contract DAAB07-91-C-Q518.
00048 Further funding for this work was provided by DARPA through
00049 Rome Research Laboratory Contract No. F30602-97-2-0247.
00050 
00051 */
00052 
00053 #include "w_defines.h"
00054 
00055 /*  -- do not edit anything above this line --   </std-header>*/
00056 
00057 #ifdef __GNUG__
00058 #pragma implementation "w_base.h"
00059 #endif
00060 
00061 #include <w_base.h>
00062 #include <sstream>
00063 
00064 /*--------------------------------------------------------------*
00065  *  constants for w_base_t                                      *
00066  *--------------------------------------------------------------*/
00067 const w_base_t::int1_t    w_base_t::int1_max  = 0x7f;
00068 const w_base_t::int1_t    w_base_t::int1_min  = (w_base_t::int1_t) 0x80u;
00069 const w_base_t::uint1_t   w_base_t::uint1_max = 0xff;
00070 const w_base_t::uint1_t   w_base_t::uint1_min = 0x0;
00071 const w_base_t::int2_t    w_base_t::int2_max  = 0x7fff;
00072 const w_base_t::int2_t    w_base_t::int2_min  = (w_base_t::int2_t) 0x8000u;
00073 const w_base_t::uint2_t   w_base_t::uint2_max = 0xffff;
00074 const w_base_t::uint2_t   w_base_t::uint2_min = 0x0;
00075 const w_base_t::int4_t    w_base_t::int4_max  = 0x7fffffff;
00076 const w_base_t::int4_t    w_base_t::int4_min  = 0x80000000;
00077 const w_base_t::uint4_t   w_base_t::uint4_max = 0xffffffff;
00078 const w_base_t::uint4_t   w_base_t::uint4_min = 0x0;
00079 
00080 #    define LONGLONGCONSTANT(i) i##LL
00081 #    define ULONGLONGCONSTANT(i) i##ULL
00082 
00083 #ifdef ARCH_LP64
00084 
00085 const w_base_t::uint8_t   w_base_t::uint8_max =
00086                 ULONGLONGCONSTANT(0xffffffffffffffff);
00087 const w_base_t::uint8_t   w_base_t::uint8_min =
00088                 ULONGLONGCONSTANT(0x0);
00089 const w_base_t::int8_t   w_base_t::int8_max =
00090                 LONGLONGCONSTANT(0x7fffffffffffffff);
00091 const w_base_t::int8_t   w_base_t::int8_min =
00092                 LONGLONGCONSTANT(0x8000000000000000);
00093 #else
00094 
00095 const w_base_t::uint8_t   w_base_t::uint8_max =
00096                 ULONGLONGCONSTANT(0xffffffff);
00097 const w_base_t::uint8_t   w_base_t::uint8_min =
00098                 ULONGLONGCONSTANT(0x0);
00099 const w_base_t::int8_t   w_base_t::int8_max =
00100                 LONGLONGCONSTANT(0x7fffffff);
00101 const w_base_t::int8_t   w_base_t::int8_min =
00102                 LONGLONGCONSTANT(0x80000000);
00103 #endif
00104 
00105 ostream&
00106 operator<<(ostream& o, const w_base_t&)
00107 {
00108     w_base_t::assert_failed("w_base::operator<<() called", __FILE__, __LINE__);
00109     return o;
00110 }
00111 
00112 void
00113 w_base_t::assert_failed(
00114     const char*        desc,
00115     const char*        file,
00116     uint4_t        line)
00117 {
00118     stringstream os;
00119     /* make the error look something like an RC in the meantime. */
00120     os << "assertion failure: " << desc << endl
00121         << "1. error in "
00122         << file << ':' << line
00123         << " Assertion failed" << endl
00124         << "\tcalled from:" << endl
00125         << "\t0) " << file << ':' << line
00126         << endl << ends;
00127     fprintf(stderr, "%s", os.str().c_str());
00128     abort();
00129 }
00130 
00131 
00132 typedef ios::fmtflags  fmtflags;
00133 
00134 #include <w_strstream.h>
00135 
00136 /* name is local to this file */
00137 static w_base_t::uint8_t    
00138 __strtou8(        
00139     const char *str,
00140     char **endptr,
00141     int     base,
00142     bool  is_signed
00143 )
00144 {
00145 #if defined(ARCH_LP64)
00146     return is_signed? strtol(str, endptr, base): strtoul(str, endptr, base);
00147 #else
00148     return is_signed? strtoll(str, endptr, base): strtoull(str, endptr, base);
00149 #endif
00150 }
00151 
00152 w_base_t::int8_t    
00153 w_base_t::strtoi8(
00154     const char *str,
00155     char **endptr,
00156     int     base
00157 )
00158 {
00159     w_base_t::int8_t    i8;
00160     w_base_t::int8_t    u8 =
00161         __strtou8(str, endptr, base, true);
00162     i8 = w_base_t::int8_t(u8);
00163     return i8;
00164 }
00165 
00166 w_base_t::uint8_t    
00167 w_base_t::strtou8(
00168     const char *str,
00169     char **endptr,
00170     int     base
00171 )
00172 {
00173     return __strtou8(str, endptr, base, false);
00174 }
00175 
00176 #if defined(SOLARIS2)
00177 #include <ieeefp.h>
00178 #else
00179 #include <cmath>
00180 #endif
00181 
00182 bool
00183 w_base_t::is_finite(const f8_t x)
00184 {
00185     bool value = false;
00186     value = finite(x);
00187     return value;
00188 }
00189 
00190 bool
00191 w_base_t::is_infinite(const f8_t x)
00192 {
00193     bool value = false;
00194 #if defined(SOLARIS2)
00195     value = !finite(x) && !isnand(x);
00196 #elif defined(MacOSX) && W_GCC_THIS_VER >= W_GCC_VER(3,0)
00197     value = !finite(x) && !__isnand(x);
00198 #else
00199     value = !finite(x) && !isnan(x);
00200 #endif
00201     return value;
00202 }
00203 
00204 bool
00205 w_base_t::is_nan(const f8_t x)
00206 {
00207     bool value = false;
00208 #if defined(SOLARIS2)
00209     value = isnand(x);
00210 #elif defined(MacOSX) && W_GCC_THIS_VER >= W_GCC_VER(3,0)
00211     value = __isnand(x);
00212 #else
00213     value = isnan(x);
00214 #endif
00215     return value;
00216 }
00217 
00218 bool
00219 w_base_t::is_infinite_or_nan(const f8_t x)
00220 {
00221     bool value = false;
00222     value = !finite(x);
00223     return value;
00224 }
00225 
00226 
00227 void    w_base_t::abort()
00228 {
00229     cout.flush();
00230     cerr.flush();
00231     ::abort();
00232 }
00233 
00234 
00235 /* Provide our own pure_virtual() so we can generate abort's if
00236    a virtual function is abused.  Name choice is somewhat
00237    hacky, since it is system and compiler dependent. */
00238 
00239 #ifdef __GNUG__
00240 #define    PURE_VIRTUAL    extern "C" void __pure_virtual()
00241 #else
00242 #define    PURE_VIRTUAL    void pure_virtual()
00243 #endif
00244 
00245 PURE_VIRTUAL
00246 {
00247     /* Just in case the iostreams generate another error ... */
00248     static    bool    called = false;
00249     if (!called)
00250         cerr << "** Pure virtual function called" << endl;
00251     called = true;
00252 
00253     w_base_t::abort();
00254     /*NOTREACHED*/
00255 }
00256 
00257 
00258 #include <netinet/in.h>
00259 w_base_t::uint2_t w_base_t::w_ntohs(w_base_t::uint2_t net)
00260 {
00261     return ntohs(net);
00262 }
00263 
00264 w_base_t::uint2_t w_base_t::w_htons(w_base_t::uint2_t host)
00265 {
00266     return htons(host);
00267 }
00268 
00269 w_base_t::uint4_t w_base_t::w_ntohl(w_base_t::uint4_t net)
00270 {
00271     return ntohl(net);
00272 }
00273 
00274 w_base_t::uint4_t w_base_t::w_htonl(w_base_t::uint4_t host)
00275 {
00276     return htonl(host);
00277 }
00278 
00279 #ifdef __GNUC__
00280 #if defined(__x86_64) || defined(i386) || defined(__i386__)
00281 #define NEED_POPC64 0
00282 #elif defined(__sparcv9)
00283 #define NEED_POPC64 0
00284 #else
00285 #define NEED_POPC64 1
00286 #endif
00287 #else // !defined(__GNUC__)
00288 #define NEED_POPC64 1
00289 #endif
00290 
00291 #if NEED_POPC64==1
00292 // adapted from http://chessprogramming.wikispaces.com/Population+Count#SWAR-Popcount
00293 typedef unsigned long long u64;
00294 static inline
00295 long popc64(u64 x) {
00296     u64 k1 = 0x5555555555555555ull;
00297     u64 k2 = 0x3333333333333333ull;
00298     u64 k4 = 0x0f0f0f0f0f0f0f0full;
00299     u64 kf = 0x0101010101010101ull;
00300     x =  x       - ((x >> 1)  & k1); //put count of each 2 bits into those 2 bits
00301     x = (x & k2) + ((x >> 2)  & k2); //put count of each 4 bits into those 4 bits
00302     x = (x       +  (x >> 4)) & k4 ; //put count of each 8 bits into those 8 bits
00303     x = (x * kf) >> 56; //returns 8 most significant bits of x + (x<<8) + (x<<16) + (x<<24) + ...
00304     return x;
00305 }
00306 #endif
00307 
00308 size_t w_base_t::pop_count(w_base_t::uint8_t bm)
00309 {
00310 #if NEED_POPC64==1
00311 #warning "using home-brew popc routine"
00312     return popc64(bm);
00313 #elif defined(__x86_64) || defined(i386) || defined(__i386__)
00314 // #warning "Using __builtin_popcountll"
00315     return __builtin_popcountll(bm);
00316 #elif defined(__sparcv9)
00317 #warning "Using gcc inline asm to access sparcv9 'popc' instruction"
00318     long rval;
00319     __asm__("popc    %[in], %[out]" : [out] "=r"(rval) : [in] "r"(x));
00320     return rval;
00321 #else
00322  // Brian Kernighan's population count
00323  // from http://chessprogramming.wikispaces.com/
00324  // Population Count
00325  // This is not the fastest for densely-populated maps though.
00326  int count=0;
00327  while(bm) {
00328   count++;
00329   bm &= bm-1; // reset LS1B
00330  }
00331  return count;
00332 #endif 
00333 }

Generated on Mon Jan 2 15:13:56 2012 for Shore Storage Manager by  doxygen 1.4.7