libm reentrancy
Norbert Lange
lange@chello.at
Thu Jan 17 21:05:00 GMT 2013
Hi,
I had to adapt newlib to a plattform with threads aswell. The way I chose
was to use
gccs __thread specifier in front of _impure_ptr, added an function for
retrieving
the thread pointer and modifying the startup-code to set this pointer to a
valid and
initialised block.
I cant remember all details now, but the __getreent() function was
somewhat more troublesome
to implement or activate, and I wanted to be able to use the __thread
keyword anyway,
so the only additional work solely for newlib was to add the __thread
keyword.
Any chance of having this optional variant in a future version of newlib?
I have to talk to my employer if you want me to post the sources, but I
doubt it
would be a problem. Its done in a hacky way, so this would be just some
running
proof-of-concept for bare metal ARM.
Best Regards, Norbert
> Let me clarify here.
>There are two thread reentrancy models. The original model has the code
> creating new reentrancy structures for each thread (other than the main
> thread) and manually specifying the reentrancy structure and calling _r
> versions of function or else redefining _impure_ptr on the fly. The
> _REENT_ONLY flag can be used to restrict all calls to the _r versions.
>A while back I added a newer model which looks for a flag:
> __DYNAMIC_REENT__ (see libc/include/sys/reent.h) which can be set up in
> config.h, etc... for a platfrom. This flag signals to define the _REENT
> macro (which in the old model is defined to point to the default
> reentrancy structure) to instead call the __getreent() function. This
> function needs to be defined by the platform and needs to returns the
> reentrancy structure for the current thread (e.g. you could implement
> this using thread-specific storage as is done in the case of
> libc/sys/linux/linuxthreads/getreent.c).
>Using the newer model, code can just use the regular C interfaces and
> everything will be handled automatically since the __getreent() function
> switches to the appropriate reentrancy structure as needed. This
> includes errno references with errno.h included.
>Now, that said, libm was never set up with the old thread reentrancy
> model in the same manner as libc was. In particular this affects theuse
> of errno which is thread-specific. The current libm refers to errnovia
> errno.h which eventually uses the structure defined for _REENT. So,one
> would need to redefine _impure_ptr manually around libm calls.
>To be proper, I should fix libm so one does not have to manually fool
> around with _impure_ptr. However, I would recommend using the new model
> is you really want to support threads as it is far superior and allows
> code to use the regular C interfaces instead of a bunch ofnewlib-created
> ones.
>-- Jeff J.
>On 01/09/2013 10:55 AM, Craig Howland wrote:
>> errno is not a problem, as it is transparently taken care of--see
>> sys/errno.h.
>> errno is not really a global, but calls a function that returns a
>> pointer to
>> the thread's individual errno within the reentrancy structure.
>> Craig
>>
>> On 01/09/2013 09:06 AM, Gregory Pietsch wrote:
>>> Oh yeah, forgot about errno. I guess the best way to avoid that is to
>>> make sure
>>> the number you are taking the square root of isn't negative. -- Gregory
>>>
>>> On 1/9/2013 4:37 AM, Marcus Hult wrote:
>>>> Hello,
>>>>
>>>> Thanks for your reply Gregory.
>>>>
>>>> The sqrt function for instance, may set the errno variable according
>>>> to the manual. Shouldn’t this function then have a reentrant version?
>>>> Or do I always need to use the _impure_ptr when using libm, to be
>>>> thread safe?
>>>>
>>>> /Marcus
More information about the Newlib
mailing list