From: mjordan@src.dec.com (Mick Jordan)
Subject: Re: Failing system calls and threads
Organization: DEC Systems Research Center
Date: Mon, 23 Nov 92 17:36:12 GMT

In article <1992Nov20.120734.23671@rdg.dec.com>, jch@rdg.dec.com (John Haxby) writes:

|> Obviously, if some other thread gets to run between the call to write() and
|> the examination of errno then the value of errno may no longer be valid or
|> useful when you come to look at it.
|> 
|> The obvious way around this is to protect the code with some suitable
|> mutex, eg
|> 
|> 	LOCK Cerrno.mu DO
|> 		write (...)
|> 		IF Cerrno.errno ...
|> 	END
|> 
|> but this has at least three significant problems: the overhead in acquiring
|> a lock around every system call is non-negligable (I assume); not all uses
|> of errno are guaranteed to be protected (especially in uses within C
|> libraries); only one outstanding system call is can be permitted (in an
|> environement that uses kernel-supported threads).

In general, when you are dealing with a library that exports shared global 
variables, written in any language (including Modula-3), multi-threaded clients 
must use locks to synchronise the operations and access to the variables.
In the specific case you mention of errno, one of the standard tricks in
the C world is to treat errno as a macro and define it as a function that
accesses a thread specific value. This is what thread-friendly C libraries
do. But most systems dont have thread-friendly libraries and unless all
C code has been recompiled against the functional errno, the solution
doesnt work.

However, the overhead in acquiring the lock is (should be) negligible
in comparision with entering the operating system. So, for example, we
chose your first solution for the Olivetti Modula-3 library.

|> The solution comes from knowing that errno is introduced by the C library
|> and not by the kernel: the kernel returns a result and an indication of
|> whether that result is an error code or a returned value.  On a VAX, the
|> indication is the carry flag, on a (DEC) mips machine, the indication
|> is left in a register when the syscall instruction `returns'.  The
|> implementation of the solution involves re-writing all of the system calls
|> so that the are of the form (expressed in C)
|> 
|> 	int err = sysfunc (&res, arg1, arg2, ...);
|> 
|> The &res is only written to the if the return result is non-zero; the
|> return result is otherwise what would be written to errno.  The Modula-3
|> implementation of, say, Unix.write would then look something like this
|> (syntax notwithstanding :-):
|> 

|> Does this make sense?  Will it avoid the problems I mentioned earlier?
|> And, a question for the other implementations: can this form of solution be
|> used? (specifically, are there any implementations out there where errno is
|> explicitly known by the kernel?)

In the days before Modula code and C code intermixed so easily, it was
possible to adopt this solution, since the Modula libraries typically
preempted all the Unix interface and dealt directly with the Unix
kernel entry rather than the C library. In general, of course, it is
neither possible nor desirable to modify the code of the library to
make it more thread friendly. In particular one cant usually find
a layer just below the surface on which you can layer a more suitable
veneer. Therefore if large scale exploitation of C and C++ code from 
Modula-3 is to be possible, we have to lobby for thread-friendly designs
at the C and C++ level.

Mick Jordan


Newsgroups: comp.lang.modula3