aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/llmath
diff options
context:
space:
mode:
authorJacek Antonelli2008-08-15 23:44:48 -0500
committerJacek Antonelli2008-08-15 23:44:48 -0500
commit9b4f54c826ffa4f94efa866068c9d6ecdfb4b424 (patch)
tree2f8ae193ab487088962e628f1ee9dee2f5901f01 /linden/indra/llmath
parentSecond Life viewer sources 1.13.2.12 (diff)
downloadmeta-impy-9b4f54c826ffa4f94efa866068c9d6ecdfb4b424.zip
meta-impy-9b4f54c826ffa4f94efa866068c9d6ecdfb4b424.tar.gz
meta-impy-9b4f54c826ffa4f94efa866068c9d6ecdfb4b424.tar.bz2
meta-impy-9b4f54c826ffa4f94efa866068c9d6ecdfb4b424.tar.xz
Second Life viewer sources 1.13.2.15
Diffstat (limited to 'linden/indra/llmath')
-rw-r--r--linden/indra/llmath/llrand.cpp59
-rw-r--r--linden/indra/llmath/llrand.h134
-rw-r--r--linden/indra/llmath/lluuid.cpp75
-rw-r--r--linden/indra/llmath/llvolume.cpp24
4 files changed, 191 insertions, 101 deletions
diff --git a/linden/indra/llmath/llrand.cpp b/linden/indra/llmath/llrand.cpp
index 38e0639..4c214c4 100644
--- a/linden/indra/llmath/llrand.cpp
+++ b/linden/indra/llmath/llrand.cpp
@@ -1,6 +1,6 @@
1/** 1/**
2 * @file llrand.cpp 2 * @file llrand.cpp
3 * @brief a few useful math functions. 3 * @brief Global random generator.
4 * 4 *
5 * Copyright (c) 2000-2007, Linden Research, Inc. 5 * Copyright (c) 2000-2007, Linden Research, Inc.
6 * 6 *
@@ -30,45 +30,34 @@
30#include "llrand.h" 30#include "llrand.h"
31#include "lluuid.h" 31#include "lluuid.h"
32 32
33/* Put this back if you re-enabled slamFPCW 33static LLRandLagFib2281 gRandomGenerator(LLUUID::getRandomSeed());
34#if LL_WINDOWS
35#include <float.h>
36#else
37#include <stdlib.h>
38#endif
39*/
40 34
41void slamFPCW( void ) 35S32 ll_rand()
42{ 36{
43/* 37 return (S32)(gRandomGenerator() * RAND_MAX);
44#if LL_WINDOWS
45 // for Intel based CPUs, slam the FP control word directly
46 WORD wTemp, wSave;
47
48 __asm fstcw wSave
49 if ( (wSave & 0x300) // Not single mode
50 ||(0x3f != (wSave & 0x3f)) // Exceptions enabled
51 ||(wSave & 0xC00)) // Not round to nearest mode
52 {
53 __asm
54 {
55 mov ax, wSave
56 and ax, not 300h ;; single mode
57 or ax, 3fh ;; disable all exceptions
58 and ax, not 0xC00 ;; round to nearest mode
59 mov wTemp, ax
60 fldcw wTemp
61 }
62 }
63#endif
64*/
65} 38}
66 39
67LLRand gLindenLabRandomNumber(LLUUID::getRandomSeed()); 40S32 ll_rand(S32 val)
41{
42 return (S32)(gRandomGenerator() * val);
43}
44
45F32 ll_frand()
46{
47 return (F32)gRandomGenerator();
48}
68 49
69F32 frand(F32 val) 50F32 ll_frand(F32 val)
70{ 51{
71// return (val * (F32)rand()/(F32)RAND_MAX); 52 return (F32)gRandomGenerator() * val;
72 return gLindenLabRandomNumber.llfrand(val);
73} 53}
74 54
55F64 ll_drand()
56{
57 return gRandomGenerator();
58}
59
60F64 ll_drand(F64 val)
61{
62 return gRandomGenerator() * val;
63}
diff --git a/linden/indra/llmath/llrand.h b/linden/indra/llmath/llrand.h
index db9f353..47b5651 100644
--- a/linden/indra/llmath/llrand.h
+++ b/linden/indra/llmath/llrand.h
@@ -1,6 +1,6 @@
1/** 1/**
2 * @file llrand.h 2 * @file llrand.h
3 * @brief Some useful math functions. 3 * @brief Information, functions, and typedefs for randomness.
4 * 4 *
5 * Copyright (c) 2000-2007, Linden Research, Inc. 5 * Copyright (c) 2000-2007, Linden Research, Inc.
6 * 6 *
@@ -28,61 +28,101 @@
28#ifndef LL_LLRAND_H 28#ifndef LL_LLRAND_H
29#define LL_LLRAND_H 29#define LL_LLRAND_H
30 30
31// As long as you #include "llviewerprecompiledheaders.h", 31#include "boost/random/lagged_fibonacci.hpp"
32// you can use "gLindenLabRandomNumber.llfrand( range );" which returns a 32#include "boost/random/mersenne_twister.hpp"
33// random number F32 ranging from 0.0f to range.
34// -Ventrella - Sept 30, 2005
35 33
36// Slams Intel processors into Single Precision FP mode 34/**
37// (which is not any faster on modern hardware) 35 * Use the boost random number generators if you want a stateful
38void slamFPCW( void ); 36 * random numbers. If you want more random numbers, use the
39 37 * c-functions since they will generate faster/better randomness
40class LLRand 38 * across the process.
41{ 39 *
42public: 40 * I tested some of the boost random engines, and picked a good double
43 LLRand(U32 seed) : mSeed(seed) {} 41 * generator and a good integer generator. I also took some timings
44 ~LLRand() {} 42 * for them on linux using gcc 3.3.5. The harness also did some other
45 43 * fairly trivial operations to try to limit compiler optimizations,
46 void seed(U32 seed) { mSeed = seed; } 44 * so these numbers are only good for relative comparisons.
45 *
46 * usec/inter algorithm
47 * 0.21 boost::minstd_rand0
48 * 0.039 boost:lagged_fibonacci19937
49 * 0.036 boost:lagged_fibonacci607
50 * 0.44 boost::hellekalek1995
51 * 0.44 boost::ecuyer1988
52 * 0.042 boost::rand48
53 * 0.043 boost::mt11213b
54 * 0.028 stdlib random()
55 * 0.05 stdlib lrand48()
56 * 0.034 stdlib rand()
57 * 0.020 the old & lame LLRand
58 */
47 59
48 U32 llrand() 60/**
49 { 61 *@brief Generate a float from [0, RAND_MAX).
50 mSeed = U64L(1664525) * mSeed + U64L(1013904223); 62 */
51 return (U32)mSeed; 63S32 ll_rand();
52 }
53 64
54 U32 llrand(U32 val) 65/**
55 { 66 *@brief Generate a float from [0, val).
56 mSeed = U64L(1664525) * mSeed + U64L(1013904223); 67 */
57 return (U32)(mSeed) % val; 68S32 ll_rand(S32 val);
58 }
59 69
60 // val is the maximum 70/**
61 F32 llfrand(F32 val) 71 *@brief Generate a float from [0, 1.0).
62 { 72 */
63 const U32 FP_ONE = 0x3f800000; 73F32 ll_frand();
64 const U32 FP_MASK = 0x007fffff;
65 U32 ir = llrand();
66 74
67 ir = FP_ONE | (FP_MASK & ir); 75/**
68 76 *@brief Generate a float from [0, val).
69 // generate random float 77 */
70 F32 fr = (*(F32 *)&ir); 78F32 ll_frand(F32 val);
71 79
72 // correct to [0..1) 80/**
73 fr -= 1.f; 81 *@brief Generate a double from [0, 1.0).
82 */
83F64 ll_drand();
74 84
75 fr *= val; 85/**
86 *@brief Generate a double from [0, val).
87 */
88F64 ll_drand(F64 val);
76 89
77 return fr; 90/**
78 } 91 * @brief typedefs for good boost lagged fibonacci.
79 92 * @see boost::lagged_fibonacci
80public: 93 *
81 U64 mSeed; 94 * These generators will quickly generate doubles. Note the memory
82}; 95 * requirements, because they are somewhat high. I chose the smallest
96 * one, and one comparable in speed but higher periodicity without
97 * outrageous memory requirements.
98 * To use:
99 * LLRandLagFib607 foo((U32)time(NULL));
100 * double bar = foo();
101 */
83 102
84F32 frand(F32 val); 103typedef boost::lagged_fibonacci607 LLRandLagFib607;
104/**<
105 * lengh of cycle: 2^32,000
106 * memory: 607*sizeof(double) (about 5K)
107 */
85 108
86extern LLRand gLindenLabRandomNumber; 109typedef boost::lagged_fibonacci2281 LLRandLagFib2281;
110/**<
111 * lengh of cycle: 2^120,000
112 * memory: 2281*sizeof(double) (about 17K)
113 */
87 114
115/**
116 * @breif typedefs for a good boost mersenne twister implementation.
117 * @see boost::mersenne_twister
118 *
119 * This fairly quickly generates U32 values
120 * To use:
121 * LLRandMT19937 foo((U32)time(NULL));
122 * U32 bar = foo();
123 *
124 * lengh of cycle: 2^19,937-1
125 * memory: about 2496 bytes
126 */
127typedef boost::mt11213b LLRandMT19937;
88#endif 128#endif
diff --git a/linden/indra/llmath/lluuid.cpp b/linden/indra/llmath/lluuid.cpp
index 216dac9..3fb31a6 100644
--- a/linden/indra/llmath/lluuid.cpp
+++ b/linden/indra/llmath/lluuid.cpp
@@ -110,6 +110,40 @@ unsigned int decode( char const * fiveChars ) throw( bad_input_data )
110} 110}
111*/ 111*/
112 112
113#define LL_USE_JANKY_RANDOM_NUMBER_GENERATOR 0
114#if LL_USE_JANKY_RANDOM_NUMBER_GENERATOR
115/**
116 * @brief a global for
117 */
118static U64 sJankyRandomSeed(LLUUID::getRandomSeed());
119
120/**
121 * @brief generate a random U32.
122 */
123U32 janky_fast_random_bytes()
124{
125 sJankyRandomSeed = U64L(1664525) * sJankyRandomSeed + U64L(1013904223);
126 return (U32)sJankyRandomSeed;
127}
128
129/**
130 * @brief generate a random U32 from [0, val)
131 */
132U32 janky_fast_random_byes_range(U32 val)
133{
134 sJankyRandomSeed = U64L(1664525) * sJankyRandomSeed + U64L(1013904223);
135 return (U32)(sJankyRandomSeed) % val;
136}
137
138/**
139 * @brief generate a random U32 from [0, val)
140 */
141U32 janky_fast_random_seeded_bytes(U32 seed, U32 val)
142{
143 seed = U64L(1664525) * (U64)(seed) + U64L(1013904223);
144 return (U32)(seed) % val;
145}
146#endif
113 147
114// Common to all UUID implementations 148// Common to all UUID implementations
115void LLUUID::toString(char *out) const 149void LLUUID::toString(char *out) const
@@ -395,8 +429,16 @@ static void get_random_bytes(void *buf, int nbytes)
395 int i; 429 int i;
396 char *cp = (char *) buf; 430 char *cp = (char *) buf;
397 431
432 // *NOTE: If we are not using the janky generator ll_rand()
433 // generates at least 3 good bytes of data since it is 0 to
434 // RAND_MAX. This could be made more efficient by copying all the
435 // bytes.
398 for (i=0; i < nbytes; i++) 436 for (i=0; i < nbytes; i++)
399 *cp++ = gLindenLabRandomNumber.llrand() & 0xFF; 437#if LL_USE_JANKY_RANDOM_NUMBER_GENERATOR
438 *cp++ = janky_fast_random_bytes() & 0xFF;
439#else
440 *cp++ = ll_rand() & 0xFF;
441#endif
400 return; 442 return;
401} 443}
402 444
@@ -738,18 +780,18 @@ void LLUUID::getCurrentTime(uuid_time_t *timestamp)
738 780
739void LLUUID::generate() 781void LLUUID::generate()
740{ 782{
741 // Create a UUID. 783 // Create a UUID.
742 784 uuid_time_t timestamp;
743
744 uuid_time_t timestamp;
745 785
746 static unsigned char node_id[6]; 786 static unsigned char node_id[6];
747 static int has_init = 0; 787 static int has_init = 0;
748 788
749 // Create a UUID. 789 // Create a UUID.
750 static uuid_time_t time_last = {0,0}; 790 static uuid_time_t time_last = {0,0};
751 static U16 clock_seq = 0; 791 static U16 clock_seq = 0;
752 static LLRand random_generator(0); // dummy seed. reset it below 792#if LL_USE_JANKY_RANDOM_NUMBER_GENERATOR
793 static U32 seed = 0L; // dummy seed. reset it below
794#endif
753 if (!has_init) 795 if (!has_init)
754 { 796 {
755 if (getNodeID(node_id) <= 0) 797 if (getNodeID(node_id) <= 0)
@@ -764,8 +806,15 @@ void LLUUID::generate()
764 } 806 }
765 807
766 getCurrentTime(&time_last); 808 getCurrentTime(&time_last);
767 random_generator.seed(time_last.low); 809#if LL_USE_JANKY_RANDOM_NUMBER_GENERATOR
768 clock_seq = (U16) random_generator.llrand(65536); 810 seed = time_last.low;
811#endif
812
813#if LL_USE_JANKY_RANDOM_NUMBER_GENERATOR
814 clock_seq = (U16)janky_fast_random_seeded_bytes(seed, 65536);
815#else
816 clock_seq = (U16)ll_rand(65536);
817#endif
769 has_init = 1; 818 has_init = 1;
770 } 819 }
771 820
diff --git a/linden/indra/llmath/llvolume.cpp b/linden/indra/llmath/llvolume.cpp
index 14d4cdf..c527e85 100644
--- a/linden/indra/llmath/llvolume.cpp
+++ b/linden/indra/llmath/llvolume.cpp
@@ -725,6 +725,8 @@ BOOL LLProfileParams::importFile(FILE *fp)
725{ 725{
726 const S32 BUFSIZE = 16384; 726 const S32 BUFSIZE = 16384;
727 char buffer[BUFSIZE]; 727 char buffer[BUFSIZE];
728 // *NOTE: changing the size or type of these buffers will require
729 // changing the sscanf below.
728 char keyword[256]; 730 char keyword[256];
729 char valuestr[256]; 731 char valuestr[256];
730 keyword[0] = 0; 732 keyword[0] = 0;
@@ -735,7 +737,7 @@ BOOL LLProfileParams::importFile(FILE *fp)
735 while (!feof(fp)) 737 while (!feof(fp))
736 { 738 {
737 fgets(buffer, BUFSIZE, fp); 739 fgets(buffer, BUFSIZE, fp);
738 sscanf(buffer, " %s %s", keyword, valuestr); 740 sscanf(buffer, " %255s %255s", keyword, valuestr);
739 if (!keyword) 741 if (!keyword)
740 { 742 {
741 continue; 743 continue;
@@ -795,6 +797,8 @@ BOOL LLProfileParams::importLegacyStream(std::istream& input_stream)
795{ 797{
796 const S32 BUFSIZE = 16384; 798 const S32 BUFSIZE = 16384;
797 char buffer[BUFSIZE]; 799 char buffer[BUFSIZE];
800 // *NOTE: changing the size or type of these buffers will require
801 // changing the sscanf below.
798 char keyword[256]; 802 char keyword[256];
799 char valuestr[256]; 803 char valuestr[256];
800 keyword[0] = 0; 804 keyword[0] = 0;
@@ -805,7 +809,7 @@ BOOL LLProfileParams::importLegacyStream(std::istream& input_stream)
805 while (input_stream.good()) 809 while (input_stream.good())
806 { 810 {
807 input_stream.getline(buffer, BUFSIZE); 811 input_stream.getline(buffer, BUFSIZE);
808 sscanf(buffer, " %s %s", keyword, valuestr); 812 sscanf(buffer, " %255s %255s", keyword, valuestr);
809 if (!keyword) 813 if (!keyword)
810 { 814 {
811 continue; 815 continue;
@@ -1215,6 +1219,8 @@ BOOL LLPathParams::importFile(FILE *fp)
1215{ 1219{
1216 const S32 BUFSIZE = 16384; 1220 const S32 BUFSIZE = 16384;
1217 char buffer[BUFSIZE]; 1221 char buffer[BUFSIZE];
1222 // *NOTE: changing the size or type of these buffers will require
1223 // changing the sscanf below.
1218 char keyword[256]; 1224 char keyword[256];
1219 char valuestr[256]; 1225 char valuestr[256];
1220 keyword[0] = 0; 1226 keyword[0] = 0;
@@ -1227,7 +1233,7 @@ BOOL LLPathParams::importFile(FILE *fp)
1227 while (!feof(fp)) 1233 while (!feof(fp))
1228 { 1234 {
1229 fgets(buffer, BUFSIZE, fp); 1235 fgets(buffer, BUFSIZE, fp);
1230 sscanf(buffer, " %s %s", keyword, valuestr); 1236 sscanf(buffer, " %255s %255s", keyword, valuestr);
1231 if (!keyword) 1237 if (!keyword)
1232 { 1238 {
1233 continue; 1239 continue;
@@ -1354,6 +1360,8 @@ BOOL LLPathParams::importLegacyStream(std::istream& input_stream)
1354{ 1360{
1355 const S32 BUFSIZE = 16384; 1361 const S32 BUFSIZE = 16384;
1356 char buffer[BUFSIZE]; 1362 char buffer[BUFSIZE];
1363 // *NOTE: changing the size or type of these buffers will require
1364 // changing the sscanf below.
1357 char keyword[256]; 1365 char keyword[256];
1358 char valuestr[256]; 1366 char valuestr[256];
1359 keyword[0] = 0; 1367 keyword[0] = 0;
@@ -1366,7 +1374,7 @@ BOOL LLPathParams::importLegacyStream(std::istream& input_stream)
1366 while (input_stream.good()) 1374 while (input_stream.good())
1367 { 1375 {
1368 input_stream.getline(buffer, BUFSIZE); 1376 input_stream.getline(buffer, BUFSIZE);
1369 sscanf(buffer, " %s %s", keyword, valuestr); 1377 sscanf(buffer, " %255s %255s", keyword, valuestr);
1370 if (!keyword) 1378 if (!keyword)
1371 { 1379 {
1372 continue; 1380 continue;
@@ -3340,13 +3348,15 @@ BOOL LLVolumeParams::importFile(FILE *fp)
3340 //llinfos << "importing volume" << llendl; 3348 //llinfos << "importing volume" << llendl;
3341 const S32 BUFSIZE = 16384; 3349 const S32 BUFSIZE = 16384;
3342 char buffer[BUFSIZE]; 3350 char buffer[BUFSIZE];
3351 // *NOTE: changing the size or type of this buffer will require
3352 // changing the sscanf below.
3343 char keyword[256]; 3353 char keyword[256];
3344 keyword[0] = 0; 3354 keyword[0] = 0;
3345 3355
3346 while (!feof(fp)) 3356 while (!feof(fp))
3347 { 3357 {
3348 fgets(buffer, BUFSIZE, fp); 3358 fgets(buffer, BUFSIZE, fp);
3349 sscanf(buffer, " %s", keyword); 3359 sscanf(buffer, " %255s", keyword);
3350 if (!keyword) 3360 if (!keyword)
3351 { 3361 {
3352 continue; 3362 continue;
@@ -3391,6 +3401,8 @@ BOOL LLVolumeParams::importLegacyStream(std::istream& input_stream)
3391{ 3401{
3392 //llinfos << "importing volume" << llendl; 3402 //llinfos << "importing volume" << llendl;
3393 const S32 BUFSIZE = 16384; 3403 const S32 BUFSIZE = 16384;
3404 // *NOTE: changing the size or type of this buffer will require
3405 // changing the sscanf below.
3394 char buffer[BUFSIZE]; 3406 char buffer[BUFSIZE];
3395 char keyword[256]; 3407 char keyword[256];
3396 keyword[0] = 0; 3408 keyword[0] = 0;
@@ -3398,7 +3410,7 @@ BOOL LLVolumeParams::importLegacyStream(std::istream& input_stream)
3398 while (input_stream.good()) 3410 while (input_stream.good())
3399 { 3411 {
3400 input_stream.getline(buffer, BUFSIZE); 3412 input_stream.getline(buffer, BUFSIZE);
3401 sscanf(buffer, " %s", keyword); 3413 sscanf(buffer, " %255s", keyword);
3402 if (!keyword) 3414 if (!keyword)
3403 { 3415 {
3404 continue; 3416 continue;