Esempio n. 1
0
static void TIME_ClockTimeToFileTime(clock_t unix_time, LPFILETIME filetime)
{
    ULONGLONG secs = RtlEnlargedUnsignedMultiply( unix_time, 10000000 );
    secs = RtlExtendedLargeIntegerDivide( secs, CLK_TCK, NULL );
    filetime->dwLowDateTime  = (DWORD)secs;
    filetime->dwHighDateTime = (DWORD)(secs >> 32);
}
Esempio n. 2
0
DWORD
TimeInMicroSeconds(
    DWORD dwTime
)
{
    DWORD Remainder;

    return RtlExtendedLargeIntegerDivide(
               RtlEnlargedUnsignedMultiply( dwTime, 1000000L),
               Frequency,
               &Remainder
           ).LowPart;
}
Esempio n. 3
0
VOID
KiCalibrateTimeAdjustment (
    PADJUST_INTERRUPT_TIME_CONTEXT Adjust
    )

/*++

Routine Description:

    This function calibrates the adjustment of time on all processors.

Arguments:

    Adjust - Supplies the operation context.

Return Value:

    None.

--*/

{

    ULONG cl;
    ULONG divisor;
    BOOLEAN Enable;
    LARGE_INTEGER InterruptTime;
    ULARGE_INTEGER li;
    PERFINFO_PO_CALIBRATED_PERFCOUNTER LogEntry;
    LARGE_INTEGER NewTickCount;
    ULONG NewTickOffset;
    LARGE_INTEGER PerfCount;
    LARGE_INTEGER PerfFreq;
    LARGE_INTEGER SetTime;

    //
    // As each processor arrives, decrement the remaining processor count. If
    // this is the last processor to arrive, then compute the time change, and
    // signal all processor when to apply the performance counter change.
    //

    if (InterlockedDecrement((PLONG)&Adjust->KiNumber)) {
        Enable = KeDisableInterrupts();

        //
        // It is possible to deadlock if one or more of the other processors
        // receives and processes a freeze request while this processor has
        // interrupts disabled. Poll for a freeze request until all processors
        // are known to be in this code.
        //

        do {
            KiPollFreezeExecution();
        } while (Adjust->KiNumber != (ULONG)-1);

        //
        // Wait to perform the time set.
        //

        while (Adjust->Barrier);

    } else {

        //
        // Set timer expiration dpc to scan the timer queues once for any
        // expired timers.
        //

        KeRemoveQueueDpc(&KiTimerExpireDpc);
        KeInsertQueueDpc(&KiTimerExpireDpc,
                         ULongToPtr(KiQueryLowTickCount() - TIMER_TABLE_SIZE),
                         NULL);

        //
        // Disable interrupts and indicate that this processor is now
        // in final portion of this code.
        //

        Enable = KeDisableInterrupts();
        InterlockedDecrement((PLONG) &Adjust->KiNumber);

        //
        // Adjust Interrupt Time.
        //

        InterruptTime.QuadPart = KeQueryInterruptTime() + Adjust->Adjustment;
        SetTime.QuadPart = Adjust->Adjustment;

        //
        // Get the current times
        //

        PerfCount = KeQueryPerformanceCounter(&PerfFreq);

        //
        // Compute performance counter for current time.
        //
        // Multiply SetTime * PerfCount and obtain 96-bit result in cl,
        // li.LowPart, li.HighPart.  Then divide the 96-bit result by
        // 10,000,000 to get new performance counter value.
        //

        li.QuadPart = RtlEnlargedUnsignedMultiply((ULONG)SetTime.LowPart,
                                                  (ULONG)PerfFreq.LowPart).QuadPart;

        cl = li.LowPart;
        li.QuadPart =
            li.HighPart + RtlEnlargedUnsignedMultiply((ULONG)SetTime.LowPart,
                                                      (ULONG)PerfFreq.HighPart).QuadPart;

        li.QuadPart =
            li.QuadPart + RtlEnlargedUnsignedMultiply((ULONG)SetTime.HighPart,
                                                      (ULONG)PerfFreq.LowPart).QuadPart;

        li.HighPart = li.HighPart + SetTime.HighPart * PerfFreq.HighPart;
        divisor = 10000000;
        Adjust->NewCount.HighPart = RtlEnlargedUnsignedDivide(li,
                                                              divisor,
                                                              &li.HighPart);

        li.LowPart = cl;
        Adjust->NewCount.LowPart = RtlEnlargedUnsignedDivide(li,
                                                             divisor,
                                                             NULL);

        Adjust->NewCount.QuadPart += PerfCount.QuadPart;

        //
        // Compute tick count and tick offset for current interrupt time.
        //

        NewTickCount = RtlExtendedLargeIntegerDivide(InterruptTime,
                                                     KeMaximumIncrement,
                                                     &NewTickOffset);

        //
        // Apply changes to interrupt time, tick count, tick offset, and the
        // performance counter.
        //

        KiTickOffset = KeMaximumIncrement - NewTickOffset;
        KeInterruptTimeBias += Adjust->Adjustment;
        SharedUserData->TickCount.High2Time = NewTickCount.HighPart;

#if defined(_WIN64)

        SharedUserData->TickCountQuad = NewTickCount.QuadPart;

#else

        SharedUserData->TickCount.LowPart   = NewTickCount.LowPart;
        SharedUserData->TickCount.High1Time = NewTickCount.HighPart;

#endif

        //
        // N.B. There is no global tick count variable on AMD64.
        //

#if defined(_X86_)

        KeTickCount.High2Time = NewTickCount.HighPart;
        KeTickCount.LowPart   = NewTickCount.LowPart;
        KeTickCount.High1Time = NewTickCount.HighPart;

#endif

#if defined(_AMD64_)

        SharedUserData->InterruptTime.High2Time = InterruptTime.HighPart;
        *((volatile ULONG64 *)&SharedUserData->InterruptTime) = InterruptTime.QuadPart;

#else

        SharedUserData->InterruptTime.High2Time = InterruptTime.HighPart;
        SharedUserData->InterruptTime.LowPart   = InterruptTime.LowPart;
        SharedUserData->InterruptTime.High1Time = InterruptTime.HighPart;

#endif

        //
        // Apply the performance counter change.
        //

        Adjust->Barrier = 0;
    }

    KeGetCurrentPrcb()->TickOffset = KiTickOffset;

#if defined(_AMD64_)

    KeGetCurrentPrcb()->MasterOffset = KiTickOffset;

#endif

    HalCalibratePerformanceCounter((LONG volatile *)&Adjust->HalNumber,
                                   (ULONGLONG)Adjust->NewCount.QuadPart);

    //
    // Log an event that the performance counter has been calibrated
    // properly and indicate the new performance counter value.
    //

    if (PERFINFO_IS_GROUP_ON(PERF_POWER)) {
        LogEntry.PerformanceCounter = KeQueryPerformanceCounter(NULL);
        PerfInfoLogBytes(PERFINFO_LOG_TYPE_PO_CALIBRATED_PERFCOUNTER,
                         &LogEntry,
                         sizeof(LogEntry));
    }

    KeEnableInterrupts(Enable);
    return;
}
Esempio n. 4
0
/*********************************************************************
 *      TIME_ClockTimeToFileTime    ([email protected], 20-Sep-1998)
 *
 *  Used by GetProcessTimes to convert clock_t into FILETIME.
 *
 *      Differences to UnixTimeToFileTime:
 *          1) Divided by CLK_TCK
 *          2) Time is relative. There is no 'starting date', so there is
 *             no need in offset correction, like in UnixTimeToFileTime
 */
static void TIME_ClockTimeToFileTime(clock_t unix_time, LPFILETIME filetime)
{
    LONGLONG secs = RtlEnlargedUnsignedMultiply( unix_time, 10000000 );
    ((LARGE_INTEGER *)filetime)->QuadPart =
       RtlExtendedLargeIntegerDivide( secs, sysconf( _SC_CLK_TCK ), NULL );
}