newlib reentrancy question
J. Johnston
jjohnstn@cygnus.com
Tue Jun 19 18:26:00 GMT 2001
Joel Sherrill wrote:
>
> Where's the best description and/or example of how to
> implement newlib pre-thread reentrancy support these
> days?
>
> I am investigating a case where cout does not work
> for the 2nd task in a system unless the 1st task
> uses it. All of the standard C routines work fine.
> In fact, the printf immediately before the cout calls
> in the 2nd task prints. The clue I think is that
> printf does not call fwrite and cout does. Here
> is how we do the per-task reentrancy structures
> now.
>
> + At system initialization, we use a global struct _reent.
> It is initialized using _REENT_INIT.
>
> + Each task has its own copy of the reent structure.
>
> + As part of a context switch the contents of _impure_ptr
> are switched.
>
> + As each task begins execution time, the following code
> is executed:
>
> ptr = (struct _reent *) calloc(1, sizeof(struct _reent));
> *ptr = (struct _reent) _REENT_INIT((*ptr));
>
> What seems to be happening is that the 2nd task gets to
> CHECK_INIT:
>
> #define CHECK_INIT(fp) \
> do \
> { \
> if ((fp)->_data == 0) \
> (fp)->_data = _REENT; \
> if (!(fp)->_data->__sdidinit) \
> __sinit ((fp)->_data); \
> } \
> while (0)
>
> and it decides to do the copy in the first if. But since
> _REENT_INIT at task_begin time set __sdidinit to 1, it
> skips the __sinit portion. Any ideas? Do you think
> that our per-task initialization should be different
> and make sure __sdidinit is 0?
>
>
Please clarify. The _REENT_INIT macro in newlib/libc/include/sys/reent.h initializes __sdidinit to
0. Have you modified this in your copy?
-- Jeff J.
More information about the Newlib
mailing list