RU/2: Форум. Общение пользователей и разработчиков OS/2 (eCS). : Ответить на сообщение
Имя:
e-mail:
FIDO:
Home page:
сохранить данные о вас
Тема:
> System Services Flow > > Very few threads actually belong to the kernel of OS/2. Every executable program(.EXE) > has at least one thread, but the kernel itself has very few. Most of the OS/2 threads > are part of executables, such as the spooler and the shell. > > Except for the scheduler/dispatcher, the OS/2 kernel really does not "run" per se; it uses > the application or user threads to accomplish its work. > > Let's trace a system call from the application, down through the kernel and device > drivers, all the way back up to the application. Let's assume the user has selected to > save a file. This will generate a call to DosWrite at some point. Even if the programmer > of this application has used the C runtime function write(), the call will ultimately be > made to DosWrite. > > DosWrite has several parameters, including the buffer to be written and a handle > to the file(obtained previously by a call to DosOpen). Inside the program's code, there > is a call to a function in a DLL called DOSCALL1. > > This function is the actual code for DosWrite. Recall that this system code resides in > DLLs to eleminate multiple copies of the code in the system, and to provide > maintainability(Note that beginning with OS/2 Warp, many of these functions have been > merged for system performance into a DLL called PMMERGE.DLL, but the external > references to the functions are still where they were, such as PMWIN.DLL and PMGRE.DLL). > > The address resolution for this call was done at load time by the OS/2 program loader, > which sets up the set of addresses to system calls. In the executable file header is a list > of all DLLs that are referenced by the code being loaded. When the loader sets up the > code at load time, these references are fixed up to the actual addresses where the code > in those DLLs lives. > > This process is known informally as "fixing up", and the actual code referrerd to as > "fixups", which will be elaborated on in a later lesson. > > Looking back at the example function call, one can see that the thread belonging to the > process executing the DosWrite jumped from executing code from the EXE into executing > code in the DLL. At some point, there is code in the DLL to make a raw file system call, > which is not published. > > It does not need to be. The interface to write a file in OS/2 is DosWrite. The subsystem > in DOSCALL1.DLL translates the file handle into raw file system information and calls > the file system functions down in the kernel. This layer of abstraction relieves the > applications of the burden of knowing what the underlying file system is; if any > modifications need to be done to the low-level code, applications need not be aware > of it. > > The raw file system call transfers the thread from executing code in the DLL to code > in the kernel - the file system, to be exact. There may be several calls and returns > between the DLL and the file system; that is not important. The point here is that the > application's thread is still doing all this work. > > At some point, the file system will use the services of the kernel and call into the > physical disk device driver. The file system knows about sectors, disk directory structures > and so on. The physical disk device driver is used to tell the disk to move the head, write > the bytes at this spot on the disk, and so on. Again, the application's thread is doing all > this work. > > When the request goes to the physical decice driver, the thread executes code that tells > the disk controller hardware to perform the specified action. When this occurs, the thread > blocks. There is nothing for it to do until the hardware signals with a hardware interrupt > that it is done. At this time, another thread can be dispatched to utilize the processor > efficiently. > > There is no reason the processor should set idle waiting for disk to get done if there are > other threads waiting to run. > > When the physical device signals that it is done, the waiting thread is put back on the > ready list with a somewhat higher priority, since it was in the processor last and gave > it up voluntarily. The scheduler/dispatcher dispatcher will dispatch this thread, which > will return up the function call chain down which it came, finally ending up at the > application with a return code. > > The device driver has some return indicator, which is given to its caller, the file system. > The file system interrupts the return code and formulates one for its caller, the DosWrite. > The code in the DLL for DosWrite takes this information and formats it in the structure or > return code that is returned from that API. > > Notice that through all of this, no kernel or OS/2 system thread was involved. One can > start to see why you will want to make use of multiple threads to perform tasks that > take time, while allowing your users to perform other actions. > > All OS/2 system services follow this same flow of execution. This is a very simplified > example - many APIs cause threads to be created and destroyed on behalf of the > application - but understanding the basic flow is vital. > > By looking at the flow of this function and multiplying it by the number of threads that > can be running at a given moment, you can see how the subsystem and the device drivers > handle overlapped I/O. In the example just given, assume another thread comes into the > device driver while the first is either still doing work in there or blocked waiting on the > device. > > This other thread will simply execute the same code in another context, block waiting > on the device, and will be dispatched when it is next on the ready list. It is a simple flow > multiplied many times. > > Because of this flow of execution, it is really the application's threads that perform all of > the system coordination and multitasking resource synchronization. Since it is the > application threads executing the code in the file system and device drivers, for example, > any coordination is done by those threads. > > In the code for the file system, video subsystem, keyboard subsystem, and all parts of > OS/2, there are many semaphores and other control structures that will serialize access > to the various system resources. For example, if two applications (actually, two threads) > try to gain access to a single device, such as an output port, the first thread will grab a > semaphore when inside the subsystem code. > > When the second thread comes along to try to execute the same function, it will try to > grab the same semaphore when inside the subsystem code. Since the first thread is not > done, the semaphore will not be available, so the second thread will have to wait until > the first is done. > > This is the premise behind OS/2's multitasking and common subsystems. The threads of the > application will coordinate themselves, not because of the application code, but because > all the threads execute a common set of code in the OS/2 subsystems. > > When you think about it, the subsystems coordinate the execution, but the subsystems > don't really run, since they don't have any threads. The application threads coordinate > execution, because they are the parts of the system that run. > > Excursion: > > The Scheduler Thread and Process Control Block Reference in OS/2: > > The following control blocks work with the scheduler: > > (A.) Thread Control Block (TCB) > > (B.) Thread Swappable Data (TSD) > > (C.) Per Task Data Area (PTDA) > > (D.) The local exception handler Long-Jump Buffer (ljmp) > > (E.) Local Information Segment (LISEG) > > (F.) Global Information Segment (GISEG) > > (G.) Process Information Block (PIB) > > (H.) Thread Information Block (TIB) > > (I.) System Stack Frames and Client Register Information > > (J.) Exit List Data Structure (EXENT) > > (K.) Exception Handler Structures > > The relationships between various Scheduler and Task Management control blocks are managed by > > (1.) Process Management > > (2.) Thread Management > > (3.) the Scheduler Finite State Machine > > (4.) Thread Tree for a Process > > (5.) Process Trees, Subtrees and Zombies > > (6.) Orphaned and Adopted Processes > > (7.) Exception Management > > (8.) Exception Handler Stack Frames > > > > > > > > >
_, _, _, _, _ _, _,_
(_ | / \ |\ | / \ |_/
, ) | , \ / | \| \ / | \
~ ~~~ ~ ~ ~ ~ ~ ~
Programmed by
Dmitri Maximovich
,
Dmitry I. Platonoff
,
Eugen Kuleshov
.
25.09.99 (c) 1999,
RU/2
. All rights reserved.
Rewritten by
Dmitry Ban
. All rights ignored.