/*---------------------------------------------------------------------- | NPT_DateTime::ToTimeStamp +---------------------------------------------------------------------*/ NPT_Result NPT_DateTime::ToTimeStamp(NPT_TimeStamp& timestamp) const { // default value timestamp.SetNanos(0); // check bounds NPT_Result result = CheckDate(*this); if (NPT_FAILED(result)) return result; // compute the number of days elapsed since 1900 NPT_UInt32 days = ElapsedDaysSince1900(*this); // compute the number of nanoseconds NPT_Int64 seconds = (NPT_Int64)days * (24*60*60) + (NPT_Int64)m_Hours * (60*60) + (NPT_Int64)m_Minutes * (60) + (NPT_Int64)m_Seconds; seconds -= (NPT_Int64)m_TimeZone*60; // adjust to the number of seconds since 1900 seconds -= (NPT_Int64)NPT_SECONDS_PER_YEAR*70 + (NPT_Int64)(17*NPT_SECONDS_PER_DAY); // 17 leap year between 1900 and 1970 timestamp.FromNanos(seconds * 1000000000 + m_NanoSeconds); return NPT_SUCCESS; }
/*---------------------------------------------------------------------- | TestBenchmark +---------------------------------------------------------------------*/ static int TestBenchmark() { unsigned char* data = new unsigned char[16*1024]; NPT_SetMemory(data, 0, sizeof(16*1024)); NPT_TimeStamp before; NPT_TimeStamp after; float elapsed; unsigned char key[16] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }; NPT_BlockCipher* cipher; NPT_BlockCipher::Create(NPT_BlockCipher::AES_128, NPT_BlockCipher::ENCRYPT, key, 16, cipher); NPT_System::GetCurrentTimeStamp(before); unsigned int block_count = 0; do { unsigned char out[16]; for (unsigned int i=0; i<1024; i++) { cipher->ProcessBlock(data+16*i, out); } block_count += 1024; NPT_System::GetCurrentTimeStamp(after); elapsed = after.ToSeconds()-before.ToSeconds(); } while (elapsed < 10.0f); NPT_Console::OutputF("AES: %d blocks in 10 seconds: %f MB/s\n", block_count, ((block_count*16.0f)/1000000.0f)/elapsed); delete data; return 0; }
/*---------------------------------------------------------------------- | NPT_Win32Thread::EntryPoint +---------------------------------------------------------------------*/ unsigned int __stdcall NPT_Win32Thread::EntryPoint(void* argument) { NPT_Win32Thread* thread = reinterpret_cast<NPT_Win32Thread*>(argument); NPT_LOG_FINER("thread in ======================="); // set random seed per thread NPT_TimeStamp now; NPT_System::GetCurrentTimeStamp(now); NPT_System::SetRandomSeed((NPT_UInt32)(now.ToNanos()) + ::GetCurrentThreadId()); thread->m_ThreadId = (DWORD)::GetCurrentThreadId(); // run the thread thread->Run(); // if the thread is detached, delete it if (thread->m_Detached) { delete thread->m_Delegator; } // done return 0; }
/*---------------------------------------------------------------------- | PLT_HttpServer::ServeFile +---------------------------------------------------------------------*/ NPT_Result PLT_HttpServer::ServeFile(const NPT_HttpRequest& request, const NPT_HttpRequestContext& context, NPT_HttpResponse& response, NPT_String file_path) { NPT_InputStreamReference stream; NPT_File file(file_path); NPT_FileInfo file_info; // prevent hackers from accessing files outside of our root if ((file_path.Find("/..") >= 0) || (file_path.Find("\\..") >= 0) || NPT_FAILED(NPT_File::GetInfo(file_path, &file_info))) { return NPT_ERROR_NO_SUCH_ITEM; } // check for range requests const NPT_String* range_spec = request.GetHeaders().GetHeaderValue(NPT_HTTP_HEADER_RANGE); // handle potential 304 only if range header not set NPT_DateTime date; NPT_TimeStamp timestamp; if (NPT_SUCCEEDED(PLT_UPnPMessageHelper::GetIfModifiedSince((NPT_HttpMessage&)request, date)) && !range_spec) { date.ToTimeStamp(timestamp); NPT_LOG_INFO_5("File %s timestamps: request=%d (%s) vs file=%d (%s)", (const char*)request.GetUrl().GetPath(), (NPT_UInt32)timestamp.ToSeconds(), (const char*)date.ToString(), (NPT_UInt32)file_info.m_ModificationTime, (const char*)NPT_DateTime(file_info.m_ModificationTime).ToString()); if (timestamp >= file_info.m_ModificationTime) { // it's a match NPT_LOG_FINE_1("Returning 304 for %s", request.GetUrl().GetPath().GetChars()); response.SetStatus(304, "Not Modified", NPT_HTTP_PROTOCOL_1_1); return NPT_SUCCESS; } } // open file if (NPT_FAILED(file.Open(NPT_FILE_OPEN_MODE_READ)) || NPT_FAILED(file.GetInputStream(stream)) || stream.IsNull()) { return NPT_ERROR_NO_SUCH_ITEM; } // set Last-Modified and Cache-Control headers if (file_info.m_ModificationTime) { NPT_DateTime last_modified = NPT_DateTime(file_info.m_ModificationTime); response.GetHeaders().SetHeader("Last-Modified", last_modified.ToString(NPT_DateTime::FORMAT_RFC_1123), true); response.GetHeaders().SetHeader("Cache-Control", "max-age=0,must-revalidate", true); //response.GetHeaders().SetHeader("Cache-Control", "max-age=1800", true); } PLT_HttpRequestContext tmp_context(request, context); return ServeStream(request, context, response, stream, PLT_MimeType::GetMimeType(file_path, &tmp_context)); }
/*---------------------------------------------------------------------- | PLT_DeviceData::GenerateNextBootId +---------------------------------------------------------------------*/ NPT_UInt32 PLT_DeviceData::GenerateNextBootId() { NPT_TimeStamp now; NPT_System::GetCurrentTimeStamp(now); NPT_UInt32 value = (NPT_UInt32)now.ToSeconds(); if (value == m_BootId) ++value; return value; }
/*---------------------------------------------------------------------- | NPT_System::GetRandomInteger +---------------------------------------------------------------------*/ NPT_UInt32 NPT_System::GetRandomInteger() { static bool seeded = false; if (seeded == false) { NPT_TimeStamp now; GetCurrentTimeStamp(now); SetRandomSeed((NPT_UInt32)now.ToNanos()); seeded = true; } return rand(); }
/*---------------------------------------------------------------------- | NPT_DateTime::ChangeTimeZone +---------------------------------------------------------------------*/ NPT_Result NPT_DateTime::ChangeTimeZone(NPT_Int32 timezone) { if (timezone < -12*60 || timezone > 12*60) { return NPT_ERROR_OUT_OF_RANGE; } NPT_TimeStamp ts; NPT_Result result = ToTimeStamp(ts); if (NPT_FAILED(result)) return result; ts.SetNanos(ts.ToNanos()+(NPT_Int64)timezone*(NPT_Int64)60*(NPT_Int64)1000000000); result = FromTimeStamp(ts); m_TimeZone = timezone; return result; }
/*---------------------------------------------------------------------- | NPT_System::SleepUntil +---------------------------------------------------------------------*/ NPT_Result NPT_System::SleepUntil(const NPT_TimeStamp& when) { struct timespec timeout; struct timeval now; int result; // get current time from system if (gettimeofday(&now, NULL)) { return NPT_FAILURE; } // setup timeout NPT_UInt64 limit = (NPT_UInt64)now.tv_sec*1000000000 + (NPT_UInt64)now.tv_usec*1000 + when.ToNanos(); timeout.tv_sec = (time_t)limit/1000000000; timeout.tv_nsec = limit%1000000000; // sleep do { result = pthread_cond_timedwait(&NPT_PosixSystem::System.m_SleepCondition, &NPT_PosixSystem::System.m_SleepMutex, &timeout); if (result == ETIMEDOUT) { return NPT_SUCCESS; } } while (result == EINTR); return NPT_FAILURE; }
void Run() { NPT_Thread::SetCurrentThreadPriority(m_Prio); NPT_TimeStamp now; NPT_TimeStamp then; NPT_System::GetCurrentTimeStamp(now); do { for (unsigned int i=0; i<10000; i++) { m_Counter++; } for (unsigned int i=0; i<10000; i++) { m_Counter--; } m_Counter++; NPT_System::GetCurrentTimeStamp(then); } while (then.ToMillis()-now.ToMillis() < 30000); }
/*---------------------------------------------------------------------- | NPT_System::GetCurrentTimeStamp +---------------------------------------------------------------------*/ NPT_Result NPT_System::GetCurrentTimeStamp(NPT_TimeStamp& now) { struct timeval now_tv; // get current time from system if (gettimeofday(&now_tv, NULL)) { now.SetNanos(0); return NPT_FAILURE; } // convert format now.SetNanos((NPT_UInt64)now_tv.tv_sec * 1000000000 + (NPT_UInt64)now_tv.tv_usec * 1000); return NPT_SUCCESS; }
void FrontEnd::broadcastIfNecessary() { ReadLocker locker1(m_stateLock); if (m_state != State_Running) { return; } NPT_TimeStamp ts; NPT_System::GetCurrentTimeStamp(ts); NPT_Int64 tsMillis = ts.ToMillis(); WriteLocker locker2(m_dsLock); for (NPT_Ordinal i = 0; i < m_deviceImplList.GetItemCount(); i++) { NPT_List<DeviceImplInfo*>::Iterator it = m_deviceImplList.GetItem(i); DeviceImplInfo *info = *it; //if (info->m_updateTS.ToMillis() + info->m_deviceImpl->m_expireSeconds * 1000 - 11000 < tsMillis) if (tsMillis - info->m_updateTS.ToMillis() > 30000) { broadcastLocked(info, true); } } }
/*---------------------------------------------------------------------- | NPT_System::GetCurrentTimeStamp +---------------------------------------------------------------------*/ NPT_Result NPT_System::GetCurrentTimeStamp(NPT_TimeStamp& now) { struct _timeb time_stamp; #if defined(_MSC_VER) && (_MSC_VER >= 1400) _ftime_s(&time_stamp); #else _ftime(&time_stamp); #endif now.SetNanos(((NPT_UInt64)time_stamp.time) * 1000000000UL + ((NPT_UInt64)time_stamp.millitm) * 1000000); return NPT_SUCCESS; }
/*---------------------------------------------------------------------- | NPT_System::GetCurrentTimeStamp +---------------------------------------------------------------------*/ NPT_Result NPT_System::GetCurrentTimeStamp(NPT_TimeStamp& now) { FILETIME time; GetSystemTimeAsFileTime(&time); ULARGE_INTEGER ltime; ltime.LowPart = time.dwLowDateTime; ltime.HighPart = time.dwHighDateTime; /* convert to 64-bits 100-nanoseconds value */ ULONGLONG time64 = ltime.QuadPart; time64 -= 116444736000000000; /* convert from the Windows epoch (Jan. 1, 1601) to the * Unix epoch (Jan. 1, 1970) */ now.FromNanos(time64*100); return NPT_SUCCESS; }
/*---------------------------------------------------------------------- | NPT_DateTime::FromTimeStamp +---------------------------------------------------------------------*/ NPT_Result NPT_DateTime::FromTimeStamp(const NPT_TimeStamp& ts, bool local) { // number of seconds from the epoch (positive or negative) NPT_Int64 seconds = ts.ToSeconds(); // check the range (we only allow up to 31 bits of negative range for seconds // in order to have the same lower bound as the 32-bit gmtime() function) if (seconds < 0 && (NPT_Int32)seconds != seconds) return NPT_ERROR_OUT_OF_RANGE; // adjust for the timezone if necessary NPT_Int32 timezone = 0; if (local) { timezone = GetLocalTimeZone(); seconds += timezone*60; } // adjust to the number of seconds since 1900 seconds += (NPT_Int64)NPT_SECONDS_PER_YEAR*70 + (NPT_Int64)(17*NPT_SECONDS_PER_DAY); // 17 leap year between 1900 and 1970 // compute the years since 1900, not adjusting for leap years NPT_UInt32 years_since_1900 = (NPT_UInt32)(seconds/NPT_SECONDS_PER_YEAR); // compute the number of seconds elapsed in the current year seconds -= (NPT_Int64)years_since_1900 * NPT_SECONDS_PER_YEAR; // adjust for leap years bool is_leap_year = false; NPT_UInt32 leap_years_since_1900 = ElapsedLeapYearsSince1900(years_since_1900+1900); if (seconds < (leap_years_since_1900 * NPT_SECONDS_PER_DAY)) { // not enough seconds in the current year to compensate, move one year back seconds += NPT_SECONDS_PER_YEAR; seconds -= leap_years_since_1900 * NPT_SECONDS_PER_DAY; --years_since_1900; if (NPT_TIME_YEAR_IS_LEAP(years_since_1900+1900) ) { seconds += NPT_SECONDS_PER_DAY; is_leap_year = true; } } else { seconds -= leap_years_since_1900 * NPT_SECONDS_PER_DAY; if (NPT_TIME_YEAR_IS_LEAP(years_since_1900+1900) ) { is_leap_year = true; } } // now we know the year m_Year = years_since_1900+1900; // compute the number of days since January 1 (0 - 365) NPT_UInt32 day_of_the_year = (NPT_UInt32)(seconds/NPT_SECONDS_PER_DAY); // compute the number of seconds in the current day seconds -= day_of_the_year * NPT_SECONDS_PER_DAY; // compute the number of months since January (0 - 11) and the day of month (1 - 31) */ const NPT_Int32* month_day = is_leap_year?NPT_TIME_MONTH_DAY_LEAP:NPT_TIME_MONTH_DAY; NPT_UInt32 month; for (month = 1; month_day[month] < (NPT_Int32)day_of_the_year ; month++) {} // now we know the month and day m_Month = month; m_Day = day_of_the_year - month_day[month-1]; // compute the number of hours since midnight (0 - 23), minutes after the hour // (0 - 59), seconds after the minute (0 - 59) and nanoseconds m_Hours = (NPT_Int32)seconds/3600; seconds -= m_Hours * 3600L; m_Minutes = (NPT_Int32)seconds / 60; m_Seconds = (NPT_Int32)seconds - m_Minutes * 60; m_NanoSeconds = (NPT_Int32)(ts.ToNanos()%1000000000); if (local) { m_TimeZone = timezone; } else { m_TimeZone = 0; } return NPT_SUCCESS; }
/*---------------------------------------------------------------------- | TestMisc +---------------------------------------------------------------------*/ static void TestMisc() { NPT_DateTime date; NPT_TimeStamp ts; NPT_String s; NPT_System::GetCurrentTimeStamp(ts); SHOULD_SUCCEED(date.FromTimeStamp(ts, false)); s = date.ToString(NPT_DateTime::FORMAT_W3C); NPT_Console::OutputF("%s\n", s.GetChars()); s = date.ToString(NPT_DateTime::FORMAT_ANSI); NPT_Console::OutputF("%s\n", s.GetChars()); s = date.ToString(NPT_DateTime::FORMAT_RFC_1036); NPT_Console::OutputF("%s\n", s.GetChars()); s = date.ToString(NPT_DateTime::FORMAT_RFC_1123); NPT_Console::OutputF("%s\n", s.GetChars()); SHOULD_SUCCEED(date.FromTimeStamp(ts, true)); s = date.ToString(NPT_DateTime::FORMAT_W3C); NPT_Console::OutputF("%s\n", s.GetChars()); s = date.ToString(NPT_DateTime::FORMAT_ANSI); NPT_Console::OutputF("%s\n", s.GetChars()); s = date.ToString(NPT_DateTime::FORMAT_RFC_1036); NPT_Console::OutputF("%s\n", s.GetChars()); s = date.ToString(NPT_DateTime::FORMAT_RFC_1123); NPT_Console::OutputF("%s\n", s.GetChars()); ts = 0.0; SHOULD_SUCCEED(date.FromTimeStamp(ts, false)); s = date.ToString(NPT_DateTime::FORMAT_W3C); SHOULD_EQUAL_S(s.GetChars(), "1970-01-01T00:00:00Z"); s = date.ToString(NPT_DateTime::FORMAT_ANSI); SHOULD_EQUAL_S(s.GetChars(), "Thu Jan 1 00:00:00 1970"); s = date.ToString(NPT_DateTime::FORMAT_RFC_1036); SHOULD_EQUAL_S(s.GetChars(), "Thursday, 01-Jan-70 00:00:00 GMT"); s = date.ToString(NPT_DateTime::FORMAT_RFC_1123); SHOULD_EQUAL_S(s.GetChars(), "Thu, 01 Jan 1970 00:00:00 GMT"); ts.SetSeconds(0xFFFFFFFF); SHOULD_SUCCEED(date.FromTimeStamp(ts, false)); s = date.ToString(NPT_DateTime::FORMAT_W3C, false); SHOULD_EQUAL_S(s.GetChars(), "2106-02-07T06:28:15Z"); NPT_TimeStamp now; NPT_System::GetCurrentTimeStamp(now); NPT_DateTime now_local(now, true); NPT_DateTime now_utc(now, false); SHOULD_EQUAL_I(now_utc.m_TimeZone, 0); NPT_TimeStamp ts1, ts2; now_local.ToTimeStamp(ts1); now_utc.ToTimeStamp(ts2); SHOULD_EQUAL_I((int)ts1.ToSeconds(), (int)ts2.ToSeconds()); ts.SetSeconds(0); NPT_DateTime d1(ts); ts.SetSeconds(ts.ToSeconds()-3600); NPT_DateTime d2(ts); d1.ToTimeStamp(ts1); d2.ToTimeStamp(ts2); SHOULD_EQUAL_I((int)ts1.ToSeconds(), (int)ts2.ToSeconds()+3600); }
/*---------------------------------------------------------------------- | TestPerformance +---------------------------------------------------------------------*/ static void TestPerformance() { for (unsigned int i=1; i<10000; i += 1000) { NPT_TimeStamp before; NPT_System::GetCurrentTimeStamp(before); for (unsigned int j=0; j<10; j++) { NPT_Map<NPT_String, NPT_String> map; for (unsigned int k=0; k<i; k++) { char key[64] = "blablabliblibloublou"; unsigned int run = NPT_System::GetRandomInteger()%8; for (unsigned int x=0; x<run; x++) { key[x] = 'A'+NPT_System::GetRandomInteger()%32; } map[key] = "hello"; } } NPT_TimeStamp after; NPT_System::GetCurrentTimeStamp(after); NPT_UInt64 duration = (after.ToNanos()-before.ToNanos())/10; printf("LinearMap insert: %d\t%d ns\t\t%d ns/item\n", i, (NPT_UInt32)duration, (NPT_UInt32)(duration/i)); } for (unsigned int i=1; i<10000; i += 1000) { NPT_TimeStamp before; NPT_System::GetCurrentTimeStamp(before); for (unsigned int j=0; j<100; j++) { NPT_HashMap<NPT_String, NPT_String> map; for (unsigned int k=0; k<i; k++) { char key[64] = "blablabliblibloublou"; unsigned int run = NPT_System::GetRandomInteger()%8; for (unsigned int x=0; x<run; x++) { key[x] = 'A'+NPT_System::GetRandomInteger()%32; } map[key] = "hello"; } } NPT_TimeStamp after; NPT_System::GetCurrentTimeStamp(after); NPT_UInt64 duration = (after.ToNanos()-before.ToNanos())/100; printf("HashMap insert: %d\t%d ns\t\t%d ns/item\n", i, (NPT_UInt32)duration, (NPT_UInt32)(duration/i)); } for (unsigned int i=1; i<10000; i += 1000) { NPT_TimeStamp before; NPT_System::GetCurrentTimeStamp(before); for (unsigned int j=0; j<100; j++) { NPT_HashMap<NPT_String, NPT_String> map; for (unsigned int k=0; k<i; k++) { char key[64] = "blablabliblibloublou"; unsigned int run = NPT_System::GetRandomInteger()%8; for (unsigned int x=0; x<run; x++) { key[x] = 'A'+NPT_System::GetRandomInteger()%32; } map[key] = "hello"; } for (unsigned int k=0; k<i; k++) { char key[64] = "blablabliblibloublou"; unsigned int run = NPT_System::GetRandomInteger()%8; for (unsigned int x=0; x<run; x++) { key[x] = 'A'+NPT_System::GetRandomInteger()%32; } map.Erase(key); } } NPT_TimeStamp after; NPT_System::GetCurrentTimeStamp(after); NPT_UInt64 duration = (after.ToNanos()-before.ToNanos())/100; printf("HashMap insert+erase: %d\t%d ns\t\t%d ns/item\n", i, (NPT_UInt32)duration, (NPT_UInt32)(duration/i)); } }