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: why "Reentrant covers for OS subroutines" use global errno?


On 08/09/2011 05:31 AM, Can Finner wrote:
Hi,
I am studying the reentrancy mechanism in newlib/libgloss, and read
several threads in newlib mail archive,
I still cannot understand following question.
Why do "Reentrant covers for OS subroutines"(in libc/reent/) use
global errno variable with codes like:
      #include<errno.h>
      #undef errno
      extern int errno;


The __getreent() support is rather new in the scheme of things for newlib.


Historically, the reentrant wrappers in libc/reent were done to wrap non-reentrant syscalls.

From libc/include/reent.h:

The target may provide the needed syscalls by any of the following:

   1) Define the reentrant versions of the syscalls directly.
      (eg: _open_r, _close_r, etc.).  Please keep the namespace clean.
      When you do this, set "syscall_dir" to "syscalls" and add
      -DREENTRANT_SYSCALLS_PROVIDED to newlib_cflags in configure.host.

   2) Define namespace clean versions of the system calls by prefixing
      them with '_' (eg: _open, _close, etc.).  Technically, there
      won't be
      true reentrancy at the syscall level, but the library will be
      namespace clean.

Number 2 applies here.

The non-reentrant syscalls don't take the extra parameter to pass them the reentrancy structure so the answer at the time was to have them set the external int errno. The wrapper sets the newlib-ized version of errno when an error occurs.

Hence there is not true reentrancy at the syscall level.

If desired, arm can go the route of 1) whereby it provides _r versions of the syscalls which then can access the reentrancy structure at will since it is passed

OR

the syscalls in arm libgloss can be modified to access the _REENT macro in the case of SINGLE_THREAD and/or arm can provide a getreent() function. In these cases, the syscalls would set _errno directly and not touch the value of int errno on an error condition. The wrapper will then not use the value of int errno and it will be reentrant.

-- Jeff J.

It is said the system can achieve reentrancy by implementing its own
__getreent function,
defining macro __DYNAMIC_REENT__ and implementing libgloss with
errno.h directly.
However, with routines in libc/reent directory, system won't be
reentrant unless defining macro
REENTRANT_SYSCALLS_PROVIDED and implementing _r versions of syscalls
in libgloss.

Think about calling sequence of a simple case for arm:

fwrite --> __swrite --> _write_r(in libc/reent) --> _write(in libgloss/arm)

routine _write_r uses global errno variable, which breaks the
reentrancy in the calling sequence.

Did I misunderstand the reentrancy mechanism in newlib/libgloss or
something wrong?

Please help, thanks in advance.



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