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]

__reclaim_reent + stdio questions and suggestion


Please CC me on any comments as I'm not subscribed to this list.

In what follows I'm looking at newlib-1.15.0...

First, a question about stdio:

1) If I read the code correctly then it seems that all FILE objects
are global and attached to _GLOBAL_REENT with one exception:
#ifndef _REENT_SMALL then there are 'per-thread' stdin/stdout/stderr
FILE objects.
What is the reason for having 'per-thread' stdin/out/err ? Shouldn't
those be per-process rather than per-thread like all other FILES?
In any case, there seems to be no reason for having 'glue' in the
reent struct. Effectively, only _GLOBAL_REENT uses it and therefore
it should IMHO be separated from reent. (Sidenote: same seems to
apply to _atexit; per-thread _atexit is apparently never used.)


2) How is memory associated with stdin/stdout/stderr released under
  the _REENT_SMALL model? It seems to me that every thread that
  calls __sinit() creates three global FILE objects that live until
  _GLOBAL_REENT is torn down.

Then a comment about __reclaim_reent and why 1) creates a problem under RTEMS:
3) We are using newlib for the RTEMS rtos. However, there are memory
leaks because __reclaim_reent() is not currently used by RTEMS. In fact,
we cannot use it because of the 'cleanup' algorithm. findfp.c:_cleanup_r()
currently calls fwalk(reent_ptr, fclose) which creates two problems:
a) as a result of 'fclose' 'fflush' is executed. However, at the point where
the thread data structures are torn down and __reclaim_reent() is called
the thread is already half dead and wouldn't be able to block
(possible side-effect of fflush or close).
b) the underlying file descriptors 0,1,2 are shared among threads and must
not be closed when a thread is terminated.
Note that fwalk(reent_ptr, fclose) *only* ends up flushing/closing FILEs
attached to 'reent_ptr' which can only be the stdin/out/err FILEs under the
non-_REENT_SMALL model since all other FILEs are global objets.


Suggestion:
IMHO, the sole job of __reclaim_reent() should be releasing the resources
held in the reent struct but it should *not* fclose stdin/out/err. It should
be the responsibility of the thread to flush stdio before terminating and
it should be the responsibility of the OS to close file descriptors. Note how
calling 'close' from __reclaim_reent() is asymmetric: __sinit assumes that file descriptors
0,1,2 are already open -- hence, when the reent struct is torn down these
descriptors should be left alone and open. It should be the job of
the surrounding environment that manages the threads and provides
fds 0,1,2 to properly dispose of them.


  I propose to either
     1) make stdin/out/err global objects
  OR
     2) provide __reclaim_fds() to release memory associated with a FILEs
        belonging to a reent struct without calling fflush or close
        (we could then use __reclaim_fds() for RTEMS and leave the current
        semantics in place if people are happy with them).

-- Till


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