15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #include "precompiled.hpp"
26 #include "classfile/classLoader.hpp"
27 #include "classfile/javaClasses.hpp"
28 #include "classfile/systemDictionary.hpp"
29 #include "classfile/vmSymbols.hpp"
30 #include "code/icBuffer.hpp"
31 #include "code/vtableStubs.hpp"
32 #include "gc_implementation/shared/vmGCOperations.hpp"
33 #include "interpreter/interpreter.hpp"
34 #include "memory/allocation.inline.hpp"
35 #include "oops/oop.inline.hpp"
36 #include "prims/jvm.h"
37 #include "prims/jvm_misc.hpp"
38 #include "prims/privilegedStack.hpp"
39 #include "runtime/arguments.hpp"
40 #include "runtime/frame.inline.hpp"
41 #include "runtime/interfaceSupport.hpp"
42 #include "runtime/java.hpp"
43 #include "runtime/javaCalls.hpp"
44 #include "runtime/mutexLocker.hpp"
45 #include "runtime/os.hpp"
46 #include "runtime/stubRoutines.hpp"
47 #include "runtime/thread.inline.hpp"
48 #include "services/attachListener.hpp"
49 #include "services/memTracker.hpp"
50 #include "services/threadService.hpp"
51 #include "utilities/defaultStream.hpp"
52 #include "utilities/events.hpp"
53 #ifdef TARGET_OS_FAMILY_linux
54 # include "os_linux.inline.hpp"
506 // Found an entry point like Agent_OnLoad_lib_name so we have a static agent
507 agent_lib->set_valid();
508 agent_lib->set_static_lib(true);
509 return true;
510 }
511 agent_lib->set_os_lib(save_handle);
512 return false;
513 }
514
515 // --------------------- heap allocation utilities ---------------------
516
517 char *os::strdup(const char *str, MEMFLAGS flags) {
518 size_t size = strlen(str);
519 char *dup_str = (char *)malloc(size + 1, flags);
520 if (dup_str == NULL) return NULL;
521 strcpy(dup_str, str);
522 return dup_str;
523 }
524
525
526
527 #ifdef ASSERT
528 #define space_before (MallocCushion + sizeof(double))
529 #define space_after MallocCushion
530 #define size_addr_from_base(p) (size_t*)(p + space_before - sizeof(size_t))
531 #define size_addr_from_obj(p) ((size_t*)p - 1)
532 // MallocCushion: size of extra cushion allocated around objects with +UseMallocOnly
533 // NB: cannot be debug variable, because these aren't set from the command line until
534 // *after* the first few allocs already happened
535 #define MallocCushion 16
536 #else
537 #define space_before 0
538 #define space_after 0
539 #define size_addr_from_base(p) should not use w/o ASSERT
540 #define size_addr_from_obj(p) should not use w/o ASSERT
541 #define MallocCushion 0
542 #endif
543 #define paranoid 0 /* only set to 1 if you suspect checking code has bug */
544
545 #ifdef ASSERT
546 inline size_t get_size(void* obj) {
547 size_t size = *size_addr_from_obj(obj);
548 if (size < 0) {
549 fatal(err_msg("free: size field of object #" PTR_FORMAT " was overwritten ("
550 SIZE_FORMAT ")", obj, size));
551 }
552 return size;
553 }
554
555 u_char* find_cushion_backwards(u_char* start) {
556 u_char* p = start;
557 while (p[ 0] != badResourceValue || p[-1] != badResourceValue ||
558 p[-2] != badResourceValue || p[-3] != badResourceValue) p--;
559 // ok, we have four consecutive marker bytes; find start
560 u_char* q = p - 4;
561 while (*q == badResourceValue) q--;
562 return q + 1;
563 }
564
565 u_char* find_cushion_forwards(u_char* start) {
566 u_char* p = start;
567 while (p[0] != badResourceValue || p[1] != badResourceValue ||
568 p[2] != badResourceValue || p[3] != badResourceValue) p++;
569 // ok, we have four consecutive marker bytes; find end of cushion
570 u_char* q = p + 4;
571 while (*q == badResourceValue) q++;
572 return q - MallocCushion;
573 }
574
575 void print_neighbor_blocks(void* ptr) {
576 // find block allocated before ptr (not entirely crash-proof)
577 if (MallocCushion < 4) {
578 tty->print_cr("### cannot find previous block (MallocCushion < 4)");
579 return;
580 }
581 u_char* start_of_this_block = (u_char*)ptr - space_before;
582 u_char* end_of_prev_block_data = start_of_this_block - space_after -1;
583 // look for cushion in front of prev. block
584 u_char* start_of_prev_block = find_cushion_backwards(end_of_prev_block_data);
585 ptrdiff_t size = *size_addr_from_base(start_of_prev_block);
586 u_char* obj = start_of_prev_block + space_before;
587 if (size <= 0 ) {
588 // start is bad; may have been confused by OS data in between objects
589 // search one more backwards
590 start_of_prev_block = find_cushion_backwards(start_of_prev_block);
591 size = *size_addr_from_base(start_of_prev_block);
592 obj = start_of_prev_block + space_before;
593 }
594
595 if (start_of_prev_block + space_before + size + space_after == start_of_this_block) {
596 tty->print_cr("### previous object: " PTR_FORMAT " (" SSIZE_FORMAT " bytes)", obj, size);
597 } else {
598 tty->print_cr("### previous object (not sure if correct): " PTR_FORMAT " (" SSIZE_FORMAT " bytes)", obj, size);
599 }
600
601 // now find successor block
602 u_char* start_of_next_block = (u_char*)ptr + *size_addr_from_obj(ptr) + space_after;
603 start_of_next_block = find_cushion_forwards(start_of_next_block);
604 u_char* next_obj = start_of_next_block + space_before;
605 ptrdiff_t next_size = *size_addr_from_base(start_of_next_block);
606 if (start_of_next_block[0] == badResourceValue &&
607 start_of_next_block[1] == badResourceValue &&
608 start_of_next_block[2] == badResourceValue &&
609 start_of_next_block[3] == badResourceValue) {
610 tty->print_cr("### next object: " PTR_FORMAT " (" SSIZE_FORMAT " bytes)", next_obj, next_size);
611 } else {
612 tty->print_cr("### next object (not sure if correct): " PTR_FORMAT " (" SSIZE_FORMAT " bytes)", next_obj, next_size);
613 }
614 }
615
616
617 void report_heap_error(void* memblock, void* bad, const char* where) {
618 tty->print_cr("## nof_mallocs = " UINT64_FORMAT ", nof_frees = " UINT64_FORMAT, os::num_mallocs, os::num_frees);
619 tty->print_cr("## memory stomp: byte at " PTR_FORMAT " %s object " PTR_FORMAT, bad, where, memblock);
620 print_neighbor_blocks(memblock);
621 fatal("memory stomping error");
622 }
623
624 void verify_block(void* memblock) {
625 size_t size = get_size(memblock);
626 if (MallocCushion) {
627 u_char* ptr = (u_char*)memblock - space_before;
628 for (int i = 0; i < MallocCushion; i++) {
629 if (ptr[i] != badResourceValue) {
630 report_heap_error(memblock, ptr+i, "in front of");
631 }
632 }
633 u_char* end = (u_char*)memblock + size + space_after;
634 for (int j = -MallocCushion; j < 0; j++) {
635 if (end[j] != badResourceValue) {
636 report_heap_error(memblock, end+j, "after");
637 }
638 }
639 }
640 }
641 #endif
642
643 //
644 // This function supports testing of the malloc out of memory
645 // condition without really running the system out of memory.
646 //
647 static u_char* testMalloc(size_t alloc_size) {
648 assert(MallocMaxTestWords > 0, "sanity check");
649
650 if ((cur_malloc_words + (alloc_size / BytesPerWord)) > MallocMaxTestWords) {
651 return NULL;
652 }
653
654 u_char* ptr = (u_char*)::malloc(alloc_size);
655
656 if (ptr != NULL) {
657 Atomic::add(((jint) (alloc_size / BytesPerWord)),
658 (volatile jint *) &cur_malloc_words);
659 }
660 return ptr;
669 // since os::malloc can be called when the libjvm.{dll,so} is
670 // first loaded and we don't have a thread yet.
671 // try to find the thread after we see that the watcher thread
672 // exists and has crash protection.
673 WatcherThread *wt = WatcherThread::watcher_thread();
674 if (wt != NULL && wt->has_crash_protection()) {
675 Thread* thread = ThreadLocalStorage::get_thread_slow();
676 if (thread == wt) {
677 assert(!wt->has_crash_protection(),
678 "Can't malloc with crash protection from WatcherThread");
679 }
680 }
681 #endif
682
683 if (size == 0) {
684 // return a valid pointer if size is zero
685 // if NULL is returned the calling functions assume out of memory.
686 size = 1;
687 }
688
689 const size_t alloc_size = size + space_before + space_after;
690
691 if (size > alloc_size) { // Check for rollover.
692 return NULL;
693 }
694
695 NOT_PRODUCT(if (MallocVerifyInterval > 0) check_heap());
696
697 u_char* ptr;
698
699 if (MallocMaxTestWords > 0) {
700 ptr = testMalloc(alloc_size);
701 } else {
702 ptr = (u_char*)::malloc(alloc_size);
703 }
704
705 #ifdef ASSERT
706 if (ptr == NULL) return NULL;
707 if (MallocCushion) {
708 for (u_char* p = ptr; p < ptr + MallocCushion; p++) *p = (u_char)badResourceValue;
709 u_char* end = ptr + space_before + size;
710 for (u_char* pq = ptr+MallocCushion; pq < end; pq++) *pq = (u_char)uninitBlockPad;
711 for (u_char* q = end; q < end + MallocCushion; q++) *q = (u_char)badResourceValue;
712 }
713 // put size just before data
714 *size_addr_from_base(ptr) = size;
715 #endif
716 u_char* memblock = ptr + space_before;
717 if ((intptr_t)memblock == (intptr_t)MallocCatchPtr) {
718 tty->print_cr("os::malloc caught, " SIZE_FORMAT " bytes --> " PTR_FORMAT, size, memblock);
719 breakpoint();
720 }
721 debug_only(if (paranoid) verify_block(memblock));
722 if (PrintMalloc && tty != NULL) tty->print_cr("os::malloc " SIZE_FORMAT " bytes --> " PTR_FORMAT, size, memblock);
723
724 // we do not track MallocCushion memory
725 MemTracker::record_malloc((address)memblock, size, memflags, caller == 0 ? CALLER_PC : caller);
726
727 return memblock;
728 }
729
730
731 void* os::realloc(void *memblock, size_t size, MEMFLAGS memflags, address caller) {
732 #ifndef ASSERT
733 NOT_PRODUCT(inc_stat_counter(&num_mallocs, 1));
734 NOT_PRODUCT(inc_stat_counter(&alloc_bytes, size));
735 MemTracker::Tracker tkr = MemTracker::get_realloc_tracker();
736 void* ptr = ::realloc(memblock, size);
737 if (ptr != NULL) {
738 tkr.record((address)memblock, (address)ptr, size, memflags,
739 caller == 0 ? CALLER_PC : caller);
740 } else {
741 tkr.discard();
742 }
743 return ptr;
744 #else
745 if (memblock == NULL) {
746 return malloc(size, memflags, (caller == 0 ? CALLER_PC : caller));
747 }
748 if ((intptr_t)memblock == (intptr_t)MallocCatchPtr) {
749 tty->print_cr("os::realloc caught " PTR_FORMAT, memblock);
750 breakpoint();
751 }
752 verify_block(memblock);
753 NOT_PRODUCT(if (MallocVerifyInterval > 0) check_heap());
754 if (size == 0) return NULL;
755 // always move the block
756 void* ptr = malloc(size, memflags, caller == 0 ? CALLER_PC : caller);
757 if (PrintMalloc) tty->print_cr("os::remalloc " SIZE_FORMAT " bytes, " PTR_FORMAT " --> " PTR_FORMAT, size, memblock, ptr);
758 // Copy to new memory if malloc didn't fail
759 if ( ptr != NULL ) {
760 memcpy(ptr, memblock, MIN2(size, get_size(memblock)));
761 if (paranoid) verify_block(ptr);
762 if ((intptr_t)ptr == (intptr_t)MallocCatchPtr) {
763 tty->print_cr("os::realloc caught, " SIZE_FORMAT " bytes --> " PTR_FORMAT, size, ptr);
764 breakpoint();
765 }
766 free(memblock);
767 }
768 return ptr;
769 #endif
770 }
771
772
773 void os::free(void *memblock, MEMFLAGS memflags) {
774 NOT_PRODUCT(inc_stat_counter(&num_frees, 1));
775 #ifdef ASSERT
776 if (memblock == NULL) return;
777 if ((intptr_t)memblock == (intptr_t)MallocCatchPtr) {
778 if (tty != NULL) tty->print_cr("os::free caught " PTR_FORMAT, memblock);
779 breakpoint();
780 }
781 verify_block(memblock);
782 NOT_PRODUCT(if (MallocVerifyInterval > 0) check_heap());
783 // Added by detlefs.
784 if (MallocCushion) {
785 u_char* ptr = (u_char*)memblock - space_before;
786 for (u_char* p = ptr; p < ptr + MallocCushion; p++) {
787 guarantee(*p == badResourceValue,
788 "Thing freed should be malloc result.");
789 *p = (u_char)freeBlockPad;
790 }
791 size_t size = get_size(memblock);
792 inc_stat_counter(&free_bytes, size);
793 u_char* end = ptr + space_before + size;
794 for (u_char* q = end; q < end + MallocCushion; q++) {
795 guarantee(*q == badResourceValue,
796 "Thing freed should be malloc result.");
797 *q = (u_char)freeBlockPad;
798 }
799 if (PrintMalloc && tty != NULL)
800 fprintf(stderr, "os::free " SIZE_FORMAT " bytes --> " PTR_FORMAT "\n", size, (uintptr_t)memblock);
801 } else if (PrintMalloc && tty != NULL) {
802 // tty->print_cr("os::free %p", memblock);
803 fprintf(stderr, "os::free " PTR_FORMAT "\n", (uintptr_t)memblock);
804 }
805 #endif
806 MemTracker::record_free((address)memblock, memflags);
807
808 ::free((char*)memblock - space_before);
809 }
810
811 void os::init_random(long initval) {
812 _rand_seed = initval;
813 }
814
815
816 long os::random() {
817 /* standard, well-known linear congruential random generator with
818 * next_rand = (16807*seed) mod (2**31-1)
819 * see
820 * (1) "Random Number Generators: Good Ones Are Hard to Find",
821 * S.K. Park and K.W. Miller, Communications of the ACM 31:10 (Oct 1988),
822 * (2) "Two Fast Implementations of the 'Minimal Standard' Random
823 * Number Generator", David G. Carta, Comm. ACM 33, 1 (Jan 1990), pp. 87-88.
824 */
825 const long a = 16807;
826 const unsigned long m = 2147483647;
827 const long q = m / a; assert(q == 127773, "weird math");
828 const long r = m % a; assert(r == 2836, "weird math");
|
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #include "precompiled.hpp"
26 #include "classfile/classLoader.hpp"
27 #include "classfile/javaClasses.hpp"
28 #include "classfile/systemDictionary.hpp"
29 #include "classfile/vmSymbols.hpp"
30 #include "code/icBuffer.hpp"
31 #include "code/vtableStubs.hpp"
32 #include "gc_implementation/shared/vmGCOperations.hpp"
33 #include "interpreter/interpreter.hpp"
34 #include "memory/allocation.inline.hpp"
35 #ifdef ASSERT
36 #include "memory/guardedMemory.hpp"
37 #endif
38 #include "oops/oop.inline.hpp"
39 #include "prims/jvm.h"
40 #include "prims/jvm_misc.hpp"
41 #include "prims/privilegedStack.hpp"
42 #include "runtime/arguments.hpp"
43 #include "runtime/frame.inline.hpp"
44 #include "runtime/interfaceSupport.hpp"
45 #include "runtime/java.hpp"
46 #include "runtime/javaCalls.hpp"
47 #include "runtime/mutexLocker.hpp"
48 #include "runtime/os.hpp"
49 #include "runtime/stubRoutines.hpp"
50 #include "runtime/thread.inline.hpp"
51 #include "services/attachListener.hpp"
52 #include "services/memTracker.hpp"
53 #include "services/threadService.hpp"
54 #include "utilities/defaultStream.hpp"
55 #include "utilities/events.hpp"
56 #ifdef TARGET_OS_FAMILY_linux
57 # include "os_linux.inline.hpp"
509 // Found an entry point like Agent_OnLoad_lib_name so we have a static agent
510 agent_lib->set_valid();
511 agent_lib->set_static_lib(true);
512 return true;
513 }
514 agent_lib->set_os_lib(save_handle);
515 return false;
516 }
517
518 // --------------------- heap allocation utilities ---------------------
519
520 char *os::strdup(const char *str, MEMFLAGS flags) {
521 size_t size = strlen(str);
522 char *dup_str = (char *)malloc(size + 1, flags);
523 if (dup_str == NULL) return NULL;
524 strcpy(dup_str, str);
525 return dup_str;
526 }
527
528
529 #define paranoid 0 /* only set to 1 if you suspect checking code has bug */
530
531 #ifdef ASSERT
532
533 static void verify_memory(void* ptr) {
534 GuardedMemory guarded(ptr);
535 if (!guarded.verify_guards()) {
536 tty->print_cr("## nof_mallocs = " UINT64_FORMAT ", nof_frees = " UINT64_FORMAT, os::num_mallocs, os::num_frees);
537 tty->print_cr("## memory stomp:");
538 guarded.print_on(tty);
539 fatal("memory stomping error");
540 }
541 }
542
543 #endif
544
545 //
546 // This function supports testing of the malloc out of memory
547 // condition without really running the system out of memory.
548 //
549 static u_char* testMalloc(size_t alloc_size) {
550 assert(MallocMaxTestWords > 0, "sanity check");
551
552 if ((cur_malloc_words + (alloc_size / BytesPerWord)) > MallocMaxTestWords) {
553 return NULL;
554 }
555
556 u_char* ptr = (u_char*)::malloc(alloc_size);
557
558 if (ptr != NULL) {
559 Atomic::add(((jint) (alloc_size / BytesPerWord)),
560 (volatile jint *) &cur_malloc_words);
561 }
562 return ptr;
571 // since os::malloc can be called when the libjvm.{dll,so} is
572 // first loaded and we don't have a thread yet.
573 // try to find the thread after we see that the watcher thread
574 // exists and has crash protection.
575 WatcherThread *wt = WatcherThread::watcher_thread();
576 if (wt != NULL && wt->has_crash_protection()) {
577 Thread* thread = ThreadLocalStorage::get_thread_slow();
578 if (thread == wt) {
579 assert(!wt->has_crash_protection(),
580 "Can't malloc with crash protection from WatcherThread");
581 }
582 }
583 #endif
584
585 if (size == 0) {
586 // return a valid pointer if size is zero
587 // if NULL is returned the calling functions assume out of memory.
588 size = 1;
589 }
590
591 #ifndef ASSERT
592 const size_t alloc_size = size;
593 #else
594 const size_t alloc_size = GuardedMemory::get_total_size(size);
595 if (size > alloc_size) { // Check for rollover.
596 return NULL;
597 }
598 #endif
599
600 NOT_PRODUCT(if (MallocVerifyInterval > 0) check_heap());
601
602 u_char* ptr;
603 if (MallocMaxTestWords > 0) {
604 ptr = testMalloc(alloc_size);
605 } else {
606 ptr = (u_char*)::malloc(alloc_size);
607 }
608
609 #ifdef ASSERT
610 if (ptr == NULL) {
611 return NULL;
612 }
613 // Wrap memory with guard
614 GuardedMemory guarded(ptr, size);
615 ptr = guarded.get_user_ptr();
616 #endif
617 if ((intptr_t)ptr == (intptr_t)MallocCatchPtr) {
618 tty->print_cr("os::malloc caught, " SIZE_FORMAT " bytes --> " PTR_FORMAT, size, ptr);
619 breakpoint();
620 }
621 debug_only(if (paranoid) verify_memory(ptr));
622 if (PrintMalloc && tty != NULL) {
623 tty->print_cr("os::malloc " SIZE_FORMAT " bytes --> " PTR_FORMAT, size, ptr);
624 }
625
626 // we do not track guard memory
627 MemTracker::record_malloc((address)ptr, size, memflags, caller == 0 ? CALLER_PC : caller);
628
629 return ptr;
630 }
631
632
633 void* os::realloc(void *memblock, size_t size, MEMFLAGS memflags, address caller) {
634 #ifndef ASSERT
635 NOT_PRODUCT(inc_stat_counter(&num_mallocs, 1));
636 NOT_PRODUCT(inc_stat_counter(&alloc_bytes, size));
637 MemTracker::Tracker tkr = MemTracker::get_realloc_tracker();
638 void* ptr = ::realloc(memblock, size);
639 if (ptr != NULL) {
640 tkr.record((address)memblock, (address)ptr, size, memflags,
641 caller == 0 ? CALLER_PC : caller);
642 } else {
643 tkr.discard();
644 }
645 return ptr;
646 #else
647 if (memblock == NULL) {
648 return os::malloc(size, memflags, (caller == 0 ? CALLER_PC : caller));
649 }
650 if ((intptr_t)memblock == (intptr_t)MallocCatchPtr) {
651 tty->print_cr("os::realloc caught " PTR_FORMAT, memblock);
652 breakpoint();
653 }
654 verify_memory(memblock);
655 NOT_PRODUCT(if (MallocVerifyInterval > 0) check_heap());
656 if (size == 0) {
657 return NULL;
658 }
659 // always move the block
660 void* ptr = os::malloc(size, memflags, caller == 0 ? CALLER_PC : caller);
661 if (PrintMalloc) {
662 tty->print_cr("os::remalloc " SIZE_FORMAT " bytes, " PTR_FORMAT " --> " PTR_FORMAT, size, memblock, ptr);
663 }
664 // Copy to new memory if malloc didn't fail
665 if ( ptr != NULL ) {
666 GuardedMemory guarded(memblock);
667 memcpy(ptr, memblock, MIN2(size, guarded.get_user_size()));
668 if (paranoid) verify_memory(ptr);
669 if ((intptr_t)ptr == (intptr_t)MallocCatchPtr) {
670 tty->print_cr("os::realloc caught, " SIZE_FORMAT " bytes --> " PTR_FORMAT, size, ptr);
671 breakpoint();
672 }
673 os::free(memblock);
674 }
675 return ptr;
676 #endif
677 }
678
679
680 void os::free(void *memblock, MEMFLAGS memflags) {
681 address trackp = (address) memblock;
682 NOT_PRODUCT(inc_stat_counter(&num_frees, 1));
683 #ifdef ASSERT
684 if (memblock == NULL) return;
685 if ((intptr_t)memblock == (intptr_t)MallocCatchPtr) {
686 if (tty != NULL) tty->print_cr("os::free caught " PTR_FORMAT, memblock);
687 breakpoint();
688 }
689 verify_memory(memblock);
690 NOT_PRODUCT(if (MallocVerifyInterval > 0) check_heap());
691
692 GuardedMemory guarded(memblock);
693 size_t size = guarded.get_user_size();
694 inc_stat_counter(&free_bytes, size);
695 memblock = guarded.release_for_freeing();
696 if (PrintMalloc && tty != NULL) {
697 fprintf(stderr, "os::free " SIZE_FORMAT " bytes --> " PTR_FORMAT "\n", size, (uintptr_t)memblock);
698 }
699 #endif
700 MemTracker::record_free(trackp, memflags);
701
702 ::free(memblock);
703 }
704
705 void os::init_random(long initval) {
706 _rand_seed = initval;
707 }
708
709
710 long os::random() {
711 /* standard, well-known linear congruential random generator with
712 * next_rand = (16807*seed) mod (2**31-1)
713 * see
714 * (1) "Random Number Generators: Good Ones Are Hard to Find",
715 * S.K. Park and K.W. Miller, Communications of the ACM 31:10 (Oct 1988),
716 * (2) "Two Fast Implementations of the 'Minimal Standard' Random
717 * Number Generator", David G. Carta, Comm. ACM 33, 1 (Jan 1990), pp. 87-88.
718 */
719 const long a = 16807;
720 const unsigned long m = 2147483647;
721 const long q = m / a; assert(q == 127773, "weird math");
722 const long r = m % a; assert(r == 2836, "weird math");
|