This is the mail archive of the 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: libm reentrancy


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
errno is not really a global, but calls a function that returns a
pointer to
the thread's individual errno within the reentrancy structure.

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:

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?


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