ash: factor out $RANDOM support
function old new delta next_random - 46 +46 ash_main 1361 1356 -5 change_random 132 97 -35 ------------------------------------------------------------------------------ (add/remove: 1/0 grow/shrink: 0/2 up/down: 46/-40) Total: 6 bytes Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
parent
a05b2b856b
commit
3ea2e82dc7
@ -8,4 +8,7 @@ lib-y:=
|
|||||||
lib-$(CONFIG_ASH) += ash.o ash_ptr_hack.o
|
lib-$(CONFIG_ASH) += ash.o ash_ptr_hack.o
|
||||||
lib-$(CONFIG_HUSH) += hush.o match.o
|
lib-$(CONFIG_HUSH) += hush.o match.o
|
||||||
lib-$(CONFIG_CTTYHACK) += cttyhack.o
|
lib-$(CONFIG_CTTYHACK) += cttyhack.o
|
||||||
|
|
||||||
lib-$(CONFIG_SH_MATH_SUPPORT) += math.o
|
lib-$(CONFIG_SH_MATH_SUPPORT) += math.o
|
||||||
|
lib-$(CONFIG_ASH_RANDOM_SUPPORT) += random.o
|
||||||
|
lib-$(CONFIG_HUSH_RANDOM_SUPPORT) += random.o
|
||||||
|
46
shell/ash.c
46
shell/ash.c
@ -51,16 +51,19 @@
|
|||||||
#include <setjmp.h>
|
#include <setjmp.h>
|
||||||
#include <fnmatch.h>
|
#include <fnmatch.h>
|
||||||
#include "math.h"
|
#include "math.h"
|
||||||
|
#if ENABLE_ASH_RANDOM_SUPPORT
|
||||||
|
# include "random.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined SINGLE_APPLET_MAIN
|
#if defined SINGLE_APPLET_MAIN
|
||||||
/* STANDALONE does not make sense, and won't compile */
|
/* STANDALONE does not make sense, and won't compile */
|
||||||
#undef CONFIG_FEATURE_SH_STANDALONE
|
# undef CONFIG_FEATURE_SH_STANDALONE
|
||||||
#undef ENABLE_FEATURE_SH_STANDALONE
|
# undef ENABLE_FEATURE_SH_STANDALONE
|
||||||
#undef IF_FEATURE_SH_STANDALONE
|
# undef IF_FEATURE_SH_STANDALONE
|
||||||
#undef IF_NOT_FEATURE_SH_STANDALONE(...)
|
# undef IF_NOT_FEATURE_SH_STANDALONE(...)
|
||||||
#define ENABLE_FEATURE_SH_STANDALONE 0
|
# define ENABLE_FEATURE_SH_STANDALONE 0
|
||||||
#define IF_FEATURE_SH_STANDALONE(...)
|
# define IF_FEATURE_SH_STANDALONE(...)
|
||||||
#define IF_NOT_FEATURE_SH_STANDALONE(...) __VA_ARGS__
|
# define IF_NOT_FEATURE_SH_STANDALONE(...) __VA_ARGS__
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef PIPE_BUF
|
#ifndef PIPE_BUF
|
||||||
@ -197,9 +200,7 @@ struct globals_misc {
|
|||||||
|
|
||||||
/* Rarely referenced stuff */
|
/* Rarely referenced stuff */
|
||||||
#if ENABLE_ASH_RANDOM_SUPPORT
|
#if ENABLE_ASH_RANDOM_SUPPORT
|
||||||
/* Random number generators */
|
random_t random_gen;
|
||||||
int32_t random_galois_LFSR; /* Galois LFSR (fast but weak). signed! */
|
|
||||||
uint32_t random_LCG; /* LCG (fast but weak) */
|
|
||||||
#endif
|
#endif
|
||||||
pid_t backgndpid; /* pid of last background process */
|
pid_t backgndpid; /* pid of last background process */
|
||||||
smallint job_warning; /* user was warned about stopped jobs (can be 2, 1 or 0). */
|
smallint job_warning; /* user was warned about stopped jobs (can be 2, 1 or 0). */
|
||||||
@ -224,8 +225,7 @@ extern struct globals_misc *const ash_ptr_to_globals_misc;
|
|||||||
#define gotsig (G_misc.gotsig )
|
#define gotsig (G_misc.gotsig )
|
||||||
#define trap (G_misc.trap )
|
#define trap (G_misc.trap )
|
||||||
#define trap_ptr (G_misc.trap_ptr )
|
#define trap_ptr (G_misc.trap_ptr )
|
||||||
#define random_galois_LFSR (G_misc.random_galois_LFSR)
|
#define random_gen (G_misc.random_gen )
|
||||||
#define random_LCG (G_misc.random_LCG )
|
|
||||||
#define backgndpid (G_misc.backgndpid )
|
#define backgndpid (G_misc.backgndpid )
|
||||||
#define job_warning (G_misc.job_warning)
|
#define job_warning (G_misc.job_warning)
|
||||||
#define INIT_G_misc() do { \
|
#define INIT_G_misc() do { \
|
||||||
@ -10075,28 +10075,18 @@ change_random(const char *value)
|
|||||||
/* Another example - taps at 32 31 30 10: */
|
/* Another example - taps at 32 31 30 10: */
|
||||||
/* MASK = 0x00400007 */
|
/* MASK = 0x00400007 */
|
||||||
|
|
||||||
|
uint32_t t;
|
||||||
|
|
||||||
if (value == NULL) {
|
if (value == NULL) {
|
||||||
/* "get", generate */
|
/* "get", generate */
|
||||||
uint32_t t;
|
t = next_random(&random_gen);
|
||||||
|
|
||||||
/* LCG has period of 2^32 and alternating lowest bit */
|
|
||||||
random_LCG = 1664525 * random_LCG + 1013904223;
|
|
||||||
/* Galois LFSR has period of 2^32-1 = 3 * 5 * 17 * 257 * 65537 */
|
|
||||||
t = (random_galois_LFSR << 1);
|
|
||||||
if (random_galois_LFSR < 0) /* if we just shifted 1 out of msb... */
|
|
||||||
t ^= MASK;
|
|
||||||
random_galois_LFSR = t;
|
|
||||||
/* Both are weak, combining them gives better randomness
|
|
||||||
* and ~2^64 period. & 0x7fff is probably bash compat
|
|
||||||
* for $RANDOM range. Combining with subtraction is
|
|
||||||
* just for fun. + and ^ would work equally well. */
|
|
||||||
t = (t - random_LCG) & 0x7fff;
|
|
||||||
/* set without recursion */
|
/* set without recursion */
|
||||||
setvar(vrandom.text, utoa(t), VNOFUNC);
|
setvar(vrandom.text, utoa(t), VNOFUNC);
|
||||||
vrandom.flags &= ~VNOFUNC;
|
vrandom.flags &= ~VNOFUNC;
|
||||||
} else {
|
} else {
|
||||||
/* set/reset */
|
/* set/reset */
|
||||||
random_galois_LFSR = random_LCG = strtoul(value, NULL, 10);
|
t = strtoul(value, NULL, 10);
|
||||||
|
INIT_RANDOM_T(&random_gen, (t ? t : 1), t);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -13271,7 +13261,7 @@ int ash_main(int argc UNUSED_PARAM, char **argv)
|
|||||||
#if ENABLE_ASH_RANDOM_SUPPORT
|
#if ENABLE_ASH_RANDOM_SUPPORT
|
||||||
/* Can use monotonic_ns() for better randomness but for now it is
|
/* Can use monotonic_ns() for better randomness but for now it is
|
||||||
* not used anywhere else in busybox... so avoid bloat */
|
* not used anywhere else in busybox... so avoid bloat */
|
||||||
random_galois_LFSR = random_LCG = rootpid + monotonic_us();
|
INIT_RANDOM_T(&random_gen, rootpid, monotonic_us());
|
||||||
#endif
|
#endif
|
||||||
init();
|
init();
|
||||||
setstackmark(&smark);
|
setstackmark(&smark);
|
||||||
|
37
shell/random.c
Normal file
37
shell/random.c
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
/* vi: set sw=4 ts=4: */
|
||||||
|
/*
|
||||||
|
* $RANDOM support.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2008 Denys Vlasenko
|
||||||
|
*
|
||||||
|
* Licensed under GPLv2, see file LICENSE in this tarball for details.
|
||||||
|
*/
|
||||||
|
#include "libbb.h"
|
||||||
|
#include "random.h"
|
||||||
|
|
||||||
|
uint32_t FAST_FUNC
|
||||||
|
next_random(random_t *rnd)
|
||||||
|
{
|
||||||
|
/* Galois LFSR parameter */
|
||||||
|
/* Taps at 32 31 29 1: */
|
||||||
|
enum { MASK = 0x8000000b };
|
||||||
|
/* Another example - taps at 32 31 30 10: */
|
||||||
|
/* MASK = 0x00400007 */
|
||||||
|
|
||||||
|
uint32_t t;
|
||||||
|
|
||||||
|
/* LCG has period of 2^32 and alternating lowest bit */
|
||||||
|
rnd->LCG = 1664525 * rnd->LCG + 1013904223;
|
||||||
|
/* Galois LFSR has period of 2^32-1 = 3 * 5 * 17 * 257 * 65537 */
|
||||||
|
t = (rnd->galois_LFSR << 1);
|
||||||
|
if (rnd->galois_LFSR < 0) /* if we just shifted 1 out of msb... */
|
||||||
|
t ^= MASK;
|
||||||
|
rnd->galois_LFSR = t;
|
||||||
|
/* Both are weak, combining them gives better randomness
|
||||||
|
* and ~2^64 period. & 0x7fff is probably bash compat
|
||||||
|
* for $RANDOM range. Combining with subtraction is
|
||||||
|
* just for fun. + and ^ would work equally well. */
|
||||||
|
t = (t - rnd->LCG) & 0x7fff;
|
||||||
|
|
||||||
|
return t;
|
||||||
|
}
|
19
shell/random.h
Normal file
19
shell/random.h
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
/* vi: set sw=4 ts=4: */
|
||||||
|
/*
|
||||||
|
* $RANDOM support.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2008 Denys Vlasenko
|
||||||
|
*
|
||||||
|
* Licensed under GPLv2, see file LICENSE in this tarball for details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef struct random_t {
|
||||||
|
/* Random number generators */
|
||||||
|
int32_t galois_LFSR; /* Galois LFSR (fast but weak). signed! */
|
||||||
|
uint32_t LCG; /* LCG (fast but weak) */
|
||||||
|
} random_t;
|
||||||
|
|
||||||
|
#define INIT_RANDOM_T(rnd, nonzero, v) \
|
||||||
|
((rnd)->galois_LFSR = (nonzero), (rnd)->LCG = (v))
|
||||||
|
|
||||||
|
uint32_t next_random(random_t *rnd) FAST_FUNC;
|
Loading…
x
Reference in New Issue
Block a user