Exemplo n.º 1
0
void CStaticResourcePool::Cleanup()
{
	FreeAll();
	if (m_pItemPool)
	{
		ReleaseStaticMemoryPool(m_pItemPool);
	}
	ClearMember();

}
Exemplo n.º 2
0
CStaticResourcePool::CStaticResourcePool()
{
	ClearMember();

}
Exemplo n.º 3
0
PKTHREAD
FASTCALL
KiFindReadyThread (
    IN ULONG Processor,
    IN KPRIORITY LowPriority
    )

/*++

Routine Description:

    This function searches the dispatcher ready queues from the specified
    high priority to the specified low priority in an attempt to find a thread
    that can execute on the specified processor.

Arguments:

    Processor - Supplies the number of the processor to find a thread for.

    LowPriority - Supplies the lowest priority dispatcher ready queue to
        examine.

Return Value:

    If a thread is located that can execute on the specified processor, then
    the address of the thread object is returned. Otherwise a null pointer is
    returned.

--*/

{

    ULONG HighPriority;
    PRLIST_ENTRY ListHead;
    PRLIST_ENTRY NextEntry;
    ULONG PrioritySet;
    KAFFINITY ProcessorSet;
    PRKTHREAD Thread;
    PRKTHREAD Thread1;
    ULONG TickLow;
    ULONG WaitTime;

    //
    // Compute the set of priority levels that should be scanned in an attempt
    // to find a thread that can run on the specified processor.
    //

    PrioritySet = (~((1 << LowPriority) - 1)) & KiReadySummary;

#if !defined(NT_UP)

    ProcessorSet = (KAFFINITY)(1 << Processor);

#endif

    FindFirstSetLeftMember(PrioritySet, &HighPriority);
    ListHead = &KiDispatcherReadyListHead[HighPriority];
    PrioritySet <<= (31 - HighPriority);
    while (PrioritySet != 0) {

        //
        // If the next bit in the priority set is a one, then examine the
        // corresponding dispatcher ready queue.
        //

        if ((LONG)PrioritySet < 0) {
            NextEntry = ListHead->Flink;

            ASSERT(NextEntry != ListHead);

#if defined(NT_UP)

            Thread = CONTAINING_RECORD(NextEntry, KTHREAD, WaitListEntry);
            RemoveEntryList(&Thread->WaitListEntry);
            if (IsListEmpty(ListHead)) {
                ClearMember(HighPriority, KiReadySummary);
            }

            return (PKTHREAD)Thread;

#else

            //
            // Scan the specified dispatcher ready queue for a suitable
            // thread to execute.
            //

            while (NextEntry != ListHead) {
                Thread = CONTAINING_RECORD(NextEntry, KTHREAD, WaitListEntry);
                NextEntry = NextEntry->Flink;
                if (Thread->Affinity & ProcessorSet) {

                    //
                    // If the found thread ran on the specified processor
                    // last, the processor is the ideal processor for the
                    // thread, the thread has been waiting for longer than
                    // a quantum, or its priority is greater than low realtime
                    // plus 8, then the selected thread is returned. Otherwise,
                    // an attempt is made to find a more appropriate thread.
                    //

                    TickLow = KiQueryLowTickCount();
                    WaitTime = TickLow - Thread->WaitTime;
                    if ((KiThreadSelectNotifyRoutine ?
                        (KiThreadSelectNotifyRoutine(((PETHREAD)Thread)->Cid.UniqueThread) == FALSE) :
                        (((ULONG)Thread->NextProcessor != Processor) &&
                        ((ULONG)Thread->IdealProcessor != Processor))) &&
                        (WaitTime < (READY_SKIP_QUANTUM + 1)) &&
                        (HighPriority < (LOW_REALTIME_PRIORITY + 9))) {

                        //
                        // Search forward in the ready queue until the end
                        // of the list is reached or a more appropriate
                        // thread is found.
                        //

                        while (NextEntry != ListHead) {
                            Thread1 = CONTAINING_RECORD(NextEntry,
                                                        KTHREAD,
                                                        WaitListEntry);

                            NextEntry = NextEntry->Flink;
                            if ((Thread1->Affinity & ProcessorSet) &&
                                (KiThreadSelectNotifyRoutine ?
                                (KiThreadSelectNotifyRoutine(((PETHREAD)Thread)->Cid.UniqueThread) != FALSE) :
                                (((ULONG)Thread1->NextProcessor == Processor) ||
                                ((ULONG)Thread1->IdealProcessor == Processor)))) {
                                Thread = Thread1;
                                break;
                            }

                            WaitTime = TickLow - Thread1->WaitTime;
                            if (WaitTime >= (READY_SKIP_QUANTUM + 1)) {
                                break;
                            }
                        }
                    }

                    if (Processor == (ULONG)Thread->IdealProcessor) {
                        KiIncrementSwitchCounter(FindIdeal);

                    } else if (Processor == (ULONG)Thread->NextProcessor) {
                        KiIncrementSwitchCounter(FindLast);

                    } else {
                        KiIncrementSwitchCounter(FindAny);
                    }

                    Thread->NextProcessor = (CCHAR)Processor;

                    RemoveEntryList(&Thread->WaitListEntry);
                    if (IsListEmpty(ListHead)) {
                        ClearMember(HighPriority, KiReadySummary);
                    }

                    return (PKTHREAD)Thread;
                }
            }

#endif

        }

        HighPriority -= 1;
        ListHead -= 1;
        PrioritySet <<= 1;
    };

    //
    // No thread could be found, return a null pointer.
    //

    return (PKTHREAD)NULL;
}
Exemplo n.º 4
0
VOID
FASTCALL
KiReadyThread (
    IN PRKTHREAD Thread
    )

/*++

Routine Description:

    This function readies a thread for execution and attempts to immediately
    dispatch the thread for execution by preempting another lower priority
    thread. If a thread can be preempted, then the specified thread enters
    the standby state and the target processor is requested to dispatch. If
    another thread cannot be preempted, then the specified thread is inserted
    either at the head or tail of the dispatcher ready selected by its priority
    acccording to whether it was preempted or not.

Arguments:

    Thread - Supplies a pointer to a dispatcher object of type thread.

Return Value:

    None.

--*/

{

    PRKPRCB Prcb;
    BOOLEAN Preempted;
    KPRIORITY Priority;
    PRKPROCESS Process;
    ULONG Processor;
    KPRIORITY ThreadPriority;
    PRKTHREAD Thread1;
    KAFFINITY IdleSet;

    //
    // Save value of thread's preempted flag, set thread preempted FALSE,
    // capture the thread priority, and set clear the read wait time.
    //

    Preempted = Thread->Preempted;
    Thread->Preempted = FALSE;
    ThreadPriority = Thread->Priority;
    Thread->WaitTime = KiQueryLowTickCount();

    //
    // If the thread's process is not in memory, then insert the thread in
    // the process ready queue and inswap the process.
    //

    Process = Thread->ApcState.Process;
    if (Process->State != ProcessInMemory) {
        Thread->State = Ready;
        Thread->ProcessReadyQueue = TRUE;
        InsertTailList(&Process->ReadyListHead, &Thread->WaitListEntry);
        if (Process->State == ProcessOutOfMemory) {
            Process->State = ProcessInTransition;
            InsertTailList(&KiProcessInSwapListHead, &Process->SwapListEntry);
            KiSwapEvent.Header.SignalState = 1;
            if (IsListEmpty(&KiSwapEvent.Header.WaitListHead) == FALSE) {
                KiWaitTest(&KiSwapEvent, BALANCE_INCREMENT);
            }
        }

        return;

    } else if (Thread->KernelStackResident == FALSE) {

        //
        // The thread's kernel stack is not resident. Increment the process
        // stack count, set the state of the thread to transition, insert
        // the thread in the kernel stack inswap list, and set the kernel
        // stack inswap event.
        //

        Process->StackCount += 1;
        Thread->State = Transition;
        InsertTailList(&KiStackInSwapListHead, &Thread->WaitListEntry);
        KiSwapEvent.Header.SignalState = 1;
        if (IsListEmpty(&KiSwapEvent.Header.WaitListHead) == FALSE) {
            KiWaitTest(&KiSwapEvent, BALANCE_INCREMENT);
        }

        return;

    } else {

        //
        // If there is an idle processor, then schedule the thread on an
        // idle processor giving preference to the processor the thread
        // last ran on. Otherwise, try to preempt either a thread in the
        // standby or running state.
        //

#if defined(NT_UP)

        Prcb = KiProcessorBlock[0];
        if (KiIdleSummary != 0) {
            KiIdleSummary = 0;
            KiIncrementSwitchCounter(IdleLast);

#else

        IdleSet = KiIdleSummary & Thread->Affinity;
        if (IdleSet != 0) {
            Processor = Thread->IdealProcessor;
            if ((IdleSet & (1 << Processor)) == 0) {
                Processor = Thread->NextProcessor;
                if ((IdleSet & (1 << Processor)) == 0) {
                    Prcb = KeGetCurrentPrcb();
                    if ((IdleSet & Prcb->SetMember) == 0) {
                        FindFirstSetLeftMember(IdleSet, &Processor);
                        KiIncrementSwitchCounter(IdleAny);

                    } else {
                        Processor = Prcb->Number;
                        KiIncrementSwitchCounter(IdleCurrent);
                    }

                } else {
                    KiIncrementSwitchCounter(IdleLast);
                }

            } else {
                KiIncrementSwitchCounter(IdleIdeal);
            }

            Thread->NextProcessor = (CCHAR)Processor;
            ClearMember(Processor, KiIdleSummary);
            Prcb = KiProcessorBlock[Processor];

#endif

            Prcb->NextThread = Thread;
            Thread->State = Standby;
            return;

        } else {

#if !defined(NT_UP)

            Processor = Thread->IdealProcessor;
            if ((Thread->Affinity & (1 << Processor)) == 0) {
                Processor = Thread->NextProcessor;
                if ((Thread->Affinity & (1 << Processor)) == 0) {
                    FindFirstSetLeftMember(Thread->Affinity, &Processor);
                }
            }

            Thread->NextProcessor = (CCHAR)Processor;
            Prcb = KiProcessorBlock[Processor];

#endif

            if (Prcb->NextThread != NULL) {
                Thread1 = Prcb->NextThread;
                if (ThreadPriority > Thread1->Priority) {
                    Thread1->Preempted = TRUE;
                    Prcb->NextThread = Thread;
                    Thread->State = Standby;
                    KiReadyThread(Thread1);
                    KiIncrementSwitchCounter(PreemptLast);
                    return;
                }

            } else {
                Thread1 = Prcb->CurrentThread;
                if (ThreadPriority > Thread1->Priority) {
                    Thread1->Preempted = TRUE;
                    Prcb->NextThread = Thread;
                    Thread->State = Standby;
                    KiRequestDispatchInterrupt(Thread->NextProcessor);
                    KiIncrementSwitchCounter(PreemptLast);
                    return;
                }
            }
        }
    }

    //
    // No thread can be preempted. Insert the thread in the dispatcher
    // queue selected by its priority. If the thread was preempted and
    // runs at a realtime priority level, then insert the thread at the
    // front of the queue. Else insert the thread at the tail of the queue.
    //

    Thread->State = Ready;
    if (Preempted != FALSE) {
        InsertHeadList(&KiDispatcherReadyListHead[ThreadPriority],
                       &Thread->WaitListEntry);

    } else {
        InsertTailList(&KiDispatcherReadyListHead[ThreadPriority],
                       &Thread->WaitListEntry);
    }

    SetMember(ThreadPriority, KiReadySummary);
    return;
}

PRKTHREAD
FASTCALL
KiSelectNextThread (
    IN PRKTHREAD Thread
    )

/*++

Routine Description:

    This function selects the next thread to run on the processor that the
    specified thread is running on. If a thread cannot be found, then the
    idle thread is selected.

Arguments:

    Thread - Supplies a pointer to a dispatcher object of type thread.

Return Value:

    The address of the selected thread object.

--*/

{

    PRKPRCB Prcb;
    ULONG Processor;
    PRKTHREAD Thread1;

    //
    // Get the processor number and the address of the processor control block.
    //

#if !defined(NT_UP)

    Processor = Thread->NextProcessor;
    Prcb = KiProcessorBlock[Processor];

#else

    Prcb = KiProcessorBlock[0];

#endif

    //
    // If a thread has already been selected to run on the specified processor,
    // then return that thread as the selected thread.
    //

    if ((Thread1 = Prcb->NextThread) != NULL) {
        Prcb->NextThread = (PKTHREAD)NULL;

    } else {

        //
        // Attempt to find a ready thread to run.
        //

#if !defined(NT_UP)

        Thread1 = KiFindReadyThread(Processor, 0);

#else

        Thread1 = KiFindReadyThread(0, 0);

#endif

        //
        // If a thread was not found, then select the idle thread and
        // set the processor member in the idle summary.
        //

        if (Thread1 == NULL) {
            KiIncrementSwitchCounter(SwitchToIdle);
            Thread1 = Prcb->IdleThread;

#if !defined(NT_UP)

            SetMember(Processor, KiIdleSummary);

#else
            KiIdleSummary = 1;

#endif

        }
    }

    //
    // Return address of selected thread object.
    //

    return Thread1;
}
Exemplo n.º 5
0
VOID
FASTCALL
KiSetPriorityThread (
    IN PRKTHREAD Thread,
    IN KPRIORITY Priority
    )

/*++

Routine Description:

    This function set the priority of the specified thread to the specified
    value. If the thread is in the standby or running state, then the processor
    may be redispatched. If the thread is in the ready state, then some other
    thread may be preempted.

Arguments:

    Thread - Supplies a pointer to a dispatcher object of type thread.

    Priority - Supplies the new thread priority value.

Return Value:

    None.

--*/

{

    PRKPRCB Prcb;
    ULONG Processor;
    KPRIORITY ThreadPriority;
    PRKTHREAD Thread1;

    ASSERT(Priority <= HIGH_PRIORITY);

    //
    // Capture the current priority of the specified thread.
    //

    ThreadPriority = Thread->Priority;

    //
    // If the new priority is not equal to the old priority, then set the
    // new priority of the thread and redispatch a processor if necessary.
    //

    if (Priority != ThreadPriority) {
        Thread->Priority = (SCHAR)Priority;

        //
        // Case on the thread state.
        //

        switch (Thread->State) {

            //
            // Ready case - If the thread is not in the process ready queue,
            // then remove it from its current dispatcher ready queue. If the
            // new priority is less than the old priority, then insert the
            // thread at the tail of the dispatcher ready queue selected by
            // the new priority. Else reready the thread for execution.
            //

        case Ready:
            if (Thread->ProcessReadyQueue == FALSE) {
                RemoveEntryList(&Thread->WaitListEntry);
                if (IsListEmpty(&KiDispatcherReadyListHead[ThreadPriority])) {
                    ClearMember(ThreadPriority, KiReadySummary);
                }

                if (Priority < ThreadPriority) {
                    InsertTailList(&KiDispatcherReadyListHead[Priority],
                                   &Thread->WaitListEntry);
                    SetMember(Priority, KiReadySummary);

                } else {
                    KiReadyThread(Thread);
                }
            }

            break;

            //
            // Standby case - If the thread's priority is being lowered, then
            // attempt to find another thread to execute. If a new thread is
            // found, then put the new thread in the standby state, and reready
            // the old thread.
            //

        case Standby:

#if !defined(NT_UP)

            Processor = Thread->NextProcessor;

#endif

            if (Priority < ThreadPriority) {

#if !defined(NT_UP)

                Thread1 = KiFindReadyThread(Processor, Priority);

#else

                Thread1 = KiFindReadyThread(0, Priority);

#endif

                if (Thread1 != NULL) {

#if !defined(NT_UP)

                    Prcb = KiProcessorBlock[Processor];

#else

                    Prcb = KiProcessorBlock[0];

#endif

                    Thread1->State = Standby;
                    Prcb->NextThread = Thread1;
                    KiReadyThread(Thread);
                }
            }

            break;

            //
            // Running case - If there is not a thread in the standby state
            // on the thread's processor and the thread's priority is being
            // lowered, then attempt to find another thread to execute. If
            // a new thread is found, then put the new thread in the standby
            // state, and request a redispatch on the thread's processor.
            //

        case Running:

#if !defined(NT_UP)

            Processor = Thread->NextProcessor;
            Prcb = KiProcessorBlock[Processor];

#else

            Prcb = KiProcessorBlock[0];

#endif

            if (Prcb->NextThread == NULL) {
                if (Priority < ThreadPriority) {

#if !defined(NT_UP)

                    Thread1 = KiFindReadyThread(Processor, Priority);

#else

                    Thread1 = KiFindReadyThread(0, Priority);

#endif

                    if (Thread1 != NULL) {
                        Thread1->State = Standby;
                        Prcb->NextThread = Thread1;

#if !defined(NT_UP)

                        KiRequestDispatchInterrupt(Processor);

#endif

                    }
                }
            }

            break;

            //
            // Initialized, Terminated, Waiting, Transition case - For
            // these states it is sufficient to just set the new thread
            // priority.
            //

        default:
            break;
        }
    }

    return;
}
Exemplo n.º 6
0
CStaticVBPool::CStaticVBPool()
{
	ClearMember();
}
Exemplo n.º 7
0
CStaticVBPool::~CStaticVBPool()
{
	Cleanup();
	ClearMember();
}
Exemplo n.º 8
0
BOOLEAN
KeFreezeExecution (
    IN PKTRAP_FRAME TrapFrame,
    IN PKEXCEPTION_FRAME ExceptionFrame
    )

/*++

Routine Description:

    This function freezes the execution of all other processors in the host
    configuration and then returns to the caller.

Arguments:

    TrapFrame - Supplies a pointer to a trap frame that describes the
        trap.

    ExceptionFrame - Supplies a pointer to an exception frame that
        describes the trap.

Return Value:

    Previous interrupt enable.

--*/

{

    BOOLEAN Enable;

#if !defined(NT_UP)

    BOOLEAN Flag;
    PKPRCB Prcb;
    ULONG TargetSet;
    ULONG BitNumber;
    KIRQL OldIrql;

#if IDBG

    ULONG Count = 30000;

#endif
#endif

    //
    // Disable interrupts.
    //

    Enable = KiDisableInterrupts();
    KiFreezeFlag = FREEZE_FROZEN;

#if !defined(NT_UP)
    //
    // Raise IRQL to HIGH_LEVEL.
    //

    KeRaiseIrql(HIGH_LEVEL, &OldIrql);

    if (FrozenState(KeGetCurrentPrcb()->IpiFrozen) == FREEZE_OWNER) {
        //
        // This processor already owns the freeze lock.
        // Return without trying to re-acquire lock or without
        // trying to IPI the other processors again
        //

        return Enable;
    }


    //
    // Try to acquire the KiFreezeExecutionLock before sending the request.
    // To prevent deadlock from occurring, we need to accept and process
    // incoming FreexeExecution requests while we are waiting to acquire
    // the FreezeExecutionFlag.
    //

    while (KiTryToAcquireSpinLock (&KiFreezeExecutionLock) == FALSE) {

        //
        // FreezeExecutionLock is busy.  Another processor may be trying
        // to IPI us - go service any IPI.
        //

        KiRestoreInterrupts(Enable);
        Flag = KiIpiServiceRoutine((PVOID)TrapFrame, (PVOID)ExceptionFrame);
        KiDisableInterrupts();

#if IDBG

        if (Flag != FALSE) {
            Count = 30000;
            continue;
        }

        KeStallExecutionProcessor (100);
        if (!Count--) {
            Count = 30000;
            if (KiTryToAcquireSpinLock (&KiFreezeLockBackup) == TRUE) {
                KiFreezeFlag |= FREEZE_BACKUP;
                break;
            }
        }

#endif

    }

    //
    // After acquiring the lock flag, we send Freeze request to each processor
    // in the system (other than us) and wait for it to become frozen.
    //

    Prcb = KeGetCurrentPrcb();  // Do this after spinlock is acquired.
    TargetSet = KeActiveProcessors & ~(1 << Prcb->Number);
    if (TargetSet) {

#if IDBG
        Count = 400;
#endif

        KiFreezeOwner = Prcb;
        Prcb->IpiFrozen = FREEZE_OWNER | FREEZE_ACTIVE;
        Prcb->SkipTick  = TRUE;
        KiIpiSend((KAFFINITY) TargetSet, IPI_FREEZE);

        while (TargetSet != 0) {
            BitNumber = KeFindFirstSetRightMember(TargetSet);
            ClearMember(BitNumber, TargetSet);
            Prcb = KiProcessorBlock[BitNumber];

#if IDBG

            while (Prcb->IpiFrozen != TARGET_FROZEN) {
                if (Count == 0) {
                    KiFreezeFlag |= FREEZE_SKIPPED_PROCESSOR;
                    break;
                }

                KeStallExecutionProcessor (10000);
                Count--;
            }

#else

            while (Prcb->IpiFrozen != TARGET_FROZEN) {
                KeYieldProcessor();
            }
#endif

        }
    }

    //
    // Save the old IRQL and return whether interrupts were previous enabled.
    //

    KiOldIrql = OldIrql;

#endif      // !defined(NT_UP)

    return Enable;
}
Exemplo n.º 9
0
VOID
KeThawExecution (
    IN BOOLEAN Enable
    )

/*++

Routine Description:

    This function thaws the execution of all other processors in the host
    configuration and then returns to the caller. It is intended for use by
    the kernel debugger.

Arguments:

    Enable - Supplies the previous interrupt enable that is to be restored
        after having thawed the execution of all other processors.

Return Value:

    None.

--*/

{
#if !defined(NT_UP)

    KIRQL OldIrql;
    ULONG TargetSet;
    ULONG BitNumber;
    ULONG Flag;
    PKPRCB Prcb;

    //
    // Before releasing FreezeExecutionLock clear any all targets IpiFrozen
    // flag.
    //

    KeGetCurrentPrcb()->IpiFrozen = RUNNING;

    TargetSet = KeActiveProcessors & ~(1 << KeGetCurrentPrcb()->Number);
    while (TargetSet != 0) {
        BitNumber = KeFindFirstSetRightMember(TargetSet);
        ClearMember(BitNumber, TargetSet);
        Prcb = KiProcessorBlock[BitNumber];
#if IDBG
        //
        // If the target processor was not forzen, then don't wait
        // for target to unfreeze.
        //

        if (FrozenState(Prcb->IpiFrozen) != TARGET_FROZEN) {
            Prcb->IpiFrozen = RUNNING;
            continue;
        }
#endif

        Prcb->IpiFrozen = TARGET_THAW;
        while (Prcb->IpiFrozen == TARGET_THAW) {
            KeYieldProcessor();
        }
    }

    //
    // Capture the previous IRQL before releasing the freeze lock.
    //

    OldIrql = KiOldIrql;

#if IDBG

    Flag = KiFreezeFlag;
    KiFreezeFlag = 0;

    if ((Flag & FREEZE_BACKUP) != 0) {
        KiReleaseSpinLock(&KiFreezeLockBackup);
    } else {
        KiReleaseSpinLock(&KiFreezeExecutionLock);
    }

#else

    KiFreezeFlag = 0;
    KiReleaseSpinLock(&KiFreezeExecutionLock);

#endif
#endif  // !defined (NT_UP)


    //
    // Flush the current TB, instruction cache, and data cache.
    //

    KeFlushCurrentTb();
    KeSweepCurrentIcache();
    KeSweepCurrentDcache();

    //
    // Lower IRQL and restore interrupt enable
    //

#if !defined(NT_UP)
    KeLowerIrql(OldIrql);
#endif
    KiRestoreInterrupts(Enable);
    return;
}
Exemplo n.º 10
0
void CStaticIBPool::Cleanup()
{
	m_StaticD3DResoucePool.Cleanup();
	ClearMember();
}