This is the mail archive of the newlib@sources.redhat.com 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: Queries concerning RTOS protection in newllib


Corinna Vinschen wrote:
On Jun 17 14:32, Antony KING wrote:
snip

As I said, reverting _GLOBAL_REENT to _impure_ptr restores the correct behaviour again. I still don't quite understand the invention of _global_impure_ptr. _GLOBAL_REENT is used a lot in newlib and due to it's redefinition to another global variable, all this functionality is potentially accessing the wrong datastructure. If you actually need a never changing _global_impure_ptr, then that's ok, but it shouldn't be used by default from all these functions and therefore not be defined as _GLOBAL_REENT, should it?


Corinna

The reason for introducing a _global_impure_ptr was because from my interpretation of the use of _GLOBAL_REENT it seemed to be intended to be used as the single data structure (shared across tasks) for the purpose of:


* the management of FILE objects, other than stdin, stdout and stderr, which are still unique to each task;
* and for the management of atexit handlers.


This can be observed from the fact that _GLOBAL_REENT is only referenced from the functions involved in these activities:

libc/stdio/findfp.c (__sfp, _cleanup)
libc/stdio/fcloseall.c (fcloseall)
libc/stdio/fflush.c (fflush)
libc/stdio/refill.c (__srefill)
libc/stdlib/atexit.c (atexit)
libc/stdlib/on_exit.c (on_exit)
libc/stdlib/exit.c (exit)

and is guaranteed thread safe via the protection accorded by the use of the __sfp_lock_acquire/release functions.

Therefore in a multi-threaded system where _REENT is mapped to a global variable (i.e. _impure_ptr) and changed on each context switch, if _GLOBAL_REENT is also mapped to the same variable then that will also be changed on each context switch as well. This will break the above expectation that a single unchanging reentrancy object is used for the management of the above resources (with the consequence that FILE objects and atexit handlers may be distributed across multiple task specific reentrancy objects).

As a result of the above observations I introduced a _global_reent_ptr variable which initially points to the same object as _impure_ptr (in the default newlib implementation) and also changed the definition of _GLOBAL_REENT to refer to this variable instead of _impure_ptr. Now when a task switch occurs _GLOBAL_REENT will still refer to the same object instead of a potentially different reentrancy object referenced by _impure_ptr.

The RTOS that I am using is a fairly typical embedded RTOS which is linked into the application. In this implementation the main thread uses the initial reentrancy object defined by newlib (in libc/reent/impure.c) and referenced to by both _impure_ptr and _global_impure_ptr. When new tasks are created each will be allocated their own reentrancy object which will be referenced by _impure_ptr after each context switch. Only when the main thread is the current task is _impure_ptr the same as _global_impure_ptr. This scheme allows for the RTOS to be shut down and restore the reentrancy structures to their initial state.

In a non multi-tasking system the introduction of a new variable should be invisible since _impure_ptr should never change from its initial value and so both _impure_ptr and _global_impure_ptr will always refer to the same object.

Of course this change has broken Cygwin's use of reentrancy structures since it seems that its manipulation of _impure_ptr and the meaning of _GLOBAL_REENT is different from the embedded RTOS that I am working on. Hence the proposal to conditionally define _GLOBAL_REENT to _impure_ptr if using newlib under Cygwin.

I hope this interpretation has not rambled on too much...

Cheers,

Antony.

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


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