4
0
mirror of git://sourceware.org/git/newlib-cygwin.git synced 2025-01-22 15:07:43 +08:00
Matt Joyce ea99f21ce6 Add --enable-newlib-reent-thread-local option
By default, Newlib uses a huge object of type struct _reent to store
thread-specific data.  This object is returned by __getreent() if the
__DYNAMIC_REENT__ Newlib configuration option is defined.

The reentrancy structure contains for example errno and the standard input,
output, and error file streams.  This means that if an application only uses
errno it has a dependency on the file stream support even if it does not use
it.  This is an issue for lower end targets and applications which need to
qualify the software according to safety standards (for example ECSS-E-ST-40C,
ECSS-Q-ST-80C, IEC 61508, ISO 26262, DO-178, DO-330, DO-333).

If the new _REENT_THREAD_LOCAL configuration option is enabled, then struct
_reent is replaced by dedicated thread-local objects for each struct _reent
member.  The thread-local objects are defined in translation units which use
the corresponding object.
2022-07-13 06:55:46 +02:00

89 lines
2.5 KiB
C

/*
FUNCTION
<<rand>>, <<srand>>---pseudo-random numbers
INDEX
rand
INDEX
srand
INDEX
rand_r
SYNOPSIS
#include <stdlib.h>
int rand(void);
void srand(unsigned int <[seed]>);
int rand_r(unsigned int *<[seed]>);
DESCRIPTION
<<rand>> returns a different integer each time it is called; each
integer is chosen by an algorithm designed to be unpredictable, so
that you can use <<rand>> when you require a random number.
The algorithm depends on a static variable called the ``random seed'';
starting with a given value of the random seed always produces the
same sequence of numbers in successive calls to <<rand>>.
You can set the random seed using <<srand>>; it does nothing beyond
storing its argument in the static variable used by <<rand>>. You can
exploit this to make the pseudo-random sequence less predictable, if
you wish, by using some other unpredictable value (often the least
significant parts of a time-varying value) as the random seed before
beginning a sequence of calls to <<rand>>; or, if you wish to ensure
(for example, while debugging) that successive runs of your program
use the same ``random'' numbers, you can use <<srand>> to set the same
random seed at the outset.
RETURNS
<<rand>> returns the next pseudo-random integer in sequence; it is a
number between <<0>> and <<RAND_MAX>> (inclusive).
<<srand>> does not return a result.
NOTES
<<rand>> and <<srand>> are unsafe for multi-threaded applications.
<<rand_r>> is thread-safe and should be used instead.
PORTABILITY
<<rand>> is required by ANSI, but the algorithm for pseudo-random
number generation is not specified; therefore, even if you use
the same random seed, you cannot expect the same sequence of results
on two different systems.
<<rand>> requires no supporting OS subroutines.
*/
#ifndef _REENT_ONLY
#include <stdlib.h>
#include <reent.h>
#ifdef _REENT_THREAD_LOCAL
_Thread_local unsigned long long _tls_rand_next = 1;
#endif
void
srand (unsigned int seed)
{
struct _reent *reent = _REENT;
_REENT_CHECK_RAND48(reent);
_REENT_RAND_NEXT(reent) = seed;
}
int
rand (void)
{
struct _reent *reent = _REENT;
/* This multiplier was obtained from Knuth, D.E., "The Art of
Computer Programming," Vol 2, Seminumerical Algorithms, Third
Edition, Addison-Wesley, 1998, p. 106 (line 26) & p. 108 */
_REENT_CHECK_RAND48(reent);
_REENT_RAND_NEXT(reent) =
_REENT_RAND_NEXT(reent) * __extension__ 6364136223846793005LL + 1;
return (int)((_REENT_RAND_NEXT(reent) >> 32) & RAND_MAX);
}
#endif /* _REENT_ONLY */