public inbox for newlib@sourceware.org
 help / color / mirror / Atom feed
From: Nick <cl26@nicolachel.net>
To: Dave Nadler <drn@nadler.com>
Cc: newlib@sourceware.org
Subject: Re: Some questions on reentrancy, __DYNAMIC_REENT__ and _impure_ptr
Date: Thu, 01 Apr 2021 23:39:34 -0400	[thread overview]
Message-ID: <05ad18dabb56d23d26f1d9c493bcce0c@nicolachel.net> (raw)
In-Reply-To: <adc582a3-909d-f5b3-b2ce-40407377d3c9@nadler.com>

Thanks Dave, haha we can never have enough of anything =)

It is a bit more challenging for me as AFAIK FreeRTOS is statically 
linked so it can easily see and change the _impure_ptr pointer. But in 
my case, the kernel is a standalone binary which loads other programs 
(that are linked with newlib, elf format) at runtime, so it either has 
to parse for that pointer during load, or require special arrangement in 
crt0 to report the pointer's location during process init.

It's feasible, but I'm hoping to get the __DYNAMIC_REENT__ method to 
work as it seems quite a bit cleaner.

Nick

2021-04-01 10:48 に Dave Nadler さんは書きました:
> On 4/1/2021 12:58 AM, Nick wrote:
> 
>> Hi,
>> 
>> I've been trying to enable reentrancy of newlib on a home brew
>> kernel for the x86 platform and have some questions on how various
>> pieces all fits together.
> 
> Oy, we can never have enough kernels ;-)
> 
> I'm not familiar with all the possible permutations.
> In FreeRTOS, the scheduler simply switches _impure_ptr before each
> context switch.
> This is perfectly thread safe given:
> - the read/write of this ptr is atomic (true on the architectures I
> know), and
> - no ISR use of anything in the RTL requiring this (ie no malloc,
> strtok, etc. in ISR)
> Here's the code from FreeRTOS:
> 
>         #if ( configUSE_NEWLIB_REENTRANT == 1 )
>         {
>             /* Switch Newlib's _impure_ptr variable to point to the
> _reent
>             structure specific to this task.
>             See the third party link
> http://www.nadler.com/embedded/newlibAndFreeRTOS.html
>             for additional information. */
>             _impure_ptr = &( pxCurrentTCB->xNewLib_reent );
>         }
>         #endif /* configUSE_NEWLIB_REENTRANT */
> 
> I hope that clears up all your questions below!
> Best Regards, Dave
> 
>> Implemented __getreent () to return a private copy of struct reent,
>> and also hard coded __DYNAMIC_REENT__ and GETREENT_PROVIDED in
>> sys/config.h to rule out any issue of passing in via build CFLAGS or
>> the CFLAGS in configure.host. Things including errno seem to work
>> but not totally making sense.
>> 
>> As many library functions are still accessing the reent structure
>> using _impure_ptr instead of calling my __getreent () function, for
>> example, the CHECK_INIT (_REENT, fp) at the beginning of __swsetup_r
>> (struct _reent *ptr, register FILE * fp).
>> 
>> Questions:
>> 
>> 1. Are the library functions expected to still use _impure_ptr
>> instead of calling __getreent () when both __DYNAMIC_REENT__ and
>> GETREENT_PROVIDED are hard coded in sys/config.h?
>> 
>> If so, how do they provide reentrancy? Since _impure_ptr is a global
>> pointer visible to all threads and threads can easily step on each
>> other's toes trying to change fields in the reent structure pointed
>> to by _impure_ptr concurrently.
>> 
>> If not, what other MACROs or changes should I make so that all the
>> library functions all use __getreent () instead of _impure_ptr? Is
>> it okay to set _impure_ptr to a bad value such as NULL in this case,
>> in order to catch any unintended access?
>> 
>> 2. in the documentation on https://sourceware.org/newlib/, the
>> following is mentioned as needed for syscalls stubs to return errno:
>> 
>> 
>> #include <errno.h>
>> #undef errno
>> extern int errno;
>> 
>> If I do include this part, all the syscalls stubs seem to do when
>> they assign values to errno is setting the global int errno; inside
>> reent.c. As user code built against the library don’t read out
>> that integer but instead calls __(), errno set by syscall stubs
>> can't be read out by user code.
>> 
>> If on the other hand I don’t include this part before my syscall
>> stubs, the errno set by them do seem to work as they also set the
>> copy in reent structures. What might I have missed here?
>> 
>> 3. There were some old discussions about manually changing
>> _impure_ptr at each context switch. But I’m wondering about the
>> validity of such a method since it seems like a really clumsy
>> maneuver for kernel code at CPL0 to reach into user space belonging
>> to different binaries to change a global pointer. What's more, if
>> manually changing _impure_ptr at each context switch is needed, then
>> what would be the purpose of __DYNAMIC_REENT__, GETREENT_PROVIDED
>> and implementing a __getreent () to get a thread local version?
>> 
>> 4. Is _global_impure_ptr thread safe? It is a bit concerning as it
>> seems to be pointing to the same copy of impure_data that some
>> libraries calls would access, and even if I try to change
>> _impure_ptr at each context switch, some threads might still be
>> accessing _global_impure_ptr concurrently?
>> 
>> 5. There were also old discussions about having to provide mutex for
>> malloc, is this still the case for newer versions of newlib like
>> 4.10?
>> 
>> Thanks!
>> Nick
> 
> --
> Dave Nadler, USA East Coast voice (978) 263-0097, drn@nadler.com,
> Skype
>  Dave.Nadler1

  reply	other threads:[~2021-04-02  3:39 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-04-01  4:58 Nick
2021-04-01 14:48 ` Dave Nadler
2021-04-02  3:39   ` Nick [this message]
2021-04-02 11:34     ` Dave Nadler
     [not found]       ` <BN3P110MB05636BD58188D760B6408B6E9A7A9@BN3P110MB0563.NAMP110.PROD.OUTLOOK.COM>
2021-04-02 16:51         ` Fw: " C Howland
2021-04-02 18:35           ` Dave Nadler
2021-04-02 18:42             ` Joel Sherrill
2021-04-02 19:20             ` Jeff Johnston
2021-04-03  1:43       ` Nick
2021-04-01 16:26 ` Jeff Johnston
2021-04-02  3:27   ` Nick

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=05ad18dabb56d23d26f1d9c493bcce0c@nicolachel.net \
    --to=cl26@nicolachel.net \
    --cc=drn@nadler.com \
    --cc=newlib@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).