Artem B. Bityuckiy
Fri Nov 28 21:37:00 GMT 2003
J. Johnston wrote:
> Artem B. Bityuckiy wrote:
>> Please, can anybody explain me why _REENT_ONLY macro is needed? For
>> what? Why some functions have on implementation and another have pair
>> with _r postfix, e.g. setlocale() and _setlocale_r(), etc. Several
>> functions have no such pair, e.g. ldiv(). And in all cases (that I've
>> seen) usual functions call _r pair adding _REENT argument. For
>> example 'setlocale(category, locale)' just calls '_setlocale_r(p,
>> category, locale), where p is 'struct _reent'. I can only guess that
>> this is needed if external (not usual Newlib) "multiprocess support
>> subsystem" is used...
>> Can anybody explain this and give me some examples when "_r" pairs
>> are really useful/needed?
> I'll start with the _r pairs. They're used to support
> threading/reentrancy. Probably the simplest example is errno. The
> storage behind errno is actually kept in newlib's reentrancy
> structure. Most users don't see this because there is a default
> reentrancy struct set up on their behalf. If you look in errno.h you
> will see that errno is a macro which calls __errno which you will find
> in libc/errno/errno.c. The function just references the default
> reentrancy structure and gives back the address of where errno is stored.
> Now, imagine you have multiple threads. You want an errno per
> thread. If you call a library function in a thread, you don't want
> another thread to overwrite that value or else you won't be able to
> check the results of your call.
> To handle this, we create _r versions of functions where the
> reentrancy struct is passed in. In a thread, you call the _r versions
> of appropriate functions and they set the errno for the reentrancy
> struct you are passing in.
> There are other such values (e.g. the last token address for strtok).
> If a function calls another function which has an _r version, it
> requires an _r version as well. An example of where this is missing
> is atol, atoi, and your new atoll. As soon as this is checked in, I
> am going to fix them. They call strtol and strtoll. These called
> functions have _r versions because they set errno. Thus, they should
> have been modified so an _r version exists as well.
> Notice in errno.h, there is a __errno_r macro which you can use to get
> the errno for a particular reentrancy struct.
> What the _REENT_ONLY flag does is to force the caller to always use
> the _r routines for appropriate functions. To do this, the default
> versions are ifdef'd out and only the _r versions are exposed. You
> can't inadvertently call strtok() from a thread because it isn't in
> the library. You are forced to call _strtok_r and specify the
> reentrancy struct. The reason you want this is that the default
> versions are not protected. If two threads call strtok(), it is a
> race condition for the token address in the reentrancy struct. This
> can be difficult to debug as any error might only show up at random.
> -- Jeff J.
Thanks Jeff for ** complete ** description!
Artem B. Bityuckiy,
More information about the Newlib