5.4 MPKXDC

MPKXDC.EXE is a tool that enables the threads within an NLM to be identified as to whether or not they can safely take advantage of multiple processors on the same machine. MPKXDC.EXE is provided in the \TOOLS\ directory of this NDK.

For more specific information, see the following sections:

5.4.1 Traditional NetWare and Multithreading

Multithreading (MT) allows an application to do multiple tasks concurrently and is an ideal paradigm for programming to symmetric multiprocessing (SMP) machines. By design the threads model shields the programmer from concerns with the details of parallelism. Moreover, if an MT application is written to correctly to run on a uniprocessor system, it will run correctly on an MP system.

From one viewpoint, all NLMs can be considered multithreaded. However, historically NLMs could not take advantage of multiple processors. Although NetWare has always run fast, the basic architecture was uniprocessor and nonpre-emptive.

In a traditional NetWare, a FIFO scheduling policy does not support priorities or time slicing, Traditional NetWare threads are allowed to run until they block or voluntarily yield the processor—a thread is not be pre-empted (that is, time sliced) under any circumstance. Explicit synchronization with other threads are not needed in this uniprocessor environment because a running thread has exclusive access to the processor. Execution order becomes the synchronizing principle. However, because a traditional NLM depends on execution order to run successfully, unmodified traditional NLMs cannot automatically exploit multiple processors.

Thus, traditional NetWare is a multithreaded environment that supports concurrency but not parallelism.

5.4.2 NetWare 4.11 SMP

NetWare 4.11 SMP was the first attempt by Novell to add symmetric multiprocessing support to NetWare through the addition of an NLM-SMP.NLM. Although this enviornment provided SMP support to NetWare, it remained nonpreemptive. It also provided backward compatibility to NLMs that could not handle multiple processors because of the traditional assumptions about execution order.

NetWare 4.11 SMP introduced the concept of NetWare threads, which operated on traitional assumptions and had to run on Processor 0, and MP threads, which were capable of exploiting parallelism by running on any available processor. By default, all threads created as NetWare threads. NetWare threads had to explicitly call an API function to become an MP threads, and MP threads had to call corresponding migration functions to become NetWare threads.

Using the SMPRPC tool at link time, an NLM developer could declare functions in an NLM to be MT (and thus MP) safe, thus certifing that they could run on any processor. Function not so identified were funneled--put to sleep, migrated to Processor 0, awakened and run with traditional assumptions about execution order, put back to sleep, and migrated to the processor from which they were called. Although funneling acts as a kind of synchronization device, it does not enable execution on any processor. Such enabling requires devices that specifically prevent global variables from being written to by more than one thread at a time or being modified as they are being read. Mutexes are examples of true synchronization devices.

5.4.3 NetWare MPK and Funneling

The NetWare 5.x and later operating system used an approach to multiprocessing that was completely different from NetWare 4.11 SMP—the Multiprocessing Kernel (MPK). Although MPK supports traditional uniprocessor NLMs, MPK was conceived, designed, and built for multiprocessing.

With MPK, the concept of a NetWare thread is replaced by the concept of a Common NetWare Binding (CNB). In the CNB, a thread runs only on Processor 0 using traditional execution order assumptions.Unless otherwise provided for, all threads are created in the CNB. However, it is possible to create threads that have all the synchronization needed for execution on any processor.

If a thread depends on execution order for the successful operatoin, its work obviously cannot be divided among available processors because the order of execution cannot be predicted. Such a thread (or such a function) is called MP unsafe. On the other hand, if a thread succcessfully employs synchronization mechanisms such as mutexes, semaphores, and condition variables, An NLM that exports and uses only threads thus enabled does not need to have its functions funneled to processor 0--because they are properly synchronized through the use of synchronization functions like those provided in the NKS API, such threads can run in parallel on any processor.

The MPKXDC.EXE tool allows the functions in an NLM to be declared MT safe or MT unsafe at link time. For instructions, see Section 6.4, Using MPKXDC.