]> Git Repo - VerusCoin.git/blame - src/util.h
Merge pull request #974 from sipa/walletupgrade
[VerusCoin.git] / src / util.h
CommitLineData
1f2e0df8 1// Copyright (c) 2009-2010 Satoshi Nakamoto
88216419 2// Copyright (c) 2009-2012 The Bitcoin developers
1f2e0df8
WL
3// Distributed under the MIT/X11 software license, see the accompanying
4// file license.txt or http://www.opensource.org/licenses/mit-license.php.
5#ifndef BITCOIN_UTIL_H
6#define BITCOIN_UTIL_H
7
8#include "uint256.h"
9
6853e627 10#ifndef WIN32
1f2e0df8 11#include <sys/types.h>
6644d98d
WL
12#include <sys/time.h>
13#include <sys/resource.h>
85663f2c 14#endif
1f2e0df8
WL
15#include <map>
16#include <vector>
17#include <string>
18
19#include <boost/thread.hpp>
20#include <boost/interprocess/sync/interprocess_recursive_mutex.hpp>
21#include <boost/date_time/gregorian/gregorian_types.hpp>
22#include <boost/date_time/posix_time/posix_time_types.hpp>
23
6644d98d
WL
24#include <openssl/sha.h>
25#include <openssl/ripemd.h>
26
67a42f92 27#include "netbase.h"
1f2e0df8 28
bde280b9
WL
29typedef long long int64;
30typedef unsigned long long uint64;
31
1f2e0df8
WL
32#define loop for (;;)
33#define BEGIN(a) ((char*)&(a))
34#define END(a) ((char*)&((&(a))[1]))
35#define UBEGIN(a) ((unsigned char*)&(a))
36#define UEND(a) ((unsigned char*)&((&(a))[1]))
37#define ARRAYLEN(array) (sizeof(array)/sizeof((array)[0]))
38#define printf OutputDebugStringF
39
40#ifdef snprintf
41#undef snprintf
42#endif
43#define snprintf my_snprintf
44
45#ifndef PRI64d
bd846c0e 46#if defined(_MSC_VER) || defined(__MSVCRT__)
1f2e0df8
WL
47#define PRI64d "I64d"
48#define PRI64u "I64u"
49#define PRI64x "I64x"
50#else
51#define PRI64d "lld"
52#define PRI64u "llu"
53#define PRI64x "llx"
54#endif
55#endif
56
57// This is needed because the foreach macro can't get over the comma in pair<t1, t2>
9aef9bca 58#define PAIRTYPE(t1, t2) std::pair<t1, t2>
1f2e0df8 59
1f2e0df8
WL
60// Align by increasing pointer, must have extra space at end of buffer
61template <size_t nBytes, typename T>
62T* alignup(T* p)
63{
64 union
65 {
66 T* ptr;
67 size_t n;
68 } u;
69 u.ptr = p;
70 u.n = (u.n + (nBytes-1)) & ~(nBytes-1);
71 return u.ptr;
72}
73
6853e627 74#ifdef WIN32
1f2e0df8
WL
75#define MSG_NOSIGNAL 0
76#define MSG_DONTWAIT 0
26ce92b3 77
1f2e0df8
WL
78#ifndef S_IRUSR
79#define S_IRUSR 0400
80#define S_IWUSR 0200
81#endif
82#define unlink _unlink
1f2e0df8 83#else
1f2e0df8
WL
84#define _vsnprintf(a,b,c,d) vsnprintf(a,b,c,d)
85#define strlwr(psz) to_lower(psz)
86#define _strlwr(psz) to_lower(psz)
87#define MAX_PATH 1024
bde280b9 88inline void Sleep(int64 n)
1f2e0df8 89{
82a10c81
GM
90 /*Boost has a year 2038 problem— if the request sleep time is past epoch+2^31 seconds the sleep returns instantly.
91 So we clamp our sleeps here to 10 years and hope that boost is fixed by 2028.*/
92 boost::thread::sleep(boost::get_system_time() + boost::posix_time::milliseconds(n>315576000000LL?315576000000LL:n));
1f2e0df8
WL
93}
94#endif
95
565c4771 96#if !defined(QT_GUI)
1f2e0df8
WL
97inline const char* _(const char* psz)
98{
99 return psz;
100}
101#endif
1f2e0df8
WL
102
103
104
105
106
107
108
109
110
111extern std::map<std::string, std::string> mapArgs;
112extern std::map<std::string, std::vector<std::string> > mapMultiArgs;
113extern bool fDebug;
114extern bool fPrintToConsole;
115extern bool fPrintToDebugger;
116extern char pszSetDataDir[MAX_PATH];
117extern bool fRequestShutdown;
118extern bool fShutdown;
119extern bool fDaemon;
120extern bool fServer;
121extern bool fCommandLine;
122extern std::string strMiscWarning;
123extern bool fTestNet;
124extern bool fNoListen;
125extern bool fLogTimestamps;
126
127void RandAddSeed();
128void RandAddSeedPerfmon();
129int OutputDebugStringF(const char* pszFormat, ...);
130int my_snprintf(char* buffer, size_t limit, const char* format, ...);
39cf857d
WL
131std::string strprintf(const std::string &format, ...);
132bool error(const std::string &format, ...);
1f2e0df8
WL
133void LogException(std::exception* pex, const char* pszThread);
134void PrintException(std::exception* pex, const char* pszThread);
135void PrintExceptionContinue(std::exception* pex, const char* pszThread);
136void ParseString(const std::string& str, char c, std::vector<std::string>& v);
bde280b9
WL
137std::string FormatMoney(int64 n, bool fPlus=false);
138bool ParseMoney(const std::string& str, int64& nRet);
139bool ParseMoney(const char* pszIn, int64& nRet);
1f2e0df8
WL
140std::vector<unsigned char> ParseHex(const char* psz);
141std::vector<unsigned char> ParseHex(const std::string& str);
922e8e29 142bool IsHex(const std::string& str);
4b603f1c
PW
143std::vector<unsigned char> DecodeBase64(const char* p, bool* pfInvalid = NULL);
144std::string DecodeBase64(const std::string& str);
145std::string EncodeBase64(const unsigned char* pch, size_t len);
146std::string EncodeBase64(const std::string& str);
3ae07355 147void ParseParameters(int argc, const char*const argv[]);
1f2e0df8
WL
148bool WildcardMatch(const char* psz, const char* mask);
149bool WildcardMatch(const std::string& str, const std::string& mask);
150int GetFilesize(FILE* file);
151void GetDataDir(char* pszDirRet);
152std::string GetConfigFile();
153std::string GetPidFile();
154void CreatePidFile(std::string pidFile, pid_t pid);
3f8cb2c5 155bool ReadConfigFile(std::map<std::string, std::string>& mapSettingsRet, std::map<std::string, std::vector<std::string> >& mapMultiSettingsRet);
6853e627 156#ifdef WIN32
822f2e3d 157std::string MyGetSpecialFolderPath(int nFolder, bool fCreate);
1f2e0df8
WL
158#endif
159std::string GetDefaultDataDir();
160std::string GetDataDir();
161void ShrinkDebugFile();
162int GetRandInt(int nMax);
bde280b9
WL
163uint64 GetRand(uint64 nMax);
164int64 GetTime();
165void SetMockTime(int64 nMockTimeIn);
166int64 GetAdjustedTime();
1f2e0df8 167std::string FormatFullVersion();
f8ded588 168std::string FormatSubVersion(const std::string& name, int nClientVersion, const std::vector<std::string>& comments);
67a42f92 169void AddTimeData(const CNetAddr& ip, int64 nTime);
1f2e0df8
WL
170
171
172
173
174
175
176
177
178
179
180
181
865ed8a1 182// Wrapper to automatically initialize mutex
1f2e0df8
WL
183class CCriticalSection
184{
1f2e0df8
WL
185protected:
186 boost::interprocess::interprocess_recursive_mutex mutex;
187public:
188 explicit CCriticalSection() { }
189 ~CCriticalSection() { }
865ed8a1
GA
190 void Enter(const char* pszName, const char* pszFile, int nLine);
191 void Leave();
192 bool TryEnter(const char* pszName, const char* pszFile, int nLine);
1f2e0df8
WL
193};
194
195// Automatically leave critical section when leaving block, needed for exception safety
196class CCriticalBlock
197{
198protected:
199 CCriticalSection* pcs;
865ed8a1 200
1f2e0df8 201public:
865ed8a1
GA
202 CCriticalBlock(CCriticalSection& csIn, const char* pszName, const char* pszFile, int nLine)
203 {
204 pcs = &csIn;
205 pcs->Enter(pszName, pszFile, nLine);
206 }
3083cf10
CG
207
208 operator bool() const
209 {
210 return true;
211 }
212
865ed8a1
GA
213 ~CCriticalBlock()
214 {
215 pcs->Leave();
216 }
1f2e0df8
WL
217};
218
1f2e0df8 219#define CRITICAL_BLOCK(cs) \
3083cf10 220 if (CCriticalBlock criticalblock = CCriticalBlock(cs, #cs, __FILE__, __LINE__))
1f2e0df8 221
88bc5f94
PW
222#define ENTER_CRITICAL_SECTION(cs) \
223 (cs).Enter(#cs, __FILE__, __LINE__)
224
225#define LEAVE_CRITICAL_SECTION(cs) \
226 (cs).Leave()
227
1f2e0df8
WL
228class CTryCriticalBlock
229{
230protected:
231 CCriticalSection* pcs;
865ed8a1 232
1f2e0df8 233public:
865ed8a1
GA
234 CTryCriticalBlock(CCriticalSection& csIn, const char* pszName, const char* pszFile, int nLine)
235 {
236 pcs = (csIn.TryEnter(pszName, pszFile, nLine) ? &csIn : NULL);
237 }
3083cf10
CG
238
239 operator bool() const
240 {
241 return Entered();
242 }
243
865ed8a1
GA
244 ~CTryCriticalBlock()
245 {
246 if (pcs)
247 {
248 pcs->Leave();
249 }
250 }
3083cf10 251 bool Entered() const { return pcs != NULL; }
1f2e0df8
WL
252};
253
254#define TRY_CRITICAL_BLOCK(cs) \
3083cf10 255 if (CTryCriticalBlock criticalblock = CTryCriticalBlock(cs, #cs, __FILE__, __LINE__))
1f2e0df8
WL
256
257
258
259
260
261
94f778bd
DN
262// This is exactly like std::string, but with a custom allocator.
263// (secure_allocator<> is defined in serialize.h)
264typedef std::basic_string<char, std::char_traits<char>, secure_allocator<char> > SecureString;
265
1f2e0df8
WL
266
267
268
269
bde280b9 270inline std::string i64tostr(int64 n)
1f2e0df8
WL
271{
272 return strprintf("%"PRI64d, n);
273}
274
275inline std::string itostr(int n)
276{
277 return strprintf("%d", n);
278}
279
bde280b9 280inline int64 atoi64(const char* psz)
1f2e0df8
WL
281{
282#ifdef _MSC_VER
283 return _atoi64(psz);
284#else
285 return strtoll(psz, NULL, 10);
286#endif
287}
288
bde280b9 289inline int64 atoi64(const std::string& str)
1f2e0df8
WL
290{
291#ifdef _MSC_VER
292 return _atoi64(str.c_str());
293#else
294 return strtoll(str.c_str(), NULL, 10);
295#endif
296}
297
298inline int atoi(const std::string& str)
299{
300 return atoi(str.c_str());
301}
302
303inline int roundint(double d)
304{
305 return (int)(d > 0 ? d + 0.5 : d - 0.5);
306}
307
bde280b9 308inline int64 roundint64(double d)
1f2e0df8 309{
bde280b9 310 return (int64)(d > 0 ? d + 0.5 : d - 0.5);
1f2e0df8
WL
311}
312
bde280b9 313inline int64 abs64(int64 n)
1f2e0df8
WL
314{
315 return (n >= 0 ? n : -n);
316}
317
318template<typename T>
319std::string HexStr(const T itbegin, const T itend, bool fSpaces=false)
320{
321 if (itbegin == itend)
322 return "";
323 const unsigned char* pbegin = (const unsigned char*)&itbegin[0];
324 const unsigned char* pend = pbegin + (itend - itbegin) * sizeof(itbegin[0]);
325 std::string str;
326 str.reserve((pend-pbegin) * (fSpaces ? 3 : 2));
327 for (const unsigned char* p = pbegin; p != pend; p++)
328 str += strprintf((fSpaces && p != pend-1 ? "%02x " : "%02x"), *p);
329 return str;
330}
331
332inline std::string HexStr(const std::vector<unsigned char>& vch, bool fSpaces=false)
333{
334 return HexStr(vch.begin(), vch.end(), fSpaces);
335}
336
1f2e0df8
WL
337template<typename T>
338void PrintHex(const T pbegin, const T pend, const char* pszFormat="%s", bool fSpaces=true)
339{
340 printf(pszFormat, HexStr(pbegin, pend, fSpaces).c_str());
341}
342
343inline void PrintHex(const std::vector<unsigned char>& vch, const char* pszFormat="%s", bool fSpaces=true)
344{
345 printf(pszFormat, HexStr(vch, fSpaces).c_str());
346}
347
bde280b9 348inline int64 GetPerformanceCounter()
1f2e0df8 349{
bde280b9 350 int64 nCounter = 0;
6853e627 351#ifdef WIN32
1f2e0df8
WL
352 QueryPerformanceCounter((LARGE_INTEGER*)&nCounter);
353#else
354 timeval t;
355 gettimeofday(&t, NULL);
356 nCounter = t.tv_sec * 1000000 + t.tv_usec;
357#endif
358 return nCounter;
359}
360
bde280b9 361inline int64 GetTimeMillis()
1f2e0df8
WL
362{
363 return (boost::posix_time::ptime(boost::posix_time::microsec_clock::universal_time()) -
364 boost::posix_time::ptime(boost::gregorian::date(1970,1,1))).total_milliseconds();
365}
366
bde280b9 367inline std::string DateTimeStrFormat(const char* pszFormat, int64 nTime)
1f2e0df8
WL
368{
369 time_t n = nTime;
370 struct tm* ptmTime = gmtime(&n);
371 char pszTime[200];
372 strftime(pszTime, sizeof(pszTime), pszFormat, ptmTime);
373 return pszTime;
374}
375
376template<typename T>
377void skipspaces(T& it)
378{
379 while (isspace(*it))
380 ++it;
381}
382
383inline bool IsSwitchChar(char c)
384{
6853e627 385#ifdef WIN32
1f2e0df8
WL
386 return c == '-' || c == '/';
387#else
388 return c == '-';
389#endif
390}
391
3ae07355
GA
392/**
393 * Return string argument or default value
394 *
395 * @param strArg Argument to get (e.g. "-foo")
396 * @param default (e.g. "1")
397 * @return command-line argument or default value
398 */
399std::string GetArg(const std::string& strArg, const std::string& strDefault);
1f2e0df8 400
3ae07355
GA
401/**
402 * Return integer argument or default value
403 *
404 * @param strArg Argument to get (e.g. "-foo")
405 * @param default (e.g. 1)
406 * @return command-line argument (0 if invalid number) or default value
407 */
408int64 GetArg(const std::string& strArg, int64 nDefault);
1f2e0df8 409
3ae07355
GA
410/**
411 * Return boolean argument or default value
412 *
413 * @param strArg Argument to get (e.g. "-foo")
414 * @param default (true or false)
415 * @return command-line argument or default value
416 */
417bool GetBoolArg(const std::string& strArg, bool fDefault=false);
1f2e0df8 418
0fcf91ea
GA
419/**
420 * Set an argument if it doesn't already have a value
421 *
422 * @param strArg Argument to set (e.g. "-foo")
423 * @param strValue Value (e.g. "1")
424 * @return true if argument gets set, false if it already had a value
425 */
426bool SoftSetArg(const std::string& strArg, const std::string& strValue);
427
428/**
429 * Set a boolean argument if it doesn't already have a value
430 *
431 * @param strArg Argument to set (e.g. "-foo")
432 * @param fValue Value (e.g. false)
433 * @return true if argument gets set, false if it already had a value
434 */
7bf8b7c2 435bool SoftSetBoolArg(const std::string& strArg, bool fValue);
1f2e0df8
WL
436
437
438
439
440
441
442
443
444
1f2e0df8
WL
445// Randomize the stack to help protect against buffer overrun exploits
446#define IMPLEMENT_RANDOMIZE_STACK(ThreadFn) \
447 { \
448 static char nLoops; \
449 if (nLoops <= 0) \
450 nLoops = GetRand(20) + 1; \
451 if (nLoops-- > 1) \
452 { \
453 ThreadFn; \
454 return; \
455 } \
456 }
457
1f2e0df8
WL
458
459template<typename T1>
460inline uint256 Hash(const T1 pbegin, const T1 pend)
461{
462 static unsigned char pblank[1];
463 uint256 hash1;
464 SHA256((pbegin == pend ? pblank : (unsigned char*)&pbegin[0]), (pend - pbegin) * sizeof(pbegin[0]), (unsigned char*)&hash1);
465 uint256 hash2;
466 SHA256((unsigned char*)&hash1, sizeof(hash1), (unsigned char*)&hash2);
467 return hash2;
468}
469
470template<typename T1, typename T2>
471inline uint256 Hash(const T1 p1begin, const T1 p1end,
472 const T2 p2begin, const T2 p2end)
473{
474 static unsigned char pblank[1];
475 uint256 hash1;
476 SHA256_CTX ctx;
477 SHA256_Init(&ctx);
478 SHA256_Update(&ctx, (p1begin == p1end ? pblank : (unsigned char*)&p1begin[0]), (p1end - p1begin) * sizeof(p1begin[0]));
479 SHA256_Update(&ctx, (p2begin == p2end ? pblank : (unsigned char*)&p2begin[0]), (p2end - p2begin) * sizeof(p2begin[0]));
480 SHA256_Final((unsigned char*)&hash1, &ctx);
481 uint256 hash2;
482 SHA256((unsigned char*)&hash1, sizeof(hash1), (unsigned char*)&hash2);
483 return hash2;
484}
485
486template<typename T1, typename T2, typename T3>
487inline uint256 Hash(const T1 p1begin, const T1 p1end,
488 const T2 p2begin, const T2 p2end,
489 const T3 p3begin, const T3 p3end)
490{
491 static unsigned char pblank[1];
492 uint256 hash1;
493 SHA256_CTX ctx;
494 SHA256_Init(&ctx);
495 SHA256_Update(&ctx, (p1begin == p1end ? pblank : (unsigned char*)&p1begin[0]), (p1end - p1begin) * sizeof(p1begin[0]));
496 SHA256_Update(&ctx, (p2begin == p2end ? pblank : (unsigned char*)&p2begin[0]), (p2end - p2begin) * sizeof(p2begin[0]));
497 SHA256_Update(&ctx, (p3begin == p3end ? pblank : (unsigned char*)&p3begin[0]), (p3end - p3begin) * sizeof(p3begin[0]));
498 SHA256_Final((unsigned char*)&hash1, &ctx);
499 uint256 hash2;
500 SHA256((unsigned char*)&hash1, sizeof(hash1), (unsigned char*)&hash2);
501 return hash2;
502}
503
504template<typename T>
f8ded588 505uint256 SerializeHash(const T& obj, int nType=SER_GETHASH, int nVersion=PROTOCOL_VERSION)
1f2e0df8
WL
506{
507 // Most of the time is spent allocating and deallocating CDataStream's
508 // buffer. If this ever needs to be optimized further, make a CStaticStream
509 // class with its buffer on the stack.
510 CDataStream ss(nType, nVersion);
511 ss.reserve(10000);
512 ss << obj;
513 return Hash(ss.begin(), ss.end());
514}
515
6644d98d 516inline uint160 Hash160(const std::vector<unsigned char>& vch)
1f2e0df8
WL
517{
518 uint256 hash1;
519 SHA256(&vch[0], vch.size(), (unsigned char*)&hash1);
520 uint160 hash2;
521 RIPEMD160((unsigned char*)&hash1, sizeof(hash1), (unsigned char*)&hash2);
522 return hash2;
523}
524
525
a8b95ce6
WL
526// Median filter over a stream of values
527// Returns the median of the last N numbers
528template <typename T> class CMedianFilter
529{
530private:
531 std::vector<T> vValues;
532 std::vector<T> vSorted;
533 int nSize;
534public:
535 CMedianFilter(int size, T initial_value):
536 nSize(size)
537 {
538 vValues.reserve(size);
539 vValues.push_back(initial_value);
540 vSorted = vValues;
541 }
542
543 void input(T value)
544 {
545 if(vValues.size() == nSize)
546 {
547 vValues.erase(vValues.begin());
548 }
549 vValues.push_back(value);
550
551 vSorted.resize(vValues.size());
552 std::copy(vValues.begin(), vValues.end(), vSorted.begin());
553 std::sort(vSorted.begin(), vSorted.end());
554 }
555
556 T median() const
557 {
558 int size = vSorted.size();
20091df7 559 assert(size>0);
a8b95ce6
WL
560 if(size & 1) // Odd number of elements
561 {
562 return vSorted[size/2];
563 }
564 else // Even number of elements
565 {
566 return (vSorted[size/2-1] + vSorted[size/2]) / 2;
567 }
568 }
1c4aab92
MH
569
570 int size() const
571 {
572 return vValues.size();
573 }
574
575 std::vector<T> sorted () const
576 {
577 return vSorted;
578 }
a8b95ce6
WL
579};
580
1f2e0df8
WL
581
582
583
584
585
586
587
588
589
590// Note: It turns out we might have been able to use boost::thread
591// by using TerminateThread(boost::thread.native_handle(), 0);
6853e627 592#ifdef WIN32
1f2e0df8
WL
593typedef HANDLE pthread_t;
594
595inline pthread_t CreateThread(void(*pfn)(void*), void* parg, bool fWantHandle=false)
596{
597 DWORD nUnused = 0;
598 HANDLE hthread =
599 CreateThread(
600 NULL, // default security
601 0, // inherit stack size from parent
602 (LPTHREAD_START_ROUTINE)pfn, // function pointer
603 parg, // argument
604 0, // creation option, start immediately
605 &nUnused); // thread identifier
606 if (hthread == NULL)
607 {
608 printf("Error: CreateThread() returned %d\n", GetLastError());
609 return (pthread_t)0;
610 }
611 if (!fWantHandle)
612 {
613 CloseHandle(hthread);
614 return (pthread_t)-1;
615 }
616 return hthread;
617}
618
619inline void SetThreadPriority(int nPriority)
620{
621 SetThreadPriority(GetCurrentThread(), nPriority);
622}
623#else
624inline pthread_t CreateThread(void(*pfn)(void*), void* parg, bool fWantHandle=false)
625{
626 pthread_t hthread = 0;
627 int ret = pthread_create(&hthread, NULL, (void*(*)(void*))pfn, parg);
628 if (ret != 0)
629 {
630 printf("Error: pthread_create() returned %d\n", ret);
631 return (pthread_t)0;
632 }
633 if (!fWantHandle)
67ed7d9d
J
634 {
635 pthread_detach(hthread);
1f2e0df8 636 return (pthread_t)-1;
67ed7d9d 637 }
1f2e0df8
WL
638 return hthread;
639}
640
641#define THREAD_PRIORITY_LOWEST PRIO_MAX
642#define THREAD_PRIORITY_BELOW_NORMAL 2
643#define THREAD_PRIORITY_NORMAL 0
644#define THREAD_PRIORITY_ABOVE_NORMAL 0
645
646inline void SetThreadPriority(int nPriority)
647{
648 // It's unclear if it's even possible to change thread priorities on Linux,
649 // but we really and truly need it for the generation threads.
650#ifdef PRIO_THREAD
651 setpriority(PRIO_THREAD, 0, nPriority);
652#else
653 setpriority(PRIO_PROCESS, 0, nPriority);
654#endif
655}
656
df401814 657inline void ExitThread(size_t nExitCode)
1f2e0df8
WL
658{
659 pthread_exit((void*)nExitCode);
660}
661#endif
662
663
664
665
666
667inline bool AffinityBugWorkaround(void(*pfn)(void*))
668{
6853e627 669#ifdef WIN32
1f2e0df8 670 // Sometimes after a few hours affinity gets stuck on one processor
b95e6376
VL
671 DWORD_PTR dwProcessAffinityMask = -1;
672 DWORD_PTR dwSystemAffinityMask = -1;
1f2e0df8
WL
673 GetProcessAffinityMask(GetCurrentProcess(), &dwProcessAffinityMask, &dwSystemAffinityMask);
674 DWORD dwPrev1 = SetThreadAffinityMask(GetCurrentThread(), dwProcessAffinityMask);
675 DWORD dwPrev2 = SetThreadAffinityMask(GetCurrentThread(), dwProcessAffinityMask);
676 if (dwPrev2 != dwProcessAffinityMask)
677 {
678 printf("AffinityBugWorkaround() : SetThreadAffinityMask=%d, ProcessAffinityMask=%d, restarting thread\n", dwPrev2, dwProcessAffinityMask);
679 if (!CreateThread(pfn, NULL))
680 printf("Error: CreateThread() failed\n");
681 return true;
682 }
683#endif
684 return false;
685}
686
6ccff2cb
NS
687inline uint32_t ByteReverse(uint32_t value)
688{
b985efaa
LR
689 value = ((value & 0xFF00FF00) >> 8) | ((value & 0x00FF00FF) << 8);
690 return (value<<16) | (value>>16);
6ccff2cb
NS
691}
692
1f2e0df8 693#endif
67a42f92 694
This page took 0.16787 seconds and 4 git commands to generate.