-
+ 75BC498BF713D76D2E9A489C71604DBB77792673C7F87343D4C6FCF5F20FAC57CDFFD5F15513B00F21F9DE257ADBEB3CA581147F41A8BE96D69379269021C723bitcoin/src/util.h(0 . 0)(1 . 774)
23845 // Copyright (c) 2009-2010 Satoshi Nakamoto
23846 // Copyright (c) 2009-2012 The Bitcoin developers
23847 // Distributed under the MIT/X11 software license, see the accompanying
23848 // file license.txt or http://www.opensource.org/licenses/mit-license.php.
23849 #ifndef BITCOIN_UTIL_H
23850 #define BITCOIN_UTIL_H
23851 
23852 #include "uint256.h"
23853 
23854 #ifndef WIN32
23855 #include <sys/types.h>
23856 #include <sys/time.h>
23857 #include <sys/resource.h>
23858 #endif
23859 #include <map>
23860 #include <vector>
23861 #include <string>
23862 
23863 #include <boost/thread.hpp>
23864 #include <boost/interprocess/sync/interprocess_recursive_mutex.hpp>
23865 #include <boost/date_time/gregorian/gregorian_types.hpp>
23866 #include <boost/date_time/posix_time/posix_time_types.hpp>
23867 
23868 #include <openssl/sha.h>
23869 #include <openssl/ripemd.h>
23870 
23871 
23872 #if defined(_MSC_VER) || defined(__BORLANDC__)
23873 typedef __int64  int64;
23874 typedef unsigned __int64  uint64;
23875 #else
23876 typedef long long  int64;
23877 typedef unsigned long long  uint64;
23878 #endif
23879 #if defined(_MSC_VER) && _MSC_VER < 1300
23880 #define for  if (false) ; else for
23881 #endif
23882 #ifndef _MSC_VER
23883 #define __forceinline  inline
23884 #endif
23885 
23886 #define loop                for (;;)
23887 #define BEGIN(a)            ((char*)&(a))
23888 #define END(a)              ((char*)&((&(a))[1]))
23889 #define UBEGIN(a)           ((unsigned char*)&(a))
23890 #define UEND(a)             ((unsigned char*)&((&(a))[1]))
23891 #define ARRAYLEN(array)     (sizeof(array)/sizeof((array)[0]))
23892 #define printf              OutputDebugStringF
23893 
23894 #ifdef snprintf
23895 #undef snprintf
23896 #endif
23897 #define snprintf my_snprintf
23898 
23899 #ifndef PRI64d
23900 #if defined(_MSC_VER) || defined(__BORLANDC__) || defined(__MSVCRT__)
23901 #define PRI64d  "I64d"
23902 #define PRI64u  "I64u"
23903 #define PRI64x  "I64x"
23904 #else
23905 #define PRI64d  "lld"
23906 #define PRI64u  "llu"
23907 #define PRI64x  "llx"
23908 #endif
23909 #endif
23910 
23911 // This is needed because the foreach macro can't get over the comma in pair<t1, t2>
23912 #define PAIRTYPE(t1, t2)    std::pair<t1, t2>
23913 
23914 // Align by increasing pointer, must have extra space at end of buffer
23915 template <size_t nBytes, typename T>
23916 T* alignup(T* p)
23917 {
23918     union
23919     {
23920         T* ptr;
23921         size_t n;
23922     } u;
23923     u.ptr = p;
23924     u.n = (u.n + (nBytes-1)) & ~(nBytes-1);
23925     return u.ptr;
23926 }
23927 
23928 #ifdef WIN32
23929 #define MSG_NOSIGNAL        0
23930 #define MSG_DONTWAIT        0
23931 #ifndef UINT64_MAX
23932 #define UINT64_MAX          _UI64_MAX
23933 #define INT64_MAX           _I64_MAX
23934 #define INT64_MIN           _I64_MIN
23935 #endif
23936 #ifndef S_IRUSR
23937 #define S_IRUSR             0400
23938 #define S_IWUSR             0200
23939 #endif
23940 #define unlink              _unlink
23941 typedef int socklen_t;
23942 #else
23943 #define WSAGetLastError()   errno
23944 #define WSAEINVAL           EINVAL
23945 #define WSAEALREADY         EALREADY
23946 #define WSAEWOULDBLOCK      EWOULDBLOCK
23947 #define WSAEMSGSIZE         EMSGSIZE
23948 #define WSAEINTR            EINTR
23949 #define WSAEINPROGRESS      EINPROGRESS
23950 #define WSAEADDRINUSE       EADDRINUSE
23951 #define WSAENOTSOCK         EBADF
23952 #define INVALID_SOCKET      (SOCKET)(~0)
23953 #define SOCKET_ERROR        -1
23954 typedef u_int SOCKET;
23955 #define _vsnprintf(a,b,c,d) vsnprintf(a,b,c,d)
23956 #define strlwr(psz)         to_lower(psz)
23957 #define _strlwr(psz)        to_lower(psz)
23958 #define MAX_PATH            1024
23959 #define Beep(n1,n2)         (0)
23960 inline void Sleep(int64 n)
23961 {
23962     /*Boost has a year 2038 problem- if the request sleep time is past epoch+2^31 seconds the sleep returns instantly.
23963       So we clamp our sleeps here to 10 years and hope that boost is fixed by 2028.*/
23964     boost::thread::sleep(boost::get_system_time() + boost::posix_time::milliseconds(n>315576000000LL?315576000000LL:n));
23965 }
23966 #endif
23967 
23968 inline int myclosesocket(SOCKET& hSocket)
23969 {
23970     if (hSocket == INVALID_SOCKET)
23971         return WSAENOTSOCK;
23972 #ifdef WIN32
23973     int ret = closesocket(hSocket);
23974 #else
23975     int ret = close(hSocket);
23976 #endif
23977     hSocket = INVALID_SOCKET;
23978     return ret;
23979 }
23980 #define closesocket(s)      myclosesocket(s)
23981 #if !defined(QT_GUI)
23982 inline const char* _(const char* psz)
23983 {
23984     return psz;
23985 }
23986 #endif
23987 
23988 
23989 
23990 
23991 
23992 
23993 
23994 
23995 
23996 extern std::map<std::string, std::string> mapArgs;
23997 extern std::map<std::string, std::vector<std::string> > mapMultiArgs;
23998 extern bool fDebug;
23999 extern bool fPrintToConsole;
24000 extern bool fPrintToDebugger;
24001 extern char pszSetDataDir[MAX_PATH];
24002 extern bool fRequestShutdown;
24003 extern bool fShutdown;
24004 extern bool fDaemon;
24005 extern bool fServer;
24006 extern bool fCommandLine;
24007 extern std::string strMiscWarning;
24008 extern bool fTestNet;
24009 extern bool fNoListen;
24010 extern bool fLogTimestamps;
24011 
24012 void RandAddSeed();
24013 void RandAddSeedPerfmon();
24014 int OutputDebugStringF(const char* pszFormat, ...);
24015 int my_snprintf(char* buffer, size_t limit, const char* format, ...);
24016 std::string strprintf(const std::string &format, ...);
24017 bool error(const std::string &format, ...);
24018 void LogException(std::exception* pex, const char* pszThread);
24019 void PrintException(std::exception* pex, const char* pszThread);
24020 void PrintExceptionContinue(std::exception* pex, const char* pszThread);
24021 void ParseString(const std::string& str, char c, std::vector<std::string>& v);
24022 std::string FormatMoney(int64 n, bool fPlus=false);
24023 bool ParseMoney(const std::string& str, int64& nRet);
24024 bool ParseMoney(const char* pszIn, int64& nRet);
24025 std::vector<unsigned char> ParseHex(const char* psz);
24026 std::vector<unsigned char> ParseHex(const std::string& str);
24027 std::vector<unsigned char> DecodeBase64(const char* p, bool* pfInvalid = NULL);
24028 std::string DecodeBase64(const std::string& str);
24029 std::string EncodeBase64(const unsigned char* pch, size_t len);
24030 std::string EncodeBase64(const std::string& str);
24031 void ParseParameters(int argc, char* argv[]);
24032 const char* wxGetTranslation(const char* psz);
24033 bool WildcardMatch(const char* psz, const char* mask);
24034 bool WildcardMatch(const std::string& str, const std::string& mask);
24035 int GetFilesize(FILE* file);
24036 void GetDataDir(char* pszDirRet);
24037 std::string GetConfigFile();
24038 std::string GetPidFile();
24039 void CreatePidFile(std::string pidFile, pid_t pid);
24040 void ReadConfigFile(std::map<std::string, std::string>& mapSettingsRet, std::map<std::string, std::vector<std::string> >& mapMultiSettingsRet);
24041 #ifdef WIN32
24042 std::string MyGetSpecialFolderPath(int nFolder, bool fCreate);
24043 #endif
24044 std::string GetDefaultDataDir();
24045 std::string GetDataDir();
24046 void ShrinkDebugFile();
24047 int GetRandInt(int nMax);
24048 uint64 GetRand(uint64 nMax);
24049 int64 GetTime();
24050 void SetMockTime(int64 nMockTimeIn);
24051 int64 GetAdjustedTime();
24052 void AddTimeData(unsigned int ip, int64 nTime);
24053 std::string FormatFullVersion();
24054 
24055 
24056 
24057 
24058 
24059 
24060 
24061 
24062 
24063 
24064 
24065 
24066 
24067 // Wrapper to automatically initialize mutex
24068 class CCriticalSection
24069 {
24070 protected:
24071     boost::interprocess::interprocess_recursive_mutex mutex;
24072 public:
24073     explicit CCriticalSection() { }
24074     ~CCriticalSection() { }
24075     void Enter(const char* pszName, const char* pszFile, int nLine);
24076     void Leave();
24077     bool TryEnter(const char* pszName, const char* pszFile, int nLine);
24078 };
24079 
24080 // Automatically leave critical section when leaving block, needed for exception safety
24081 class CCriticalBlock
24082 {
24083 protected:
24084     CCriticalSection* pcs;
24085 
24086 public:
24087     CCriticalBlock(CCriticalSection& csIn, const char* pszName, const char* pszFile, int nLine)
24088     {
24089         pcs = &csIn;
24090         pcs->Enter(pszName, pszFile, nLine);
24091     }
24092 
24093     operator bool() const
24094     {
24095         return true;
24096     }
24097 
24098     ~CCriticalBlock()
24099     {
24100         pcs->Leave();
24101     }
24102 };
24103 
24104 #define CRITICAL_BLOCK(cs)     \
24105     if (CCriticalBlock criticalblock = CCriticalBlock(cs, #cs, __FILE__, __LINE__))
24106 
24107 #define ENTER_CRITICAL_SECTION(cs) \
24108     (cs).Enter(#cs, __FILE__, __LINE__)
24109 
24110 #define LEAVE_CRITICAL_SECTION(cs) \
24111     (cs).Leave()
24112 
24113 class CTryCriticalBlock
24114 {
24115 protected:
24116     CCriticalSection* pcs;
24117 
24118 public:
24119     CTryCriticalBlock(CCriticalSection& csIn, const char* pszName, const char* pszFile, int nLine)
24120     {
24121         pcs = (csIn.TryEnter(pszName, pszFile, nLine) ? &csIn : NULL);
24122     }
24123 
24124     operator bool() const
24125     {
24126         return Entered();
24127     }
24128 
24129     ~CTryCriticalBlock()
24130     {
24131         if (pcs)
24132         {
24133             pcs->Leave();
24134         }
24135     }
24136     bool Entered() const { return pcs != NULL; }
24137 };
24138 
24139 #define TRY_CRITICAL_BLOCK(cs)     \
24140     if (CTryCriticalBlock criticalblock = CTryCriticalBlock(cs, #cs, __FILE__, __LINE__))
24141 
24142 
24143 
24144 
24145 
24146 
24147 // This is exactly like std::string, but with a custom allocator.
24148 // (secure_allocator<> is defined in serialize.h)
24149 typedef std::basic_string<char, std::char_traits<char>, secure_allocator<char> > SecureString;
24150 
24151 // This is exactly like std::string, but with a custom allocator.
24152 // (secure_allocator<> is defined in serialize.h)
24153 typedef std::basic_string<char, std::char_traits<char>, secure_allocator<char> > SecureString;
24154 
24155 
24156 
24157 
24158 
24159 inline std::string i64tostr(int64 n)
24160 {
24161     return strprintf("%"PRI64d, n);
24162 }
24163 
24164 inline std::string itostr(int n)
24165 {
24166     return strprintf("%d", n);
24167 }
24168 
24169 inline int64 atoi64(const char* psz)
24170 {
24171 #ifdef _MSC_VER
24172     return _atoi64(psz);
24173 #else
24174     return strtoll(psz, NULL, 10);
24175 #endif
24176 }
24177 
24178 inline int64 atoi64(const std::string& str)
24179 {
24180 #ifdef _MSC_VER
24181     return _atoi64(str.c_str());
24182 #else
24183     return strtoll(str.c_str(), NULL, 10);
24184 #endif
24185 }
24186 
24187 inline int atoi(const std::string& str)
24188 {
24189     return atoi(str.c_str());
24190 }
24191 
24192 inline int roundint(double d)
24193 {
24194     return (int)(d > 0 ? d + 0.5 : d - 0.5);
24195 }
24196 
24197 inline int64 roundint64(double d)
24198 {
24199     return (int64)(d > 0 ? d + 0.5 : d - 0.5);
24200 }
24201 
24202 inline int64 abs64(int64 n)
24203 {
24204     return (n >= 0 ? n : -n);
24205 }
24206 
24207 template<typename T>
24208 std::string HexStr(const T itbegin, const T itend, bool fSpaces=false)
24209 {
24210     if (itbegin == itend)
24211         return "";
24212     const unsigned char* pbegin = (const unsigned char*)&itbegin[0];
24213     const unsigned char* pend = pbegin + (itend - itbegin) * sizeof(itbegin[0]);
24214     std::string str;
24215     str.reserve((pend-pbegin) * (fSpaces ? 3 : 2));
24216     for (const unsigned char* p = pbegin; p != pend; p++)
24217         str += strprintf((fSpaces && p != pend-1 ? "%02x " : "%02x"), *p);
24218     return str;
24219 }
24220 
24221 inline std::string HexStr(const std::vector<unsigned char>& vch, bool fSpaces=false)
24222 {
24223     return HexStr(vch.begin(), vch.end(), fSpaces);
24224 }
24225 
24226 template<typename T>
24227 std::string HexNumStr(const T itbegin, const T itend, bool f0x=true)
24228 {
24229     if (itbegin == itend)
24230         return "";
24231     const unsigned char* pbegin = (const unsigned char*)&itbegin[0];
24232     const unsigned char* pend = pbegin + (itend - itbegin) * sizeof(itbegin[0]);
24233     std::string str = (f0x ? "0x" : "");
24234     str.reserve(str.size() + (pend-pbegin) * 2);
24235     for (const unsigned char* p = pend-1; p >= pbegin; p--)
24236         str += strprintf("%02x", *p);
24237     return str;
24238 }
24239 
24240 inline std::string HexNumStr(const std::vector<unsigned char>& vch, bool f0x=true)
24241 {
24242     return HexNumStr(vch.begin(), vch.end(), f0x);
24243 }
24244 
24245 template<typename T>
24246 void PrintHex(const T pbegin, const T pend, const char* pszFormat="%s", bool fSpaces=true)
24247 {
24248     printf(pszFormat, HexStr(pbegin, pend, fSpaces).c_str());
24249 }
24250 
24251 inline void PrintHex(const std::vector<unsigned char>& vch, const char* pszFormat="%s", bool fSpaces=true)
24252 {
24253     printf(pszFormat, HexStr(vch, fSpaces).c_str());
24254 }
24255 
24256 inline int64 GetPerformanceCounter()
24257 {
24258     int64 nCounter = 0;
24259 #ifdef WIN32
24260     QueryPerformanceCounter((LARGE_INTEGER*)&nCounter);
24261 #else
24262     timeval t;
24263     gettimeofday(&t, NULL);
24264     nCounter = t.tv_sec * 1000000 + t.tv_usec;
24265 #endif
24266     return nCounter;
24267 }
24268 
24269 inline int64 GetTimeMillis()
24270 {
24271     return (boost::posix_time::ptime(boost::posix_time::microsec_clock::universal_time()) -
24272             boost::posix_time::ptime(boost::gregorian::date(1970,1,1))).total_milliseconds();
24273 }
24274 
24275 inline std::string DateTimeStrFormat(const char* pszFormat, int64 nTime)
24276 {
24277     time_t n = nTime;
24278     struct tm* ptmTime = gmtime(&n);
24279     char pszTime[200];
24280     strftime(pszTime, sizeof(pszTime), pszFormat, ptmTime);
24281     return pszTime;
24282 }
24283 
24284 template<typename T>
24285 void skipspaces(T& it)
24286 {
24287     while (isspace(*it))
24288         ++it;
24289 }
24290 
24291 inline bool IsSwitchChar(char c)
24292 {
24293 #ifdef WIN32
24294     return c == '-' || c == '/';
24295 #else
24296     return c == '-';
24297 #endif
24298 }
24299 
24300 inline std::string GetArg(const std::string& strArg, const std::string& strDefault)
24301 {
24302     if (mapArgs.count(strArg))
24303         return mapArgs[strArg];
24304     return strDefault;
24305 }
24306 
24307 inline int64 GetArg(const std::string& strArg, int64 nDefault)
24308 {
24309     if (mapArgs.count(strArg))
24310         return atoi64(mapArgs[strArg]);
24311     return nDefault;
24312 }
24313 
24314 inline bool GetBoolArg(const std::string& strArg, bool fDefault=false)
24315 {
24316     if (mapArgs.count(strArg))
24317     {
24318         if (mapArgs[strArg].empty())
24319             return true;
24320         return (atoi(mapArgs[strArg]) != 0);
24321     }
24322     return fDefault;
24323 }
24324 
24325 /**
24326  * Set an argument if it doesn't already have a value
24327  *
24328  * @param strArg Argument to set (e.g. "-foo")
24329  * @param strValue Value (e.g. "1")
24330  * @return true if argument gets set, false if it already had a value
24331  */
24332 bool SoftSetArg(const std::string& strArg, const std::string& strValue);
24333 
24334 /**
24335  * Set a boolean argument if it doesn't already have a value
24336  *
24337  * @param strArg Argument to set (e.g. "-foo")
24338  * @param fValue Value (e.g. false)
24339  * @return true if argument gets set, false if it already had a value
24340  */
24341 bool SoftSetArg(const std::string& strArg, bool fValue);
24342 
24343 
24344 
24345 
24346 
24347 
24348 
24349 
24350 
24351 inline void heapchk()
24352 {
24353 #ifdef WIN32
24354     /// for debugging
24355     //if (_heapchk() != _HEAPOK)
24356     //    DebugBreak();
24357 #endif
24358 }
24359 
24360 // Randomize the stack to help protect against buffer overrun exploits
24361 #define IMPLEMENT_RANDOMIZE_STACK(ThreadFn)     \
24362     {                                           \
24363         static char nLoops;                     \
24364         if (nLoops <= 0)                        \
24365             nLoops = GetRand(20) + 1;           \
24366         if (nLoops-- > 1)                       \
24367         {                                       \
24368             ThreadFn;                           \
24369             return;                             \
24370         }                                       \
24371     }
24372 
24373 #define CATCH_PRINT_EXCEPTION(pszFn)     \
24374     catch (std::exception& e) {          \
24375         PrintException(&e, (pszFn));     \
24376     } catch (...) {                      \
24377         PrintException(NULL, (pszFn));   \
24378     }
24379 
24380 
24381 
24382 
24383 
24384 
24385 
24386 
24387 
24388 
24389 template<typename T1>
24390 inline uint256 Hash(const T1 pbegin, const T1 pend)
24391 {
24392     static unsigned char pblank[1];
24393     uint256 hash1;
24394     SHA256((pbegin == pend ? pblank : (unsigned char*)&pbegin[0]), (pend - pbegin) * sizeof(pbegin[0]), (unsigned char*)&hash1);
24395     uint256 hash2;
24396     SHA256((unsigned char*)&hash1, sizeof(hash1), (unsigned char*)&hash2);
24397     return hash2;
24398 }
24399 
24400 template<typename T1, typename T2>
24401 inline uint256 Hash(const T1 p1begin, const T1 p1end,
24402                     const T2 p2begin, const T2 p2end)
24403 {
24404     static unsigned char pblank[1];
24405     uint256 hash1;
24406     SHA256_CTX ctx;
24407     SHA256_Init(&ctx);
24408     SHA256_Update(&ctx, (p1begin == p1end ? pblank : (unsigned char*)&p1begin[0]), (p1end - p1begin) * sizeof(p1begin[0]));
24409     SHA256_Update(&ctx, (p2begin == p2end ? pblank : (unsigned char*)&p2begin[0]), (p2end - p2begin) * sizeof(p2begin[0]));
24410     SHA256_Final((unsigned char*)&hash1, &ctx);
24411     uint256 hash2;
24412     SHA256((unsigned char*)&hash1, sizeof(hash1), (unsigned char*)&hash2);
24413     return hash2;
24414 }
24415 
24416 template<typename T1, typename T2, typename T3>
24417 inline uint256 Hash(const T1 p1begin, const T1 p1end,
24418                     const T2 p2begin, const T2 p2end,
24419                     const T3 p3begin, const T3 p3end)
24420 {
24421     static unsigned char pblank[1];
24422     uint256 hash1;
24423     SHA256_CTX ctx;
24424     SHA256_Init(&ctx);
24425     SHA256_Update(&ctx, (p1begin == p1end ? pblank : (unsigned char*)&p1begin[0]), (p1end - p1begin) * sizeof(p1begin[0]));
24426     SHA256_Update(&ctx, (p2begin == p2end ? pblank : (unsigned char*)&p2begin[0]), (p2end - p2begin) * sizeof(p2begin[0]));
24427     SHA256_Update(&ctx, (p3begin == p3end ? pblank : (unsigned char*)&p3begin[0]), (p3end - p3begin) * sizeof(p3begin[0]));
24428     SHA256_Final((unsigned char*)&hash1, &ctx);
24429     uint256 hash2;
24430     SHA256((unsigned char*)&hash1, sizeof(hash1), (unsigned char*)&hash2);
24431     return hash2;
24432 }
24433 
24434 template<typename T>
24435 uint256 SerializeHash(const T& obj, int nType=SER_GETHASH, int nVersion=VERSION)
24436 {
24437     // Most of the time is spent allocating and deallocating CDataStream's
24438     // buffer.  If this ever needs to be optimized further, make a CStaticStream
24439     // class with its buffer on the stack.
24440     CDataStream ss(nType, nVersion);
24441     ss.reserve(10000);
24442     ss << obj;
24443     return Hash(ss.begin(), ss.end());
24444 }
24445 
24446 inline uint160 Hash160(const std::vector<unsigned char>& vch)
24447 {
24448     uint256 hash1;
24449     SHA256(&vch[0], vch.size(), (unsigned char*)&hash1);
24450     uint160 hash2;
24451     RIPEMD160((unsigned char*)&hash1, sizeof(hash1), (unsigned char*)&hash2);
24452     return hash2;
24453 }
24454 
24455 
24456 // Median filter over a stream of values
24457 // Returns the median of the last N numbers
24458 template <typename T> class CMedianFilter
24459 {
24460 private:
24461     std::vector<T> vValues;
24462     std::vector<T> vSorted;
24463     int nSize;
24464 public:
24465     CMedianFilter(int size, T initial_value):
24466         nSize(size)
24467     {
24468         vValues.reserve(size);
24469         vValues.push_back(initial_value);
24470         vSorted = vValues;
24471     }
24472     
24473     void input(T value)
24474     {
24475         if(vValues.size() == nSize)
24476         {
24477             vValues.erase(vValues.begin());
24478         }
24479         vValues.push_back(value);
24480 
24481         vSorted.resize(vValues.size());
24482         std::copy(vValues.begin(), vValues.end(), vSorted.begin());
24483         std::sort(vSorted.begin(), vSorted.end());
24484     }
24485 
24486     T median() const
24487     {
24488         int size = vSorted.size();
24489         assert(size>0);
24490         if(size & 1) // Odd number of elements
24491         {
24492             return vSorted[size/2];
24493         }
24494         else // Even number of elements
24495         {
24496             return (vSorted[size/2-1] + vSorted[size/2]) / 2;
24497         }
24498     }
24499 };
24500 
24501 
24502 
24503 
24504 
24505 
24506 
24507 
24508 
24509 
24510 // Note: It turns out we might have been able to use boost::thread
24511 // by using TerminateThread(boost::thread.native_handle(), 0);
24512 #ifdef WIN32
24513 typedef HANDLE pthread_t;
24514 
24515 inline pthread_t CreateThread(void(*pfn)(void*), void* parg, bool fWantHandle=false)
24516 {
24517     DWORD nUnused = 0;
24518     HANDLE hthread =
24519         CreateThread(
24520             NULL,                        // default security
24521             0,                           // inherit stack size from parent
24522             (LPTHREAD_START_ROUTINE)pfn, // function pointer
24523             parg,                        // argument
24524             0,                           // creation option, start immediately
24525             &nUnused);                   // thread identifier
24526     if (hthread == NULL)
24527     {
24528         printf("Error: CreateThread() returned %d\n", GetLastError());
24529         return (pthread_t)0;
24530     }
24531     if (!fWantHandle)
24532     {
24533         CloseHandle(hthread);
24534         return (pthread_t)-1;
24535     }
24536     return hthread;
24537 }
24538 
24539 inline void SetThreadPriority(int nPriority)
24540 {
24541     SetThreadPriority(GetCurrentThread(), nPriority);
24542 }
24543 #else
24544 inline pthread_t CreateThread(void(*pfn)(void*), void* parg, bool fWantHandle=false)
24545 {
24546     pthread_t hthread = 0;
24547     int ret = pthread_create(&hthread, NULL, (void*(*)(void*))pfn, parg);
24548     if (ret != 0)
24549     {
24550         printf("Error: pthread_create() returned %d\n", ret);
24551         return (pthread_t)0;
24552     }
24553     if (!fWantHandle)
24554     {
24555         pthread_detach(hthread);
24556         return (pthread_t)-1;
24557     }
24558     return hthread;
24559 }
24560 
24561 #define THREAD_PRIORITY_LOWEST          PRIO_MAX
24562 #define THREAD_PRIORITY_BELOW_NORMAL    2
24563 #define THREAD_PRIORITY_NORMAL          0
24564 #define THREAD_PRIORITY_ABOVE_NORMAL    0
24565 
24566 inline void SetThreadPriority(int nPriority)
24567 {
24568     // It's unclear if it's even possible to change thread priorities on Linux,
24569     // but we really and truly need it for the generation threads.
24570 #ifdef PRIO_THREAD
24571     setpriority(PRIO_THREAD, 0, nPriority);
24572 #else
24573     setpriority(PRIO_PROCESS, 0, nPriority);
24574 #endif
24575 }
24576 
24577 inline bool TerminateThread(pthread_t hthread, unsigned int nExitCode)
24578 {
24579     return (pthread_cancel(hthread) == 0);
24580 }
24581 
24582 inline void ExitThread(size_t nExitCode)
24583 {
24584     pthread_exit((void*)nExitCode);
24585 }
24586 #endif
24587 
24588 
24589 
24590 
24591 
24592 inline bool AffinityBugWorkaround(void(*pfn)(void*))
24593 {
24594 #ifdef WIN32
24595     // Sometimes after a few hours affinity gets stuck on one processor
24596     DWORD_PTR dwProcessAffinityMask = -1;
24597     DWORD_PTR dwSystemAffinityMask = -1;
24598     GetProcessAffinityMask(GetCurrentProcess(), &dwProcessAffinityMask, &dwSystemAffinityMask);
24599     DWORD dwPrev1 = SetThreadAffinityMask(GetCurrentThread(), dwProcessAffinityMask);
24600     DWORD dwPrev2 = SetThreadAffinityMask(GetCurrentThread(), dwProcessAffinityMask);
24601     if (dwPrev2 != dwProcessAffinityMask)
24602     {
24603         printf("AffinityBugWorkaround() : SetThreadAffinityMask=%d, ProcessAffinityMask=%d, restarting thread\n", dwPrev2, dwProcessAffinityMask);
24604         if (!CreateThread(pfn, NULL))
24605             printf("Error: CreateThread() failed\n");
24606         return true;
24607     }
24608 #endif
24609     return false;
24610 }
24611 
24612 inline uint32_t ByteReverse(uint32_t value)
24613 {
24614     value = ((value & 0xFF00FF00) >> 8) | ((value & 0x00FF00FF) << 8);
24615     return (value<<16) | (value>>16);
24616 }
24617 
24618 #endif