3.4 Preemptive or Nonpreemptive Environment

The NetWare operating system was originally designed without time slicing (preemption). All NLM applications needed to relinquish control of the CPU by blocking or by explicitly yielding control. Beginning with NetWare 5, the scheduler performs preemption, but only for NLM applications that are linked with XDC data. (For information on this process, see XDCDATA.) NLM applications not linked for preemption are required to relinquish control to the operating system.

This means that you can design your application to run with or without preemption. If you select nonpreemption, your threads run until they knowingly call a function that blocks (relinquishes control to the operating system). Because the operating system waits for threads to block, nonpreemptive NLM applications are expected to govern their use of the CPU time so they do not to take control of the CPU for indefinite periods of time.

These NLM applications must either quickly complete the request, do things to regularly relinquish control (such as I/O requests), or explicitly relinquish control by calling a function such as pthread_yield, thr_yield, or NXThreadYield. In general, the NLM should run for about .1 millisecond on a 1.6 GHZ processor and then relinquish control. As you design your application, you don't need to be concerned about yielding too frequently. If your application hasn't run long enough, the MPK scheduler does not yield and allows your application to continue to run.

If you select preemption, you must still design your application so that it relinquishes control. You cannot completely rely on XDC data and the preemption process to prevent your application from taking control of the CPU for too long of an interval and thus precipitating a CPU hog abend.