Легенда:
новое сообщение
закрытая нитка
новое сообщение
в закрытой нитке
старое сообщение
|
- Напоминаю, что масса вопросов по функционированию форума снимается после прочтения его описания.
- Новичкам также крайне полезно ознакомиться с данным документом.
вот что накопал в сырцах винды 11.05.05 14:16 Число просмотров: 4785
Автор: Killer{R} <Dmitry> Статус: Elderman
|
KAFFINITY
KeSetAffinityThread (
IN PKTHREAD Thread,
IN KAFFINITY Affinity
)
/*++
Routine Description:
This function sets the affinity of a specified thread to a new
value. If the new affinity is not a proper subset of the parent
process affinity, or is null, then an error condition is raised.
If the specified thread is running on, or about to run on, a
processor for which it is no longer able to run, then the target
processor is rescheduled. If the specified thread is in a ready
state and is not in the parent process ready queue, then it is
rereadied to reevaluate any additional processors it may run on.
Arguments:
Thread - Supplies a pointer to a dispatcher object of type thread.
Affinity - Supplies the new of set of processors on which the thread
can run.
Return Value:
The previous affinity of the specified thread.
--*/
{
KAFFINITY OldAffinity;
KIRQL OldIrql;
PKPRCB Prcb;
PKPROCESS Process;
ULONG Processor;
KPRIORITY ThreadPriority;
PRKTHREAD Thread1;
ASSERT_THREAD(Thread);
ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
//
// Raise IRQL to dispatcher level and lock dispatcher database.
//
KiLockDispatcherDatabase(&OldIrql);
//
// Capture the current affinity of the specified thread and get address
// of parent process object;
//
OldAffinity = Thread->UserAffinity;
Process = Thread->ApcStatePointer[0]->Process;
//
// If new affinity is not a proper subset of the parent process affinity,
// or the new affinity is null, then bugcheck.
//
if (((Affinity & Process->Affinity) != (Affinity))|(!Affinity)) {
KeBugCheck(INVALID_AFFINITY_SET);
}
//
// Set the thread user affinity to the specified value.
//
// If the thread is not current executing with system affinity active,
// then set the thread current affinity and switch on the thread state.
//
Thread->UserAffinity = Affinity;
if (Thread->SystemAffinityActive == FALSE) {
Thread->Affinity = Affinity;
switch (Thread->State) {
//
// Ready State.
//
// If the thread is not in the process ready queue, then remove
// it from its current dispatcher ready queue and reready it for
// execution.
//
case Ready:
if (Thread->ProcessReadyQueue == FALSE) {
RemoveEntryList(&Thread->WaitListEntry);
ThreadPriority = Thread->Priority;
if (IsListEmpty(&KiDispatcherReadyListHead[ThreadPriority]) != FALSE) {
ClearMember(ThreadPriority, KiReadySummary);
}
KiReadyThread(Thread);
}
break;
//
// Standby State.
//
// If the target processor is not in the new affinity set, then
// set the next thread to null for the target processor, select
// a new thread to run on the target processor, and reready the
// thread for execution.
//
case Standby:
Processor = Thread->NextProcessor;
Prcb = KiProcessorBlock[Processor];
if ((Prcb->SetMember & Affinity) == 0) {
Prcb->NextThread = NULL;
Thread1 = KiSelectNextThread(Thread);
Thread1->State = Standby;
Prcb->NextThread = Thread1;
KiReadyThread(Thread);
}
break;
//
// Running State.
//
// If the target processor is not in the new affinity set and
// another thread has not already been selected for execution
// on the target processor, then select a new thread for the
// target processor, and cause the target processor to be
// redispatched.
//
case Running:
Processor = Thread->NextProcessor;
Prcb = KiProcessorBlock[Processor];
if (((Prcb->SetMember & Affinity) == 0) &&
(Prcb->NextThread == NULL)) {
Thread1 = KiSelectNextThread(Thread);
Thread1->State = Standby;
Prcb->NextThread = Thread1;
KiRequestDispatchInterrupt(Processor);
}
break;
//
// Initialized, Terminated, Waiting, Transition case - For these
// states it is sufficient to just set the new thread affinity.
//
default:
break;
}
}
//
// Unlock dispatcher database, lower IRQL to its previous value, and
// return the previous user affinity.
//
KiUnlockDispatcherDatabase(OldIrql);
return OldAffinity;
}
я так понимаю мои подозрения оправдались (см. case Running) и возможна ситуация когда поток будет еще некоторое время исполняться на текущем процессоре. Или я чтото пропустил/не так понял?
|
|
|