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