Example #1
0
/**
	sys_thread_cpu_time : void -> float
	<doc>Return the most accurate CPU time spent in user mode in the current thread (in seconds)</doc>
**/
static value sys_thread_cpu_time() {
#if defined(NEKO_WINDOWS)
	FILETIME unused;
	FILETIME utime;
	if( !GetThreadTimes(GetCurrentThread(),&unused,&unused,&unused,&utime) )
		neko_error();
	return alloc_float( ((tfloat)utime.dwHighDateTime) * 65.536 * 6.5536 + (((tfloat)utime.dwLowDateTime) / 10000000) );
#elif defined(NEKO_MAC)
	val_throw(alloc_string("sys_thread_cpu_time not implmented on OSX"));
	return val_null;
#else
	struct timespec t;
	if( clock_gettime(CLOCK_THREAD_CPUTIME_ID,&t) )
		neko_error();
	return alloc_float( t.tv_sec + t.tv_nsec * 1e-9 );
#endif
}
Example #2
0
//-----------------------------------------------------------------------------
// 取得執行緒執行時間
bool GetRunTime(IN unsigned long ulThreadID, OUT __int64 &i64KernelTime, OUT __int64 &i64UserTime)
{
    C_WHandle ccThread = OpenThread(THREAD_QUERY_INFORMATION, FALSE, ulThreadID);

    if(ccThread == nullptr)
        return C_NOutput::Instance().Error(ERRORNSTD, __T("thread null"));

    FILETIME tCreateTime, tExitTime, tKernelTime, tUserTime;

    if(GetThreadTimes(static_cast<HANDLE>(ccThread), &tCreateTime, &tExitTime, &tKernelTime, &tUserTime) == FALSE)
        return C_NOutput::Instance().Error(ERRORNSTD, C_ErrorWin(), __T("get thread runtime failed"));

    i64KernelTime = (Int64ShllMod32(tKernelTime.dwHighDateTime, 32) | tKernelTime.dwLowDateTime);
    i64UserTime = (Int64ShllMod32(tUserTime.dwHighDateTime, 32) | tUserTime.dwLowDateTime);

    return true;
}
Example #3
0
extern "C" __declspec(dllexport) DWORD GetProcessMainThreadId(DWORD procId)
{

#ifndef MAKEULONGLONG
#define MAKEULONGLONG(ldw, hdw) ((ULONGLONG(hdw) << 32) | ((ldw) & 0xFFFFFFFF))
#endif
#ifndef MAXULONGLONG
#define MAXULONGLONG ((ULONGLONG)~((ULONGLONG)0))
#endif

    DWORD dwMainThreadID = 0;
    ULONGLONG ullMinCreateTime = MAXULONGLONG;
    //includes all threads in the system
    HANDLE hThreadSnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
    if (hThreadSnap != INVALID_HANDLE_VALUE) {
        THREADENTRY32 th32;
        th32.dwSize = sizeof(THREADENTRY32);
        BOOL bOK = TRUE;
        //Enumerate all threads in the system and filter on th32OwnerProcessID = pid
        for (bOK = Thread32First(hThreadSnap, &th32); bOK ; bOK = Thread32Next(hThreadSnap, &th32)) {
            //if (th32.dwSize >= FIELD_OFFSET(THREADENTRY32, th32OwnerProcessID) + sizeof(th32.th32OwnerProcessID)) {
            if (th32.th32OwnerProcessID == procId && (th32.dwSize >= FIELD_OFFSET(THREADENTRY32, th32OwnerProcessID) + sizeof(th32.th32OwnerProcessID))) {
                //_tprintf(_T("DEBUG Enumerate Process (%ld) Thread Id: %ld\n"), procId, th32.th32ThreadID);
                HANDLE hThread = OpenThread(THREAD_QUERY_INFORMATION, TRUE, th32.th32ThreadID);
                if (hThread) {
                    FILETIME afTimes[4] = {0};
                    if (GetThreadTimes(hThread,	&afTimes[0], &afTimes[1], &afTimes[2], &afTimes[3])) {
                        ULONGLONG ullTest = MAKEULONGLONG(afTimes[0].dwLowDateTime, afTimes[0].dwHighDateTime);
                        if (ullTest && ullTest < ullMinCreateTime) { //check each thread's creation time
                            ullMinCreateTime = ullTest;
                            dwMainThreadID = th32.th32ThreadID; // let it be main thread
                        }
                    }
                    CloseHandle(hThread); //must close opened thread
                }
            }
        }
#ifndef UNDER_CE
        CloseHandle(hThreadSnap); //close thread snapshot
#else
        CloseToolhelp32Snapshot(hThreadSnap); //close thread snapshot
#endif
    }
    return dwMainThreadID; //returns main thread id or returns 0 if can't find it
}
Example #4
0
// Returns the time the current thread has spent executing, in milliseconds.
static inline unsigned getCPUTime()
{
#if OS(DARWIN)
    mach_msg_type_number_t infoCount = THREAD_BASIC_INFO_COUNT;
    thread_basic_info_data_t info;

    // Get thread information
    mach_port_t threadPort = mach_thread_self();
    thread_info(threadPort, THREAD_BASIC_INFO, reinterpret_cast<thread_info_t>(&info), &infoCount);
    mach_port_deallocate(mach_task_self(), threadPort);
    
    unsigned time = info.user_time.seconds * 1000 + info.user_time.microseconds / 1000;
    time += info.system_time.seconds * 1000 + info.system_time.microseconds / 1000;
    
    return time;
#elif OS(WINDOWS)
    union {
        FILETIME fileTime;
        unsigned long long fileTimeAsLong;
    } userTime, kernelTime;
    
    // GetThreadTimes won't accept NULL arguments so we pass these even though
    // they're not used.
    FILETIME creationTime, exitTime;
    
    GetThreadTimes(GetCurrentThread(), &creationTime, &exitTime, &kernelTime.fileTime, &userTime.fileTime);
    
    return static_cast<unsigned>(userTime.fileTimeAsLong / 10000 + kernelTime.fileTimeAsLong / 10000);
#elif OS(SYMBIAN)
    RThread current;
    TTimeIntervalMicroSeconds cpuTime;

    TInt err = current.GetCpuTime(cpuTime);
    ASSERT_WITH_MESSAGE(err == KErrNone, "GetCpuTime failed with %d", err);
    return cpuTime.Int64() / 1000;
#elif PLATFORM(BREWMP)
    // This function returns a continuously and linearly increasing millisecond
    // timer from the time the device was powered on.
    // There is only one thread in BREW, so this is enough.
    return GETUPTIMEMS();
#else
    // FIXME: We should return the time the current thread has spent executing.
    return currentTime() * 1000;
#endif
}
qtimestamp getTimestamp()
{
#ifdef Q_OS_WINCE
    // This implementation is based on code found here:
    // http://social.msdn.microsoft.com/Forums/en/vssmartdevicesnative/thread/74870c6c-76c5-454c-8533-812cfca585f8
    HANDLE currentThread = GetCurrentThread();
    FILETIME creationTime, exitTime, kernalTime, userTime;
    GetThreadTimes(currentThread, &creationTime, &exitTime, &kernalTime, &userTime);

    ULARGE_INTEGER uli;
    uli.LowPart = userTime.dwLowDateTime;
    uli.HighPart = userTime.dwHighDateTime;
    ULONGLONG systemTimeInMS = uli.QuadPart/10000;
    return static_cast<qtimestamp>(systemTimeInMS);
#else
    return clock();
#endif
}
Example #6
0
int Ten18::Util::EnumerateNativeThreads(bool traceFullInfo, const char* msg)
{
    Ten18_UNUSED(traceFullInfo);
    DebugOut(msg);

    int numThreads = 0;
    auto snapshot = MakeScoped(CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0), [] (HANDLE snapshot) { Ten18_HOPE_FOR.True = CloseHandle(snapshot); });
    Ten18_EXPECT.Not(INVALID_HANDLE_VALUE) = static_cast<HANDLE>(snapshot);
    
    THREADENTRY32 te = {};
    te.dwSize = sizeof(te);
    const auto minSizeOfInterest = (std::min)((FIELD_OFFSET(THREADENTRY32, th32OwnerProcessID) + sizeof(te.th32OwnerProcessID)),
                                              (FIELD_OFFSET(THREADENTRY32, th32OwnerProcessID) + sizeof(te.th32ThreadID)));
    if (Thread32First(snapshot, &te))
    {
        do
        {
            if (te.dwSize >= minSizeOfInterest)
                if (te.th32OwnerProcessID == GetCurrentProcessId())
                {                
                    ++numThreads;
                    auto thread = MakeScoped(OpenThread(THREAD_QUERY_INFORMATION, FALSE, te.th32ThreadID), [] (HANDLE t) { Ten18_HOPE_FOR.NotZero = CloseHandle(t); });
                    Ten18_EXPECT.NotNull = static_cast<HANDLE>(thread);

                    ULONG64 cycleTime = 0;
                    Ten18_EXPECT.True = QueryThreadCycleTime(thread, &cycleTime);
                    
                    FILETIME create, exit, kernel, user;
                    Ten18_EXPECT.True = GetThreadTimes(thread, &create, &exit, &kernel, &user);

                    Format("\tNative Thread %0 - Create: %1, Exit: %2, Kernel: %3, User: %4, Cycles: %5",
                        te.th32ThreadID, create.dwLowDateTime, exit.dwLowDateTime, kernel.dwLowDateTime, user.dwLowDateTime, static_cast<int>(cycleTime)).DebugOut();
                }
                
            te.dwSize = sizeof(te);
        }
        while (Thread32Next(snapshot, &te));
    }
    
    Format("Number of Native Threads: %0", numThreads).DebugOut();

    return numThreads;
}
int main( int argc , char* argv[] )
{
	double t = Time();

	cmdLineParse( argc-1 , &argv[1] , sizeof(params)/sizeof(cmdLineReadable*) , params , 1 );
	if( Density.set ) Execute< 2 , PlyValueVertex< Real > , true  >( argc , argv );
	else              Execute< 2 ,      PlyVertex< Real > , false >( argc , argv );
#ifdef _WIN32
	if( Performance.set )
	{
		HANDLE cur_thread=GetCurrentThread();
		FILETIME tcreat, texit, tkernel, tuser;
		if( GetThreadTimes( cur_thread , &tcreat , &texit , &tkernel , &tuser ) )
			printf( "Time (Wall/User/Kernel): %.2f / %.2f / %.2f\n" , Time()-t , to_seconds( tuser ) , to_seconds( tkernel ) );
		else printf( "Time: %.2f\n" , Time()-t );
		HANDLE h = GetCurrentProcess();
		PROCESS_MEMORY_COUNTERS pmc;
		if( GetProcessMemoryInfo( h , &pmc , sizeof(pmc) ) ) printf( "Peak Memory (MB): %d\n" , pmc.PeakWorkingSetSize>>20 );
	}
Example #8
0
 unsigned long long CTraceFn::ThreadTime()
 {
    unsigned long long ret( 0 );
    
    FILETIME creationTime;
    FILETIME exitTime;
    FILETIME kernelTime;
    FILETIME userTime;
    
    if( GetThreadTimes( GetCurrentThread(), &creationTime, &exitTime, &kernelTime, &userTime ) )
    {
       unsigned long long theKernelTime( static_cast< unsigned long long >( kernelTime.dwHighDateTime ) << 32 | kernelTime.dwLowDateTime );
       unsigned long long theUserTime( static_cast< unsigned long long >( userTime.dwHighDateTime ) << 32 | userTime.dwLowDateTime );
       
       ret = ( theKernelTime + theUserTime );
    }
    
    return ret;
 }
Example #9
0
int getrusage(int who, struct rusage *usage)
{
  FILETIME creation_time, exit_time, kernel_time, user_time;
  PROCESS_MEMORY_COUNTERS pmc;

  memset(usage, 0, sizeof(struct rusage));

  if(who == RUSAGE_SELF)
  {
    if(!GetProcessTimes(GetCurrentProcess(), &creation_time, &exit_time, &kernel_time, &user_time))
    {
      fprintf(stdout, "failed at GetProcessTimes\n");
      return -1;
    }

    if(!GetProcessMemoryInfo(GetCurrentProcess(), &pmc, sizeof(pmc)))
    {
      fprintf(stdout, "failed at GetProcessMemoryInfo\n");
      return -1;
    }

    usage_to_timeval(&kernel_time, &usage->ru_stime);
    usage_to_timeval(&user_time, &usage->ru_utime);
    usage->ru_majflt = pmc.PageFaultCount;
    usage->ru_maxrss = pmc.PeakWorkingSetSize / 1024;
    return 0;
  }
  else if(who == RUSAGE_THREAD)
  {
    if(!GetThreadTimes(GetCurrentThread(), &creation_time, &exit_time, &kernel_time, &user_time))
    {
      fprintf(stdout, "failed at GetThreadTimes\n");
      return -1;
    }
    usage_to_timeval(&kernel_time, &usage->ru_stime);
    usage_to_timeval(&user_time, &usage->ru_utime);
    return 0;
  }
  else
  {
    return -1;
  }
}
Example #10
0
// Stop the timer
void
HPFCounter::Stop()
{
  if(m_start.QuadPart)
  {
    QueryPerformanceCounter(&m_end);
    m_total += ((double)(m_end.QuadPart - m_start.QuadPart)) / (double)m_frequency.QuadPart;

    m_start.QuadPart = 0L;
    m_end  .QuadPart = 0L;
  }

  // Get the thread times, ignoring creation and end
  FILETIME creation   = { 0, 0};
  FILETIME exitTime   = { 0, 0};
  FILETIME kernelTime = { 0, 0};
  FILETIME userTime   = { 0, 0};
  GetThreadTimes(GetCurrentThread(),&creation,&exitTime,&kernelTime,&userTime);

//   TRACE ("Thread times\n");
//   TRACE ("- User   hi : %x\n",userTime.dwHighDateTime);
//   TRACE ("- User   lo : %x\n",userTime.dwLowDateTime);
//   TRACE ("- Kernel hi : %x\n",kernelTime.dwHighDateTime);
//   TRACE ("- Kernel lo : %x\n\n",kernelTime.dwLowDateTime);

  // Calculate how much kernel time we just used since last time
  FILETIME slice = SubFiletimes(&kernelTime,&m_kernelTime);
  m_kernelTimeSlice = AddFiletimes(&m_kernelTimeSlice,&slice);
  m_kernelTime = kernelTime;

//   TRACE("Kernel Slice times\n");
//   TRACE ("- slice hi : %x\n",m_kernelTimeSlice.dwHighDateTime);
//   TRACE ("- slice lo : %x\n",m_kernelTimeSlice.dwLowDateTime);

  // Calculate how much user time we just used since last time
  slice = SubFiletimes(&userTime,&m_userTime);
  m_userTimeSlice = AddFiletimes(&m_userTimeSlice,&slice);
  m_userTime = userTime;

//   TRACE("User Slice times\n");
//   TRACE ("- slice hi : %x\n",m_userTimeSlice.dwHighDateTime);
//   TRACE ("- slice lo : %x\n",m_userTimeSlice.dwLowDateTime);
}
Example #11
0
POV_ULONG Timer::GetThreadTime () const
{
    FILETIME    ct;
    FILETIME    et;
    __int64     kt;
    __int64     ut;
    BOOL        success;

    POV_ASSERT (mCPUTimeSupported);

    success = GetThreadTimes (mThreadHandle, &ct, &et,
                              reinterpret_cast<FILETIME *>(&kt),
                              reinterpret_cast<FILETIME *>(&ut));

    POV_ASSERT (success);
    if (!success)
        return 0;

    return ((kt + ut) / 10000);
}
Example #12
0
void xbt_os_threadtimer_stop(xbt_os_timer_t timer)
{
#if HAVE_POSIX_GETTIME
  clock_gettime(CLOCK_THREAD_CPUTIME_ID, &(timer->stop));
#elif HAVE_GETTIMEOFDAY && defined(__MACH__) && defined(__APPLE__)
  mach_msg_type_number_t count = THREAD_BASIC_INFO_COUNT;
  thread_basic_info_data_t thi_data;
  thread_basic_info_t thi = &thi_data;
  thread_info(mach_thread_self(), THREAD_BASIC_INFO, (thread_info_t)thi, &count);
  timer->stop.tv_usec =  thi->system_time.microseconds + thi->user_time.microseconds;
  timer->stop.tv_sec = thi->system_time.seconds + thi->user_time.seconds;
#elif HAVE_GETTIMEOFDAY //if nothing else is available, return just time
  gettimeofday(&(timer->stop), NULL);
#elif defined(_WIN32)
  HANDLE h = GetCurrentThread();
  FILETIME creationTime, exitTime, kernelTime, userTime;
  GetThreadTimes(h, &creationTime, &exitTime, &kernelTime, &userTime);
  w32_times_to_timeval(&timer->stop, &kernelTime, &userTime);
#endif
}
Example #13
0
static void
stop_timer (void)
{
#ifdef _WIN32
#ifdef __MINGW32CE__
  GetThreadTimes (GetCurrentThread (),
                   &stopped_at.creation_time, &stopped_at.exit_time,
                   &stopped_at.kernel_time, &stopped_at.user_time);
#else
  GetProcessTimes (GetCurrentProcess (),
                   &stopped_at.creation_time, &stopped_at.exit_time,
                   &stopped_at.kernel_time, &stopped_at.user_time);
#endif
#else
  struct tms tmp;

  times (&tmp);
  stopped_at = tmp.tms_utime;
#endif
}
double currentCPUTime()
{
#if OS(DARWIN)
    mach_msg_type_number_t infoCount = THREAD_BASIC_INFO_COUNT;
    thread_basic_info_data_t info;

    // Get thread information
    mach_port_t threadPort = mach_thread_self();
    thread_info(threadPort, THREAD_BASIC_INFO, reinterpret_cast<thread_info_t>(&info), &infoCount);
    mach_port_deallocate(mach_task_self(), threadPort);
    
    double time = info.user_time.seconds + info.user_time.microseconds / 1000000.;
    time += info.system_time.seconds + info.system_time.microseconds / 1000000.;
    
    return time;
#elif OS(WINDOWS)
    union {
        FILETIME fileTime;
        unsigned long long fileTimeAsLong;
    } userTime, kernelTime;
    
    // GetThreadTimes won't accept null arguments so we pass these even though
    // they're not used.
    FILETIME creationTime, exitTime;
    
    GetThreadTimes(GetCurrentThread(), &creationTime, &exitTime, &kernelTime.fileTime, &userTime.fileTime);
    
    return userTime.fileTimeAsLong / 10000000. + kernelTime.fileTimeAsLong / 10000000.;
#elif OS(QNX)
    struct timespec time;
    if (clock_gettime(CLOCK_THREAD_CPUTIME_ID, &time))
        CRASH();
    return time.tv_sec + time.tv_nsec / 1.0e9;
#else
    // FIXME: We should return the time the current thread has spent executing.

    // use a relative time from first call in order to avoid an overflow
    static double firstTime = currentTime();
    return currentTime() - firstTime;
#endif
}
static DWORD GetMainThreadId() {
  std::vector<ThreadInfo> threads;

  HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
  if (snapshot != INVALID_HANDLE_VALUE) {
    THREADENTRY32 thread_entry;
    thread_entry.dwSize = sizeof(thread_entry);
    if (Thread32First(snapshot, &thread_entry)) {
      DWORD process_id = GetProcessId(GetCurrentProcess());
      do {
        if (thread_entry.dwSize >=
            FIELD_OFFSET(THREADENTRY32, th32OwnerProcessID) +
                         sizeof(thread_entry.th32OwnerProcessID)) {
          if (thread_entry.th32OwnerProcessID == process_id) {
            ThreadInfo thread = {0};
            thread.id = thread_entry.th32ThreadID;
            threads.push_back(thread);
          }
        }
        thread_entry.dwSize = sizeof(thread_entry);
      } while (Thread32Next(snapshot, &thread_entry));
    }
    CloseHandle(snapshot);
  }

  for (std::vector<ThreadInfo>::iterator it = threads.begin();
       it != threads.end(); it++) {
    ThreadInfo &info = *it;
    HANDLE handle = GetThreadHandle(info.id, THREAD_QUERY_INFORMATION);
    GetThreadTimes(handle, &info.creation_time, &info.exit_time,
                           &info.kernel_time,   &info.user_time);
  }

  threads.erase(std::remove_if(threads.begin(), threads.end(),
                               InvalidThread()), threads.end());
  if (!threads.empty()) {
    return std::min_element(threads.begin(), threads.end(),
                            CompareThreads())->id;
  }
  return 0;
}
Example #16
0
/**
 * Return the amount of USER time used by a thread.
 * 
 * @param[in] thread
 * @return actual time on USER used by thread (nanoseconds) or
 * negative value if not supported.
 */
I_64 VMCALL
hythread_get_user_time (hythread_t thread)
{

#if defined(WIN32)
  FILETIME creationTime, exitTime, kernelTime, userTime;
  I_64 totalTime;
  /* WARNING! Not supported on Win95!  Need to test to ensure this fails gracefully */
  if (GetThreadTimes
      (thread->handle, &creationTime, &exitTime, &kernelTime, &userTime))
    {
      totalTime =
	((I_64) userTime.
	 dwLowDateTime | ((I_64) userTime.dwHighDateTime << 32));
      /* totalTime is in 100's of nanos.  Convert to nanos */
      return totalTime * 100;
    }
#endif /* WIN32 */

  return -1;
}
Example #17
0
void set_breakpoints(void) {
    HANDLE hTool32 = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
    if(hTool32 != INVALID_HANDLE_VALUE) {
        THREADENTRY32 thread_entry32;
        thread_entry32.dwSize = sizeof(THREADENTRY32);
        FILETIME exit_time, kernel_time, user_time;
        FILETIME creation_time;
        FILETIME prev_creation_time;
        prev_creation_time.dwLowDateTime = 0xFFFFFFFF;
        prev_creation_time.dwHighDateTime = INT_MAX;
        HANDLE hMainThread = NULL;
        if(Thread32First(hTool32, &thread_entry32)) {
            do {
                if(thread_entry32.dwSize >= FIELD_OFFSET(THREADENTRY32, th32OwnerProcessID) + sizeof(thread_entry32.th32OwnerProcessID)
                    && thread_entry32.th32OwnerProcessID == GetCurrentProcessId()
                    && thread_entry32.th32ThreadID != GetCurrentThreadId()) {
                        HANDLE hThread = OpenThread(THREAD_SET_CONTEXT | THREAD_GET_CONTEXT | THREAD_QUERY_INFORMATION,
                            FALSE, thread_entry32.th32ThreadID);
                        GetThreadTimes(hThread, &creation_time, &exit_time, &kernel_time, &user_time);
                        if(CompareFileTime(&creation_time, &prev_creation_time) == -1) {
                            memcpy(&prev_creation_time, &creation_time, sizeof(FILETIME));
                            if(hMainThread != NULL)
                                CloseHandle(hMainThread);
                            hMainThread = hThread;
                        }
                        else
                            CloseHandle(hThread);
                }
                thread_entry32.dwSize = sizeof(THREADENTRY32);
            } while(Thread32Next(hTool32, &thread_entry32));
            AddVectoredExceptionHandler(1, ExceptionFilter);
            CONTEXT thread_context = {CONTEXT_DEBUG_REGISTERS};
            thread_context.Dr0 = func_addr;
            thread_context.Dr7 = (1 << 0);
            SetThreadContext(hMainThread, &thread_context);
            CloseHandle(hMainThread);
        }
        CloseHandle(hTool32);
    }
}
Example #18
0
void xbt_os_threadtimer_resume(xbt_os_timer_t timer)
{
#ifdef HAVE_POSIX_GETTIME
    timer->elapse.tv_sec += timer->stop.tv_sec - timer->start.tv_sec;
    timer->elapse.tv_nsec += timer->stop.tv_nsec - timer->start.tv_nsec;
    clock_gettime(CLOCK_THREAD_CPUTIME_ID, &(timer->start));
#elif defined(HAVE_GETTIMEOFDAY) && defined(__MACH__) && defined(__APPLE__)
    timer->elapse.tv_sec += timer->stop.tv_sec - timer->start.tv_sec;
    timer->elapse.tv_usec += timer->stop.tv_usec - timer->start.tv_usec;
    mach_msg_type_number_t count = THREAD_BASIC_INFO_COUNT;
    thread_basic_info_data_t thi_data;
    thread_basic_info_t thi = &thi_data;
    thread_info(mach_thread_self(), THREAD_BASIC_INFO, (thread_info_t)thi, &count);
    timer->start.tv_usec =  thi->system_time.microseconds + thi->user_time.microseconds;
    timer->start.tv_sec = thi->system_time.seconds + thi->user_time.seconds;
#elif defined(HAVE_GETTIMEOFDAY)
    timer->elapse.tv_sec += timer->stop.tv_sec - timer->start.tv_sec;
    timer->elapse.tv_usec += timer->stop.tv_usec - timer->start.tv_usec;
    gettimeofday(&(timer->start), NULL);
#elif defined(_XBT_WIN32)
    timer->elapse.tv_sec += timer->stop.tv_sec - timer->start.tv_sec;
    timer->elapse.tv_usec += timer->stop.tv_usec - timer->start.tv_usec;
#  if defined(WIN32_WCE) || (_WIN32_WINNT < 0x0400)
    THROW_UNIMPLEMENTED;
#  else
    HANDLE h = GetCurrentThread();
    FILETIME creationTime, exitTime, kernelTime, userTime;
    GetThreadTimes(h, &creationTime, &exitTime, &kernelTime, &userTime);
    unsigned __int64 ktm, utm;
    ktm = (unsigned __int64) kernelTime.dwHighDateTime << 32;
    ktm |= kernelTime.dwLowDateTime;
    ktm /= 10;
    utm = (unsigned __int64) userTime.dwHighDateTime << 32;
    utm |= userTime.dwLowDateTime;
    utm /= 10;
    timer->start.tv_sec = (long) (ktm / 1000000L) + (long) (utm / 1000000L);
    timer->start.tv_usec = (long) (ktm % 1000000L) + (long) (utm % 1000000L);
#  endif                        /* windows version checker */
#endif
}
Example #19
0
void ProcessImpl::timesImpl(long& userTime, long& kernelTime)
{
	FILETIME ftCreation;
	FILETIME ftExit;
	FILETIME ftKernel;
	FILETIME ftUser;

	if (GetThreadTimes(GetCurrentThread(), &ftCreation, &ftExit, &ftKernel, &ftUser) != 0)
	{
		ULARGE_INTEGER time;
		time.LowPart  = ftKernel.dwLowDateTime;
		time.HighPart = ftKernel.dwHighDateTime;
		kernelTime    = long(time.QuadPart/10000000L);
		time.LowPart  = ftUser.dwLowDateTime;
		time.HighPart = ftUser.dwHighDateTime;
		userTime      = long(time.QuadPart/10000000L);
	}
	else
	{
		userTime = kernelTime = -1;
	}
}
Example #20
0
/**返回当前线程创建到退出消耗的CPU时间
*/
void mvg::synch::getCurrentThreadTimes(
	time_t			&creationTime,
	time_t			&exitTime,
	double			&cpuTime)
{
	MVG_START

	FILETIME	timCreat, timExit, timKernel, timUser;
	uint64_t	t;

	HANDLE threadHandle;

	// 根据ID得到当前线程的handle
	threadHandle = OpenThread(READ_CONTROL | THREAD_QUERY_INFORMATION, FALSE, GetCurrentThreadId());  // threadId);
	if (!threadHandle)	 THROW_EXCEPTION("Cannot open the thread with the given 'threadId'");

	if (!GetThreadTimes(threadHandle, &timCreat, &timExit, &timKernel, &timUser))
	{
		CloseHandle(threadHandle);
		THROW_EXCEPTION("Error accessing thread times!");
	}

	CloseHandle(threadHandle);

	t = (((uint64_t)timCreat.dwHighDateTime) << 32) | timCreat.dwLowDateTime;
	creationTime = (t - 116444736000000000ULL) / 10000000;

	t = (((uint64_t)timExit.dwHighDateTime) << 32) | timExit.dwLowDateTime;
	exitTime = (t - 116444736000000000ULL) / 10000000;

	// CPU时间是用户+内核
	int64_t	t1 = (((uint64_t)timKernel.dwHighDateTime) << 32) | timKernel.dwLowDateTime;
	int64_t	t2 = (((uint64_t)timUser.dwHighDateTime) << 32) | timUser.dwLowDateTime;

	cpuTime = ((double)(t1 + t2)) * 100e-9;	// FILETIME counts intervals of 100ns


	MVG_END
}
void CThreadPerformanceCounter::DoPerformanceCount()
{
	if(m_TreadHandle)
	{
		m_CycleCount++;
		if(m_CountIntervalTimer.IsTimeOut(m_CountIntervalTime))
		{
			m_CountIntervalTimer.SaveTime();

			UINT64 CurPerformanceCount=CEasyTimerEx::GetTime();
			float CPUTime=(float)(CurPerformanceCount-m_StartPerformanceCount)/CEasyTimerEx::TIME_UNIT_PER_SECOND;		
			m_StartPerformanceCount=CurPerformanceCount;

			m_CycleTime=CPUTime*1000.0f/m_CycleCount;
			m_CycleCount=0;

			UINT64 CurCPUUsedTime;
#ifdef WIN32
			FILETIME CreationTime,ExitTime,KernelTime,UserTime;
			if(!GetThreadTimes(m_TreadHandle,
				&CreationTime,&ExitTime,
				&KernelTime,&UserTime))
			{
				PrintSystemLog(0,_T("获取线程CPU时间失败%d"),GetLastError());
			}
			CurCPUUsedTime=((UINT64)KernelTime.dwLowDateTime)|(((UINT64)KernelTime.dwHighDateTime)<<32);
			CurCPUUsedTime+=((UINT64)UserTime.dwLowDateTime)|(((UINT64)UserTime.dwHighDateTime)<<32);
#else
			timespec OrginTime;		
			clock_gettime(CLOCK_THREAD_CPUTIME_ID,&OrginTime);
			CurCPUUsedTime=(UINT64)OrginTime.tv_sec*1000000000+OrginTime.tv_nsec;
#endif

			m_CPUUsedRate=(float)(CurCPUUsedTime-m_StartCPUUsedTime)/(CPUTime*m_CPUCount*10000000.0f);

			m_StartCPUUsedTime=CurCPUUsedTime;
		}
	}
}
Example #22
0
float CThread::GetRelativeUsage()
{
  unsigned __int64 iTime = GetTickCount();
  iTime *= 10000; // convert into 100ns tics

  // only update every 1 second
  if( iTime < m_iLastTime + 1000*10000 ) return m_fLastUsage;

  FILETIME CreationTime, ExitTime, UserTime, KernelTime;
  if( GetThreadTimes( m_ThreadHandle, &CreationTime, &ExitTime, &KernelTime, &UserTime ) )
  {
    unsigned __int64 iUsage = 0;
    iUsage += (((unsigned __int64)UserTime.dwHighDateTime) << 32) + ((unsigned __int64)UserTime.dwLowDateTime);
    iUsage += (((unsigned __int64)KernelTime.dwHighDateTime) << 32) + ((unsigned __int64)KernelTime.dwLowDateTime);

    m_fLastUsage = (float)( iUsage - m_iLastUsage ) / (float)( iTime - m_iLastTime );
    m_iLastUsage = iUsage;
    m_iLastTime = iTime;

    return m_fLastUsage;
  }
  return 0.0f; 
}
Example #23
0
TimerWord ThreadUserTimer::GetCurrentTimerValue()
{
#if defined(CRYPTOPP_WIN32_AVAILABLE) && defined(THREAD_TIMER_AVAILABLE)
	static bool getCurrentThreadImplemented = true;
	if (getCurrentThreadImplemented)
	{
		FILETIME now, ignored;
		if (!GetThreadTimes(GetCurrentThread(), &ignored, &ignored, &ignored, &now))
		{
			const DWORD lastError = GetLastError();
			if (lastError == ERROR_CALL_NOT_IMPLEMENTED)
			{
				getCurrentThreadImplemented = false;
				goto GetCurrentThreadNotImplemented;
			}
			throw Exception(Exception::OTHER_ERROR, "ThreadUserTimer: GetThreadTimes failed with error " + IntToString(lastError));
		}
		return now.dwLowDateTime + ((TimerWord)now.dwHighDateTime << 32);
	}
GetCurrentThreadNotImplemented:
	return (TimerWord)clock() * (10*1000*1000 / CLOCKS_PER_SEC);
#elif defined(CRYPTOPP_WIN32_AVAILABLE) && !defined(THREAD_TIMER_AVAILABLE)
	LARGE_INTEGER now;
	if (!QueryPerformanceCounter(&now))
	{
		const DWORD lastError = GetLastError();
		throw Exception(Exception::OTHER_ERROR, "ThreadUserTimer: QueryPerformanceCounter failed with error " + IntToString(lastError));
	}
	return now.QuadPart;
#elif defined(CRYPTOPP_UNIX_AVAILABLE)
	tms now;
	times(&now);
	return now.tms_utime;
#else
	return clock();
#endif
}
Example #24
0
/*
 * This function is called on a timer, and it will monitor
 * frequently changing quantities such as the state of physical and
 * virtual memory, the state of the process's message queue, which
 * window is in the foreground, which owns the clipboard, etc.
 */
void noise_regular(void)
{
    HWND w;
    DWORD z;
    POINT pt;
    MEMORYSTATUS memstat;
    FILETIME times[4];

#ifdef MPEXT
    EnterCriticalSection(&noise_section);
#endif
    w = GetForegroundWindow();
    random_add_noise(&w, sizeof(w));
    w = GetCapture();
    random_add_noise(&w, sizeof(w));
    w = GetClipboardOwner();
    random_add_noise(&w, sizeof(w));
    z = GetQueueStatus(QS_ALLEVENTS);
    random_add_noise(&z, sizeof(z));

    GetCursorPos(&pt);
    random_add_noise(&pt, sizeof(pt));

    GlobalMemoryStatus(&memstat);
    random_add_noise(&memstat, sizeof(memstat));

    GetThreadTimes(GetCurrentThread(), times, times + 1, times + 2,
		   times + 3);
    random_add_noise(&times, sizeof(times));
    GetProcessTimes(GetCurrentProcess(), times, times + 1, times + 2,
		    times + 3);
    random_add_noise(&times, sizeof(times));
#ifdef MPEXT
    LeaveCriticalSection(&noise_section);
#endif
}
Example #25
0
DWORD GetProcessMainThread(DWORD dwProcID)
{
	DWORD dwMainThreadID = 0;
	ULONGLONG ullMinCreateTime = MAXULONGLONG;

	HANDLE hThreadSnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
	if (hThreadSnap != INVALID_HANDLE_VALUE) {
		THREADENTRY32 th32;
		th32.dwSize = sizeof(THREADENTRY32);
		BOOL bOK = TRUE;
		for (bOK = Thread32First(hThreadSnap, &th32); bOK;
			bOK = Thread32Next(hThreadSnap, &th32)) {
			if (th32.th32OwnerProcessID == dwProcID) {
				HANDLE hThread = OpenThread(THREAD_QUERY_INFORMATION,
					TRUE, th32.th32ThreadID);
				if (hThread) {
					FILETIME afTimes[4] = { 0 };
					if (GetThreadTimes(hThread,
						&afTimes[0], &afTimes[1], &afTimes[2], &afTimes[3])) {
						ULONGLONG ullTest = MAKEULONGLONG(afTimes[0].dwLowDateTime,
							afTimes[0].dwHighDateTime);
						if (ullTest && ullTest < ullMinCreateTime) {
							ullMinCreateTime = ullTest;
							dwMainThreadID = th32.th32ThreadID; // let it be main... :)
						}
					}
					CloseHandle(hThread);
				}
			}
		}

		CloseHandle(hThreadSnap);
	}

	return (dwMainThreadID);
}
Example #26
0
/* This is the fastpoll function which gathers up info by calling various api's */
BOOL FastPoll (void)
{
	int nOriginalRandIndex = nRandIndex;
	static BOOL addedFixedItems = FALSE;
	FILETIME creationTime, exitTime, kernelTime, userTime;
	SIZE_T minimumWorkingSetSize, maximumWorkingSetSize;
	LARGE_INTEGER performanceCount;
	MEMORYSTATUS memoryStatus;
	HANDLE handle;
	POINT point;

	/* Get various basic pieces of system information */
	RandaddIntPtr (GetActiveWindow ());	/* Handle of active window */
	RandaddIntPtr (GetCapture ());	/* Handle of window with mouse
					   capture */
	RandaddIntPtr (GetClipboardOwner ());	/* Handle of clipboard owner */
	RandaddIntPtr (GetClipboardViewer ());	/* Handle of start of
						   clpbd.viewer list */
	RandaddIntPtr (GetCurrentProcess ());	/* Pseudohandle of current
						   process */
	RandaddInt32 (GetCurrentProcessId ());	/* Current process ID */
	RandaddIntPtr (GetCurrentThread ());	/* Pseudohandle of current
						   thread */
	RandaddInt32 (GetCurrentThreadId ());	/* Current thread ID */
	RandaddInt32 (GetCurrentTime ());	/* Milliseconds since Windows
						   started */
	RandaddIntPtr (GetDesktopWindow ());	/* Handle of desktop window */
	RandaddIntPtr (GetFocus ());	/* Handle of window with kb.focus */
	RandaddInt32 (GetInputState ());	/* Whether sys.queue has any events */
	RandaddInt32 (GetMessagePos ());	/* Cursor pos.for last message */
	RandaddInt32 (GetMessageTime ());	/* 1 ms time for last message */
	RandaddIntPtr (GetOpenClipboardWindow ());	/* Handle of window with
							   clpbd.open */
	RandaddIntPtr (GetProcessHeap ());	/* Handle of process heap */
	RandaddIntPtr (GetProcessWindowStation ());	/* Handle of procs
							   window station */
	RandaddInt32 (GetQueueStatus (QS_ALLEVENTS));	/* Types of events in
							   input queue */

	/* Get multiword system information */
	GetCaretPos (&point);	/* Current caret position */
	RandaddBuf ((unsigned char *) &point, sizeof (POINT));
	GetCursorPos (&point);	/* Current mouse cursor position */
	RandaddBuf ((unsigned char *) &point, sizeof (POINT));

	/* Get percent of memory in use, bytes of physical memory, bytes of
	   free physical memory, bytes in paging file, free bytes in paging
	   file, user bytes of address space, and free user bytes */
	memoryStatus.dwLength = sizeof (MEMORYSTATUS);
	GlobalMemoryStatus (&memoryStatus);
	RandaddBuf ((unsigned char *) &memoryStatus, sizeof (MEMORYSTATUS));

	/* Get thread and process creation time, exit time, time in kernel
	   mode, and time in user mode in 100ns intervals */
	handle = GetCurrentThread ();
	GetThreadTimes (handle, &creationTime, &exitTime, &kernelTime, &userTime);
	RandaddBuf ((unsigned char *) &creationTime, sizeof (FILETIME));
	RandaddBuf ((unsigned char *) &exitTime, sizeof (FILETIME));
	RandaddBuf ((unsigned char *) &kernelTime, sizeof (FILETIME));
	RandaddBuf ((unsigned char *) &userTime, sizeof (FILETIME));
	handle = GetCurrentProcess ();
	GetProcessTimes (handle, &creationTime, &exitTime, &kernelTime, &userTime);
	RandaddBuf ((unsigned char *) &creationTime, sizeof (FILETIME));
	RandaddBuf ((unsigned char *) &exitTime, sizeof (FILETIME));
	RandaddBuf ((unsigned char *) &kernelTime, sizeof (FILETIME));
	RandaddBuf ((unsigned char *) &userTime, sizeof (FILETIME));

	/* Get the minimum and maximum working set size for the current
	   process */
	GetProcessWorkingSetSize (handle, &minimumWorkingSetSize,
				  &maximumWorkingSetSize);
	RandaddIntPtr (minimumWorkingSetSize);
	RandaddIntPtr (maximumWorkingSetSize);

	/* The following are fixed for the lifetime of the process so we only
	   add them once */
	if (addedFixedItems == 0)
	{
		STARTUPINFO startupInfo;

		/* Get name of desktop, console window title, new window
		   position and size, window flags, and handles for stdin,
		   stdout, and stderr */
		startupInfo.cb = sizeof (STARTUPINFO);
		GetStartupInfo (&startupInfo);
		RandaddBuf ((unsigned char *) &startupInfo, sizeof (STARTUPINFO));
		addedFixedItems = TRUE;
	}
	/* The docs say QPC can fail if appropriate hardware is not
	   available. It works on 486 & Pentium boxes, but hasn't been tested
	   for 386 or RISC boxes */
	if (QueryPerformanceCounter (&performanceCount))
		RandaddBuf ((unsigned char *) &performanceCount, sizeof (LARGE_INTEGER));
	else
	{
		/* Millisecond accuracy at best... */
		DWORD dwTicks = GetTickCount ();
		RandaddBuf ((unsigned char *) &dwTicks, sizeof (dwTicks));
	}

	// CryptoAPI: We always have a valid CryptoAPI context when we arrive here but
	//            we keep the check for clarity purpose
	if ( !CryptoAPIAvailable )
		return FALSE;
	if (CryptGenRandom (hCryptProv, sizeof (buffer), buffer)) 
	{
		RandaddBuf (buffer, sizeof (buffer));
		burn (buffer, sizeof(buffer));
	}
	else
	{
		/* return error in case CryptGenRandom fails */
		CryptoAPILastError = GetLastError ();
		return FALSE;
	}

	/* Apply the pool mixing function */
	Randmix();

	/* Restore the original pool cursor position. If this wasn't done, mouse coordinates
	   could be written to a limited area of the pool, especially when moving the mouse
	   uninterruptedly. The severity of the problem would depend on the length of data
	   written by FastPoll (if it was equal to the size of the pool, mouse coordinates
	   would be written only to a particular 4-byte area, whenever moving the mouse
	   uninterruptedly). */
	nRandIndex = nOriginalRandIndex;

	return TRUE;
}
Example #27
0
 void Run(void) override {
   WaitForStateUpdate([this] { return m_continue; });
   while(m_spinCount--);
   GetThreadTimes(m_kernelTime, m_userTime);
 }
Example #28
0
DWORD CalculationThread (LPVOID lpvoid) {
	(void)lpvoid;
  bool needcalculationsslow;

  NMEA_INFO     tmpGPS;
  DERIVED_INFO  tmpCALCULATED;
  FILETIME CreationTime, ExitTime, StartKernelTime, EndKernelTime, StartUserTime, EndUserTime ;
  needcalculationsslow = false;

  // let's not create a deadlock here, setting the go after another race condition
  goCalculationThread=true; // 091119 CHECK
  // wait for proper startup signal
  while (!MapWindow::IsDisplayRunning()) {
    Sleep(100);
  }

  // while (!goCalculating) Sleep(100);
  Sleep(1000); // 091213  BUGFIX need to syncronize !!! TOFIX02 TODO

  while (!MapWindow::CLOSETHREAD) {

    WaitForSingleObject(dataTriggerEvent, 5000);
    ResetEvent(dataTriggerEvent);
    if (MapWindow::CLOSETHREAD) break; // drop out on exit

    GetThreadTimes( hCalculationThread, &CreationTime, &ExitTime,&StartKernelTime,&StartUserTime);

    // make local copy before editing...
    LockFlightData();
      FLARM_RefreshSlots(&GPS_INFO);
      memcpy(&tmpGPS,&GPS_INFO,sizeof(NMEA_INFO));
      memcpy(&tmpCALCULATED,&CALCULATED_INFO,sizeof(DERIVED_INFO));
    UnlockFlightData();

    DoCalculationsVario(&tmpGPS,&tmpCALCULATED);
    if (!tmpGPS.VarioAvailable) {
    	TriggerVarioUpdate(); // emulate vario update
    } 
    
    if(DoCalculations(&tmpGPS,&tmpCALCULATED)){
	#if (WINDOWSPC>0) && !TESTBENCH
	#else
        if (!INPAN)
	#endif
	{
           MapWindow::MapDirty = true;
	}
        needcalculationsslow = true;

        if (tmpCALCULATED.Circling)
          MapWindow::mode.Fly(MapWindow::Mode::MODE_FLY_CIRCLING);
        else if (tmpCALCULATED.FinalGlide)
          MapWindow::mode.Fly(MapWindow::Mode::MODE_FLY_FINAL_GLIDE);
        else
          MapWindow::mode.Fly(MapWindow::Mode::MODE_FLY_CRUISE);
    }
        
    if (MapWindow::CLOSETHREAD) break; // drop out on exit

    // This is activating another run for Thread Draw
    TriggerRedraws(&tmpGPS, &tmpCALCULATED);

    if (MapWindow::CLOSETHREAD) break; // drop out on exit

    if (SIMMODE) {
	if (needcalculationsslow || ( ReplayLogger::IsEnabled() ) ) { 
		DoCalculationsSlow(&tmpGPS,&tmpCALCULATED);
		needcalculationsslow = false;
	}
    } else {
	if (needcalculationsslow) {
		DoCalculationsSlow(&tmpGPS,&tmpCALCULATED);
		needcalculationsslow = false;
	}
    }

    if (MapWindow::CLOSETHREAD) break; // drop out on exit

    // values changed, so copy them back now: ONLY CALCULATED INFO
    // should be changed in DoCalculations, so we only need to write
    // that one back (otherwise we may write over new data)
    LockFlightData();
    memcpy(&CALCULATED_INFO,&tmpCALCULATED,sizeof(DERIVED_INFO));
    UnlockFlightData();

    // update live tracker with new values
    // this is a nonblocking call, live tracker runs on different thread
     LiveTrackerUpdate(&tmpGPS, &tmpCALCULATED);

    if (FlightDataRecorderActive) UpdateFlightDataRecorder(&tmpGPS,&tmpCALCULATED);
   
    
    if ( (GetThreadTimes( hCalculationThread, &CreationTime, &ExitTime,&EndKernelTime,&EndUserTime)) == 0) {
               Cpu_Calc=9999;
    } else {
               Cpustats(&Cpu_Calc,&StartKernelTime, &EndKernelTime, &StartUserTime, &EndUserTime);
    }
  }
  return 0;
}
Example #29
0
extern "C" int clock_gettime(clockid_t clock_id, struct timespec* tp) {
  if (!tp) {
    errno = EFAULT;
    return -1;
  }

  const auto unanosToTimespec = [](timespec* tp, unsigned_nanos t) -> int {
    static constexpr unsigned_nanos one_sec(std::chrono::seconds(1));
    tp->tv_sec =
        time_t(std::chrono::duration_cast<std::chrono::seconds>(t).count());
    tp->tv_nsec = long((t % one_sec).count());
    return 0;
  };

  FILETIME createTime, exitTime, kernalTime, userTime;
  switch (clock_id) {
    case CLOCK_REALTIME: {
      auto now = std::chrono::system_clock::now().time_since_epoch();
      duration_to_ts(now, tp);
      return 0;
    }
    case CLOCK_MONOTONIC: {
      auto now = std::chrono::steady_clock::now().time_since_epoch();
      duration_to_ts(now, tp);
      return 0;
    }
    case CLOCK_PROCESS_CPUTIME_ID: {
      if (!GetProcessTimes(
              GetCurrentProcess(),
              &createTime,
              &exitTime,
              &kernalTime,
              &userTime)) {
        errno = EINVAL;
        return -1;
      }

      return unanosToTimespec(
          tp,
          filetimeToUnsignedNanos(kernalTime) +
              filetimeToUnsignedNanos(userTime));
    }
    case CLOCK_THREAD_CPUTIME_ID: {
      if (!GetThreadTimes(
              GetCurrentThread(),
              &createTime,
              &exitTime,
              &kernalTime,
              &userTime)) {
        errno = EINVAL;
        return -1;
      }

      return unanosToTimespec(
          tp,
          filetimeToUnsignedNanos(kernalTime) +
              filetimeToUnsignedNanos(userTime));
    }

    default:
      errno = EINVAL;
      return -1;
  }
}
Example #30
0
DWORD SerialPort::RxThread() {
#if ( (WINDOWSPC == 0)) && !NEWCOMM	// 100222
    DWORD dwCommModemStatus = 0;
    // Specify a set of events to be monitored for the port.
#endif
    DWORD dwBytesTransferred = 0; // 091117 initialized variables
    _Buff_t szString;
    FILETIME CreationTime, ExitTime, StartKernelTime, EndKernelTime, StartUserTime, EndUserTime;

    Purge();
#if TRACETHREAD
    StartupStore(_T("##############  PORT=%d threadid=%d\n"), GetPortIndex(), GetCurrentThreadId());
    if (GetPortIndex() = 0) _THREADID_PORT1 = GetCurrentThreadId();
    if (GetPortIndex() = 1) _THREADID_PORT2 = GetCurrentThreadId();
    if (GetPortIndex() != 1 && GetPortIndex() != 2) _THREADID_UNKNOWNPORT = GetCurrentThreadId();
#endif
    // Specify a set of events to be monitored for the port.
    _dwMask = EV_RXFLAG | EV_CTS | EV_DSR | EV_RING | EV_RXCHAR;

#if ( (WINDOWSPC == 0)) && !NEWCOMM
    SetCommMask(hPort, _dwMask);
#endif
#if (WINDOWSPC<1)
    if (!_PollingMode) SetCommMask(hPort, _dwMask);
#endif

    while ((hPort != INVALID_HANDLE_VALUE) && (::WaitForSingleObject(hStop, 0) == WAIT_TIMEOUT)) {
        GetThreadTimes(hReadThread, &CreationTime, &ExitTime, &StartKernelTime, &StartUserTime);

        UpdateStatus();

#if (WINDOWSPC>0) || NEWCOMM // 091206
        // PC version does BUSY WAIT
        Sleep(50); // ToDo rewrite the whole driver to use overlaped IO on W2K or higher
#else
        if (_PollingMode)
            Sleep(100);
        else
            // Wait for an event to occur for the port.
            if (!WaitCommEvent(hPort, &dwCommModemStatus, 0)) {
            // error reading from port
            Sleep(100);
        }
#endif

        // Re-specify the set of events to be monitored for the port.
        //    SetCommMask(hPort, dwMask1);

        // #if (WINDOWSPC == 0) 091206
#if ( (WINDOWSPC == 0)) && !NEWCOMM
        if (_PollingMode || (dwCommModemStatus & EV_RXFLAG) || (dwCommModemStatus & EV_RXCHAR)) // Do this only for non-PC
#endif
        {
            // Loop for waiting for the data.
            do {
                // Read the data from the serial port.
                dwBytesTransferred = ReadData(szString);
                if (dwBytesTransferred > 0) {
                    if (ProgramStarted >= psNormalOp) { // ignore everything until started
                        std::for_each(begin(szString), begin(szString) + dwBytesTransferred, std::bind1st(std::mem_fun(&SerialPort::ProcessChar), this));
                    }
                } else {
                    dwBytesTransferred = 0;
                }

                Sleep(50); // JMW20070515: give port some time to
                // fill... prevents ReadFile from causing the
                // thread to take up too much CPU
                if ((GetThreadTimes(hReadThread, &CreationTime, &ExitTime, &EndKernelTime, &EndUserTime)) == 0) {
                    if (GetPortIndex() == 0)
                        Cpu_PortA = 9999;
                    else
                        Cpu_PortB = 9999;
                } else {
                    Cpustats((GetPortIndex() == 0) ? &Cpu_PortA : &Cpu_PortB, &StartKernelTime, &EndKernelTime, &StartUserTime, &EndUserTime);
                }

                if (::WaitForSingleObject(hStop, 0) != WAIT_TIMEOUT) {
                    dwBytesTransferred = 0;
                }
            } while (dwBytesTransferred != 0);
        }

        // give port some time to fill
        Sleep(5);

        // Retrieve modem control-register values.
#if ((WINDOWSPC == 0)) 
        if (!_PollingMode) {
            // this is causing problems on PC BT, apparently. Setting Polling will not call this, but it is a bug
            GetCommModemStatus(hPort, &dwCommModemStatus);
        }
#endif
    }

    DirtyPurge();

    return 0;
}