-
+ 75BC498BF713D76D2E9A489C71604DBB77792673C7F87343D4C6FCF5F20FAC57CDFFD5F15513B00F21F9DE257ADBEB3CA581147F41A8BE96D69379269021C723
bitcoin/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