Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can a thread be pre-empted in the midst of a system call to kernel?

I'm running 2 threads ( assume they are pthreads for the moment) . Thread_1() makes a user-defined API call which ultimately does some work in the kernel . Thread_2() is totally in user-space.

My question is : Can Thread_2() start executing by pre-empting Thread_1() while the API call is in progress , the control is somewhere inside the kernel ? If not , why , and if I want this scenario to occur ( for any reasons ) , what do I have to do ?

like image 452
TCSGrad Avatar asked Dec 12 '09 02:12

TCSGrad


People also ask

Can a kernel thread be preempted?

Kernel preemption is an important feature among mainstream OS kernels. It allows that a kernel thread can be preempted by another kernel thread by performing context switch.

Can system calls be preempted?

The kernel allows a thread to be preempted by a more favored thread, even when a system call is executing. This capability provides better system responsiveness for large multi-user systems. Because system calls can be preempted, access to global data must be serialized.

How does system call interact with kernel?

A system call is a way for programs to interact with the operating system. A computer program makes a system call when it makes a request to the operating system's kernel. System call provides the services of the operating system to the user programs via Application Program Interface(API).

Are Linux threads preemptive?

Under Linux, user-space programs have always been preemptible : the kernel interrupts user-space programs to switch to other threads, using the regular clock tick. So, the kernel doesn't wait for user-space programs to explicitly release the processor (which is the case in cooperative multitasking).


3 Answers

Calls to the kernel are considered to be either blocking or nonblocking. A blocking call (such as waiting for data to read from a network socket) can certainly be preempted with no action required on your part. Other threads will continue to run. Nonblocking kernel calls can be considered to be very fast and in practical terms it won't matter if you can actually preempt them or not.

Generally, when writing multithreaded code, you concentrate on how those threads interact with each other, and leave their interaction with the kernel up to the kernel to manage. It's designed to do a pretty good job.

like image 193
Greg Hewgill Avatar answered Sep 22 '22 10:09

Greg Hewgill


That depends on the kernel. Classically kernels did not allow preemption (except at specific points when it would sleep a thread). But newer kernels have starting enabling preemption within the kernel itself.

Linux supports a preemptible kernel when it is built with CONFIG_PREEMPT. From the kernel documentation:

This option reduces the latency of the kernel by making all kernel code (that is not executing in a critical section) preemptible. This allows reaction to interactive events by permitting a low priority process to be preempted involuntarily even if it is in kernel mode executing a system call and would otherwise not be about to reach a natural preemption point. This allows applications to run more 'smoothly' even when the system is under load, at the cost of slightly lower throughput and a slight runtime overhead to kernel code.

Select this if you are building a kernel for a desktop or embedded system with latency requirements in the milliseconds range.

like image 25
R Samuel Klatchko Avatar answered Sep 23 '22 10:09

R Samuel Klatchko


If you are asking whether a blocking kernel call like an fread() which requires disk IO can be pre-empted, then yes.

More specifically a blocking call will basically put Thread_1 to sleep while waiting for whatever it's waiting for. If Thread_1 is asleep then Thread_2 will be scheduled to run (unless there's something of higher priority waiting to run).

Edit: If you want a way to be "fairly confident" that Thread_1 is performing a blocking call, make Thread_2 lower priority than Thread_1 (so that it generally doesn't run unless Thread_1 is blocked) and when it runs, it elevates its priority to a higher level than Thread_1 until the hardware interrupt has been delivered, at which point it lowers its priority and calls sched_yield().

like image 34
Artelius Avatar answered Sep 22 '22 10:09

Artelius