Skip to content

Instantly share code, notes, and snippets.

@skeeto
Last active June 14, 2020 16:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save skeeto/a3c5a0f084721acd96ef9a652855bc8d to your computer and use it in GitHub Desktop.
Save skeeto/a3c5a0f084721acd96ef9a652855bc8d to your computer and use it in GitHub Desktop.
PCG32 patch for Emacs
Switch to a permuted congruential generator
Rather than try to detect and use whatever PRNG happens to be a
available on the system, just implement a PRNG in Emacs. This generator
is stronger, faster, and more reliable than any system-provided PRNG.
This implementation also works on all platforms supported by Emacs.
This is a mixture of GPL-licensed code and my own. To the extent that it
is possible, I hereby release my changes into the public domain.
---
admin/CPP-DEFINES | 2 -
lib/gnulib.mk.in | 15 ---
lib/stdlib.in.h | 269 ----------------------------------------------
m4/stdlib_h.m4 | 6 --
msdos/autogen/Makefile.in | 10 --
msdos/autogen/config.in | 6 --
msdos/sedlibmk.inp | 2 -
src/conf_post.h | 8 --
src/sysdep.c | 93 ++++++----------
9 files changed, 31 insertions(+), 380 deletions(-)
--- a/admin/CPP-DEFINES
+++ b/admin/CPP-DEFINES
@@ -201,7 +201,6 @@
HAVE_LIBXMU
HAVE_LOCALTIME_R
HAVE_LOCAL_SOCKETS
-HAVE_LRAND48
HAVE_LSTAT
HAVE_LUTIMES
HAVE_M17N_FLT
@@ -239,7 +238,6 @@
HAVE_PTYS
HAVE_PTY_H
HAVE_PWD_H
-HAVE_RANDOM
HAVE_READLINK
HAVE_READLINKAT
HAVE_RECVFROM
--- a/lib/gnulib.mk.in
+++ b/lib/gnulib.mk.in
@@ -396,8 +396,6 @@
GNULIB_PWRITE = @GNULIB_PWRITE@
GNULIB_QSORT_R = @GNULIB_QSORT_R@
GNULIB_RAISE = @GNULIB_RAISE@
-GNULIB_RANDOM = @GNULIB_RANDOM@
-GNULIB_RANDOM_R = @GNULIB_RANDOM_R@
GNULIB_RAWMEMCHR = @GNULIB_RAWMEMCHR@
GNULIB_READ = @GNULIB_READ@
GNULIB_READDIR = @GNULIB_READDIR@
@@ -619,9 +617,6 @@
HAVE_PWRITE = @HAVE_PWRITE@
HAVE_QSORT_R = @HAVE_QSORT_R@
HAVE_RAISE = @HAVE_RAISE@
-HAVE_RANDOM = @HAVE_RANDOM@
-HAVE_RANDOM_H = @HAVE_RANDOM_H@
-HAVE_RANDOM_R = @HAVE_RANDOM_R@
HAVE_RAWMEMCHR = @HAVE_RAWMEMCHR@
HAVE_READDIR = @HAVE_READDIR@
HAVE_READLINK = @HAVE_READLINK@
@@ -656,7 +651,6 @@
HAVE_STRTOLD = @HAVE_STRTOLD@
HAVE_STRTOLL = @HAVE_STRTOLL@
HAVE_STRTOULL = @HAVE_STRTOULL@
-HAVE_STRUCT_RANDOM_DATA = @HAVE_STRUCT_RANDOM_DATA@
HAVE_STRUCT_SIGACTION_SA_SIGACTION = @HAVE_STRUCT_SIGACTION_SA_SIGACTION@
HAVE_STRUCT_TIMEVAL = @HAVE_STRUCT_TIMEVAL@
HAVE_STRVERSCMP = @HAVE_STRVERSCMP@
@@ -922,8 +916,6 @@
REPLACE_PWRITE = @REPLACE_PWRITE@
REPLACE_QSORT_R = @REPLACE_QSORT_R@
REPLACE_RAISE = @REPLACE_RAISE@
-REPLACE_RANDOM = @REPLACE_RANDOM@
-REPLACE_RANDOM_R = @REPLACE_RANDOM_R@
REPLACE_READ = @REPLACE_READ@
REPLACE_READLINK = @REPLACE_READLINK@
REPLACE_READLINKAT = @REPLACE_READLINKAT@
@@ -2659,8 +2651,6 @@
-e 's/@''GNULIB_PTSNAME_R''@/$(GNULIB_PTSNAME_R)/g' \
-e 's/@''GNULIB_PUTENV''@/$(GNULIB_PUTENV)/g' \
-e 's/@''GNULIB_QSORT_R''@/$(GNULIB_QSORT_R)/g' \
- -e 's/@''GNULIB_RANDOM''@/$(GNULIB_RANDOM)/g' \
- -e 's/@''GNULIB_RANDOM_R''@/$(GNULIB_RANDOM_R)/g' \
-e 's/@''GNULIB_REALLOC_POSIX''@/$(GNULIB_REALLOC_POSIX)/g' \
-e 's/@''GNULIB_REALLOCARRAY''@/$(GNULIB_REALLOCARRAY)/g' \
-e 's/@''GNULIB_REALPATH''@/$(GNULIB_REALPATH)/g' \
@@ -2694,9 +2684,6 @@
-e 's|@''HAVE_PTSNAME''@|$(HAVE_PTSNAME)|g' \
-e 's|@''HAVE_PTSNAME_R''@|$(HAVE_PTSNAME_R)|g' \
-e 's|@''HAVE_QSORT_R''@|$(HAVE_QSORT_R)|g' \
- -e 's|@''HAVE_RANDOM''@|$(HAVE_RANDOM)|g' \
- -e 's|@''HAVE_RANDOM_H''@|$(HAVE_RANDOM_H)|g' \
- -e 's|@''HAVE_RANDOM_R''@|$(HAVE_RANDOM_R)|g' \
-e 's|@''HAVE_REALLOCARRAY''@|$(HAVE_REALLOCARRAY)|g' \
-e 's|@''HAVE_REALPATH''@|$(HAVE_REALPATH)|g' \
-e 's|@''HAVE_RPMATCH''@|$(HAVE_RPMATCH)|g' \
@@ -2722,8 +2709,6 @@
-e 's|@''REPLACE_PTSNAME_R''@|$(REPLACE_PTSNAME_R)|g' \
-e 's|@''REPLACE_PUTENV''@|$(REPLACE_PUTENV)|g' \
-e 's|@''REPLACE_QSORT_R''@|$(REPLACE_QSORT_R)|g' \
- -e 's|@''REPLACE_RANDOM''@|$(REPLACE_RANDOM)|g' \
- -e 's|@''REPLACE_RANDOM_R''@|$(REPLACE_RANDOM_R)|g' \
-e 's|@''REPLACE_REALLOC''@|$(REPLACE_REALLOC)|g' \
-e 's|@''REPLACE_REALPATH''@|$(REPLACE_REALPATH)|g' \
-e 's|@''REPLACE_SETENV''@|$(REPLACE_SETENV)|g' \
--- a/lib/stdlib.in.h
+++ b/lib/stdlib.in.h
@@ -58,38 +58,6 @@
# include <io.h>
#endif
-#if @GNULIB_RANDOM_R@
-
-/* OSF/1 5.1 declares 'struct random_data' in <random.h>, which is included
- from <stdlib.h> if _REENTRANT is defined. Include it whenever we need
- 'struct random_data'. */
-# if @HAVE_RANDOM_H@
-# include <random.h>
-# endif
-
-# if !@HAVE_STRUCT_RANDOM_DATA@ || @REPLACE_RANDOM_R@ || !@HAVE_RANDOM_R@
-# include <stdint.h>
-# endif
-
-# if !@HAVE_STRUCT_RANDOM_DATA@
-/* Define 'struct random_data'.
- But allow multiple gnulib generated <stdlib.h> replacements to coexist. */
-# if !GNULIB_defined_struct_random_data
-struct random_data
-{
- int32_t *fptr; /* Front pointer. */
- int32_t *rptr; /* Rear pointer. */
- int32_t *state; /* Array of state values. */
- int rand_type; /* Type of random number generator. */
- int rand_deg; /* Degree of random number generator. */
- int rand_sep; /* Distance between front and rear. */
- int32_t *end_ptr; /* Pointer behind state table. */
-};
-# define GNULIB_defined_struct_random_data 1
-# endif
-# endif
-#endif
-
#if (@GNULIB_MKSTEMP@ || @GNULIB_MKSTEMPS@ || @GNULIB_MKOSTEMP@ || @GNULIB_MKOSTEMPS@ || @GNULIB_GETSUBOPT@ || defined GNULIB_POSIXCHECK) && ! defined __GLIBC__ && !(defined _WIN32 && ! defined __CYGWIN__)
/* On Mac OS X 10.3, only <unistd.h> declares mkstemp. */
/* On Mac OS X 10.5, only <unistd.h> declares mkstemps. */
@@ -590,243 +558,6 @@
# endif
#endif
-
-#if @GNULIB_RANDOM_R@
-# if !@HAVE_RANDOM_R@
-# ifndef RAND_MAX
-# define RAND_MAX 2147483647
-# endif
-# endif
-#endif
-
-
-#if @GNULIB_RANDOM@
-# if @REPLACE_RANDOM@
-# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
-# undef random
-# define random rpl_random
-# endif
-_GL_FUNCDECL_RPL (random, long, (void));
-_GL_CXXALIAS_RPL (random, long, (void));
-# else
-# if !@HAVE_RANDOM@
-_GL_FUNCDECL_SYS (random, long, (void));
-# endif
-/* Need to cast, because on Haiku, the return type is
- int. */
-_GL_CXXALIAS_SYS_CAST (random, long, (void));
-# endif
-_GL_CXXALIASWARN (random);
-#elif defined GNULIB_POSIXCHECK
-# undef random
-# if HAVE_RAW_DECL_RANDOM
-_GL_WARN_ON_USE (random, "random is unportable - "
- "use gnulib module random for portability");
-# endif
-#endif
-
-#if @GNULIB_RANDOM@
-# if @REPLACE_RANDOM@
-# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
-# undef srandom
-# define srandom rpl_srandom
-# endif
-_GL_FUNCDECL_RPL (srandom, void, (unsigned int seed));
-_GL_CXXALIAS_RPL (srandom, void, (unsigned int seed));
-# else
-# if !@HAVE_RANDOM@
-_GL_FUNCDECL_SYS (srandom, void, (unsigned int seed));
-# endif
-/* Need to cast, because on FreeBSD, the first parameter is
- unsigned long seed. */
-_GL_CXXALIAS_SYS_CAST (srandom, void, (unsigned int seed));
-# endif
-_GL_CXXALIASWARN (srandom);
-#elif defined GNULIB_POSIXCHECK
-# undef srandom
-# if HAVE_RAW_DECL_SRANDOM
-_GL_WARN_ON_USE (srandom, "srandom is unportable - "
- "use gnulib module random for portability");
-# endif
-#endif
-
-#if @GNULIB_RANDOM@
-# if @REPLACE_INITSTATE@
-# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
-# undef initstate
-# define initstate rpl_initstate
-# endif
-_GL_FUNCDECL_RPL (initstate, char *,
- (unsigned int seed, char *buf, size_t buf_size)
- _GL_ARG_NONNULL ((2)));
-_GL_CXXALIAS_RPL (initstate, char *,
- (unsigned int seed, char *buf, size_t buf_size));
-# else
-# if !@HAVE_INITSTATE@ || !@HAVE_DECL_INITSTATE@
-_GL_FUNCDECL_SYS (initstate, char *,
- (unsigned int seed, char *buf, size_t buf_size)
- _GL_ARG_NONNULL ((2)));
-# endif
-/* Need to cast, because on FreeBSD, the first parameter is
- unsigned long seed. */
-_GL_CXXALIAS_SYS_CAST (initstate, char *,
- (unsigned int seed, char *buf, size_t buf_size));
-# endif
-_GL_CXXALIASWARN (initstate);
-#elif defined GNULIB_POSIXCHECK
-# undef initstate
-# if HAVE_RAW_DECL_INITSTATE
-_GL_WARN_ON_USE (initstate, "initstate is unportable - "
- "use gnulib module random for portability");
-# endif
-#endif
-
-#if @GNULIB_RANDOM@
-# if @REPLACE_SETSTATE@
-# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
-# undef setstate
-# define setstate rpl_setstate
-# endif
-_GL_FUNCDECL_RPL (setstate, char *, (char *arg_state) _GL_ARG_NONNULL ((1)));
-_GL_CXXALIAS_RPL (setstate, char *, (char *arg_state));
-# else
-# if !@HAVE_SETSTATE@ || !@HAVE_DECL_SETSTATE@
-_GL_FUNCDECL_SYS (setstate, char *, (char *arg_state) _GL_ARG_NONNULL ((1)));
-# endif
-/* Need to cast, because on Mac OS X 10.13, HP-UX, Solaris the first parameter
- is const char *arg_state. */
-_GL_CXXALIAS_SYS_CAST (setstate, char *, (char *arg_state));
-# endif
-_GL_CXXALIASWARN (setstate);
-#elif defined GNULIB_POSIXCHECK
-# undef setstate
-# if HAVE_RAW_DECL_SETSTATE
-_GL_WARN_ON_USE (setstate, "setstate is unportable - "
- "use gnulib module random for portability");
-# endif
-#endif
-
-
-#if @GNULIB_RANDOM_R@
-# if @REPLACE_RANDOM_R@
-# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
-# undef random_r
-# define random_r rpl_random_r
-# endif
-_GL_FUNCDECL_RPL (random_r, int, (struct random_data *buf, int32_t *result)
- _GL_ARG_NONNULL ((1, 2)));
-_GL_CXXALIAS_RPL (random_r, int, (struct random_data *buf, int32_t *result));
-# else
-# if !@HAVE_RANDOM_R@
-_GL_FUNCDECL_SYS (random_r, int, (struct random_data *buf, int32_t *result)
- _GL_ARG_NONNULL ((1, 2)));
-# endif
-_GL_CXXALIAS_SYS (random_r, int, (struct random_data *buf, int32_t *result));
-# endif
-_GL_CXXALIASWARN (random_r);
-#elif defined GNULIB_POSIXCHECK
-# undef random_r
-# if HAVE_RAW_DECL_RANDOM_R
-_GL_WARN_ON_USE (random_r, "random_r is unportable - "
- "use gnulib module random_r for portability");
-# endif
-#endif
-
-#if @GNULIB_RANDOM_R@
-# if @REPLACE_RANDOM_R@
-# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
-# undef srandom_r
-# define srandom_r rpl_srandom_r
-# endif
-_GL_FUNCDECL_RPL (srandom_r, int,
- (unsigned int seed, struct random_data *rand_state)
- _GL_ARG_NONNULL ((2)));
-_GL_CXXALIAS_RPL (srandom_r, int,
- (unsigned int seed, struct random_data *rand_state));
-# else
-# if !@HAVE_RANDOM_R@
-_GL_FUNCDECL_SYS (srandom_r, int,
- (unsigned int seed, struct random_data *rand_state)
- _GL_ARG_NONNULL ((2)));
-# endif
-_GL_CXXALIAS_SYS (srandom_r, int,
- (unsigned int seed, struct random_data *rand_state));
-# endif
-_GL_CXXALIASWARN (srandom_r);
-#elif defined GNULIB_POSIXCHECK
-# undef srandom_r
-# if HAVE_RAW_DECL_SRANDOM_R
-_GL_WARN_ON_USE (srandom_r, "srandom_r is unportable - "
- "use gnulib module random_r for portability");
-# endif
-#endif
-
-#if @GNULIB_RANDOM_R@
-# if @REPLACE_RANDOM_R@
-# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
-# undef initstate_r
-# define initstate_r rpl_initstate_r
-# endif
-_GL_FUNCDECL_RPL (initstate_r, int,
- (unsigned int seed, char *buf, size_t buf_size,
- struct random_data *rand_state)
- _GL_ARG_NONNULL ((2, 4)));
-_GL_CXXALIAS_RPL (initstate_r, int,
- (unsigned int seed, char *buf, size_t buf_size,
- struct random_data *rand_state));
-# else
-# if !@HAVE_RANDOM_R@
-_GL_FUNCDECL_SYS (initstate_r, int,
- (unsigned int seed, char *buf, size_t buf_size,
- struct random_data *rand_state)
- _GL_ARG_NONNULL ((2, 4)));
-# endif
-/* Need to cast, because on Haiku, the third parameter is
- unsigned long buf_size. */
-_GL_CXXALIAS_SYS_CAST (initstate_r, int,
- (unsigned int seed, char *buf, size_t buf_size,
- struct random_data *rand_state));
-# endif
-_GL_CXXALIASWARN (initstate_r);
-#elif defined GNULIB_POSIXCHECK
-# undef initstate_r
-# if HAVE_RAW_DECL_INITSTATE_R
-_GL_WARN_ON_USE (initstate_r, "initstate_r is unportable - "
- "use gnulib module random_r for portability");
-# endif
-#endif
-
-#if @GNULIB_RANDOM_R@
-# if @REPLACE_RANDOM_R@
-# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
-# undef setstate_r
-# define setstate_r rpl_setstate_r
-# endif
-_GL_FUNCDECL_RPL (setstate_r, int,
- (char *arg_state, struct random_data *rand_state)
- _GL_ARG_NONNULL ((1, 2)));
-_GL_CXXALIAS_RPL (setstate_r, int,
- (char *arg_state, struct random_data *rand_state));
-# else
-# if !@HAVE_RANDOM_R@
-_GL_FUNCDECL_SYS (setstate_r, int,
- (char *arg_state, struct random_data *rand_state)
- _GL_ARG_NONNULL ((1, 2)));
-# endif
-/* Need to cast, because on Haiku, the first parameter is
- void *arg_state. */
-_GL_CXXALIAS_SYS_CAST (setstate_r, int,
- (char *arg_state, struct random_data *rand_state));
-# endif
-_GL_CXXALIASWARN (setstate_r);
-#elif defined GNULIB_POSIXCHECK
-# undef setstate_r
-# if HAVE_RAW_DECL_SETSTATE_R
-_GL_WARN_ON_USE (setstate_r, "setstate_r is unportable - "
- "use gnulib module random_r for portability");
-# endif
-#endif
-
#if @GNULIB_REALLOC_POSIX@
# if @REPLACE_REALLOC@
--- a/m4/stdlib_h.m4
+++ b/m4/stdlib_h.m4
@@ -19,9 +19,6 @@
# include <sys/time.h>
# include <sys/loadavg.h>
#endif
-#if HAVE_RANDOM_H
-# include <random.h>
-#endif
]], [_Exit atoll canonicalize_file_name getloadavg getsubopt grantpt
initstate initstate_r mbtowc mkdtemp mkostemp mkostemps mkstemp mkstemps
posix_openpt ptsname ptsname_r qsort_r random random_r reallocarray
@@ -96,9 +93,6 @@
HAVE_PTSNAME=1; AC_SUBST([HAVE_PTSNAME])
HAVE_PTSNAME_R=1; AC_SUBST([HAVE_PTSNAME_R])
HAVE_QSORT_R=1; AC_SUBST([HAVE_QSORT_R])
- HAVE_RANDOM=1; AC_SUBST([HAVE_RANDOM])
- HAVE_RANDOM_H=1; AC_SUBST([HAVE_RANDOM_H])
- HAVE_RANDOM_R=1; AC_SUBST([HAVE_RANDOM_R])
HAVE_REALLOCARRAY=1; AC_SUBST([HAVE_REALLOCARRAY])
HAVE_REALPATH=1; AC_SUBST([HAVE_REALPATH])
HAVE_RPMATCH=1; AC_SUBST([HAVE_RPMATCH])
--- a/msdos/autogen/Makefile.in
+++ b/msdos/autogen/Makefile.in
@@ -602,8 +602,6 @@
GNULIB_PUTS = @GNULIB_PUTS@
GNULIB_PWRITE = @GNULIB_PWRITE@
GNULIB_RAISE = @GNULIB_RAISE@
-GNULIB_RANDOM = @GNULIB_RANDOM@
-GNULIB_RANDOM_R = @GNULIB_RANDOM_R@
GNULIB_RAWMEMCHR = @GNULIB_RAWMEMCHR@
GNULIB_READ = @GNULIB_READ@
GNULIB_READDIR = @GNULIB_READDIR@
@@ -802,9 +800,6 @@
HAVE_PTSNAME_R = @HAVE_PTSNAME_R@
HAVE_PWRITE = @HAVE_PWRITE@
HAVE_RAISE = @HAVE_RAISE@
-HAVE_RANDOM = @HAVE_RANDOM@
-HAVE_RANDOM_H = @HAVE_RANDOM_H@
-HAVE_RANDOM_R = @HAVE_RANDOM_R@
HAVE_RAWMEMCHR = @HAVE_RAWMEMCHR@
HAVE_READDIR = @HAVE_READDIR@
HAVE_READLINK = @HAVE_READLINK@
@@ -836,7 +831,6 @@
HAVE_STRTOD = @HAVE_STRTOD@
HAVE_STRTOLL = @HAVE_STRTOLL@
HAVE_STRTOULL = @HAVE_STRTOULL@
-HAVE_STRUCT_RANDOM_DATA = @HAVE_STRUCT_RANDOM_DATA@
HAVE_STRUCT_SIGACTION_SA_SIGACTION = @HAVE_STRUCT_SIGACTION_SA_SIGACTION@
HAVE_STRUCT_TIMEVAL = @HAVE_STRUCT_TIMEVAL@
HAVE_STRVERSCMP = @HAVE_STRVERSCMP@
@@ -1072,7 +1066,6 @@
REPLACE_PUTENV = @REPLACE_PUTENV@
REPLACE_PWRITE = @REPLACE_PWRITE@
REPLACE_RAISE = @REPLACE_RAISE@
-REPLACE_RANDOM_R = @REPLACE_RANDOM_R@
REPLACE_READ = @REPLACE_READ@
REPLACE_READLINK = @REPLACE_READLINK@
REPLACE_REALLOC = @REPLACE_REALLOC@
@@ -2393,9 +2386,6 @@
@BUILDING_FOR_WINDOWSNT_FALSE@ -e 's|@''HAVE_POSIX_OPENPT''@|$(HAVE_POSIX_OPENPT)|g' \
@BUILDING_FOR_WINDOWSNT_FALSE@ -e 's|@''HAVE_PTSNAME''@|$(HAVE_PTSNAME)|g' \
@BUILDING_FOR_WINDOWSNT_FALSE@ -e 's|@''HAVE_PTSNAME_R''@|$(HAVE_PTSNAME_R)|g' \
-@BUILDING_FOR_WINDOWSNT_FALSE@ -e 's|@''HAVE_RANDOM''@|$(HAVE_RANDOM)|g' \
-@BUILDING_FOR_WINDOWSNT_FALSE@ -e 's|@''HAVE_RANDOM_H''@|$(HAVE_RANDOM_H)|g' \
-@BUILDING_FOR_WINDOWSNT_FALSE@ -e 's|@''HAVE_RANDOM_R''@|$(HAVE_RANDOM_R)|g' \
@BUILDING_FOR_WINDOWSNT_FALSE@ -e 's|@''HAVE_REALPATH''@|$(HAVE_REALPATH)|g' \
@BUILDING_FOR_WINDOWSNT_FALSE@ -e 's|@''HAVE_RPMATCH''@|$(HAVE_RPMATCH)|g' \
@BUILDING_FOR_WINDOWSNT_FALSE@ -e 's|@''HAVE_SECURE_GETENV''@|$(HAVE_SECURE_GETENV)|g' \
--- a/msdos/autogen/config.in
+++ b/msdos/autogen/config.in
@@ -726,9 +726,6 @@
/* Define to 1 if the system has the type 'long long int'. */
#undef HAVE_LONG_LONG_INT
-/* Define to 1 if you have the `lrand48' function. */
-#undef HAVE_LRAND48
-
/* Define to 1 if you have the `lstat' function. */
#undef HAVE_LSTAT
@@ -842,9 +839,6 @@
/* Define to 1 if you have the <pwd.h> header file. */
#undef HAVE_PWD_H
-/* Define to 1 if you have the `random' function. */
-#undef HAVE_RANDOM
-
/* Define to 1 if you have the `readlink' function. */
#undef HAVE_READLINK
--- a/msdos/sedlibmk.inp
+++ b/msdos/sedlibmk.inp
@@ -224,9 +224,7 @@
/^HAVE_PCLOSE *=/s/@HAVE_PCLOSE@/1/
/^HAVE_POPEN *=/s/@HAVE_POPEN@/1/
/^HAVE_POSIX_SIGNALBLOCKING *=/s/@HAVE_POSIX_SIGNALBLOCKING@/1/
-/^HAVE_RANDOM_H *=/s/@HAVE_RANDOM_H@/1/
/^HAVE_RAISE *=/s/@HAVE_RAISE@/1/
-/^HAVE_RANDOM *=/s/@HAVE_RANDOM@/1/
/^HAVE_READDIR *=/s/@HAVE_READDIR@/1/
/^HAVE_REWINDDIR *=/s/@HAVE_REWINDDIR@/1/
/^HAVE_SETENV *=/s/@HAVE_SETENV@/1/
--- a/src/conf_post.h
+++ b/src/conf_post.h
@@ -117,15 +117,7 @@
#endif
#endif /* HYBRID_MALLOC */
-/* We have to go this route, rather than the old hpux9 approach of
- renaming the functions via macros. The system's stdlib.h has fully
- prototyped declarations, which yields a conflicting definition of
- srand48; it tries to redeclare what was once srandom to be srand48.
- So we go with HAVE_LRAND48 being defined. */
#ifdef HPUX
-#undef srandom
-#undef random
-#undef HAVE_RANDOM
#undef HAVE_RINT
#endif /* HPUX */
--- a/src/sysdep.c
+++ b/src/sysdep.c
@@ -2237,82 +2237,38 @@
#endif
}
-#ifndef HAVE_RANDOM
-#ifdef random
-#define HAVE_RANDOM
-#endif
-#endif
-
-/* Figure out how many bits the system's random number generator uses.
- `random' and `lrand48' are assumed to return 31 usable bits.
- BSD `rand' returns a 31 bit value but the low order bits are unusable;
- so we'll shift it and treat it like the 15-bit USG `rand'. */
-
-#ifndef RAND_BITS
-# ifdef HAVE_RANDOM
-# define RAND_BITS 31
-# else /* !HAVE_RANDOM */
-# ifdef HAVE_LRAND48
-# define RAND_BITS 31
-# define random lrand48
-# else /* !HAVE_LRAND48 */
-# define RAND_BITS 15
-# if RAND_MAX == 32767
-# define random rand
-# else /* RAND_MAX != 32767 */
-# if RAND_MAX == 2147483647
-# define random() (rand () >> 16)
-# else /* RAND_MAX != 2147483647 */
-# ifdef USG
-# define random rand
-# else
-# define random() (rand () >> 16)
-# endif /* !USG */
-# endif /* RAND_MAX != 2147483647 */
-# endif /* RAND_MAX != 32767 */
-# endif /* !HAVE_LRAND48 */
-# endif /* !HAVE_RANDOM */
-#endif /* !RAND_BITS */
-
-#ifdef HAVE_RANDOM
-typedef unsigned int random_seed;
-static void set_random_seed (random_seed arg) { srandom (arg); }
-#elif defined HAVE_LRAND48
-/* Although srand48 uses a long seed, this is unsigned long to avoid
- undefined behavior on signed integer overflow in init_random. */
-typedef unsigned long int random_seed;
-static void set_random_seed (random_seed arg) { srand48 (arg); }
-#else
-typedef unsigned int random_seed;
-static void set_random_seed (random_seed arg) { srand (arg); }
-#endif
+/* Permuted congruential generator with 32-output and 64-bit state. */
+static unsigned long long pcg32[2];
void
seed_random (void *seed, ptrdiff_t seed_size)
{
- random_seed arg = 0;
- unsigned char *argp = (unsigned char *) &arg;
unsigned char *seedp = seed;
+ pcg32[0] = 0xcbf29ce484222325ULL;
+ pcg32[1] = ~pcg32[0];
for (ptrdiff_t i = 0; i < seed_size; i++)
- argp[i % sizeof arg] ^= seedp[i];
- set_random_seed (arg);
+ {
+ pcg32[0] ^= seedp[i];
+ pcg32[0] *= 0x00000100000001B3ULL;
+ pcg32[1] ^= seedp[i];
+ pcg32[1] *= 0x00000100000001B3ULL;
+ }
}
void
init_random (void)
{
- random_seed v;
bool success = false;
/* First, try seeding the PRNG from the operating system's entropy
source. This approach is both fast and secure. */
#ifdef WINDOWSNT
- success = w32_init_random (&v, sizeof v) == 0;
+ success = w32_init_random (&pcg32, sizeof pcg32) == 0;
#else
int fd = emacs_open ("/dev/urandom", O_RDONLY, 0);
if (0 <= fd)
{
- success = emacs_read (fd, &v, sizeof v) == sizeof v;
+ success = emacs_read (fd, &pcg32, sizeof pcg32) == sizeof pcg32;
close (fd);
}
#endif
@@ -2321,17 +2277,28 @@
some systems, can be somewhat slow. */
if (!success)
success = EQ (emacs_gnutls_global_init (), Qt)
- && gnutls_rnd (GNUTLS_RND_NONCE, &v, sizeof v) == 0;
+ && gnutls_rnd (GNUTLS_RND_NONCE, &pcg32, sizeof pcg32) == 0;
/* If _that_ didn't work, just use the current time value and PID.
It's at least better than XKCD 221. */
if (!success)
{
struct timespec t = current_timespec ();
- v = getpid () ^ t.tv_sec ^ t.tv_nsec;
+ seed_random (&t, sizeof(t));
}
+}
- set_random_seed (v);
+/*
+ * Return the next 32 bits from the PCG.
+ */
+unsigned long
+pcg32_gen (void)
+{
+ unsigned long long s = pcg32[0] & 0xffffffffffffffffULL;
+ pcg32[0] = pcg32[0] * 6364136223846793005ULL + (pcg32[1] | 1);
+ unsigned long x = (((s >> 18) ^ s) >> 27) & 0xffffffffUL;
+ unsigned rot = s >> 59;
+ return (x >> rot) | (x << ((-rot) & 31));
}
/*
@@ -2344,9 +2311,9 @@
{
EMACS_UINT val = 0;
int i;
- for (i = 0; i < (FIXNUM_BITS + RAND_BITS - 1) / RAND_BITS; i++)
- val = (random () ^ (val << RAND_BITS)
- ^ (val >> (EMACS_INT_WIDTH - RAND_BITS)));
+ for (i = 0; i < (FIXNUM_BITS + 32 - 1) / 32; i++)
+ val = (pcg32_gen () ^ (val << 32)
+ ^ (val >> (EMACS_INT_WIDTH - 32)));
val ^= val >> (EMACS_INT_WIDTH - FIXNUM_BITS);
return val & INTMASK;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment