Ejemplo n.º 1
0
int main()
{
    ULONG Min = ~0;
    ULONG Max = ~0;
    ULONG Cur = ~0;
    NtQueryTimerResolution(&Max, &Min, &Cur);
    printf("NtQueryTimerResolution -> Max=%08luns Min=%08luns Cur=%08luns\n", Min * 100, Max * 100, Cur * 100);

#if 0
    /* figure out the 100ns relative to the 1970 epoc. */
    SYSTEMTIME st;
    st.wYear = 1970;
    st.wMonth = 1;
    st.wDayOfWeek = 4; /* Thor's day. */
    st.wDay = 1;
    st.wHour = 0;
    st.wMinute = 0;
    st.wSecond = 0;
    st.wMilliseconds = 0;

    FILETIME ft;
    if (SystemTimeToFileTime(&st, &ft))
    {
        printf("epoc is %I64u (0x%08x%08x)\n", ft, ft.dwHighDateTime, ft.dwLowDateTime);
        if (FileTimeToSystemTime(&ft, &st))
            printf("unix epoc: %d-%02d-%02d %02d:%02d:%02d.%03d (week day %d)\n",
                st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond, st.wMilliseconds, st.wDayOfWeek);
        else
            printf("FileTimeToSystemTime failed, lasterr=%d\n", GetLastError());
    }
    else
        printf("SystemTimeToFileTime failed, lasterr=%d\n", GetLastError());

    ft.dwHighDateTime = 0;
    ft.dwLowDateTime = 0;
    if (FileTimeToSystemTime(&ft, &st))
        printf("nt time start: %d-%02d-%02d %02d:%02d:%02d.%03d (week day %d)\n",
            st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond, st.wMilliseconds, st.wDayOfWeek);
    else
        printf("FileTimeToSystemTime failed, lasterr=%d\n", GetLastError());
#endif
    return 0;
}
Ejemplo n.º 2
0
Archivo: timer.c Proyecto: xwlan/flinux
DEFINE_SYSCALL(clock_getres, int, clk_id, struct timespec *, res)
{
	log_info("clock_getres(%d, 0x%p)", clk_id, res);
	if (!mm_check_write(res, sizeof(struct timespec)))
		return -L_EFAULT;
	switch (clk_id)
	{
	case CLOCK_REALTIME:
	{
		ULONG coarse, fine, actual;
		NtQueryTimerResolution(&coarse, &fine, &actual);
		uint64_t ns = (uint64_t)actual * NANOSECONDS_PER_TICK;
		res->tv_sec = ns / NANOSECONDS_PER_SECOND;
		res->tv_nsec = ns % NANOSECONDS_PER_SECOND;
		return 0;
	}
	case CLOCK_MONOTONIC:
	case CLOCK_MONOTONIC_COARSE:
	case CLOCK_MONOTONIC_RAW:
	{
		LARGE_INTEGER freq;
		QueryPerformanceFrequency(&freq);
		uint64_t ns = (double)1. / (double)freq.QuadPart;
		if (ns == 0)
		{
			res->tv_sec = 0;
			res->tv_nsec = 1;
		}
		else
		{
			res->tv_sec = ns / NANOSECONDS_PER_SECOND;
			res->tv_nsec = ns % NANOSECONDS_PER_SECOND;
		}
		return 0;
	}
	default:
		return -L_EINVAL;
	}
}
Ejemplo n.º 3
0
RTDECL(int) RTTimerCreate(PRTTIMER *ppTimer, unsigned uMilliesInterval, PFNRTTIMER pfnTimer, void *pvUser)
{
#ifndef USE_WINMM
    /*
     * On windows we'll have to set the timer resolution before
     * we start the timer.
     */
    ULONG ulMax = UINT32_MAX;
    ULONG ulMin = UINT32_MAX;
    ULONG ulCur = UINT32_MAX;
    NtQueryTimerResolution(&ulMax, &ulMin, &ulCur);
    Log(("NtQueryTimerResolution -> ulMax=%lu00ns ulMin=%lu00ns ulCur=%lu00ns\n", ulMax, ulMin, ulCur));
    if (ulCur > ulMin && ulCur > 10000 /* = 1ms */)
    {
        if (NtSetTimerResolution(10000, TRUE, &ulCur) >= 0)
            Log(("Changed timer resolution to 1ms.\n"));
        else if (NtSetTimerResolution(20000, TRUE, &ulCur) >= 0)
            Log(("Changed timer resolution to 2ms.\n"));
        else if (NtSetTimerResolution(40000, TRUE, &ulCur) >= 0)
            Log(("Changed timer resolution to 4ms.\n"));
        else if (ulMin <= 50000 && NtSetTimerResolution(ulMin, TRUE, &ulCur) >= 0)
            Log(("Changed timer resolution to %lu *100ns.\n", ulMin));
        else
        {
            AssertMsgFailed(("Failed to configure timer resolution!\n"));
            return VERR_INTERNAL_ERROR;
        }
    }
#endif /* !USE_WINN */

    /*
     * Create new timer.
     */
    int rc = VERR_IPE_UNINITIALIZED_STATUS;
    PRTTIMER pTimer = (PRTTIMER)RTMemAlloc(sizeof(*pTimer));
    if (pTimer)
    {
        pTimer->u32Magic    = RTTIMER_MAGIC;
        pTimer->pvUser      = pvUser;
        pTimer->pfnTimer    = pfnTimer;
        pTimer->iTick       = 0;
        pTimer->uMilliesInterval = uMilliesInterval;
#ifdef USE_WINMM
        /* sync kill doesn't work. */
        pTimer->TimerId     = timeSetEvent(uMilliesInterval, 0, rttimerCallback, (DWORD_PTR)pTimer, TIME_PERIODIC | TIME_CALLBACK_FUNCTION);
        if (pTimer->TimerId)
        {
            ULONG ulMax = UINT32_MAX;
            ULONG ulMin = UINT32_MAX;
            ULONG ulCur = UINT32_MAX;
            NtQueryTimerResolution(&ulMax, &ulMin, &ulCur);
            Log(("NtQueryTimerResolution -> ulMax=%lu00ns ulMin=%lu00ns ulCur=%lu00ns\n", ulMax, ulMin, ulCur));

            *ppTimer = pTimer;
            return VINF_SUCCESS;
        }
        rc = VERR_INVALID_PARAMETER;

#else /* !USE_WINMM */

        /*
         * Create Win32 event semaphore.
         */
        pTimer->iError = 0;
        pTimer->hTimer = CreateWaitableTimer(NULL, TRUE, NULL);
        if (pTimer->hTimer)
        {
#ifdef USE_APC
            /*
             * Create wait semaphore.
             */
            pTimer->hevWait = CreateEvent(NULL, FALSE, FALSE, NULL);
            if (pTimer->hevWait)
#endif
            {
                /*
                 * Kick off the timer thread.
                 */
                rc = RTThreadCreate(&pTimer->Thread, rttimerCallback, pTimer, 0, RTTHREADTYPE_TIMER, RTTHREADFLAGS_WAITABLE, "Timer");
                if (RT_SUCCESS(rc))
                {
                    /*
                     * Wait for the timer to successfully create the timer
                     * If we don't get a response in 10 secs, then we assume we're screwed.
                     */
                    rc = RTThreadUserWait(pTimer->Thread, 10000);
                    if (RT_SUCCESS(rc))
                    {
                        rc = pTimer->iError;
                        if (RT_SUCCESS(rc))
                        {
                            *ppTimer = pTimer;
                            return VINF_SUCCESS;
                        }
                    }
                    ASMAtomicXchgU32(&pTimer->u32Magic, RTTIMER_MAGIC + 1);
                    RTThreadWait(pTimer->Thread, 250, NULL);
                    CancelWaitableTimer(pTimer->hTimer);
                }
#ifdef USE_APC
                CloseHandle(pTimer->hevWait);
#endif
            }
            CloseHandle(pTimer->hTimer);
        }
#endif /* !USE_WINMM */

        AssertMsgFailed(("Failed to create timer uMilliesInterval=%d. rc=%d\n", uMilliesInterval, rc));
        RTMemFree(pTimer);
    }
    else
        rc = VERR_NO_MEMORY;
    return rc;
}
Ejemplo n.º 4
0
RT_C_DECLS_END



int main(int argc, char **argv)
{
    int rc = RTR3InitExe(argc, &argv, 0);
    if (RT_FAILURE(rc))
        return RTMsgInitFailure(rc);

    /*
     * Parse arguments.
     */
    bool        fVerbose   = true;
    uint32_t    u32NewRes  = 0;
    uint32_t    cSecsSleep = UINT32_MAX;

    static const RTGETOPTDEF s_aOptions[] =
    {
        { "--resolution",  'r', RTGETOPT_REQ_UINT32 },
        { "--sleep",       's', RTGETOPT_REQ_UINT32 },
        { "--quiet",       'q', RTGETOPT_REQ_NOTHING },
        { "--verbose",     'v', RTGETOPT_REQ_NOTHING },
    };

    RTGETOPTUNION ValueUnion;
    RTGETOPTSTATE GetState;
    RTGetOptInit(&GetState, argc, argv, s_aOptions, RT_ELEMENTS(s_aOptions), 1, 0);
    while ((rc = RTGetOpt(&GetState, &ValueUnion)))
    {
        switch (rc)
        {
            case 'r':
                u32NewRes = ValueUnion.u32;
                if (u32NewRes > 16*10000 /* 16 ms */ || u32NewRes < 1000 /* 100 microsec */)
                    return RTMsgErrorExit(RTEXITCODE_SYNTAX,
                                          "syntax error: the new timer resolution (%RU32) is out of range\n",
                                          u32NewRes);
                break;

            case 's':
                cSecsSleep = ValueUnion.u32;
                break;

            case 'q':
                fVerbose = false;
                break;

            case 'v':
                fVerbose = true;
                break;

            case 'h':
                RTPrintf("Usage: ntsetfreq [-q|--quiet] [-v|--verbose] [-r|--resolution <100ns>] [-s|--sleep <1s>]\n");
                return RTEXITCODE_SUCCESS;

            default:
                return RTGetOptPrintError(rc, &ValueUnion);
        }
    }


    /*
     * Query the current resolution.
     */
    ULONG   Cur = ~0;
    ULONG   Min = ~0;
    ULONG   Max = ~0;
    LONG    Status;
    if (fVerbose || !u32NewRes)
    {
        Status = NtQueryTimerResolution(&Min, &Max, &Cur);
        if (Status >= 0)
            RTMsgInfo("cur: %u (%u.%02u Hz)  min: %u (%u.%02u Hz)  max: %u (%u.%02u Hz)\n",
                      Cur, 10000000 / Cur, (10000000 / (Cur * 100)) % 100,
                      Min, 10000000 / Min, (10000000 / (Min * 100)) % 100,
                      Max, 10000000 / Max, (10000000 / (Max * 100)) % 100);
        else
            RTMsgError("NTQueryTimerResolution failed with status %#x\n", Status);
    }

    if (u32NewRes)
    {
        Status = NtSetTimerResolution(u32NewRes, TRUE, &Cur);
        if (Status < 0)
            RTMsgError("NTSetTimerResolution(%RU32,,) failed with status %#x\n", u32NewRes, Status);
        else if (fVerbose)
        {
            Cur = Min = Max = ~0;
            Status = NtQueryTimerResolution(&Min, &Max, &Cur);
            if (Status >= 0)
                RTMsgInfo("new: %u (%u.%02u Hz) requested %RU32 (%u.%02u Hz)\n",
                          Cur, 10000000 / Cur, (10000000 / (Cur * 100)) % 100,
                          u32NewRes, 10000000 / u32NewRes, (10000000 / (u32NewRes * 100)) % 100);
            else
                RTMsgError("NTSetTimerResolution succeeded but the NTQueryTimerResolution call failed with status %#x (ignored)\n", Status);
            Status = 0;
        }
    }

    if (u32NewRes && Status >= 0)
    {
        if (cSecsSleep == UINT32_MAX)
            for (;;)
                RTThreadSleep(RT_INDEFINITE_WAIT);
        else
            while (cSecsSleep-- > 0)
                RTThreadSleep(1000);
    }

    return Status >= 0 ? 0 : 1;
}