-
+ E6CDEECB0F0BB148D529F779B1EC02BD9A73C55C57A42E31DF8B8BC3118E5B3CE90E4A38F4853BA6AE64B085B8AD9F7D26AF0951A24F600713FA4898E46FBD82
bitcoin/src/util.h
(0 . 0)(1 . 805)
25860 // /****************************\
25861 // * EXPERIMENTAL BRANCH. *
25862 // * FOR LABORATORY USE ONLY. *
25863 // ********************************
25864 // ************
25865 // **************
25866 // ****************
25867 // **** **** ****
25868 // *** *** ***
25869 // *** *** ***
25870 // *** * * **
25871 // ******** ********
25872 // ******* ******
25873 // *** **
25874 // * ******* **
25875 // ** * * * * *
25876 // ** * * ***
25877 // **** * * * * ****
25878 // **** *** * * ** ***
25879 // **** ********* ******
25880 // ******* ***** *******
25881 // ********* ****** **
25882 // ** ****** ******
25883 // ** ******* **
25884 // ** ******* ***
25885 // **** ******** ************
25886 // ************ ************
25887 // ******** *******
25888 // ****** ****
25889 // *** ***
25890 // ********************************
25891 // Copyright (c) 2009-2010 Satoshi Nakamoto
25892 // Copyright (c) 2009-2012 The Bitcoin developers
25893 // Distributed under the MIT/X11 software license, see the accompanying
25894 // file license.txt or http://www.opensource.org/licenses/mit-license.php.
25895 #ifndef BITCOIN_UTIL_H
25896 #define BITCOIN_UTIL_H
25897
25898 #include "uint256.h"
25899
25900 #ifndef WIN32
25901 #include <sys/types.h>
25902 #include <sys/time.h>
25903 #include <sys/resource.h>
25904 #endif
25905 #include <map>
25906 #include <vector>
25907 #include <string>
25908
25909 #include <boost/thread.hpp>
25910 #include <boost/interprocess/sync/interprocess_recursive_mutex.hpp>
25911 #include <boost/date_time/gregorian/gregorian_types.hpp>
25912 #include <boost/date_time/posix_time/posix_time_types.hpp>
25913
25914 #include <openssl/sha.h>
25915 #include <openssl/ripemd.h>
25916
25917
25918 #if defined(_MSC_VER) || defined(__BORLANDC__)
25919 typedef __int64 int64;
25920 typedef unsigned __int64 uint64;
25921 #else
25922 typedef long long int64;
25923 typedef unsigned long long uint64;
25924 #endif
25925 #if defined(_MSC_VER) && _MSC_VER < 1300
25926 #define for if (false) ; else for
25927 #endif
25928 #ifndef _MSC_VER
25929 #define __forceinline inline
25930 #endif
25931
25932 #define loop for (;;)
25933 #define BEGIN(a) ((char*)&(a))
25934 #define END(a) ((char*)&((&(a))[1]))
25935 #define UBEGIN(a) ((unsigned char*)&(a))
25936 #define UEND(a) ((unsigned char*)&((&(a))[1]))
25937 #define ARRAYLEN(array) (sizeof(array)/sizeof((array)[0]))
25938 #define printf OutputDebugStringF
25939
25940 #ifdef snprintf
25941 #undef snprintf
25942 #endif
25943 #define snprintf my_snprintf
25944
25945 #ifndef PRI64d
25946 #if defined(_MSC_VER) || defined(__BORLANDC__) || defined(__MSVCRT__)
25947 #define PRI64d "I64d"
25948 #define PRI64u "I64u"
25949 #define PRI64x "I64x"
25950 #else
25951 #define PRI64d "lld"
25952 #define PRI64u "llu"
25953 #define PRI64x "llx"
25954 #endif
25955 #endif
25956
25957 // This is needed because the foreach macro can't get over the comma in pair<t1, t2>
25958 #define PAIRTYPE(t1, t2) std::pair<t1, t2>
25959
25960 // Align by increasing pointer, must have extra space at end of buffer
25961 template <size_t nBytes, typename T>
25962 T* alignup(T* p)
25963 {
25964 union
25965 {
25966 T* ptr;
25967 size_t n;
25968 } u;
25969 u.ptr = p;
25970 u.n = (u.n + (nBytes-1)) & ~(nBytes-1);
25971 return u.ptr;
25972 }
25973
25974 #ifdef WIN32
25975 #define MSG_NOSIGNAL 0
25976 #define MSG_DONTWAIT 0
25977 #ifndef UINT64_MAX
25978 #define UINT64_MAX _UI64_MAX
25979 #define INT64_MAX _I64_MAX
25980 #define INT64_MIN _I64_MIN
25981 #endif
25982 #ifndef S_IRUSR
25983 #define S_IRUSR 0400
25984 #define S_IWUSR 0200
25985 #endif
25986 #define unlink _unlink
25987 typedef int socklen_t;
25988 #else
25989 #define WSAGetLastError() errno
25990 #define WSAEINVAL EINVAL
25991 #define WSAEALREADY EALREADY
25992 #define WSAEWOULDBLOCK EWOULDBLOCK
25993 #define WSAEMSGSIZE EMSGSIZE
25994 #define WSAEINTR EINTR
25995 #define WSAEINPROGRESS EINPROGRESS
25996 #define WSAEADDRINUSE EADDRINUSE
25997 #define WSAENOTSOCK EBADF
25998 #define INVALID_SOCKET (SOCKET)(~0)
25999 #define SOCKET_ERROR -1
26000 typedef u_int SOCKET;
26001 #define _vsnprintf(a,b,c,d) vsnprintf(a,b,c,d)
26002 #define strlwr(psz) to_lower(psz)
26003 #define _strlwr(psz) to_lower(psz)
26004 #define MAX_PATH 1024
26005 #define Beep(n1,n2) (0)
26006 inline void Sleep(int64 n)
26007 {
26008 /*Boost has a year 2038 problem— if the request sleep time is past epoch+2^31 seconds the sleep returns instantly.
26009 So we clamp our sleeps here to 10 years and hope that boost is fixed by 2028.*/
26010 boost::thread::sleep(boost::get_system_time() + boost::posix_time::milliseconds(n>315576000000LL?315576000000LL:n));
26011 }
26012 #endif
26013
26014 inline int myclosesocket(SOCKET& hSocket)
26015 {
26016 if (hSocket == INVALID_SOCKET)
26017 return WSAENOTSOCK;
26018 #ifdef WIN32
26019 int ret = closesocket(hSocket);
26020 #else
26021 int ret = close(hSocket);
26022 #endif
26023 hSocket = INVALID_SOCKET;
26024 return ret;
26025 }
26026 #define closesocket(s) myclosesocket(s)
26027 #if !defined(QT_GUI)
26028 inline const char* _(const char* psz)
26029 {
26030 return psz;
26031 }
26032 #endif
26033
26034
26035
26036
26037
26038
26039
26040
26041
26042 extern std::map<std::string, std::string> mapArgs;
26043 extern std::map<std::string, std::vector<std::string> > mapMultiArgs;
26044 extern bool fDebug;
26045 extern bool fPrintToConsole;
26046 extern bool fPrintToDebugger;
26047 extern char pszSetDataDir[MAX_PATH];
26048 extern bool fRequestShutdown;
26049 extern bool fShutdown;
26050 extern bool fDaemon;
26051 extern bool fServer;
26052 extern bool fCommandLine;
26053 extern std::string strMiscWarning;
26054 extern bool fTestNet;
26055 extern bool fNoListen;
26056 extern bool fLogTimestamps;
26057
26058 void RandAddSeed();
26059 void RandAddSeedPerfmon();
26060 int OutputDebugStringF(const char* pszFormat, ...);
26061 int my_snprintf(char* buffer, size_t limit, const char* format, ...);
26062 std::string strprintf(const std::string &format, ...);
26063 bool error(const std::string &format, ...);
26064 void LogException(std::exception* pex, const char* pszThread);
26065 void PrintException(std::exception* pex, const char* pszThread);
26066 void PrintExceptionContinue(std::exception* pex, const char* pszThread);
26067 void ParseString(const std::string& str, char c, std::vector<std::string>& v);
26068 std::string FormatMoney(int64 n, bool fPlus=false);
26069 bool ParseMoney(const std::string& str, int64& nRet);
26070 bool ParseMoney(const char* pszIn, int64& nRet);
26071 std::vector<unsigned char> ParseHex(const char* psz);
26072 std::vector<unsigned char> ParseHex(const std::string& str);
26073 std::vector<unsigned char> DecodeBase64(const char* p, bool* pfInvalid = NULL);
26074 std::string DecodeBase64(const std::string& str);
26075 std::string EncodeBase64(const unsigned char* pch, size_t len);
26076 std::string EncodeBase64(const std::string& str);
26077 void ParseParameters(int argc, char* argv[]);
26078 const char* wxGetTranslation(const char* psz);
26079 bool WildcardMatch(const char* psz, const char* mask);
26080 bool WildcardMatch(const std::string& str, const std::string& mask);
26081 int GetFilesize(FILE* file);
26082 void GetDataDir(char* pszDirRet);
26083 std::string GetConfigFile();
26084 std::string GetPidFile();
26085 void CreatePidFile(std::string pidFile, pid_t pid);
26086 void ReadConfigFile(std::map<std::string, std::string>& mapSettingsRet, std::map<std::string, std::vector<std::string> >& mapMultiSettingsRet);
26087 #ifdef WIN32
26088 std::string MyGetSpecialFolderPath(int nFolder, bool fCreate);
26089 #endif
26090 std::string GetDefaultDataDir();
26091 std::string GetDataDir();
26092 void ShrinkDebugFile();
26093 int GetRandInt(int nMax);
26094 uint64 GetRand(uint64 nMax);
26095 int64 GetTime();
26096 void SetMockTime(int64 nMockTimeIn);
26097 int64 GetAdjustedTime();
26098 void AddTimeData(unsigned int ip, int64 nTime);
26099 std::string FormatFullVersion();
26100
26101
26102
26103
26104
26105
26106
26107
26108
26109
26110
26111
26112
26113 // Wrapper to automatically initialize mutex
26114 class CCriticalSection
26115 {
26116 protected:
26117 boost::interprocess::interprocess_recursive_mutex mutex;
26118 public:
26119 explicit CCriticalSection() { }
26120 ~CCriticalSection() { }
26121 void Enter(const char* pszName, const char* pszFile, int nLine);
26122 void Leave();
26123 bool TryEnter(const char* pszName, const char* pszFile, int nLine);
26124 };
26125
26126 // Automatically leave critical section when leaving block, needed for exception safety
26127 class CCriticalBlock
26128 {
26129 protected:
26130 CCriticalSection* pcs;
26131
26132 public:
26133 CCriticalBlock(CCriticalSection& csIn, const char* pszName, const char* pszFile, int nLine)
26134 {
26135 pcs = &csIn;
26136 pcs->Enter(pszName, pszFile, nLine);
26137 }
26138
26139 operator bool() const
26140 {
26141 return true;
26142 }
26143
26144 ~CCriticalBlock()
26145 {
26146 pcs->Leave();
26147 }
26148 };
26149
26150 #define CRITICAL_BLOCK(cs) \
26151 if (CCriticalBlock criticalblock = CCriticalBlock(cs, #cs, __FILE__, __LINE__))
26152
26153 #define ENTER_CRITICAL_SECTION(cs) \
26154 (cs).Enter(#cs, __FILE__, __LINE__)
26155
26156 #define LEAVE_CRITICAL_SECTION(cs) \
26157 (cs).Leave()
26158
26159 class CTryCriticalBlock
26160 {
26161 protected:
26162 CCriticalSection* pcs;
26163
26164 public:
26165 CTryCriticalBlock(CCriticalSection& csIn, const char* pszName, const char* pszFile, int nLine)
26166 {
26167 pcs = (csIn.TryEnter(pszName, pszFile, nLine) ? &csIn : NULL);
26168 }
26169
26170 operator bool() const
26171 {
26172 return Entered();
26173 }
26174
26175 ~CTryCriticalBlock()
26176 {
26177 if (pcs)
26178 {
26179 pcs->Leave();
26180 }
26181 }
26182 bool Entered() const { return pcs != NULL; }
26183 };
26184
26185 #define TRY_CRITICAL_BLOCK(cs) \
26186 if (CTryCriticalBlock criticalblock = CTryCriticalBlock(cs, #cs, __FILE__, __LINE__))
26187
26188
26189
26190
26191
26192
26193 // This is exactly like std::string, but with a custom allocator.
26194 // (secure_allocator<> is defined in serialize.h)
26195 typedef std::basic_string<char, std::char_traits<char>, secure_allocator<char> > SecureString;
26196
26197 // This is exactly like std::string, but with a custom allocator.
26198 // (secure_allocator<> is defined in serialize.h)
26199 typedef std::basic_string<char, std::char_traits<char>, secure_allocator<char> > SecureString;
26200
26201
26202
26203
26204
26205 inline std::string i64tostr(int64 n)
26206 {
26207 return strprintf("%"PRI64d, n);
26208 }
26209
26210 inline std::string itostr(int n)
26211 {
26212 return strprintf("%d", n);
26213 }
26214
26215 inline int64 atoi64(const char* psz)
26216 {
26217 #ifdef _MSC_VER
26218 return _atoi64(psz);
26219 #else
26220 return strtoll(psz, NULL, 10);
26221 #endif
26222 }
26223
26224 inline int64 atoi64(const std::string& str)
26225 {
26226 #ifdef _MSC_VER
26227 return _atoi64(str.c_str());
26228 #else
26229 return strtoll(str.c_str(), NULL, 10);
26230 #endif
26231 }
26232
26233 inline int atoi(const std::string& str)
26234 {
26235 return atoi(str.c_str());
26236 }
26237
26238 inline int roundint(double d)
26239 {
26240 return (int)(d > 0 ? d + 0.5 : d - 0.5);
26241 }
26242
26243 inline int64 roundint64(double d)
26244 {
26245 return (int64)(d > 0 ? d + 0.5 : d - 0.5);
26246 }
26247
26248 inline int64 abs64(int64 n)
26249 {
26250 return (n >= 0 ? n : -n);
26251 }
26252
26253 template<typename T>
26254 std::string HexStr(const T itbegin, const T itend, bool fSpaces=false)
26255 {
26256 if (itbegin == itend)
26257 return "";
26258 const unsigned char* pbegin = (const unsigned char*)&itbegin[0];
26259 const unsigned char* pend = pbegin + (itend - itbegin) * sizeof(itbegin[0]);
26260 std::string str;
26261 str.reserve((pend-pbegin) * (fSpaces ? 3 : 2));
26262 for (const unsigned char* p = pbegin; p != pend; p++)
26263 str += strprintf((fSpaces && p != pend-1 ? "%02x " : "%02x"), *p);
26264 return str;
26265 }
26266
26267 inline std::string HexStr(const std::vector<unsigned char>& vch, bool fSpaces=false)
26268 {
26269 return HexStr(vch.begin(), vch.end(), fSpaces);
26270 }
26271
26272 template<typename T>
26273 std::string HexNumStr(const T itbegin, const T itend, bool f0x=true)
26274 {
26275 if (itbegin == itend)
26276 return "";
26277 const unsigned char* pbegin = (const unsigned char*)&itbegin[0];
26278 const unsigned char* pend = pbegin + (itend - itbegin) * sizeof(itbegin[0]);
26279 std::string str = (f0x ? "0x" : "");
26280 str.reserve(str.size() + (pend-pbegin) * 2);
26281 for (const unsigned char* p = pend-1; p >= pbegin; p--)
26282 str += strprintf("%02x", *p);
26283 return str;
26284 }
26285
26286 inline std::string HexNumStr(const std::vector<unsigned char>& vch, bool f0x=true)
26287 {
26288 return HexNumStr(vch.begin(), vch.end(), f0x);
26289 }
26290
26291 template<typename T>
26292 void PrintHex(const T pbegin, const T pend, const char* pszFormat="%s", bool fSpaces=true)
26293 {
26294 printf(pszFormat, HexStr(pbegin, pend, fSpaces).c_str());
26295 }
26296
26297 inline void PrintHex(const std::vector<unsigned char>& vch, const char* pszFormat="%s", bool fSpaces=true)
26298 {
26299 printf(pszFormat, HexStr(vch, fSpaces).c_str());
26300 }
26301
26302 inline int64 GetPerformanceCounter()
26303 {
26304 int64 nCounter = 0;
26305 #ifdef WIN32
26306 QueryPerformanceCounter((LARGE_INTEGER*)&nCounter);
26307 #else
26308 timeval t;
26309 gettimeofday(&t, NULL);
26310 nCounter = t.tv_sec * 1000000 + t.tv_usec;
26311 #endif
26312 return nCounter;
26313 }
26314
26315 inline int64 GetTimeMillis()
26316 {
26317 return (boost::posix_time::ptime(boost::posix_time::microsec_clock::universal_time()) -
26318 boost::posix_time::ptime(boost::gregorian::date(1970,1,1))).total_milliseconds();
26319 }
26320
26321 inline std::string DateTimeStrFormat(const char* pszFormat, int64 nTime)
26322 {
26323 time_t n = nTime;
26324 struct tm* ptmTime = gmtime(&n);
26325 char pszTime[200];
26326 strftime(pszTime, sizeof(pszTime), pszFormat, ptmTime);
26327 return pszTime;
26328 }
26329
26330 template<typename T>
26331 void skipspaces(T& it)
26332 {
26333 while (isspace(*it))
26334 ++it;
26335 }
26336
26337 inline bool IsSwitchChar(char c)
26338 {
26339 #ifdef WIN32
26340 return c == '-' || c == '/';
26341 #else
26342 return c == '-';
26343 #endif
26344 }
26345
26346 inline std::string GetArg(const std::string& strArg, const std::string& strDefault)
26347 {
26348 if (mapArgs.count(strArg))
26349 return mapArgs[strArg];
26350 return strDefault;
26351 }
26352
26353 inline int64 GetArg(const std::string& strArg, int64 nDefault)
26354 {
26355 if (mapArgs.count(strArg))
26356 return atoi64(mapArgs[strArg]);
26357 return nDefault;
26358 }
26359
26360 inline bool GetBoolArg(const std::string& strArg, bool fDefault=false)
26361 {
26362 if (mapArgs.count(strArg))
26363 {
26364 if (mapArgs[strArg].empty())
26365 return true;
26366 return (atoi(mapArgs[strArg]) != 0);
26367 }
26368 return fDefault;
26369 }
26370
26371 /**
26372 * Set an argument if it doesn't already have a value
26373 *
26374 * @param strArg Argument to set (e.g. "-foo")
26375 * @param strValue Value (e.g. "1")
26376 * @return true if argument gets set, false if it already had a value
26377 */
26378 bool SoftSetArg(const std::string& strArg, const std::string& strValue);
26379
26380 /**
26381 * Set a boolean argument if it doesn't already have a value
26382 *
26383 * @param strArg Argument to set (e.g. "-foo")
26384 * @param fValue Value (e.g. false)
26385 * @return true if argument gets set, false if it already had a value
26386 */
26387 bool SoftSetArg(const std::string& strArg, bool fValue);
26388
26389
26390
26391
26392
26393
26394
26395
26396
26397 inline void heapchk()
26398 {
26399 #ifdef WIN32
26400 /// for debugging
26401 //if (_heapchk() != _HEAPOK)
26402 // DebugBreak();
26403 #endif
26404 }
26405
26406 // Randomize the stack to help protect against buffer overrun exploits
26407 #define IMPLEMENT_RANDOMIZE_STACK(ThreadFn) \
26408 { \
26409 static char nLoops; \
26410 if (nLoops <= 0) \
26411 nLoops = GetRand(20) + 1; \
26412 if (nLoops-- > 1) \
26413 { \
26414 ThreadFn; \
26415 return; \
26416 } \
26417 }
26418
26419 #define CATCH_PRINT_EXCEPTION(pszFn) \
26420 catch (std::exception& e) { \
26421 PrintException(&e, (pszFn)); \
26422 } catch (...) { \
26423 PrintException(NULL, (pszFn)); \
26424 }
26425
26426
26427
26428
26429
26430
26431
26432
26433
26434
26435 template<typename T1>
26436 inline uint256 Hash(const T1 pbegin, const T1 pend)
26437 {
26438 static unsigned char pblank[1];
26439 uint256 hash1;
26440 SHA256((pbegin == pend ? pblank : (unsigned char*)&pbegin[0]), (pend - pbegin) * sizeof(pbegin[0]), (unsigned char*)&hash1);
26441 uint256 hash2;
26442 SHA256((unsigned char*)&hash1, sizeof(hash1), (unsigned char*)&hash2);
26443 return hash2;
26444 }
26445
26446 template<typename T1, typename T2>
26447 inline uint256 Hash(const T1 p1begin, const T1 p1end,
26448 const T2 p2begin, const T2 p2end)
26449 {
26450 static unsigned char pblank[1];
26451 uint256 hash1;
26452 SHA256_CTX ctx;
26453 SHA256_Init(&ctx);
26454 SHA256_Update(&ctx, (p1begin == p1end ? pblank : (unsigned char*)&p1begin[0]), (p1end - p1begin) * sizeof(p1begin[0]));
26455 SHA256_Update(&ctx, (p2begin == p2end ? pblank : (unsigned char*)&p2begin[0]), (p2end - p2begin) * sizeof(p2begin[0]));
26456 SHA256_Final((unsigned char*)&hash1, &ctx);
26457 uint256 hash2;
26458 SHA256((unsigned char*)&hash1, sizeof(hash1), (unsigned char*)&hash2);
26459 return hash2;
26460 }
26461
26462 template<typename T1, typename T2, typename T3>
26463 inline uint256 Hash(const T1 p1begin, const T1 p1end,
26464 const T2 p2begin, const T2 p2end,
26465 const T3 p3begin, const T3 p3end)
26466 {
26467 static unsigned char pblank[1];
26468 uint256 hash1;
26469 SHA256_CTX ctx;
26470 SHA256_Init(&ctx);
26471 SHA256_Update(&ctx, (p1begin == p1end ? pblank : (unsigned char*)&p1begin[0]), (p1end - p1begin) * sizeof(p1begin[0]));
26472 SHA256_Update(&ctx, (p2begin == p2end ? pblank : (unsigned char*)&p2begin[0]), (p2end - p2begin) * sizeof(p2begin[0]));
26473 SHA256_Update(&ctx, (p3begin == p3end ? pblank : (unsigned char*)&p3begin[0]), (p3end - p3begin) * sizeof(p3begin[0]));
26474 SHA256_Final((unsigned char*)&hash1, &ctx);
26475 uint256 hash2;
26476 SHA256((unsigned char*)&hash1, sizeof(hash1), (unsigned char*)&hash2);
26477 return hash2;
26478 }
26479
26480 template<typename T>
26481 uint256 SerializeHash(const T& obj, int nType=SER_GETHASH, int nVersion=VERSION)
26482 {
26483 // Most of the time is spent allocating and deallocating CDataStream's
26484 // buffer. If this ever needs to be optimized further, make a CStaticStream
26485 // class with its buffer on the stack.
26486 CDataStream ss(nType, nVersion);
26487 ss.reserve(10000);
26488 ss << obj;
26489 return Hash(ss.begin(), ss.end());
26490 }
26491
26492 inline uint160 Hash160(const std::vector<unsigned char>& vch)
26493 {
26494 uint256 hash1;
26495 SHA256(&vch[0], vch.size(), (unsigned char*)&hash1);
26496 uint160 hash2;
26497 RIPEMD160((unsigned char*)&hash1, sizeof(hash1), (unsigned char*)&hash2);
26498 return hash2;
26499 }
26500
26501
26502 // Median filter over a stream of values
26503 // Returns the median of the last N numbers
26504 template <typename T> class CMedianFilter
26505 {
26506 private:
26507 std::vector<T> vValues;
26508 std::vector<T> vSorted;
26509 int nSize;
26510 public:
26511 CMedianFilter(int size, T initial_value):
26512 nSize(size)
26513 {
26514 vValues.reserve(size);
26515 vValues.push_back(initial_value);
26516 vSorted = vValues;
26517 }
26518
26519 void input(T value)
26520 {
26521 if(vValues.size() == nSize)
26522 {
26523 vValues.erase(vValues.begin());
26524 }
26525 vValues.push_back(value);
26526
26527 vSorted.resize(vValues.size());
26528 std::copy(vValues.begin(), vValues.end(), vSorted.begin());
26529 std::sort(vSorted.begin(), vSorted.end());
26530 }
26531
26532 T median() const
26533 {
26534 int size = vSorted.size();
26535 assert(size>0);
26536 if(size & 1) // Odd number of elements
26537 {
26538 return vSorted[size/2];
26539 }
26540 else // Even number of elements
26541 {
26542 return (vSorted[size/2-1] + vSorted[size/2]) / 2;
26543 }
26544 }
26545 };
26546
26547
26548
26549
26550
26551
26552
26553
26554
26555
26556 // Note: It turns out we might have been able to use boost::thread
26557 // by using TerminateThread(boost::thread.native_handle(), 0);
26558 #ifdef WIN32
26559 typedef HANDLE pthread_t;
26560
26561 inline pthread_t CreateThread(void(*pfn)(void*), void* parg, bool fWantHandle=false)
26562 {
26563 DWORD nUnused = 0;
26564 HANDLE hthread =
26565 CreateThread(
26566 NULL, // default security
26567 0, // inherit stack size from parent
26568 (LPTHREAD_START_ROUTINE)pfn, // function pointer
26569 parg, // argument
26570 0, // creation option, start immediately
26571 &nUnused); // thread identifier
26572 if (hthread == NULL)
26573 {
26574 printf("Error: CreateThread() returned %d\n", GetLastError());
26575 return (pthread_t)0;
26576 }
26577 if (!fWantHandle)
26578 {
26579 CloseHandle(hthread);
26580 return (pthread_t)-1;
26581 }
26582 return hthread;
26583 }
26584
26585 inline void SetThreadPriority(int nPriority)
26586 {
26587 SetThreadPriority(GetCurrentThread(), nPriority);
26588 }
26589 #else
26590 inline pthread_t CreateThread(void(*pfn)(void*), void* parg, bool fWantHandle=false)
26591 {
26592 pthread_t hthread = 0;
26593 int ret = pthread_create(&hthread, NULL, (void*(*)(void*))pfn, parg);
26594 if (ret != 0)
26595 {
26596 printf("Error: pthread_create() returned %d\n", ret);
26597 return (pthread_t)0;
26598 }
26599 if (!fWantHandle)
26600 {
26601 pthread_detach(hthread);
26602 return (pthread_t)-1;
26603 }
26604 return hthread;
26605 }
26606
26607 #define THREAD_PRIORITY_LOWEST PRIO_MAX
26608 #define THREAD_PRIORITY_BELOW_NORMAL 2
26609 #define THREAD_PRIORITY_NORMAL 0
26610 #define THREAD_PRIORITY_ABOVE_NORMAL 0
26611
26612 inline void SetThreadPriority(int nPriority)
26613 {
26614 // It's unclear if it's even possible to change thread priorities on Linux,
26615 // but we really and truly need it for the generation threads.
26616 #ifdef PRIO_THREAD
26617 setpriority(PRIO_THREAD, 0, nPriority);
26618 #else
26619 setpriority(PRIO_PROCESS, 0, nPriority);
26620 #endif
26621 }
26622
26623 inline bool TerminateThread(pthread_t hthread, unsigned int nExitCode)
26624 {
26625 return (pthread_cancel(hthread) == 0);
26626 }
26627
26628 inline void ExitThread(size_t nExitCode)
26629 {
26630 pthread_exit((void*)nExitCode);
26631 }
26632 #endif
26633
26634
26635
26636
26637
26638 inline bool AffinityBugWorkaround(void(*pfn)(void*))
26639 {
26640 #ifdef WIN32
26641 // Sometimes after a few hours affinity gets stuck on one processor
26642 DWORD_PTR dwProcessAffinityMask = -1;
26643 DWORD_PTR dwSystemAffinityMask = -1;
26644 GetProcessAffinityMask(GetCurrentProcess(), &dwProcessAffinityMask, &dwSystemAffinityMask);
26645 DWORD dwPrev1 = SetThreadAffinityMask(GetCurrentThread(), dwProcessAffinityMask);
26646 DWORD dwPrev2 = SetThreadAffinityMask(GetCurrentThread(), dwProcessAffinityMask);
26647 if (dwPrev2 != dwProcessAffinityMask)
26648 {
26649 printf("AffinityBugWorkaround() : SetThreadAffinityMask=%d, ProcessAffinityMask=%d, restarting thread\n", dwPrev2, dwProcessAffinityMask);
26650 if (!CreateThread(pfn, NULL))
26651 printf("Error: CreateThread() failed\n");
26652 return true;
26653 }
26654 #endif
26655 return false;
26656 }
26657
26658 inline uint32_t ByteReverse(uint32_t value)
26659 {
26660 value = ((value & 0xFF00FF00) >> 8) | ((value & 0x00FF00FF) << 8);
26661 return (value<<16) | (value>>16);
26662 }
26663
26664 #endif