There are two major environments under which a kernel extension can run:
A kernel extension runs in the process environment when invoked either by a user process in kernel mode or by a kernel process. A kernel extension is executing in the interrupt environment when invoked as part of an interrupt handler.
A kernel extension can determine in which environment it is called to run by calling the getpid or thread_self kernel service. These services respectively return the process or thread identifier of the current process or thread , or a value of -1 if called in the interrupt environment. Some kernel services can be called in both environments, while others can only be called in the process environment.
Note: No floating-point functions can be used in the kernel.
A routine runs in the process environment when it is called by a user-mode process or by a kernel process. Routines running in the process environment are executed at an interrupt priority of INTBASE (the least favored priority). A kernel extension running in this environment can cause page faults by accessing pageable code or data. It can also be replaced by another process of equal or higher process priority.
A routine running in the process environment can sleep or be interrupted by routines executing in the interrupt environment. A kernel routine that runs on behalf of a user-mode process can only invoke system calls that have no parameters passed by reference. A kernel process, however, can use all system calls listed in the "System Calls Available to Kernel Extensions" if necessary.
A routine runs in the interrupt environment when called on behalf of an interrupt handler. A kernel routine executing in this environment cannot request data that has been paged out of memory and therefore cannot cause page faults by accessing pageable code or data. In addition, the kernel routine has a stack of limited size, is not subject to replacement by another process, and cannot perform any function that would cause it to sleep.
A routine in this environment is only interruptible either by interrupts that have priority more favored than the current priority or by exceptions. These routines cannot use system calls and can use only kernel services available in both the process and interrupt environments.
A process in kernel mode can also put itself into an environment similar to the interrupt environment. This action, occurring when the interrupt priority is changed to a priority more favored than INTBASE, can be accomplished by calling the i_disabledisable_lock kernel service. A kernel-mode process is sometimes required to do this to serialize access to a resource shared by a routine executing in the interrupt environment. When this is the case, the process operates under most of the same restrictions as a routine executing in the interrupt environment. However, the e_sleep, e_wait, e_sleepl, et_wait, lockl, and unlockl process can sleep, wait, and use locking kernel services if the event word or lock word is pinned.
Note: Locks should only be used when serializing access with respect to other processes. They are not adequate when attempting to serialize access to a resource accessed by a routine executing in the interrupt environment.
Routines executed in this environment can adversely affect system real-time performance and are therefore limited to a specific maximum path length. Guidelines for the maximum path length are determined by the interrupt priority at which the routines are executed. "Understanding Interrupts" provides more information.
System Calls Available to Kernel Extensions.
The i_disable kernel service, e_sleep kernel service, e_wait kernel service, e_sleepl kernel service, et_wait kernel service, lockl kernel service, unlockl kernel service.