Queries concerning RTOS protection in newllib

Antony KING antony.king@st.com
Thu Jun 17 15:14:00 GMT 2004

Hi Corinna,

Which part of the patch was causing the problem ? Was it just the 
introduction of _global_impure_ptr ? I recently discovered a problem 
which was exposed by this patch when the _cleanup_r function was changed 
from walking the FILE object list with fflush() to fclose(). I wonder if 
this is the cause of the unexpected truncation.

Note that I have also submitted another patch, 
http://sources.redhat.com/ml/newlib/2004/msg00302.html, which changes 
the effect of _fwalk (called via _reclaim_reent) to only walk the FILE 
objects in current task's reent structure and not the global reentrancy 
structure (aka _GLOBAL_REENT), which is handled via the exit() function.

Since the problem seems to be with the capture of stdout, I wonder if 
the problem is related to the fact that the standard i/o handles (0, 1, 
2) are shared by all tasks and so when _reclaim_reent is called it will 
be closing these shared handles and thus, unless protected in some way, 
i/o on these handles by other tasks will be lost. In our system the 
implementation of _close (actually _close_r) prevents the closure of the 
standard handles, e.g.:

_close_r (ptr, fd)
      struct _reent *ptr;
      int fd;
    * Since the stdin, stdout & stderr file handles
    * are shared by all tasks, we do not want to allow
    * any one task to close them - hence the following
    * filter.
   if ((fd != __sfileno(_stdin_r(ptr))) &&
       (fd != __sfileno(_stdout_r(ptr))) &&
       (fd != __sfileno(_stderr_r(ptr))))
     return _SH_posix_Close (fd);
     return -1;

This is not very subtle but at least it is safe. I suspect that this 
solution is not applicable to Cygwin since it will prevent the re-use of 
the standard handles via open/dup.

If your problems are related to "walking" with fclose instead of fflush 
then perhaps what is needed is a method by which the implementation of 
_cleanup_r can be configured to select the function to "walk" over the 
FILE object list. This option could be set by a config file or through 
configure, e.g. (in libc/stdio/findfp.c):

#define _STDIO_CLEANUP_FUNCTION fflush	/* `cheating' */

_DEFUN(_cleanup_r, (ptr),
        struct _reent *ptr)

The above approach would restore the original behaviour (i.e. flushing 
the stdio streams) and would also allow other systems to select their 
desired behaviour.

I have also had a quick look in the cygwin sources (1.5.9-1) and the use 
of _REENT, _GLOBAL_REENT and _impure_ptr is a little tricky to follow 
given what Cygwin is doing when handling forking, shared libraries and 
thread local storage. If Cygwin is overriding libc/reent/impure.c (which 
it seems to be doing in winsup/cygwin/lib/_cygwin_crt0_common.cc) then 
in addition to the above change (in _cleanup_r) perhaps the definition 
of _GLOBAL_REENT can also be conditional on whether newlib is being 
targeted for Cygwin, e.g. (in libc/include/sys/reent.h):

#ifdef __CYGWIN__
#define _GLOBAL_REENT _impure_ptr
#define _GLOBAL_REENT _global_impure_ptr

which may restore the behaviour you need. Alternatively as well as 
manipulating _impure_ptr Cygwin can manipulate _global_impure_ptr as well.



Corinna Vinschen wrote:
> I just found that the below patch broke Cygwin.  While running a build
> in bison, I got an error message that I'm using an old version of m4.
> Which wasn't true.  The configure script asks for a specific string in
> the --help output of m4, roughly
>   case `m4 --help` in
>   *reload-state*) ...
>   esac
> The reason that this doesn't work anymore is that the output of the
> backquoted command is truncated.  I found that Anthony's patch is the
> culprit.  If I back it out, Cygwin works fine again.
> The reason seem to be the invention of the _global_impure_ptr which
> then in turn is used in _GLOBAL_REENT.  Cygwin already implements
> changing _impure_ptr in case of context switches and it relies on
> this functionality.
> The below described patch apparently breaks backward compatibility.
> However, I'm not fluent enough in the impure_ptr business to offer
> the "right" solution except for backing out this patch again.
> Corinna
> On Jun 11 16:44, Jeff Johnston wrote:
>>Thanks Antony.  Patch checked in.  A patch was also required to get 
>>x86-linux building with these changes so I added that as well.  In the 
>>future, it would be helpful to me if you could add a ChangeLog entry for 
>>any changes you make.
>>-- Jeff J.
>>Antony KING wrote:
>>>I am currently in the process of adapting newlib co-operate with an ST
>>>developed embedded RTOS. FYI this RTOS is pretty much standard in terms
>>>of capability (e.g. tasks, mutexes, semaphores, interrupt handlers) and
>>>an application is RTOS enabled by simply linking in a static library and
>>>using the API. The target is an SH4 based device.
>>>My goal in adapting newlib for this RTOS is that the same static C
>>>library can be used in applications which either use the RTOS library or
>>>do not. Also, I would like to reduce the impact of changes I need to
>>>make to newlib. As a result I have provided my own implementation of
>>>sys/lock.h which implements the locking API as stub functions (instead
>>>of empty macros) which will be overridden when a application is linked
>>>against the RTOS static library. Also, I am aiming to get the RTOS to
>>>switch the task re-entrancy structures by modifying _impure_ptr at each
>>>context switch (instead of using a __getreent() function).
>>>Enough of the background, now my queries and solutions:
>>>1) There is a macro _GLOBAL_REENT which is used to obtain the global
>>>re-entrancy structure used for managing the atexit handlers and FILE
>>>objects. This is currently defined to be _impure_ptr which of course is
>>>incompatible with changing _impure_ptr on each context switch.
>>>My solution is to add a new variable, _global_impure_ptr, to impure.c
>>>which initially has the same value as _impure_ptr and is the value
>>>returned by _GLOBAL_REENT. The value of this variable should never change.
>>>Files affected: impure.c, sys/reent.h
>>>2) Given that I am providing an alternative implementation of sys/lock.h
>>>the current type definition for the FILE lock (_flock_t) is incorrect,
>>>especially in light of the explicit casting (and de-referencing) to
>>>_LOCK_RECURSIVE_T in a number of files when invoking the locking API.
>>>The reason is that the definition of _LOCK_RECURSIVE_T may not be the
>>>same size as the current type (int) for _flock_t.
>>>I think _flock_t should be redefined to be of type _LOCK_RECURSIVE_T
>>>(instead of int) and all the explicit casting be removed.
>>>Files affected: sys/_types.h, fclose.h findfp.c fopen.c, freopen.c,
>>>fopen64.c, vfprintf.c
>>>3) It would be useful if the stub implementations of the specialised
>>>locking APIs __malloc_lock/unlock and __env_lock/unlock use the locking
>>>API defined in sys/lock.h. This would then mean that these functions
>>>would not need overriding by an RTOS if sys/lock.h is RTOS ready.
>>>(Actually I do have to override the malloc lock API since I need to
>>>pre-allocate the malloc lock object under the control of the RTOS since
>>>the type is opaque and cannot be fully initialised statically).
>>>Files affected: envlock.c, mlock.c.
>>>Similarly it would also be useful for the stdio file locking API
>>>_flockfile/_funlockfile to be modified in the same way.
>>>Files affected: sys/stdio.h.
>>>I have attached a patch file incorporating all the changes I have made
>>>to the newlib library (against a CVS snapshot dated 03 June 2004). The
>>>implementation of the locking API (lock.h and lock.c) is also attached
>>>for reference.
>>>Please note that the patch includes some additional changes in the file
>>>sys/_reent.h where the re-entrancy structure initialisation macros have
>>>been slightly re-worked to make them more readable (for me :-), complete
>>>(I hope) and efficient (greater use of memset). Also the implementation
>>>of _cleanup_r has been altered so that fclose is called instead of
>>>fflush when walking the FILE object list.
>>>Comments please (and sorry for the overlong email).

Antony King                        | Email: antony.king@st.com
STMicroelectronics (R&D) Ltd.      |
Bristol, BS32 4SQ. United Kingdom. | Tel: +44 (0)1454 462646

More information about the Newlib mailing list