We assume that the kernel noticed the arrival of a signal and invoked one of the functions mentioned in the previous sections to prepare the process descriptor of the process that is supposed to receive the signal. But in case that process was not running on the CPU at that moment, the kernel deferred the task of delivering the signal. We now turn to the activities that the kernel performs to ensure that pending signals of a process are handled.
As mentioned in the section "Returning from Interrupts and
Exceptions" in Chapter
4, the kernel checks the value of the
TIF_SIGPENDING flag of the process before
allowing the process to resume its execution in User Mode. Thus, the
kernel checks for the existence of pending signals every time it
finishes handling an interrupt or an exception.
To handle the nonblocked pending signals, the kernel invokes the
do_signal( ) function, which receives
The address of the stack area where the User Mode register contents of the current process are saved.
The address of a variable where the function is supposed to
save the bit mask array of blocked signals. It is
NULL if there is no need to save the bit
Our description of the
) function will focus on the general mechanism of signal delivery; the actual code is burdened with lots of details dealing with race conditions and other special cases—such as freezing the system, generating core dumps, stopping and killing a whole thread group, and ...