SMP scheduling fixes

Obey thread affinity
Fix bogus invariant in KeAcquireSpinLockAtDpcLevel
Protect display with spinlock

svn path=/trunk/; revision=1809
This commit is contained in:
David Welch 2001-04-17 23:39:26 +00:00
parent f29036d97b
commit d41145488c
11 changed files with 164 additions and 143 deletions

View file

@ -7,3 +7,4 @@ depends
depends.exe
mkconfig
mkconfig.exe
ntoskrnl.dbg

View file

@ -1,4 +1,4 @@
/* $Id: display.c,v 1.12 2001/03/16 18:11:21 dwelch Exp $
/* $Id: display.c,v 1.13 2001/04/17 23:39:25 dwelch Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -179,11 +179,8 @@ HalAcquireDisplayOwnership (
}
VOID
STDCALL
HalDisplayString (
IN PCH String
)
VOID STDCALL
HalDisplayString (IN PCH String)
/*
* FUNCTION: Switches the screen to HAL console mode (BSOD) if not there
* already and displays a string
@ -197,9 +194,13 @@ HalDisplayString (
#ifdef SCREEN_SYNCHRONIZATION
int offset;
#endif
static KSPIN_LOCK Lock;
pch = String;
__asm__ ("cli\n\t");
KeAcquireSpinLockAtDpcLevel(&Lock);
if (HalOwnsDisplay == FALSE)
{
HalResetDisplay ();
@ -251,6 +252,8 @@ HalDisplayString (
WRITE_PORT_UCHAR((PUCHAR)CRTC_COMMAND, CRTC_CURHI);
WRITE_PORT_UCHAR((PUCHAR)CRTC_DATA, (offset >> 8) & 0xff);
#endif
KeReleaseSpinLockFromDpcLevel(&Lock);
__asm__ ("sti\n\t");
}

View file

@ -1,4 +1,4 @@
/* $Id: mp.c,v 1.10 2001/04/16 23:29:54 dwelch Exp $
/* $Id: mp.c,v 1.11 2001/04/17 23:39:25 dwelch Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -227,8 +227,8 @@ VOID IOAPICUnmaskIrq(
IOAPICWrite(Apic, IOAPIC_REDTBL+2*Irq, *((PULONG)&Entry));
}
static VOID IOAPICSetupIds(
VOID)
static VOID
IOAPICSetupIds(VOID)
{
ULONG tmp, apic, i;
UCHAR old_id;
@ -246,7 +246,8 @@ static VOID IOAPICSetupIds(
if (IOAPICMap[apic].ApicId >= 0xf) {
DPRINT1("BIOS bug, IO-APIC#%d ID is %d in the MPC table!...\n",
apic, IOAPICMap[apic].ApicId);
DPRINT1("... fixing up to %d. (tell your hw vendor)\n", GET_IOAPIC_ID(tmp));
DPRINT1("... fixing up to %d. (tell your hw vendor)\n",
GET_IOAPIC_ID(tmp));
IOAPICMap[apic].ApicId = GET_IOAPIC_ID(tmp);
}

View file

@ -89,6 +89,8 @@ KeApplicationProcessorInit(VOID)
* Initialize a default LDT
*/
Ki386InitializeLdt();
__asm__ __volatile__ ("sti\n\t");
}
VOID
@ -122,6 +124,8 @@ KeInit1(VOID)
PcrsAllocated++;
Ki386InitializeLdt();
__asm__ __volatile__ ("sti\n\t");
}
VOID

View file

@ -75,7 +75,7 @@ _Ki386RetToV86Mode:
/*
* Save the old initial stack
*/
movl _CurrentThread, %esi
movl %fs:KPCR_CURRENT_THREAD, %esi
movl KTHREAD_INITIAL_STACK(%esi), %edi
pushl %edi
@ -187,7 +187,7 @@ _KiV86Complete:
/*
* We also need to set the stack in the kthread structure
*/
movl $_CurrentThread, %esi
movl %fs:KPCR_CURRENT_THREAD, %esi
movl KTHREAD_INITIAL_STACK(%esi), %edi
movl %eax, KTHREAD_INITIAL_STACK(%esi)

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: main.c,v 1.92 2001/04/17 04:11:00 dwelch Exp $
/* $Id: main.c,v 1.93 2001/04/17 23:39:25 dwelch Exp $
*
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/ke/main.c
@ -454,9 +454,12 @@ ExpInitializeExecutive(VOID)
KeNumberProcessors = 0;
while (!HalAllProcessorsStarted())
{
if (KeNumberProcessors != 0)
{
KePrepareForApplicationProcessorInit(KeNumberProcessors);
PsPrepareForApplicationProcessorInit(KeNumberProcessors);
}
HalInitializeProcessor(KeNumberProcessors);
KeNumberProcessors++;
}

View file

@ -1,4 +1,4 @@
/* $Id: spinlock.c,v 1.7 2001/04/17 04:11:01 dwelch Exp $
/* $Id: spinlock.c,v 1.8 2001/04/17 23:39:25 dwelch Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -74,9 +74,13 @@ KeAcquireSpinLockAtDpcLevel (PKSPIN_LOCK SpinLock)
{
ULONG i;
if (!(SpinLock->Lock == 0 || SpinLock->Lock == 1))
/*
* FIXME: This depends on gcc assembling this test to a single load from
* the spinlock's value.
*/
if ((ULONG)SpinLock->Lock >= 2)
{
DbgPrint("Lock %x has bad value %x\n", SpinLock, i);
DbgPrint("Lock %x has bad value %x\n", SpinLock, SpinLock->Lock);
KeBugCheck(0);
}

View file

@ -1,4 +1,4 @@
/* $Id: timer.c,v 1.44 2001/04/13 16:12:25 chorns Exp $
/* $Id: timer.c,v 1.45 2001/04/17 23:39:25 dwelch Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -422,8 +422,6 @@ KiUpdateSystemTime (KIRQL oldIrql, ULONG Eip)
* FUNCTION: Handles a timer interrupt
*/
{
char* vidmem=(char *)physical_to_linear(0xb8000 + 160 - 2);
KiRawTicks++;
if (TimerInitDone == FALSE)
@ -436,16 +434,6 @@ KiUpdateSystemTime (KIRQL oldIrql, ULONG Eip)
KiTimerTicks++;
system_time = system_time + CLOCK_INCREMENT;
vidmem[0] = ' ';
if (oldIrql < DISPATCH_LEVEL)
{
vidmem[1] = 0x17;
}
else
{
vidmem[1] = 0x27;
}
/*
* Queue a DPC that will expire timers
*/

View file

@ -45,6 +45,7 @@ PsIdleThreadMain(PVOID Context)
VOID PsInitIdleThread(VOID)
{
KPRIORITY Priority;
ULONG Affinity;
PsCreateSystemThread(&PsIdleThreadHandle,
THREAD_ALL_ACCESS,
@ -59,4 +60,9 @@ VOID PsInitIdleThread(VOID)
ThreadPriority,
&Priority,
sizeof(Priority));
Affinity = 1 << 0;
NtSetInformationThread(PsIdleThreadHandle,
ThreadAffinityMask,
&Affinity,
sizeof(Affinity));
}

View file

@ -1,4 +1,4 @@
/* $Id: thread.c,v 1.76 2001/04/17 04:11:01 dwelch Exp $
/* $Id: thread.c,v 1.77 2001/04/17 23:39:26 dwelch Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -48,8 +48,6 @@ static PETHREAD IdleThreads[MAXIMUM_PROCESSORS];
ULONG PiNrThreads = 0;
ULONG PiNrRunnableThreads = 0;
PETHREAD CurrentThread = NULL;
static GENERIC_MAPPING PiThreadMapping = {THREAD_READ,
THREAD_WRITE,
THREAD_EXECUTE,
@ -59,12 +57,13 @@ static GENERIC_MAPPING PiThreadMapping = {THREAD_READ,
PKTHREAD STDCALL KeGetCurrentThread(VOID)
{
return(&(CurrentThread->Tcb));
return(KeGetCurrentKPCR()->CurrentThread);
}
PETHREAD STDCALL PsGetCurrentThread(VOID)
{
return(CurrentThread);
PKTHREAD CurrentThread = KeGetCurrentKPCR()->CurrentThread;
return(CONTAINING_RECORD(CurrentThread, ETHREAD, Tcb));
}
HANDLE STDCALL PsGetCurrentThreadId(VOID)
@ -144,8 +143,13 @@ static PETHREAD PsScanThreadList (KPRIORITY Priority, ULONG Affinity)
{
current = CONTAINING_RECORD(current_entry, ETHREAD,
Tcb.QueueListEntry);
assert(current->Tcb.State == THREAD_STATE_RUNNABLE);
DPRINT("current->Tcb.UserAffinity %x Affinity %x PID %d %d\n",
current->Tcb.UserAffinity, Affinity, current->Cid.UniqueThread,
Priority);
if (current->Tcb.UserAffinity & Affinity)
{
RemoveEntryList(&current->Tcb.QueueListEntry);
return(current);
}
current_entry = current_entry->Flink;
@ -160,6 +164,11 @@ VOID PsDispatchThreadNoLock (ULONG NewThreadStatus)
KPRIORITY CurrentPriority;
PETHREAD Candidate;
ULONG Affinity;
PKTHREAD KCurrentThread = KeGetCurrentKPCR()->CurrentThread;
PETHREAD CurrentThread = CONTAINING_RECORD(KCurrentThread, ETHREAD, Tcb);
DPRINT("PsDispatchThread() %d/%d\n", KeGetCurrentProcessorNumber(),
CurrentThread->Cid.UniqueThread);
CurrentThread->Tcb.State = NewThreadStatus;
if (CurrentThread->Tcb.State == THREAD_STATE_RUNNABLE)
@ -201,7 +210,8 @@ VOID PsDispatchThreadNoLock (ULONG NewThreadStatus)
KeBugCheck(0);
}
VOID PsDispatchThread(ULONG NewThreadStatus)
VOID
PsDispatchThread(ULONG NewThreadStatus)
{
KIRQL oldIrql;
@ -214,7 +224,7 @@ VOID PsDispatchThread(ULONG NewThreadStatus)
/*
* Save wait IRQL
*/
CurrentThread->Tcb.WaitIrql = oldIrql;
KeGetCurrentKPCR()->CurrentThread->WaitIrql = oldIrql;
PsDispatchThreadNoLock(NewThreadStatus);
KeLowerIrql(oldIrql);
}
@ -316,6 +326,8 @@ PsPrepareForApplicationProcessorInit(ULONG Id)
IdleThreads[Id] = IdleThread;
NtClose(IdleThreadHandle);
DbgPrint("IdleThread for Processor %d has PID %d\n",
Id, IdleThread->Cid.UniqueThread);
}
VOID
@ -363,7 +375,6 @@ PsInitThreadManagment(VOID)
HalInitFirstTask(FirstThread);
FirstThread->Tcb.State = THREAD_STATE_RUNNING;
FirstThread->Tcb.FreezeCount = 0;
CurrentThread = FirstThread;
KeGetCurrentKPCR()->CurrentThread = (PVOID)FirstThread;
NtClose(FirstThreadHandle);

View file

@ -74,7 +74,7 @@ NtSetInformationThread(HANDLE ThreadHandle,
break;
case ThreadAffinityMask:
Status = STATUS_NOT_IMPLEMENTED;
Thread->Tcb.UserAffinity = *((PULONG)ThreadInformation);
break;
case ThreadImpersonationToken: