summaryrefslogtreecommitdiffhomepage
path: root/mrbgems/mruby-random/src/random.c
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/mruby-random/src/random.c
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/mruby-random/src/random.c')
-rw-r--r--mrbgems/mruby-random/src/random.c99
1 files changed, 20 insertions, 79 deletions
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)