Make __sdidinit unused

Remove dependency on __sdidinit member of struct _reent to check
object initialization. Like __sdidinit, the __cleanup member of
struct _reent is initialized in the __sinit() function. Checking
initialization against __cleanup serves the same purpose and will
reduce overhead in the __sfp() function in a follow up patch.
This commit is contained in:
Matt Joyce 2022-02-22 11:18:38 +01:00 committed by Corinna Vinschen
parent 054b00d96a
commit 44b60f0c4b
14 changed files with 33 additions and 32 deletions

View File

@ -124,7 +124,7 @@ extern void __sinit (struct _reent *);
#define CHECK_INIT(ptr) \ #define CHECK_INIT(ptr) \
do \ do \
{ \ { \
if ((ptr) && !(ptr)->__sdidinit) \ if ((ptr) && !(ptr)->__cleanup) \
__sinit (ptr); \ __sinit (ptr); \
} \ } \
while (0) while (0)

View File

@ -89,7 +89,7 @@ extern void __sinit (struct _reent *);
#define CHECK_INIT(ptr) \ #define CHECK_INIT(ptr) \
do \ do \
{ \ { \
if ((ptr) && !(ptr)->__sdidinit) \ if ((ptr) && !(ptr)->__cleanup) \
__sinit (ptr); \ __sinit (ptr); \
} \ } \
while (0) while (0)

View File

@ -175,7 +175,7 @@ extern void __sinit (struct _reent *);
# define _REENT_SMALL_CHECK_INIT(ptr) \ # define _REENT_SMALL_CHECK_INIT(ptr) \
do \ do \
{ \ { \
if ((ptr) && !(ptr)->__sdidinit) \ if ((ptr) && !(ptr)->__cleanup) \
__sinit (ptr); \ __sinit (ptr); \
} \ } \
while (0) while (0)
@ -389,7 +389,9 @@ struct _reent
char *_emergency; char *_emergency;
int __sdidinit; /* 1 means stdio has been init'd */ /* No longer used, but member retained for binary compatibility.
Now, the __cleanup member is used to check initialization. */
int _unused_sdidinit;
int _unspecified_locale_info; /* unused, reserved for locale stuff */ int _unspecified_locale_info; /* unused, reserved for locale stuff */
struct __locale_t *_locale;/* per-thread locale */ struct __locale_t *_locale;/* per-thread locale */
@ -626,7 +628,9 @@ struct _reent
int _unspecified_locale_info; /* unused, reserved for locale stuff */ int _unspecified_locale_info; /* unused, reserved for locale stuff */
struct __locale_t *_locale;/* per-thread locale */ struct __locale_t *_locale;/* per-thread locale */
int __sdidinit; /* 1 means stdio has been init'd */ /* No longer used, but member retained for binary compatibility.
Now, the __cleanup member is used to check initialization. */
int _unused_sdidinit;
void (*__cleanup) (struct _reent *); void (*__cleanup) (struct _reent *);

View File

@ -104,7 +104,7 @@ FILE *__sfp (struct _reent *);
#define __sfp_free(fp) ( (fp)->_fp = 0 ) #define __sfp_free(fp) ( (fp)->_fp = 0 )
#define CHECK_INIT(ptr) \ #define CHECK_INIT(ptr) \
do { if ((ptr) && !(ptr)->__sdidinit) __sinit (ptr); } while (0) do { if ((ptr) && !(ptr)->__cleanup) __sinit (ptr); } while (0)
#define CHECK_STD_INIT(ptr) /* currently, do nothing */ #define CHECK_STD_INIT(ptr) /* currently, do nothing */
#define CHECK_STR_INIT(ptr) /* currently, do nothing */ #define CHECK_STR_INIT(ptr) /* currently, do nothing */
#endif /* __ASSEMBLER__ */ #endif /* __ASSEMBLER__ */

View File

@ -66,7 +66,6 @@ void
__sinit (struct _reent *s) __sinit (struct _reent *s)
{ {
s->__cleanup = __cleanup; s->__cleanup = __cleanup;
s->__sdidinit = 1;
s->_stdin = &s->__sf[0]; s->_stdin = &s->__sf[0];
s->_stdin->_fp = SPE_STDIN; s->_stdin->_fp = SPE_STDIN;

View File

@ -118,7 +118,7 @@ _reclaim_reent (struct _reent *ptr)
if (ptr->_sig_func) if (ptr->_sig_func)
_free_r (ptr, ptr->_sig_func);*/ _free_r (ptr, ptr->_sig_func);*/
if (ptr->__sdidinit) if (ptr->__cleanup)
{ {
/* cleanup won't reclaim memory 'coz usually it's run /* cleanup won't reclaim memory 'coz usually it's run
before the program exits, and who wants to wait for that? */ before the program exits, and who wants to wait for that? */

View File

@ -152,7 +152,7 @@ __sfp (struct _reent *d)
_newlib_sfp_lock_start (); _newlib_sfp_lock_start ();
if (!_GLOBAL_REENT->__sdidinit) if (_GLOBAL_REENT->__cleanup == NULL)
__sinit (_GLOBAL_REENT); __sinit (_GLOBAL_REENT);
for (g = &_GLOBAL_REENT->__sglue;; g = g->_next) for (g = &_GLOBAL_REENT->__sglue;; g = g->_next)
{ {
@ -246,7 +246,7 @@ __sinit (struct _reent *s)
{ {
__sinit_lock_acquire (); __sinit_lock_acquire ();
if (s->__sdidinit) if (s->__cleanup)
{ {
__sinit_lock_release (); __sinit_lock_release ();
return; return;
@ -264,11 +264,6 @@ __sinit (struct _reent *s)
#else #else
s->__sglue._niobs = 0; s->__sglue._niobs = 0;
s->__sglue._iobs = NULL; s->__sglue._iobs = NULL;
/* Avoid infinite recursion when calling __sfp for _GLOBAL_REENT. The
problem is that __sfp checks for _GLOBAL_REENT->__sdidinit and calls
__sinit if it's 0. */
if (s == _GLOBAL_REENT)
s->__sdidinit = 1;
# ifndef _REENT_GLOBAL_STDIO_STREAMS # ifndef _REENT_GLOBAL_STDIO_STREAMS
s->_stdin = __sfp(s); s->_stdin = __sfp(s);
s->_stdout = __sfp(s); s->_stdout = __sfp(s);
@ -294,8 +289,6 @@ __sinit (struct _reent *s)
stderr_init (s->_stderr); stderr_init (s->_stderr);
#endif /* _REENT_GLOBAL_STDIO_STREAMS */ #endif /* _REENT_GLOBAL_STDIO_STREAMS */
s->__sdidinit = 1;
__sinit_lock_release (); __sinit_lock_release ();
} }

View File

@ -202,7 +202,7 @@ extern _READ_WRITE_RETURN_TYPE __swrite64 (struct _reent *, void *,
do \ do \
{ \ { \
struct _reent *_check_init_ptr = (ptr); \ struct _reent *_check_init_ptr = (ptr); \
if ((_check_init_ptr) && !(_check_init_ptr)->__sdidinit) \ if ((_check_init_ptr) && !(_check_init_ptr)->__cleanup) \
__sinit (_check_init_ptr); \ __sinit (_check_init_ptr); \
if ((fp) == (FILE *)&__sf_fake_stdin) \ if ((fp) == (FILE *)&__sf_fake_stdin) \
(fp) = _stdin_r(_check_init_ptr); \ (fp) = _stdin_r(_check_init_ptr); \
@ -217,7 +217,7 @@ extern _READ_WRITE_RETURN_TYPE __swrite64 (struct _reent *, void *,
do \ do \
{ \ { \
struct _reent *_check_init_ptr = (ptr); \ struct _reent *_check_init_ptr = (ptr); \
if ((_check_init_ptr) && !(_check_init_ptr)->__sdidinit) \ if ((_check_init_ptr) && !(_check_init_ptr)->__cleanup) \
__sinit (_check_init_ptr); \ __sinit (_check_init_ptr); \
} \ } \
while (0) while (0)
@ -227,7 +227,7 @@ extern _READ_WRITE_RETURN_TYPE __swrite64 (struct _reent *, void *,
do \ do \
{ \ { \
struct _reent *_check_init_ptr = (ptr); \ struct _reent *_check_init_ptr = (ptr); \
if ((_check_init_ptr) && !(_check_init_ptr)->__sdidinit) \ if ((_check_init_ptr) && !(_check_init_ptr)->__cleanup) \
__sinit (_check_init_ptr); \ __sinit (_check_init_ptr); \
} \ } \
while (0) while (0)

View File

@ -174,7 +174,7 @@ nbf:
* We're committed to buffering from here, so make sure we've * We're committed to buffering from here, so make sure we've
* registered to flush buffers on exit. * registered to flush buffers on exit.
*/ */
if (!reent->__sdidinit) if (!reent->__cleanup)
__sinit(reent); __sinit(reent);
#ifdef _FSEEK_OPTIMIZATION #ifdef _FSEEK_OPTIMIZATION

View File

@ -60,7 +60,7 @@ extern void __sinit (struct _reent *);
#define CHECK_INIT(ptr) \ #define CHECK_INIT(ptr) \
do \ do \
{ \ { \
if ((ptr) && !(ptr)->__sdidinit) \ if ((ptr) && !(ptr)->__cleanup) \
__sinit (ptr); \ __sinit (ptr); \
} \ } \
while (0) while (0)

View File

@ -60,8 +60,8 @@ _cygtls::init_thread (void *x, DWORD (*func) (void *, void *))
local_clib._stdin = _GLOBAL_REENT->_stdin; local_clib._stdin = _GLOBAL_REENT->_stdin;
local_clib._stdout = _GLOBAL_REENT->_stdout; local_clib._stdout = _GLOBAL_REENT->_stdout;
local_clib._stderr = _GLOBAL_REENT->_stderr; local_clib._stderr = _GLOBAL_REENT->_stderr;
local_clib.__sdidinit = _GLOBAL_REENT->__sdidinit ? -1 : 0; if (_GLOBAL_REENT->__cleanup)
local_clib.__cleanup = _GLOBAL_REENT->__cleanup; local_clib.__cleanup = _cygtls::cleanup_early;
local_clib.__sglue._niobs = 3; local_clib.__sglue._niobs = 3;
local_clib.__sglue._iobs = &_GLOBAL_REENT->__sf[0]; local_clib.__sglue._iobs = &_GLOBAL_REENT->__sf[0];
} }
@ -149,6 +149,12 @@ _cygtls::remove (DWORD wait)
} }
} }
void
_cygtls::cleanup_early (struct _reent *)
{
/* Do nothing */
}
#ifdef __x86_64__ #ifdef __x86_64__
void san::leave () void san::leave ()
{ {

View File

@ -272,6 +272,7 @@ public:
will_wait_for_signal = false; will_wait_for_signal = false;
} }
void handle_SIGCONT (); void handle_SIGCONT ();
static void cleanup_early(struct _reent *);
private: private:
void __reg3 call2 (DWORD (*) (void *, void *), void *, void *); void __reg3 call2 (DWORD (*) (void *, void *), void *, void *);
void remove_pending_sigs (); void remove_pending_sigs ();

View File

@ -824,15 +824,13 @@ main_thread_sinit ()
As soon as the main thread calls a stdio function, this would be As soon as the main thread calls a stdio function, this would be
rectified. But if another thread calls a stdio function on rectified. But if another thread calls a stdio function on
stdin/out/err before the main thread does, all the required stdin/out/err before the main thread does, all the required
initialization of stdin/out/err will be done, but _REENT->__sdidinit initialization of stdin/out/err will be done, but _REENT->__cleanup
is *still* 0. This in turn will result in a call to __sinit in the is *still* NULL. This in turn will result in a call to __sinit in the
wrong spot. The input or output buffer will be NULLed and nothing is wrong spot. The input or output buffer will be NULLed and nothing is
read or written in the first stdio function call in the main thread. read or written in the first stdio function call in the main thread.
To fix this issue we have to copy over the relevant part of _GLOBAL_REENT To fix this issue we set __cleanup to _cygtls::cleanup_early here. */
to _REENT here again. */ _REENT->__cleanup = _cygtls::cleanup_early;
_REENT->__sdidinit = -1;
_REENT->__cleanup = _GLOBAL_REENT->__cleanup;
} }
/* Take over from libc's crt0.o and start the application. Note the /* Take over from libc's crt0.o and start the application. Note the

View File

@ -564,8 +564,8 @@ pthread::exit (void *value_ptr)
mutex.unlock (); mutex.unlock ();
} }
if (_my_tls.local_clib.__sdidinit < 0) if (_my_tls.local_clib.__cleanup == _cygtls::cleanup_early)
_my_tls.local_clib.__sdidinit = 0; _my_tls.local_clib.__cleanup = NULL;
_reclaim_reent (_REENT); _reclaim_reent (_REENT);
if (InterlockedDecrement (&MT_INTERFACE->threadcount) == 0) if (InterlockedDecrement (&MT_INTERFACE->threadcount) == 0)