diff options
| author | chasonr <[email protected]> | 2014-02-25 00:06:31 -0500 |
|---|---|---|
| committer | chasonr <[email protected]> | 2014-02-25 00:06:31 -0500 |
| commit | 7c9ff7c8ff118a1d3cdd1cae5ea9b4bbfac8cefb (patch) | |
| tree | 62d029f6fced07e4a1b1d7a820ac5bf76fbcb70d /mrbgems/mruby-random/src | |
| parent | ebd976be842c0c16be855e7f9d7cea71a95311f0 (diff) | |
| download | mruby-7c9ff7c8ff118a1d3cdd1cae5ea9b4bbfac8cefb.tar.gz mruby-7c9ff7c8ff118a1d3cdd1cae5ea9b4bbfac8cefb.zip | |
Implement default Random instance.
Previously, the default random number generator was implemented using static
storage. This storage is common to all instances of mruby in a process, and
use of the default random number generator in one instance will perturb the
default random number generator in other instances. It is also not thread
safe.
With this change, the default random number generator is defined as
Random::DEFAULT, as it is in CRuby.
Diffstat (limited to 'mrbgems/mruby-random/src')
| -rw-r--r-- | mrbgems/mruby-random/src/mt19937ar.c | 4 | ||||
| -rw-r--r-- | mrbgems/mruby-random/src/random.c | 99 |
2 files changed, 24 insertions, 79 deletions
diff --git a/mrbgems/mruby-random/src/mt19937ar.c b/mrbgems/mruby-random/src/mt19937ar.c index 2c22b23ad..b237af56d 100644 --- a/mrbgems/mruby-random/src/mt19937ar.c +++ b/mrbgems/mruby-random/src/mt19937ar.c @@ -14,8 +14,10 @@ #define UPPER_MASK 0x80000000UL /* most significant w-r bits */ #define LOWER_MASK 0x7fffffffUL /* least significant r bits */ +#if 0 /* dead_code */ static unsigned long mt[N]; /* the array for the state vector */ static int mti=N+1; /* mti==N+1 means mt[N] is not initialized */ +#endif /* dead_code */ void mrb_random_init_genrand(mt_state *t, unsigned long s) { @@ -74,6 +76,7 @@ double mrb_random_genrand_real1(mt_state *t) /* divided by 2^32-1 */ } +#if 0 /* dead_code */ /* initializes mt[N] with a seed */ void init_genrand(unsigned long s) { @@ -191,3 +194,4 @@ double genrand_res53(void) return(a*67108864.0+b)*(1.0/9007199254740992.0); } /* These real versions are due to Isaku Wada, 2002/01/09 added */ +#endif /* dead_code */ diff --git a/mrbgems/mruby-random/src/random.c b/mrbgems/mruby-random/src/random.c index ac8f24a18..a708923d3 100644 --- a/mrbgems/mruby-random/src/random.c +++ b/mrbgems/mruby-random/src/random.c @@ -20,51 +20,9 @@ static const struct mrb_data_type mt_state_type = { MT_STATE_KEY, mrb_free, }; -static void mt_g_srand(unsigned long seed) -{ - init_genrand(seed); -} +static mrb_value mrb_random_rand(mrb_state *mrb, mrb_value self); +static mrb_value mrb_random_srand(mrb_state *mrb, mrb_value self); -static unsigned long mt_g_rand(void) -{ - return genrand_int32(); -} - -static double mt_g_rand_real(void) -{ - return genrand_real1(); -} - -static mrb_value -mrb_random_mt_g_srand(mrb_state *mrb, mrb_value seed) -{ - if (mrb_nil_p(seed)) { - seed = mrb_fixnum_value(time(NULL) + mt_g_rand()); - if (mrb_fixnum(seed) < 0) { - seed = mrb_fixnum_value( 0 - mrb_fixnum(seed)); - } - } - - mt_g_srand((unsigned) mrb_fixnum(seed)); - - return seed; -} - -static mrb_value -mrb_random_mt_g_rand(mrb_state *mrb, mrb_value max) -{ - mrb_value value; - - if (mrb_fixnum(max) == 0) { - value = mrb_float_value(mrb, mt_g_rand_real()); - } - else { - value = mrb_fixnum_value(mt_g_rand() % mrb_fixnum(max)); - } - - return value; -} - static void mt_srand(mt_state *t, unsigned long seed) { @@ -133,38 +91,22 @@ get_opt(mrb_state* mrb) return arg; } -static void -mrb_random_g_rand_seed(mrb_state *mrb) -{ - mrb_value seed; - - seed = mrb_gv_get(mrb, mrb_intern_lit(mrb, GLOBAL_RAND_SEED_KEY)); - if (mrb_nil_p(seed)) { - mrb_random_mt_g_srand(mrb, mrb_nil_value()); - } -} - static mrb_value mrb_random_g_rand(mrb_state *mrb, mrb_value self) { - mrb_value max; - - max = get_opt(mrb); - mrb_random_g_rand_seed(mrb); - return mrb_random_mt_g_rand(mrb, max); + mrb_value random = mrb_const_get(mrb, + mrb_obj_value(mrb_class_get(mrb, "Random")), + mrb_intern_lit(mrb, "DEFAULT")); + return mrb_random_rand(mrb, random); } static mrb_value mrb_random_g_srand(mrb_state *mrb, mrb_value self) { - mrb_value seed; - mrb_value old_seed; - - seed = get_opt(mrb); - seed = mrb_random_mt_g_srand(mrb, seed); - old_seed = mrb_gv_get(mrb, mrb_intern_lit(mrb, GLOBAL_RAND_SEED_KEY)); - mrb_gv_set(mrb, mrb_intern_lit(mrb, GLOBAL_RAND_SEED_KEY), seed); - return old_seed; + mrb_value random = mrb_const_get(mrb, + mrb_obj_value(mrb_class_get(mrb, "Random")), + mrb_intern_lit(mrb, "DEFAULT")); + return mrb_random_srand(mrb, random); } static mrb_value @@ -258,12 +200,13 @@ mrb_ary_shuffle_bang(mrb_state *mrb, mrb_value ary) if (RARRAY_LEN(ary) > 1) { mrb_get_args(mrb, "|d", &random, &mt_state_type); - if (random) { - mrb_random_rand_seed(mrb, random); - } - else { - mrb_random_g_rand_seed(mrb); + if (random == NULL) { + mrb_value random_val = mrb_const_get(mrb, + mrb_obj_value(mrb_class_get(mrb, "Random")), + mrb_intern_lit(mrb, "DEFAULT")); + random = (mt_state *)DATA_PTR(random_val); } + mrb_random_rand_seed(mrb, random); mrb_ary_modify(mrb, mrb_ary_ptr(ary)); @@ -271,12 +214,7 @@ mrb_ary_shuffle_bang(mrb_state *mrb, mrb_value ary) mrb_int j; mrb_value tmp; - if (random) { - j = mrb_fixnum(mrb_random_mt_rand(mrb, random, mrb_fixnum_value(RARRAY_LEN(ary)))); - } - else { - j = mrb_fixnum(mrb_random_mt_g_rand(mrb, mrb_fixnum_value(RARRAY_LEN(ary)))); - } + j = mrb_fixnum(mrb_random_mt_rand(mrb, random, mrb_fixnum_value(RARRAY_LEN(ary)))); tmp = RARRAY_PTR(ary)[i]; RARRAY_PTR(ary)[i] = RARRAY_PTR(ary)[j]; @@ -322,6 +260,9 @@ void mrb_mruby_random_gem_init(mrb_state *mrb) mrb_define_method(mrb, array, "shuffle", mrb_ary_shuffle, MRB_ARGS_OPT(1)); mrb_define_method(mrb, array, "shuffle!", mrb_ary_shuffle_bang, MRB_ARGS_OPT(1)); + + mrb_const_set(mrb, mrb_obj_value(random), mrb_intern_lit(mrb, "DEFAULT"), + mrb_obj_new(mrb, random, 0, NULL)); } void mrb_mruby_random_gem_final(mrb_state *mrb) |
