summaryrefslogtreecommitdiffhomepage
path: root/mrbgems
diff options
context:
space:
mode:
authorchasonr <[email protected]>2014-02-25 00:06:31 -0500
committerchasonr <[email protected]>2014-02-25 00:06:31 -0500
commit7c9ff7c8ff118a1d3cdd1cae5ea9b4bbfac8cefb (patch)
tree62d029f6fced07e4a1b1d7a820ac5bf76fbcb70d /mrbgems
parentebd976be842c0c16be855e7f9d7cea71a95311f0 (diff)
downloadmruby-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')
-rw-r--r--mrbgems/mruby-random/src/mt19937ar.c4
-rw-r--r--mrbgems/mruby-random/src/random.c99
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)