87 using namespace std::chrono;
91 #pragma intrinsic (_InterlockedDecrement)
92 #pragma intrinsic (_InterlockedIncrement)
93 #pragma intrinsic (_InterlockedExchange)
94 #pragma intrinsic (_InterlockedExchange64)
95 #pragma intrinsic (_InterlockedCompareExchange)
96 #pragma intrinsic (_InterlockedCompareExchange64)
105 #define R250_IA (sizeof(uint32)*103)
106 #define R250_IB (sizeof(uint32)*R250_LEN-R250_IA)
107 #define R521_IA (sizeof(uint32)*168)
108 #define R521_IB (sizeof(uint32)*R521_LEN-R521_IA)
113 bool CalcTimeout(
struct timespec &timeout, uint32 ms) {
116 if (gettimeofday(&now, NULL) != 0)
119 timeout.tv_sec = now.tv_sec + ms / 1000;
120 long us = now.tv_usec + ms % 1000;
125 timeout.tv_nsec = us * 1000;
131 if (gettimeofday(&tv, NULL))
133 return (tv.tv_usec + tv.tv_sec * 1000000LL);
137 void Error::PrintBinary(
void* p, uint32 size,
bool asInt,
const char* title) {
139 printf(
"--- %s %u ---\n", title, size);
141 for (uint32 n = 0; n < size; n++) {
142 c = *(((
unsigned char*)p) + n);
144 printf(
"[%u] ", (
unsigned int)c);
147 if ((n > 0) && ((n + 1) % 10 == 0))
153 SharedLibrary *SharedLibrary::New(
const char *fileName) {
155 SharedLibrary *sl =
new SharedLibrary();
156 if (sl->load(fileName))
165 SharedLibrary::SharedLibrary() : library_(NULL) {
168 SharedLibrary::~SharedLibrary() {
171 FreeLibrary(library_);
178 SharedLibrary *SharedLibrary::load(
const char *fileName) {
180 library_ = LoadLibrary(TEXT(fileName));
183 DWORD error = GetLastError();
184 std::cerr <<
"> Error: unable to load shared library " << fileName <<
" :" << error << std::endl;
193 char *libraryName = (
char *)calloc(1, strlen(fileName) + 6 + 1);
194 if (strstr(fileName,
"lib") == NULL) {
195 strcat(libraryName,
"lib");
197 strcat(libraryName, fileName);
198 if (strstr(fileName + (strlen(fileName) - 3),
".so") == NULL) {
199 strcat(libraryName,
".so");
201 library_ = dlopen(libraryName, RTLD_NOW | RTLD_GLOBAL);
203 std::cout <<
"> Error: unable to load shared library " << fileName <<
" :" << dlerror() << std::endl;
214 void Thread::TerminateAndWait(Thread **threads, uint32 threadCount) {
217 for (uint32 i = 0; i < threadCount; i++) {
218 threads[i]->terminate();
219 Thread::Wait(threads[i]);
223 void Thread::TerminateAndWait(Thread *thread) {
227 Thread::Wait(thread);
230 void Thread::Wait(Thread **threads, uint32 threadCount) {
235 for (uint32 i = 0; i < threadCount; i++)
236 WaitForSingleObject(threads[i]->thread_, INFINITE);
238 for (uint32 i = 0; i < threadCount; i++)
239 pthread_join(threads[i]->thread_, NULL);
243 void Thread::Wait(Thread *thread) {
248 WaitForSingleObject(thread->thread_, INFINITE);
250 pthread_join(thread->thread_, NULL);
254 void Thread::Sleep(milliseconds ms) {
256 ::Sleep((uint32)ms.count());
263 void Thread::Sleep() {
272 Thread::Thread() : is_meaningful_(false) {
280 CloseHandle(thread_);
286 void Thread::start(thread_function f) {
288 thread_ = CreateThread(NULL, 65536, f,
this, 0, NULL);
290 pthread_create(&thread_, NULL, f,
this);
292 is_meaningful_ =
true;
295 void Thread::suspend() {
297 SuspendThread(thread_);
299 pthread_kill(thread_, SIGSTOP);
303 void Thread::resume() {
305 ResumeThread(thread_);
307 pthread_kill(thread_, SIGCONT);
311 void Thread::terminate() {
313 TerminateThread(thread_, 0);
315 pthread_cancel(thread_);
321 void TimeProbe::set() {
323 cpu_counts_ = getCounts();
326 int64 TimeProbe::getCounts() {
328 LARGE_INTEGER counter;
329 QueryPerformanceCounter(&counter);
330 return counter.QuadPart;
332 static struct timeval tv;
333 static struct timezone tz;
334 gettimeofday(&tv, &tz);
335 return (((int64)tv.tv_sec) * 1000000) + (int64)tv.tv_usec;
339 void TimeProbe::check() {
341 cpu_counts_ = getCounts() - cpu_counts_;
347 typedef LONG NTSTATUS;
348 typedef NTSTATUS(__stdcall *NSTR)(ULONG, BOOLEAN, PULONG);
349 #define STATUS_SUCCESS ((NTSTATUS)0x00000000L)
350 bool NtSetTimerResolution(IN ULONG RequestedResolution, IN BOOLEAN Set, OUT PULONG ActualResolution);
355 float64 Time::Period_;
357 Timestamp Time::InitTime_;
359 void Time::Init(uint32 r) {
362 HMODULE NTDll = ::LoadLibrary(
"NTDLL");
363 ULONG actualResolution = 0;
366 NSTR pNSTR = (NSTR)::GetProcAddress(NTDll,
"NtSetTimerResolution");
368 nts = (*pNSTR)(10 * r,
true, &actualResolution);
371 QueryPerformanceFrequency(&f);
372 Period_ = 1000000.0 / f.QuadPart;
373 struct _timeb local_time;
375 auto now = Timestamp(microseconds((int64)(local_time.time * 1000 + local_time.millitm) * 1000));
377 InitTime_ = Timestamp(seconds(0));
378 InitTime_ = now - Get().time_since_epoch();
381 InitTime_ = system_clock::now() - duration_cast<microseconds>(steady_clock::now().time_since_epoch());
385 Timestamp Time::Get() {
387 LARGE_INTEGER counter;
388 QueryPerformanceCounter(&counter);
389 return InitTime_ + microseconds((uint64)(counter.QuadPart * Period_));
391 return InitTime_ + duration_cast<microseconds>(steady_clock::now().time_since_epoch());
395 std::string Time::ToString_seconds(Timestamp::duration duration) {
397 uint64 t = abs(duration_cast<microseconds>(duration).count());
399 uint64 us = t % 1000;
400 uint64 ms = t / 1000;
401 uint64 s = ms / 1000;
405 result += std::to_string(s);
407 result += std::to_string(ms);
409 result += std::to_string(us);
415 std::string Time::ToString_year(Timestamp timestamp) {
417 uint64 t = abs(duration_cast<microseconds>(timestamp.time_since_epoch()).count());
419 uint64 us = t % 1000;
420 uint64 ms = t / 1000;
421 uint64 s = ms / 1000;
424 time_t _gmt_time = s;
425 struct tm *_t = gmtime(&_gmt_time);
427 std::string _s = asctime(_t);
428 std::string year = _s.substr(_s.length() - 5, 4);
429 _s.erase(_s.length() - 6, 5);
430 std::string hh_mm_ss = _s.substr(_s.length() - 9, 8);
432 hh_mm_ss += std::to_string(ms);
434 hh_mm_ss += std::to_string(us);
436 _s.erase(_s.length() - 9, 9);
447 uint8 Host::Name(
char *name) {
450 GetComputerName(name, &s);
453 struct utsname utsname;
455 strcpy(name, utsname.nodename);
463 const uint32 Semaphore::Infinite = INFINITE;
470 const uint32 Semaphore::Infinite = INT_MAX;
473 Semaphore::Semaphore(uint32 initialCount, uint32 maxCount) {
475 s_ = CreateSemaphore(NULL, initialCount, maxCount, NULL);
477 sem_init(&s_, 0, initialCount);
481 Semaphore::~Semaphore() {
489 bool Semaphore::acquire(uint32 timeout) {
491 uint32 r = WaitForSingleObject(s_, timeout);
492 return r == WAIT_TIMEOUT;
497 CalcTimeout(t, timeout);
498 r = sem_timedwait(&s_, &t);
503 void Semaphore::release(uint32 count) {
505 ReleaseSemaphore(s_, count, NULL);
507 for (uint32 c = 0; c < count; c++)
512 void Semaphore::reset() {
529 const uint32 Mutex::Infinite = INFINITE;
536 const uint32 Mutex::Infinite = INT_MAX;
541 m_ = CreateMutex(NULL,
false, NULL);
543 pthread_mutex_init(&m_, NULL);
551 pthread_mutex_destroy(&m_);
555 bool Mutex::acquire(uint32 timeout) {
557 uint32 r = WaitForSingleObject(m_, timeout);
558 return r == WAIT_TIMEOUT;
560 int64 start = Time::Get();
561 int64 uTimeout = timeout * 1000;
563 while (pthread_mutex_trylock(&m_) != 0) {
565 if (Time::Get() - start >= uTimeout)
573 void Mutex::release() {
577 pthread_mutex_unlock(&m_);
583 CriticalSection::CriticalSection() {
585 InitializeCriticalSection(&cs_);
587 pthread_mutex_init(&CS, NULL);
591 CriticalSection::~CriticalSection() {
593 DeleteCriticalSection(&cs_);
595 pthread_mutex_destroy(&CS);
599 void CriticalSection::enter() {
601 EnterCriticalSection(&cs_);
603 pthread_mutex_lock(&CS);
607 void CriticalSection::leave() {
609 LeaveCriticalSection(&cs_);
611 pthread_mutex_unlock(&CS);
618 const uint32 Timer::Infinite = INFINITE;
620 const uint32 Timer::Infinite = INT_MAX;
622 static void timer_signal_handler(
int sig, siginfo_t *siginfo,
void *context) {
623 SemaTex* sematex = (SemaTex*)siginfo->si_value.sival_ptr;
626 pthread_mutex_lock(&sematex->mutex);
627 pthread_cond_broadcast(&sematex->semaphore);
628 pthread_mutex_unlock(&sematex->mutex);
634 t_ = CreateWaitableTimer(NULL,
false, NULL);
636 printf(
"Error creating timer\n");
639 pthread_cond_init(&sematex.semaphore, NULL);
640 pthread_mutex_init(&sematex.mutex, NULL);
643 struct sigevent timer_event;
645 sigemptyset(&sa.sa_mask);
646 sa.sa_flags = SA_SIGINFO;
647 sa.sa_sigaction = timer_signal_handler;
648 sigaction(SIGRTMIN, &sa, NULL);
650 timer_event.sigev_notify = SIGEV_SIGNAL;
651 timer_event.sigev_signo = SIGRTMIN;
652 timer_event.sigev_value.sival_ptr = (
void *)&sematex;
653 int ret = timer_create(CLOCK_REALTIME, &timer_event, &timer);
655 printf(
"Error creating timer: %d\n", ret);
664 pthread_cond_destroy(&sematex.semaphore);
665 pthread_mutex_destroy(&sematex.mutex);
670 void Timer::start(microseconds deadline, milliseconds period) {
672 LARGE_INTEGER _deadline;
673 _deadline.QuadPart = -10LL * deadline.count();
674 bool r = SetWaitableTimer(t_, &_deadline, (
long)period.count(), NULL, NULL, 0);
676 printf(
"Error arming timer\n");
679 struct itimerspec newtv;
682 uint64 t = deadline.count();
683 uint64 p = period_ * 1000;
684 newtv.it_interval.tv_sec = p / 1000000;
685 newtv.it_interval.tv_nsec = (p % 1000000) * 1000;
686 newtv.it_value.tv_sec = t / 1000000;
687 newtv.it_value.tv_nsec = (t % 1000000) * 1000;
689 pthread_mutex_lock(&sematex.mutex);
691 int ret = timer_settime(timer, 0, &newtv, NULL);
693 printf(
"Error arming timer: %d\n", ret);
695 sigemptyset(&allsigs);
697 pthread_mutex_unlock(&sematex.mutex);
701 bool Timer::wait(uint32 timeout) {
703 uint32 r = WaitForSingleObject(t_, timeout);
704 return r == WAIT_TIMEOUT;
707 struct timespec ttimeout;
709 pthread_mutex_lock(&sematex.mutex);
710 if (timeout == INT_MAX) {
711 res = (pthread_cond_wait(&sematex.semaphore, &sematex.mutex) == 0);
714 CalcTimeout(ttimeout, timeout);
715 res = (pthread_cond_timedwait(&sematex.semaphore, &sematex.mutex, &ttimeout) == 0);
717 pthread_mutex_unlock(&sematex.mutex);
726 e_ = CreateEvent(NULL,
true,
false, NULL);
742 WaitForSingleObject(e_, INFINITE);
756 void Event::reset() {
766 void SignalHandler::Add(signal_handler h) {
768 if (SetConsoleCtrlHandler(h,
true) == 0) {
770 int e = GetLastError();
771 std::cerr <<
"Error: " << e <<
" failed to add signal handler" << std::endl;
775 signal(SIGABRT, SIG_IGN);
776 signal(SIGPIPE, SIG_IGN);
777 signal(SIGBUS, SIG_IGN);
788 void SignalHandler::Remove(signal_handler h) {
790 SetConsoleCtrlHandler(h,
false);
792 signal(SIGABRT, SIG_IGN);
793 signal(SIGPIPE, SIG_IGN);
794 signal(SIGBUS, SIG_IGN);
796 signal(SIGTERM, SIG_DFL);
797 signal(SIGINT, SIG_DFL);
798 signal(SIGABRT, SIG_DFL);
807 int32 Atomic::Increment32(int32
volatile *v) {
809 return InterlockedIncrement((
long*)v);
811 __sync_add_and_fetch(v, 1);
816 int32 Atomic::Decrement32(int32
volatile *v) {
818 return InterlockedDecrement((
long*)v);
820 __sync_add_and_fetch(v, -1);
825 int32 Atomic::CompareAndSwap32(int32
volatile *target, int32 v1, int32 v2) {
827 return _InterlockedCompareExchange((
long*)target, v2, v1);
830 return __sync_val_compare_and_swap(target, v1, v2);
834 int64 Atomic::CompareAndSwap64(int64
volatile *target, int64 v1, int64 v2) {
836 return _InterlockedCompareExchange64(target, v2, v1);
839 return __sync_val_compare_and_swap(target, v1, v2);
851 int32 Atomic::Swap32(int32
volatile *target, int32 v) {
853 return _InterlockedExchange((
long*)target, v);
855 return __sync_fetch_and_sub(target, v);
859 int64 Atomic::Swap64(int64
volatile *target, int64 v) {
861 return CompareAndSwap64(target, v, v);
863 return __sync_fetch_and_sub(target, v);
877 uint8 BSR(word data) {
881 _BitScanReverse(&index, data);
883 #elif defined ARCH_64
885 _BitScanReverse64(&index, data);
890 return (uint8)(31 - __builtin_clz((uint32_t)data));
891 #elif defined ARCH_64
892 return (uint8)(63 - __builtin_clzll((uint64_t)data));
899 FastSemaphore::FastSemaphore(uint32 initialCount, uint32 maxCount) : Semaphore(initialCount > 0 ? 1 : 0, 1), count_(initialCount), maxCount_(maxCount) {
902 FastSemaphore::~FastSemaphore() {
905 void FastSemaphore::acquire() {
908 while ((c = Atomic::Decrement32(&count_)) >= maxCount_);
910 Semaphore::acquire();
913 void FastSemaphore::release() {
915 int32 c = Atomic::Increment32(&count_);
917 Semaphore::release();
944 bool Error::PrintLastOSErrorMessage(
const char* title) {
945 int32 err = Error::GetLastOSErrorNumber();
947 if (!Error::GetOSErrorMessage(buf, 1024, err))
948 printf(
"%s: [%d] (could not get error message)\n", title, err);
950 printf(
"%s: [%d] %s\n", title, err, buf);
954 int32 Error::GetLastOSErrorNumber() {
956 int32 err = WSAGetLastError();
964 bool Error::GetOSErrorMessage(
char* buffer, uint32 buflen, int32 err) {
968 strcpy(buffer,
"String buffer not large enough");
972 err = Error::GetLastOSErrorNumber();
975 if (err == WSANOTINITIALISED) {
976 strcpy(buffer,
"Cannot initialize WinSock!");
978 else if (err == WSAENETDOWN) {
979 strcpy(buffer,
"The network subsystem or the associated service provider has failed");
981 else if (err == WSAEAFNOSUPPORT) {
982 strcpy(buffer,
"The specified address family is not supported");
984 else if (err == WSAEINPROGRESS) {
985 strcpy(buffer,
"A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function");
987 else if (err == WSAEMFILE) {
988 strcpy(buffer,
"No more socket descriptors are available");
990 else if (err == WSAENOBUFS) {
991 strcpy(buffer,
"No buffer space is available. The socket cannot be created");
993 else if (err == WSAEPROTONOSUPPORT) {
994 strcpy(buffer,
"The specified protocol is not supported");
996 else if (err == WSAEPROTOTYPE) {
997 strcpy(buffer,
"The specified protocol is the wrong type for this socket");
999 else if (err == WSAESOCKTNOSUPPORT) {
1000 strcpy(buffer,
"The specified socket type is not supported in this address family");
1002 else if (err == WSAEADDRINUSE) {
1003 strcpy(buffer,
"The socket's local address is already in use and the socket was not marked to allow address reuse with SO_REUSEADDR. This error usually occurs during execution of the bind function, but could be delayed until this function if the bind was to a partially wildcard address (involving ADDR_ANY) and if a specific address needs to be committed at the time of this function");
1005 else if (err == WSAEINVAL) {
1006 strcpy(buffer,
"The socket has not been bound with bind");
1008 else if (err == WSAEISCONN) {
1009 strcpy(buffer,
"The socket is already connected");
1011 else if (err == WSAENOTSOCK) {
1012 strcpy(buffer,
"The descriptor is not a socket");
1014 else if (err == WSAEOPNOTSUPP) {
1015 strcpy(buffer,
"The referenced socket is not of a type that supports the listen operation");
1017 else if (err == WSAEADDRNOTAVAIL) {
1018 strcpy(buffer,
"The specified address is not a valid address for this machine");
1020 else if (err == WSAEFAULT) {
1021 strcpy(buffer,
"The name or namelen parameter is not a valid part of the user address space, the namelen parameter is too small, the name parameter contains an incorrect address format for the associated address family, or the first two bytes of the memory block specified by name does not match the address family associated with the socket descriptor s");
1023 else if (err == WSAEMFILE) {
1024 strcpy(buffer,
"The queue is nonempty upon entry to accept and there are no descriptors available");
1026 else if (err == SOCKETWOULDBLOCK) {
1027 strcpy(buffer,
"The socket is marked as nonblocking and no connections are present to be accepted");
1029 else if (err == WSAETIMEDOUT) {
1030 strcpy(buffer,
"Attempt to connect timed out without establishing a connection");
1032 else if (err == WSAENETUNREACH) {
1033 strcpy(buffer,
"The network cannot be reached from this host at this time");
1035 else if (err == WSAEISCONN) {
1036 strcpy(buffer,
"The socket is already connected (connection-oriented sockets only)");
1038 else if (err == WSAECONNREFUSED) {
1039 strcpy(buffer,
"The attempt to connect was forcefully rejected");
1041 else if (err == WSAEAFNOSUPPORT) {
1042 strcpy(buffer,
"Addresses in the specified family cannot be used with this socket");
1044 else if (err == WSAEADDRNOTAVAIL) {
1045 strcpy(buffer,
"The remote address is not a valid address (such as ADDR_ANY)");
1047 else if (err == WSAEALREADY) {
1048 strcpy(buffer,
"A nonblocking connect call is in progress on the specified socket");
1050 else if (err == WSAECONNRESET) {
1051 strcpy(buffer,
"Connection was reset");
1053 else if (err == WSAECONNABORTED) {
1054 strcpy(buffer,
"Software caused connection abort");
1057 strcpy(buffer,
"Socket error with no description");
1061 strcpy(buffer, strerror(err));
1069 bool WaitForSocketReadability(socket s, int32 timeout) {
1089 ldiv_t d = ldiv(timeout * 1000, 1000000);
1095 int ret = select(maxfd, &rdds, NULL, NULL, &tv);
1099 bool WaitForSocketWriteability(socket s, int32 timeout) {
1119 ldiv_t d = ldiv(timeout * 1000, 1000000);
1125 return(select(maxfd, NULL, &wds, NULL, &tv) > 0);
1130 int32 String::StartsWith(
const std::string &s,
const std::string &str) {
1131 std::string::size_type pos = s.find_first_of(str);
1138 int32 String::EndsWith(
const std::string &s,
const std::string &str) {
1139 std::string::size_type pos = s.find_last_of(str);
1140 if (pos == s.size() - str.size())
1146 void String::MakeUpper(std::string &str)
1148 std::transform(str.begin(), str.end(), str.begin(), toupper);
1151 void String::MakeLower(std::string &str)
1153 std::transform(str.begin(), str.end(), str.begin(), tolower);
1156 void String::Trim(std::string& str,
const char* chars2remove)
1158 TrimLeft(str, chars2remove);
1159 TrimRight(str, chars2remove);
1162 void String::TrimLeft(std::string& str,
const char* chars2remove)
1166 std::string::size_type pos = str.find_first_not_of(chars2remove);
1168 if (pos != std::string::npos)
1171 str.erase(str.begin(), str.end());
1175 void String::TrimRight(std::string& str,
const char* chars2remove)
1179 std::string::size_type pos = str.find_last_not_of(chars2remove);
1181 if (pos != std::string::npos)
1184 str.erase(str.begin(), str.end());
1189 void String::ReplaceLeading(std::string& str,
const char* chars2replace,
char c)
1193 std::string::size_type pos = str.find_first_not_of(chars2replace);
1195 if (pos != std::string::npos)
1196 str.replace(0, pos, pos, c);
1200 str.replace(str.begin(), str.end() - 1, n - 1, c);
1207 int32 Random::r250_index_;
1208 int32 Random::r521_index_;
1209 uint32 Random::r250_buffer_[R250_LEN];
1210 uint32 Random::r521_buffer_[R521_LEN];
1212 void Random::Init() {
1216 uint32 mask2 = 0xFFFFFFFF;
1218 while (i-- > R250_LEN)
1219 r521_buffer_[i] = rand();
1222 r250_buffer_[i] = rand();
1223 r521_buffer_[i] = rand();
1230 r250_buffer_[i] = (rand() | mask1) & mask2;
1231 r521_buffer_[i] = (rand() | mask1) & mask2;
1235 r250_buffer_[0] = mask1;
1236 r521_buffer_[0] = mask2;
1241 float32 Random::operator ()(uint32 range) {
1253 int32 i1 = r250_index_;
1254 int32 i2 = r521_index_;
1255 uint8 *b1 = (uint8 *)r250_buffer_;
1256 uint8 *b2 = (uint8 *)r521_buffer_;
1257 uint32 *tmp1, *tmp2;
1268 tmp1 = (uint32 *)(b1 + i1);
1269 r = (*(uint32 *)(b1 + j1)) ^ (*tmp1);
1271 tmp2 = (uint32 *)(b2 + i2);
1272 s = (*(uint32 *)(b2 + j2)) ^ (*tmp2);
1275 i1 = (i1 !=
sizeof(uint32)*(R250_LEN - 1)) ? (i1 +
sizeof(uint32)) : 0;
1277 i2 = (i2 !=
sizeof(uint32)*(R521_LEN - 1)) ? (i2 +
sizeof(uint32)) : 0;