This is the mail archive of the newlib@sourceware.org mailing list for the newlib project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

RE: Reentrant functions & concurrency


> -----Original Message-----
> From: Jeff Johnston [mailto:jjohnstn@redhat.com] 
[...]
> > Shouldn't there be a _LOCK_T __errno_lock defined 
> somewhere, a call to 
> > __lock_acquire (__errno_lock) just before the line "errno = 
> 0;" and a 
> > call to __lock_release (__errno_lock) just before the line "return 
> > ret;"?
> 
> This is a historical situation.  If you look at 
> libc/include/reent.h you will see the following comment which 
> acknowledges that supplying just underscore versions of 
> syscalls won't be truly reentrant at the syscall
> level:
[..]
> Now that there are locks in newlib, adding them as mentioned 
> above is a sound idea.  There is one modification required.  
> x86-linux specifies MISSING_SYSCALL_NAMES and the syscalls 
> themselves are reentrant (i.e. 
> they use normal errno, not the external one provided).  I am 
> guessing that RTEMS would be in the same boat.  It would be 
> useful to be able to turn the errno locking off via a flag (e.g. 
> SYSCALLS_USE_REENTRANT_ERRNO) when it is not needed.  The 
> locking macros would be indirectly specified via macros in a 
> local.h header.  Would you like me to whip up something or do 
> you already have a trial patch to modify?

I pondered this question some more last night.  I now believe that the
fiction of "reentrant" system calls in a "non-reentrant" system is
useless: either a system has thread-safe POSIX-style system calls and
solves the problem of a thread-local errno on its own (e.g., Linux), or
it does not; but then it won't have POSIX-style system calls (that use
errno) at all, since that would be broken:

Currently, newlib uses the _<syscall> routines defined in libgloss/*.c
(or libgloss/libnosys/*.c) as its porting layer.  On a system without
POSIX-style system calls, this API adds the global variable errno which
needs to be mutex protected across system calls.  By mutex protecting
errno, we will have effectively single-threaded the system-call layer:
only a single thread in the system will be able to be "in" a system call
at any one time.  E.g.: Thread A calls _read(), which locks errrno and
then waits for user input, thread B calls _gettimeofday(), which blocks,
waiting for the errno lock to become free, until the _read() in thread A
returns.  This would not be desirable at all.

Therefore, the porting layer API must be moved "up" one layer, to the
functions defined in newlib/libc/reent/*.c.  The API provided by these
routines makes no assumption of a system-wide errno and the problem
disappears.

However, such a change might also require newlib/libc/reent to be moved
to libgloss and probably have wide repercussions on the build system.
What do you think?

Regards,

Konrad Schwarz


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]