68 |
68 |
69 OSThread* os::_starting_thread = NULL; |
69 OSThread* os::_starting_thread = NULL; |
70 address os::_polling_page = NULL; |
70 address os::_polling_page = NULL; |
71 volatile int32_t* os::_mem_serialize_page = NULL; |
71 volatile int32_t* os::_mem_serialize_page = NULL; |
72 uintptr_t os::_serialize_page_mask = 0; |
72 uintptr_t os::_serialize_page_mask = 0; |
73 long os::_rand_seed = 1; |
73 volatile unsigned int os::_rand_seed = 1; |
74 int os::_processor_count = 0; |
74 int os::_processor_count = 0; |
75 int os::_initial_active_processor_count = 0; |
75 int os::_initial_active_processor_count = 0; |
76 size_t os::_page_sizes[os::page_sizes_max]; |
76 size_t os::_page_sizes[os::page_sizes_max]; |
77 |
77 |
78 #ifndef PRODUCT |
78 #ifndef PRODUCT |
720 void* membase = MemTracker::record_free(memblock); |
720 void* membase = MemTracker::record_free(memblock); |
721 ::free(membase); |
721 ::free(membase); |
722 #endif |
722 #endif |
723 } |
723 } |
724 |
724 |
725 void os::init_random(long initval) { |
725 void os::init_random(unsigned int initval) { |
726 _rand_seed = initval; |
726 _rand_seed = initval; |
727 } |
727 } |
728 |
728 |
729 |
729 |
730 long os::random() { |
730 static int random_helper(unsigned int rand_seed) { |
731 /* standard, well-known linear congruential random generator with |
731 /* standard, well-known linear congruential random generator with |
732 * next_rand = (16807*seed) mod (2**31-1) |
732 * next_rand = (16807*seed) mod (2**31-1) |
733 * see |
733 * see |
734 * (1) "Random Number Generators: Good Ones Are Hard to Find", |
734 * (1) "Random Number Generators: Good Ones Are Hard to Find", |
735 * S.K. Park and K.W. Miller, Communications of the ACM 31:10 (Oct 1988), |
735 * S.K. Park and K.W. Miller, Communications of the ACM 31:10 (Oct 1988), |
736 * (2) "Two Fast Implementations of the 'Minimal Standard' Random |
736 * (2) "Two Fast Implementations of the 'Minimal Standard' Random |
737 * Number Generator", David G. Carta, Comm. ACM 33, 1 (Jan 1990), pp. 87-88. |
737 * Number Generator", David G. Carta, Comm. ACM 33, 1 (Jan 1990), pp. 87-88. |
738 */ |
738 */ |
739 const long a = 16807; |
739 const unsigned int a = 16807; |
740 const unsigned long m = 2147483647; |
740 const unsigned int m = 2147483647; |
741 const long q = m / a; assert(q == 127773, "weird math"); |
741 const int q = m / a; assert(q == 127773, "weird math"); |
742 const long r = m % a; assert(r == 2836, "weird math"); |
742 const int r = m % a; assert(r == 2836, "weird math"); |
743 |
743 |
744 // compute az=2^31p+q |
744 // compute az=2^31p+q |
745 unsigned long lo = a * (long)(_rand_seed & 0xFFFF); |
745 unsigned int lo = a * (rand_seed & 0xFFFF); |
746 unsigned long hi = a * (long)((unsigned long)_rand_seed >> 16); |
746 unsigned int hi = a * (rand_seed >> 16); |
747 lo += (hi & 0x7FFF) << 16; |
747 lo += (hi & 0x7FFF) << 16; |
748 |
748 |
749 // if q overflowed, ignore the overflow and increment q |
749 // if q overflowed, ignore the overflow and increment q |
750 if (lo > m) { |
750 if (lo > m) { |
751 lo &= m; |
751 lo &= m; |
756 // if (p+q) overflowed, ignore the overflow and increment (p+q) |
756 // if (p+q) overflowed, ignore the overflow and increment (p+q) |
757 if (lo > m) { |
757 if (lo > m) { |
758 lo &= m; |
758 lo &= m; |
759 ++lo; |
759 ++lo; |
760 } |
760 } |
761 return (_rand_seed = lo); |
761 return lo; |
|
762 } |
|
763 |
|
764 int os::random() { |
|
765 // Make updating the random seed thread safe. |
|
766 while (true) { |
|
767 unsigned int seed = _rand_seed; |
|
768 int rand = random_helper(seed); |
|
769 if (Atomic::cmpxchg(rand, &_rand_seed, seed) == seed) { |
|
770 return rand; |
|
771 } |
|
772 } |
762 } |
773 } |
763 |
774 |
764 // The INITIALIZED state is distinguished from the SUSPENDED state because the |
775 // The INITIALIZED state is distinguished from the SUSPENDED state because the |
765 // conditions in which a thread is first started are different from those in which |
776 // conditions in which a thread is first started are different from those in which |
766 // a suspension is resumed. These differences make it hard for us to apply the |
777 // a suspension is resumed. These differences make it hard for us to apply the |
1127 if (old_fp - ufp > 64 * K) return true; |
1138 if (old_fp - ufp > 64 * K) return true; |
1128 |
1139 |
1129 return false; |
1140 return false; |
1130 #endif |
1141 #endif |
1131 } |
1142 } |
1132 |
|
1133 #ifdef ASSERT |
|
1134 extern "C" void test_random() { |
|
1135 const double m = 2147483647; |
|
1136 double mean = 0.0, variance = 0.0, t; |
|
1137 long reps = 10000; |
|
1138 unsigned long seed = 1; |
|
1139 |
|
1140 tty->print_cr("seed %ld for %ld repeats...", seed, reps); |
|
1141 os::init_random(seed); |
|
1142 long num; |
|
1143 for (int k = 0; k < reps; k++) { |
|
1144 num = os::random(); |
|
1145 double u = (double)num / m; |
|
1146 assert(u >= 0.0 && u <= 1.0, "bad random number!"); |
|
1147 |
|
1148 // calculate mean and variance of the random sequence |
|
1149 mean += u; |
|
1150 variance += (u*u); |
|
1151 } |
|
1152 mean /= reps; |
|
1153 variance /= (reps - 1); |
|
1154 |
|
1155 assert(num == 1043618065, "bad seed"); |
|
1156 tty->print_cr("mean of the 1st 10000 numbers: %f", mean); |
|
1157 tty->print_cr("variance of the 1st 10000 numbers: %f", variance); |
|
1158 const double eps = 0.0001; |
|
1159 t = fabsd(mean - 0.5018); |
|
1160 assert(t < eps, "bad mean"); |
|
1161 t = (variance - 0.3355) < 0.0 ? -(variance - 0.3355) : variance - 0.3355; |
|
1162 assert(t < eps, "bad variance"); |
|
1163 } |
|
1164 #endif |
|
1165 |
1143 |
1166 |
1144 |
1167 // Set up the boot classpath. |
1145 // Set up the boot classpath. |
1168 |
1146 |
1169 char* os::format_boot_path(const char* format_string, |
1147 char* os::format_boot_path(const char* format_string, |