Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>[Edit - the term "reentrant" gets used in a couple of different senses. This answer uses the basic "multiple contexts can be executing the same code at the same time." This usually applies to a single routine, but can be extended to apply to a set of cooperating routines, generally routines which share data. An extreme case of this is when applied to a complete program - a web server, or an operating system. A web-server might be considered non-reentrant if it could only deal with one client at a time. (Ugh!) An operating system kernel might be called non-reentrant if only one process/thread/processor could be executing kernel code at a time. </p> <p>Operating systems like that occurred during the transition to multi-processor systems. Many went through a slow transition from written-for-uniprocessors to one-single-lock-protects-everything (i.e. non-reentrant) through various stages of finer and finer grained locking. IIRC, linux finally got rid of the "big kernel lock" at approx. version 2.6.37 - but it was mostly gone long before that, just protecting remnants not yet converted to a multiprocessing implementation.</p> <p>The rest of this answer is written in terms of individual routines, rather than complete programs.] </p> <p>If you are in user space, you don't need to do anything. You call whatever system calls you want, and the right thing happens.</p> <p>So I'm going to presume you are asking about code in the kernel. </p> <p>Conceptually, it's fairly simple. It's also pretty much identical to what happens in a multi-threaded program in user space, when multiple threads call the same subroutine. (Let's assume it's a C program - other languages may have differently named mechanisms.) </p> <p>When the system call implementation is using automatic (stack) variables, it has its own copy - no problem with re-entrancy. When it needs to use global data, it generally needs to use some kind of locking - the specific locking required depends on the specific data it's using, and what it's doing with that data. </p> <p>This is all pretty generic, so perhaps an example might help. </p> <p>Let's say the system call want to modify some attribute of a process. The process is represented by a <code>struct task_struct</code> which is a member of various linked lists. Those linked lists are protected by the <code>tasklist_lock</code>. Your system call gets the <code>tasklist_lock</code>, finds the right process, possibly gets a per-process lock controlling the field it cares about, modifies the field, and drops both locks. </p> <p>One more detail, which is the case of processes executing <em>different</em> system calls, which don't share data with each other. With a reasonable implementation, there are no conflicts at all. One process can get itself into the kernel to handle its system call without affecting the other processes. I don't remember looking specifically at the linux implementation, but I imagine it's "reasonable". Something like a trap into an exception handler, which looks in a table to find the subroutine to handle the specific system call requested. The table is effectively <code>const</code>, so no locks required. </p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload