From: dak@messua.informatik.rwth-aachen.de (David Kastrup)
Newsgroups: comp.programming
Subject: Re: reentrant code
Date: 12 Dec 92 22:58:09 GMT
Organization: Rechnerbetrieb Informatik - RWTH Aachen
Distribution: world
NNTP-Posting-Host: messua.informatik.rwth-aachen.de

crawford@boole.mitre.org (Randy Crawford) writes:

>In article <GARY.92Dec9104702@kuwait.gdfwc3> gdfwc3!gary@uunet.uu.net writes:
>>What are the requirements for code to be reentrant?  When can
>>non-reentrant code hurt you?  Can someone recommend a good reference
>>on this subject?

>Reentrant code must allow more than one task to concurrently execute the
>same instructions in the same memory space.  If one thread of execution makes 
>use of data which is the same data used by another thread, a possibility 
>exists for one thread to overwrite the data written by the other.  This may 
>not be apparent unless you remember that we are discussing programs which 
>execute on pre-emptive multitasking operation systems.  When a task is 

>With non-reentrant code this isn't a problem.  All the code and data for each
>task are in a separate process space from the other concurrent tasks, so tasks 
>can't interfere with each other's data.  But reentrant code is meant to remain 
>in memory after a context switch, allowing another task to reuse the memory 
>and save the cost of swapping it out and then back in immediately.  The cost 
>of this is that global variables within the reentrant code remain accessible 
>to other concurrent tasks, and one task can overwrite the data written by a 
>previous task before the first task had a chance to finish using the data.  
>If I haven't beaten this to death yet, let me offer an example to help illus-
>trate.

>I think that nearly all Unix system functions are reentrant, with the sole 
>exceptions being a few C I/O functions like printf(), scanf(), etc.

>As far as good references on reentrancy, most OS texts discuss it (Deitel's
>book and Peterson and Silberschatz's both do).  It's really an OS feature
>and not part of programming language or compiler subject matter, so I wouldn't
>look there for it.  Most OS-specific internals texts cover it as well (I think 
>Bach's and Leffler's internals texts on SysV and BSD Unix do).  In Unix,
>reentrancy is equivalent to setting what is called the `sticky bit' of a
>program to keep it in memory if possible during context switches.  This is
>commonly done for often used system routines and utilities (like ls or vi).

Most of that I do not agree with.
The problems of reentrancy are a bit different from concurrency. Reentrancy
may be a subject in system programming, because any subroutine an
interrupt routine uses must work without disturbing an instance of
the routine active before the interrupt. You can do that by saving all
variables on some stack, restoring them afterward. Z80 Versions of Turbo
Pascal did just that with local variables, because variables on the
stack were not especially supported by the processor.

This technique is still there in interrupt routines saving all REGISTERS
they might use.

Note that this reentrancy scheme works fine with interrupts as well as
with recursions, with the latter NOT if you pass any variables of the
recursion by reference.

It does not work with concurrency.

Reentrancy is also not merely a hidden OS-matter, at least not in Unix,
because signal handlers may not use nonreentrant routines they might
have interrupted.

And the sticky bit is an entirely different thing. In older versions of
Unix, it told the system that execution of a program was likely to
occur that often, that the system better keep a copy of the program
in the swap area. Note that in this blissful old time, EVERY program
was allocated in the swap area. So the fork() system call was pretty
simple: it swapped the process, but did not invalidate the copy in core.

I cannot rule out all possibility that this copy might have had an
already altered
data area, and so the programs with sticky bit would have to be reentrant
on systems not supporting shared text. But I believe in the sanity of
the early Unix system designers.

By the way, concurrency or multithreadability is important for shared
libraries.
Newsgroups: comp.programming