Exemple #1
0
/*++

Routine Description:

    Clock interrupt handler for processors other than 0.

Arguments:

    Interrupt

    ServiceContext

    TrapFrame

Return Value:

    TRUE

--*/
BOOLEAN
HalpHandleDecrementerInterrupt1(
    IN PKINTERRUPT Interrupt,
    IN PVOID ServiceContext,
    IN PVOID TrapFrame
    )
{
	KIRQL OldIrql;
	ULONG CpuId;
	
	HASSERT(!MSR(EE));

	CpuId = GetCpuId();
	
	//
	// Raise irql via updating the PCR
	//
	OldIrql = PCR->CurrentIrql;
	PCR->CurrentIrql = CLOCK2_LEVEL;
	RInterruptMask(CpuId) = (Irql2Mask[CLOCK2_LEVEL] & registeredInts[CpuId]);
	WaitForRInterruptMask(CpuId);
	
	//
	// Reset DECREMENTER (no account for latency)
	//
	HalpUpdateDecrementer(HalpFullTickClockCount);
	
	//
	// Call the kernel to update run time for this thread and process.
	//
	KeUpdateRunTime(TrapFrame);

	HDBG(DBG_PROC1DBG,
		{
			//
			// Check for the debugger BreakIn only every minute or so.
			// (decrementer is interms of ms so we multiple by 10,000
			// on the order of a minute).
			//
			static Count = 0;
			if (++Count > 10000) {
				Count = 0;
				if (KdDebuggerEnabled && KdPollBreakIn()) {
					HalpEnableInterrupts();
					DbgBreakPointWithStatus(DBG_STATUS_CONTROL_C);
					HalpDisableInterrupts();
				}
			}
		}
	);
Exemple #2
0
VOID
FASTCALL
KeUpdateSystemTime(IN PKTRAP_FRAME TrapFrame,
                   IN ULONG Increment,
                   IN KIRQL Irql)
{
    PKPRCB Prcb = KeGetCurrentPrcb();
    ULARGE_INTEGER CurrentTime, InterruptTime;
    LONG OldTickOffset;

    /* Check if this tick is being skipped */
    if (Prcb->SkipTick)
    {
        /* Handle it next time */
        Prcb->SkipTick = FALSE;

        /* Increase interrupt count and end the interrupt */
        Prcb->InterruptCount++;
        KiEndInterrupt(Irql, TrapFrame);

        /* Note: non-x86 return back to the caller! */
        return;
    }

    /* Add the increment time to the shared data */
    InterruptTime.QuadPart = *(ULONGLONG*)&SharedUserData->InterruptTime;
    InterruptTime.QuadPart += Increment;
    KiWriteSystemTime(&SharedUserData->InterruptTime, InterruptTime);

    /* Check for timer expiration */
    KiCheckForTimerExpiration(Prcb, TrapFrame, InterruptTime);

    /* Update the tick offset */
    OldTickOffset = InterlockedExchangeAdd(&KiTickOffset, -(LONG)Increment);

    /* If the debugger is enabled, check for break-in request */
    if (KdDebuggerEnabled && KdPollBreakIn())
    {
        /* Break-in requested! */
        DbgBreakPointWithStatus(DBG_STATUS_CONTROL_C);
    }

    /* Check for full tick */
    if (OldTickOffset <= (LONG)Increment)
    {
        /* Update the system time */
        CurrentTime.QuadPart = *(ULONGLONG*)&SharedUserData->SystemTime;
        CurrentTime.QuadPart += KeTimeAdjustment;
        KiWriteSystemTime(&SharedUserData->SystemTime, CurrentTime);

        /* Update the tick count */
        CurrentTime.QuadPart = (*(ULONGLONG*)&KeTickCount) + 1;
        KiWriteSystemTime(&KeTickCount, CurrentTime);

        /* Update it in the shared user data */
        KiWriteSystemTime(&SharedUserData->TickCount, CurrentTime);

        /* Check for expiration with the new tick count as well */
        KiCheckForTimerExpiration(Prcb, TrapFrame, InterruptTime);

        /* Reset the tick offset */
        KiTickOffset += KeMaximumIncrement;

        /* Update processor/thread runtime */
        KeUpdateRunTime(TrapFrame, Irql);
    }
    else
    {
        /* Increase interrupt count only */
        Prcb->InterruptCount++;
    }

    /* Disable interrupts and end the interrupt */
    KiEndInterrupt(Irql, TrapFrame);
}