ion(a)svn.reactos.com wrote:
Thread Creation and Context Switching re-write, plus
Idle/First Thread minimization attempt. Full changelog on ML, too large to post here
Main Differences in new Task Swithcer:
- All written in Intel Syntax
- Single file and function handles both cases of System and User thread
switching and contexts.
- Starting Frame creation during Thread Context Creation is now
structure-based instead of a stack array. Cleaner
to read and more explicative.
- ExceptionList is properly set to -1 when needed. This should make PSEH
2 work.
- Context switch routine now has ALL registers available to it,
including EBP.
- Context switch routine uses access to KPCR through a register,
improving speed.
- KPCR Stack Data properly updated during context switch.
- KTSS CR3 properly updated during context switch.
- LDT, CR3 and IOPM are only updated if the new thread's process is
different, increasing speed for the simple path.
- The LDT and TEB Selectors are written directly in the GDT, bypassing a
complicated STDCALL routine which messed up
registers and was slow.
- Kthread.ContextSwitches is properly incremented now.
- Kthread.State is properly set to Running now.
The three goals were Speed, Clarity, Completeness.
Other Differences:
- Threads used to start either in PsBeginThread or
PsBeginThreadWithContext. PsBeginThread would lower to passive and call
the start routine with the start context, then terminate.
PsBeginThreadWithContext also lowered irql, but then restored debug
registers and used KiServiceExit to go to user-mode. A new function now
exists called KiThreadStartup, based on NT's implementation (see Inside
Windows 2000). It lowers IRQL to APC_LEVEL and then calls the System
Routine, which is on the stack with the two parameters (StartRoutine and
STartcontext). This System Routine ressembles
PsBeginThread/PsBeginThreadWithContext. Depending on how the thread was
created, it can either by PspSystemThreadStartup, which lowers IRQL to
passive and then calls the StartRoutine. Or, it can be
PspUserThreadStartup, which queues the User-Mode APC and inserts it,
then lowers IRQL to passive and notifies the Debugger. Notice that the
APC is now queued here, much later then before. After that, we return to
KiThreadStartup, which will bugcheck if the system thread returned (it
shouldn't), or will use KiServiceExit2, which does the same as the old
ros, which is to restore the debug registers. IT then immediately does
an IRET after cleaning the trap frame. Calling KiServiceExit is not
correct because it might end up using SYSEXIT when clearly we weren't
SYSENTERED.
- Idle thread, first thread, first process and idle process are concepts
which ROS gets really wrong. I have a patch which fixes these issues,
but it is still heavily under testing. Until then, this patch also
includes some changes which make the Idle/First Thread much less heavy,
and are simple blocks of memory with the minimum amount of data possible
to have a working system. They are not objects anymore, nor should they
be. This isn't the final implementation but ressembles it and lays the
minimal groundwork.
- I will make a shorter patch-fix which will make
Ki386InitializeThreadWithContext use the KeContextToTrapFrame function
and complete it as well, in order to use only the fields which were
specified by the caller.
Best regards,
Alex Ionescu