Is DOS the ideal parallel environment - Part III

By Asaf Shelly (16 posts) on September 15, 2008 at 12:19 pm

Part 2 of this article talked about the parallel design of the UNIX operating system that was highley advanced at the time. This part talks about the design and implementation of the Windows NT Kernel that managed to maintain the original parallel design to a large extent. This article is presented as background information for a new design model called Operation View Model.

Windows Kernel
Windows Kernel is a completely different operating system than Windows User Mode that we all know. Windows Kernel is an embedded real-time system in its core and essence. The system can handle massive amounts of operations at a time, When a higher priority event is received the lower priority operation is immediately paused so that the higher operation can begin, operations travel between objects and between layers, and the system is using a 'floating stack'. Windows NT Kernel is a real-time embedded system that is designed for the parallel world.

This operating system was designed to work in parallel. The system design enforces parallel design compatibility and therefore all system components support parallel work. Driver verification program (Driver Signing) makes sure that all drivers comply with this parallel design.

Device driver developers are commonly hardware engineers or must have deep understanding of the hardware (higher level network and multimedia put aside). This means that driver developers usually expect multiple events coming in asynchronously, and the code reflects that. Several events can come from any of: user applications, other kernel drivers, and the hardware.

Windows NT Kernel developers understand the parallel world and write good parallel code, and the system design enforces good parallel design methodologies. This makes this operating system very good for the parallel world. With that come the problems. The majority of developers find it very difficult to understand this parallel design and the OS environment. The tools are very hard to work with and are not even close to User Mode Windows (Visual Studio .Net, Borland C++ Builder, Eclipse, etc) and the compiler toolkit had only recently been improved. This is just like any other real-time embedded system. Debugging tools are also problematic for this OS and there are three basic methodologies for debugging a component in the system:
1. Text Outputs: It is possible to use an equivalent to Win32 OutputDebugString API, and this can also be sent to an external port.
2. Break Points: It is also possible to break the execution on an event such as reaching a certain point in the code. The problem is that for this to function properly the entire system has to be halted.
3. Profiling: By using a profiler it is possible to see system events without greatly interrupting the execution flow. If you expect buffers to come from the network and you keep pausing the system over breakpoints then multiple network buffers will be lost and you might change the condition that created the bug in the first place.
If you it didn't pop out yet then allow me to help: When we try to debug parallel systems today these are the tools that we use. Text outputs are very favorable and when you start working with parallel code you will find yourself increasing the use of text outputs in place of using breakpoints and step-by-stepping. As for profiling see the tools provided by www.SysInternal.com. These were created to help with kernel and system profiling and now we find ourselves using these tools when we debug our parallel user-mode code. The only concept that was not yet employed outside the kernel is pausing the entire system for a breakpoint. Imagine a service handling a network buffer and resetting an event. If you just pause your application as we do today the service can still do multiple things in the background. The kernel of course enjoys the assumption that all working elements are on the same machine.

Windows NT Kernel defines the system design. This starts with defining that each system component, a driver, must support a predefined functionality, even if it means simply reply that it does not. Here are the basic operations:
Create – prepare to handle another user and allocate the required resources
Close – deallocate these resources
Wtite – Receive information
Read – information required
Control – handle some special control operation
Cancel – Stop the ongoing operation
A simple example is the Serial port: We create a file called "COM1", we can WriteFile to send output, ReadFile to read input, and we can I/O Control it to change the baud-rate and bit parity. When we are done we Close the Handle.

NT drivers are organized in layers. Any driver that manages hardware is the device driver for that hardware. Commonly the Device Driver is supplies by the device manufacturer and it is the only element in the system that knows how to talk to the device. The device driver creates a Virtual Device that represents the physical device. For example a Write operation will be sent to the Virtual Device and the device driver will translate that to I/O operations for the physical device. Any driver that does not talk directly to hardware is on a higher layer. An example is a USB Printer device that is connected to the USB port (system root hub) which is connected to the CPU through the PCI BUS. When we write to this printer we send the document to the USB Printer driver that sends it to the USB BUS driver that sends it to the PCI bus driver.

When the system is layered and every system component supports a universal interface, it is very simple to add filters to the system. A driver can declare that it is a filter driver and attach itself to another driver's input from the upper layer or output to the lower layer. We say that it is an upper filter or a lower filter respectively. This is supported by system design. A firewall is this type of filter. With firewalls we also get sniffers that monitor network traffic. When everything can be filtered then everything can be monitored. See http://www.SysInternal.com tools that use this feature extensively.

The system is organized in layers of drivers and each driver is an object in the system. The File System as an Object Store has names for all these driver objects. In other words the Windows NT Kernel is a fully object oriented system. With that the developers must have clear execution flow and inside a driver object oriented methodologies are used as minimally as possible (high level, single instance drivers might look differently). Functions are pretty long and state is maintained within a function. We have an object oriented system that has a clear flow of execution, however this system only defines that operation travel one way and there is a clear understanding of who is servicing who. This is fundamentally different from most OO systems that we know today where object relations and hierarchy only describe inheritance and not execution flows.

In the Windows NT Kernel there are no locks when accessing a resource. Instead every resource has a single owner. A device is owned by the Device Driver. Each memory address space and each I/O space must be owned before they can be accessed. When a driver owns a resource no other driver can receive ownership over that resource. (See windows device manager, device properties has a tab called resources). Every driver that wants to access an owned resource has to communicate with the resource owner, hence there are no locks between drivers over these global resources.

Windows NT Kernel does not use processes and threads as we know them. Instead kernel drivers can run under any user-mode thread that just happened to run when the event was set. Windows NT Kernel does not identify an operation using a stack of a thread. Instead the kernel drivers use a 'floating stack'. This stack is not managed by the CPU. Every thread receives a request object as an event. This object has all the information required to handle the event including the input and output buffer and the type of request. Events travel from top to bottom and on the other way around. The request object (see IRP on MSDN) also stores the system managed stack. Each driver asks for it's own stack location to work with. When a request travels down the request object is added with new driver stack locations and when the request returns each driver can continue to work with its own stack location for that request. This way there is no CPU context switch and also the system is simulating a new thread for each request and event in the system. For performance optimizations the system allows a special method called Fast I/O, however a driver does not have to support it and if for any reason Fast I/O cannot be performed (unsupported, memory paging required, etc) the system will automatically generate a request object (IRP) to replace the Fast I/O operation.

The model defines objects in layers with events traveling between these objects according to the layers. This means private storage for each driver and a private storage for each event. The driver works with both when performing an operation.

Windows NT Kernel has a very good design for the parallel world. Copy this design for your applications if you can. With that there are a few minor problems with this system, for example there are only a few system priority levels, which means that it is hard to deterministically define event sequences for non-related events. For example when the hard drive is performing a write operation then the USB device has to wait for it to complete and cannot interrupt. There are other problems with this system but these are mostly related to performance and real-time. As far as parallel work is in question the Windows NT Kernel is a very good parallel system.
 
Next is the last part of this article which will describe the DOS as a parallel environment.

Categories: Parallel Programming, Software Engineering

Comments (1)

September 15, 2008 1:20 PM PDT

Aaron Tersteeg (Intel)
Total Points:
15,561
Status Points:
15,561
Community Manager
Great information. Thank you for taking the time to educate us on how these things work. Can't wait to hear about DOS...

Trackbacks (2)


Leave a comment  

To obtain technical support, please go to Software Support.
Name (required)*

Email (required; will not be displayed on this page)*

Your URL (optional)


Comment*