00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042 #include "scv/scv_util.h"
00043 #include "scv/scv_random.h"
00044 #include "scv/scv_report.h"
00045
00046 #include <stdio.h>
00047 #include <stdlib.h>
00048
00049
00050 #ifdef _MSC_VER
00051 inline int rand_r(unsigned int *) { return rand(); }
00052 #endif
00053
00054
00055
00056
00057
00059
00060
00061
00063
00064 class scv_random_error {
00065 public:
00066 static void missing_algorithm(const string algorithm_name) {
00067 _scv_message::message(_scv_message::RANDOM_NULL_ALGORITHM,algorithm_name.c_str());
00068 }
00069
00070 static void out_of_order_seed(const string instance_name_p,
00071 const string fileNameP)
00072 {
00073 if (instance_name_p =="") {
00074 _scv_message::message(_scv_message::RANDOM_OUT_OF_ORDER_SEED,
00075 "<anonymous>",fileNameP.c_str());
00076 } else {
00077 _scv_message::message(_scv_message::RANDOM_OUT_OF_ORDER_SEED,
00078 instance_name_p.c_str(),fileNameP.c_str());
00079 }
00080 }
00081 static void cannot_match_seed(const string instance_name,
00082 const string fileName)
00083 {
00084 if (instance_name == "") {
00085 _scv_message::message(_scv_message::RANDOM_CANNOT_MATCH_SEED,
00086 "<anonymous>",fileName.c_str());
00087 } else {
00088 _scv_message::message(_scv_message::RANDOM_CANNOT_MATCH_SEED,
00089 instance_name.c_str(),fileName.c_str());
00090 }
00091 }
00092 static void retrieving_with_same_name(const string instance_name,
00093 const string fileName)
00094 {
00095 if (instance_name == "") {
00096 _scv_message::message(_scv_message::RANDOM_RETRIEVING_SEED_WITH_SAME_NAME,
00097 "<anonymous>",fileName.c_str());
00098 } else {
00099 _scv_message::message(_scv_message::RANDOM_RETRIEVING_SEED_WITH_SAME_NAME,
00100 instance_name.c_str(), fileName.c_str());
00101 }
00102 }
00103 static void storing_with_same_name(const string instance_name,
00104 const string fileName)
00105 {
00106 if (instance_name == "") {
00107 _scv_message::message(_scv_message::RANDOM_STORING_SEED_WITH_SAME_NAME,
00108 "<anonymous>",fileName.c_str());
00109 } else {
00110 _scv_message::message(_scv_message::RANDOM_STORING_SEED_WITH_SAME_NAME,
00111 instance_name.c_str(), fileName.c_str());
00112 }
00113 }
00114 static void seed_monitor_not_off(const string fileName)
00115 {
00116 _scv_message::message(_scv_message::RANDOM_SEED_MONITOR_NOT_OFF,
00117 fileName.c_str());
00118 }
00119 static void seed_not_exhausted(const string fileName) {
00120 _scv_message::message(_scv_message::RANDOM_SEED_NOT_EXHAUSTED,
00121 fileName.c_str());
00122 }
00123 static void cannot_open_seed_file(const string fileName) {
00124 _scv_message::message(_scv_message::RANDOM_CANNOT_OPEN_SEED_FILE,
00125 fileName.c_str());
00126 }
00127 };
00128
00130
00131
00132
00134
00135 #ifdef OLD_SEED_GENERATION_SEMANTICS
00136 static scv_random * s_seed_generator = NULL;
00137 #endif
00138
00139 static bool s_retrieve = false;
00140 static void retrieve_seed(const string & name, unsigned long long * seed);
00141 static unsigned long long _scv_generate_seed(const string& name);
00142 static void _scv_update_current_thread_info(const string& name);
00143 static inline unsigned int _scv_jrand48(unsigned short next[3]);
00144
00145 static string s_current_thread_name;
00146 static char s_current_inst_num[64];
00147 static int s_inst_num;
00148
00149 static string _scv_get_unique_name(const string & name);
00150 static string _scv_extract_name(const char * str);
00151
00152
00153 class _scv_random_impl {
00154 public:
00155 static int debug;
00156 scv_random::value_generation_algorithm _alg_type;
00157 unsigned long long _seed;
00158 scv_random::alg_func _algorithm;
00159 union {
00160 unsigned long long _next;
00161 unsigned int _rand_next;
00162 unsigned short _next48[3];
00163 } u ;
00164
00165 _scv_random_impl(const string name,
00166 unsigned long long seed,
00167 scv_random::alg_func algorithm,
00168 scv_random::value_generation_algorithm alg_type) :
00169 _alg_type(alg_type) {
00170
00171
00172
00173
00174
00175
00176
00177 _scv_update_current_thread_info(name);
00178
00179 if (seed == 0) {
00180 #ifdef OLD_SEED_GENERATION_SEMANTICS
00181 if (!s_seed_generator) scv_random::set_global_seed();
00182 #endif
00183 _seed = _scv_generate_seed(name);
00184 } else {
00185 _seed = seed;
00186 }
00187
00188 if (s_retrieve) retrieve_seed(_scv_get_unique_name(name), &_seed);
00189
00190 _algorithm = algorithm;
00191 if (_algorithm) {
00192 u._next = _seed;
00193 } else if (_alg_type == scv_random::RAND48) {
00194 u._next48[0] = (unsigned short)(_seed >> 16);
00195 u._next48[1] = (unsigned short)(_seed & 0xffff);
00196 u._next48[2] = 0x330E;
00197 } else if (_alg_type == scv_random::RAND ||
00198 _alg_type == scv_random::RAND32) {
00199 u._rand_next = (unsigned int)_seed;
00200 } else {
00201 _scv_message::message(_scv_message::INTERNAL_ERROR, " unknown _alg_type ");
00202 }
00203 }
00204 ~_scv_random_impl() {}
00205
00206 unsigned int next() {
00207 if (_algorithm) {
00208 return _algorithm(u._next);
00209 } else if (_alg_type == scv_random::RAND48) {
00210 return _scv_jrand48(u._next48);
00211 } else if (_alg_type == scv_random::RAND) {
00212 return rand_r(&u._rand_next);
00213 } else if (_alg_type == scv_random::RAND32) {
00214 #ifdef LINUX_SOURCE
00215 return rand_r(&u._rand_next);
00216 #else
00217
00218
00219
00220 unsigned int val = rand_r(&u._rand_next);
00221 val |= (rand_r(&u._rand_next) << 16);
00222 return val;
00223 #endif
00224 } else {
00225
00226 return 0;
00227 }
00228 }
00229
00230 unsigned int testNext() {
00231 if (_algorithm) {
00232 unsigned long long tmp = u._next;
00233 return _algorithm(tmp);
00234 } else if (_alg_type == scv_random::RAND48) {
00235 unsigned short tmp[3];
00236 tmp[0] = u._next48[0];
00237 tmp[1] = u._next48[1];
00238 tmp[2] = u._next48[2];
00239 return _scv_jrand48(tmp);
00240 } else if (_alg_type == scv_random::RAND) {
00241 return rand_r(&u._rand_next);
00242 } else {
00243
00244 return 0;
00245 }
00246 }
00247 static int get_debug(void) {
00248 return debug;
00249 }
00250 static void set_debug(int dbg) {
00251 if ( debug == dbg ) return;
00252 debug = dbg;
00253 scv_debug::set_facility_level(scv_debug::RANDOMIZATION, dbg);
00254 }
00255 };
00256
00257 int _scv_random_impl::debug = scv_debug::INITIAL_DEBUG_LEVEL;
00258
00260
00261
00262
00263
00264
00265
00266
00267
00269
00270 unsigned long long scv_random::global_seed = 1;
00271
00272 scv_random::value_generation_algorithm scv_random::global_alg_type = scv_random::RAND48;
00273
00274
00275
00276
00277 static scv_random::alg_func s_algorithm = NULL;
00278 extern unsigned long long _scv_default_global_init_seed(
00279 unsigned long job_number = 0);
00280 extern unsigned long long _scv_get_seed_from_name(const char *, unsigned);
00281
00282 static void _scv_set_algorithm(scv_random::value_generation_algorithm alg,
00283 scv_random::alg_func custom_alg, scv_random::alg_func * scv_be_set,
00284 const string & algorithm_name) ;
00285
00286 void scv_random::set_global_seed(unsigned long long seed)
00287 {
00288 #ifdef OLD_SEED_GENERATION_SEMANTICS
00289 if (s_seed_generator) {
00290 delete s_seed_generator;
00291 s_seed_generator = NULL;
00292 }
00293 if (seed==0) seed = _scv_default_global_init_seed();
00294 #endif
00295
00296 global_seed = seed;
00297
00298 #ifdef OLD_SEED_GENERATION_SEMANTICS
00299 s_seed_generator = new scv_random("internal seed generator",seed);
00300 #endif
00301
00302 }
00303
00304 unsigned long long scv_random::get_global_seed(void) {
00305 return global_seed;
00306 }
00307
00308 unsigned long long scv_random::pick_random_seed(unsigned long job_number) {
00309 return _scv_default_global_init_seed(job_number);
00310 }
00311
00312 void scv_random::set_default_algorithm(value_generation_algorithm alg,
00313 alg_func custom_alg) {
00314 ::_scv_set_algorithm(alg,custom_alg,&s_algorithm,
00315 "the global algorithm for scv_random");
00316 global_alg_type = alg;
00317 }
00318
00319 static list<scv_random *>& s_list_of_generators();
00320
00321 void scv_random::get_generators(list<scv_random *>& genList)
00322 {
00323 list<scv_random*>::iterator iter;
00324 for (iter = s_list_of_generators().begin();
00325 !(iter == s_list_of_generators().end());
00326 iter++ ) {
00327 genList.push_back(*iter);
00328 }
00329 }
00330
00331
00332
00333
00334 static void addSelf(scv_random * self);
00335
00336 scv_random::scv_random(const char* name)
00337 : _scv_data_structure(_scv_extract_name(name).c_str()),
00338 _coreP(new _scv_random_impl(_name,0,s_algorithm, global_alg_type))
00339 {
00340 _name = _scv_get_unique_name(_name);
00341 addSelf(this);
00342 }
00343
00344 scv_random::scv_random(unsigned long long seed)
00345 : _scv_data_structure("<anonymous>"),
00346 _coreP(new _scv_random_impl(_name,seed,s_algorithm, global_alg_type))
00347 {
00348 _name = _scv_get_unique_name(_name);
00349 addSelf(this);
00350 }
00351
00352 scv_random::scv_random(const char* name, unsigned long long seed)
00353 : _scv_data_structure(_scv_extract_name(name).c_str()),
00354 _coreP(new _scv_random_impl(_name,seed,s_algorithm, global_alg_type))
00355 {
00356 _name = _scv_get_unique_name(_name);
00357 addSelf(this);
00358 }
00359
00360 scv_random::scv_random(const scv_random& other,
00361 const char* name, unsigned long long seed)
00362 : _scv_data_structure(_scv_extract_name(name).c_str()),
00363 _coreP(new _scv_random_impl(_name,seed,other._coreP->_algorithm, other._coreP->_alg_type))
00364 {
00365 _name = _scv_get_unique_name(_name);
00366 addSelf(this);
00367 }
00368
00369 scv_random::~scv_random()
00370 {
00371 s_list_of_generators().remove(this);
00372 delete _coreP;
00373 }
00374
00375
00376
00377
00378
00379 unsigned int scv_random::next()
00380 {
00381 return _coreP->next();
00382 }
00383
00384 void scv_random::set_algorithm(value_generation_algorithm m,
00385 alg_func algorithm)
00386 {
00387 _coreP->_alg_type = m;
00388 ::_scv_set_algorithm(m,algorithm,&_coreP->_algorithm,get_name());
00389 }
00390
00391 unsigned long long scv_random::get_initial_seed() const
00392 {
00393 return _coreP->_seed;
00394 }
00395
00396 unsigned long long scv_random::get_current_seed() const
00397 {
00398 if (_coreP->_algorithm) {
00399 return _coreP->u._next;
00400 } else if (_coreP->_alg_type == scv_random::RAND48) {
00401 unsigned long long seed = 0;
00402 unsigned long long tmp = 0;
00403
00404 tmp = _coreP->u._next48[2];
00405 seed = tmp << 32;
00406
00407 tmp = _coreP->u._next48[1];
00408 seed = seed | tmp << 16;
00409
00410 tmp = _coreP->u._next48[0];
00411 seed = seed | tmp;
00412
00413 return seed;
00414 } else if (_coreP->_alg_type == scv_random::RAND ||
00415 _coreP->_alg_type == scv_random::RAND32) {
00416 return _coreP->u._rand_next;
00417 } else {
00418
00419 return 0;
00420 }
00421
00422 return 0;
00423 }
00424
00425 void scv_random::set_current_seed(unsigned long long seed)
00426 {
00427 if (_coreP->_algorithm) {
00428 _coreP->u._next = seed;
00429 } else if (_coreP->_alg_type == scv_random::RAND48) {
00430 _coreP->u._next48[0] = (unsigned short ) (seed & 0xffff);
00431 _coreP->u._next48[1] = (unsigned short ) (seed >> 16) & 0xffff;
00432 _coreP->u._next48[2] = (unsigned short ) (seed >> 32) & 0xffff;
00433 } else if (_coreP->_alg_type == scv_random::RAND ||
00434 _coreP->_alg_type == scv_random::RAND32) {
00435 _coreP->u._rand_next = (unsigned int)seed;
00436 } else {
00437
00438 }
00439 return;
00440 }
00441
00442
00443
00444
00445
00446
00447
00448
00449 void scv_random::print_initial_seeds(const char* fileName)
00450 {
00451 if (fileName != NULL) {
00452 FILE * filePtr = fopen(fileName,"wb");
00453
00454 list<scv_random*>::iterator iter;
00455 for (iter = s_list_of_generators().begin();
00456 !(iter == s_list_of_generators().end());
00457 ++iter) {
00458
00459 string s = (*iter)->get_name();
00460 if (s!="") {
00461 fprintf(filePtr,"\"%s\" :: %llu\n",s.c_str(),
00462 (*iter)->get_initial_seed());
00463 } else {
00464 fprintf(filePtr,"\"<anonymous>\" :: %llu\n",(*iter)->get_initial_seed());
00465 }
00466 }
00467 } else {
00468 print_initial_seeds();
00469 }
00470 }
00471
00472 void scv_random::print_initial_seeds(ostream& os)
00473 {
00474 list<scv_random*>::iterator iter;
00475 for (iter = s_list_of_generators().begin();
00476 !(iter == s_list_of_generators().end());
00477 ++iter) {
00478 string s = (*iter)->get_name();
00479 if (s!="") {
00480 os << "\"" << s.c_str() << "\" :: " <<
00481 (*iter)->get_initial_seed() << endl;
00482 } else {
00483 os << "\"<anonymous>\" :: " << (*iter)->get_initial_seed() << endl;
00484 }
00485 }
00486 }
00487
00488 void scv_random::print_current_seeds(const char* fileName)
00489 {
00490 if (fileName != NULL) {
00491 FILE * filePtr = fopen(fileName,"wb");
00492
00493 list<scv_random*>::iterator iter;
00494 for (iter = s_list_of_generators().begin();
00495 !(iter == s_list_of_generators().end());
00496 ++iter) {
00497
00498 string s = (*iter)->get_name();
00499 if (s!="") {
00500 fprintf(filePtr,"\"%s\" :: %llu\n",s.c_str(),
00501 (*iter)->get_current_seed());
00502 } else {
00503 fprintf(filePtr,"\"<anonymous>\" :: %llu\n",
00504 (*iter)->get_current_seed());
00505 }
00506 }
00507 } else {
00508 print_current_seeds();
00509 }
00510 }
00511
00512 void scv_random::print_current_seeds(ostream& os)
00513 {
00514 list<scv_random*>::iterator iter;
00515 for (iter = s_list_of_generators().begin();
00516 !(iter == s_list_of_generators().end());
00517 ++iter) {
00518 string s = (*iter)->get_name();
00519 if (s!="") {
00520 os << "\"" << s.c_str() << "\" :: " <<
00521 (*iter)->get_current_seed() << endl;
00522 } else {
00523 os << "\"<anonymous>\" :: " << (*iter)->get_current_seed() << endl;
00524 }
00525 }
00526 }
00527
00528 static bool s_store = false;
00529 static bool s_exclusive_seed_file = false;
00530 static FILE *s_seed_file_ptr = NULL;
00531 static int s_numOutstanding_seeds = 0;
00532 static bool s_warnedOutOfOrder = false;
00533 static bool s_warned_same_name = false;
00534 static bool s_warned_anonymous = false;
00535 static bool s_has_anonymous_generator = false;
00536
00537 static string& s_seed_file_name();
00538 static _scv_associative_array<string,list<unsigned long long> >& s_outstanding_seeds();
00539 static _scv_associative_array<string,int>& s_names();
00540 static bool readname_and_seed(string& nextName, unsigned long long& next_seed);
00541 static _scv_associative_array<string, int> unique_name_hash("unique_name_hash", 0);
00542
00543 void scv_random::seed_monitor_on(bool retrieve, const char* fileName)
00544 {
00545 if (s_store || s_retrieve) {
00546 scv_random_error::seed_monitor_not_off(s_seed_file_name());
00547 seed_monitor_off();
00548 }
00549 if (fileName != NULL) {
00550 s_exclusive_seed_file = true;
00551 if (retrieve) {
00552 s_store = false;
00553 s_retrieve = true;
00554 s_seed_file_name() = fileName;
00555 s_seed_file_ptr = fopen(fileName,"r");
00556 #ifdef OLD_SEED_GENERATION_SEMANTICS
00557 if (s_seed_generator) {
00558 delete s_seed_generator;
00559 s_seed_generator = NULL;
00560 }
00561 #endif
00562 } else {
00563 s_store = true;
00564 s_retrieve = false;
00565 s_seed_file_name() = fileName;
00566 s_seed_file_ptr = fopen(fileName,"wb");
00567 }
00568 if (!s_seed_file_ptr) {
00569 scv_random_error::cannot_open_seed_file(fileName);
00570 s_store = false;
00571 s_retrieve = false;
00572 }
00573 }
00574 }
00575
00576 void scv_random::seed_monitor_on(bool retrieve, const char* sectionName,
00577 FILE * file)
00578 {
00579 if (s_store || s_retrieve) {
00580 scv_random_error::seed_monitor_not_off(s_seed_file_name());
00581 seed_monitor_off();
00582 }
00583 if (file) {
00584 s_exclusive_seed_file = false;
00585 s_seed_file_name() = sectionName?sectionName:"";
00586 s_seed_file_ptr = file;
00587 if (retrieve) {
00588 s_store = false;
00589 s_retrieve = true;
00590 } else {
00591 s_store = true;
00592 s_retrieve = false;
00593 }
00594 #ifdef OLD_SEED_GENERATION_SEMANTICS
00595 if (s_seed_generator) {
00596 delete s_seed_generator;
00597 s_seed_generator = NULL;
00598 }
00599 #endif
00600 }
00601 }
00602
00603 void scv_random::seed_monitor_off()
00604 {
00605 if (s_store || s_retrieve) {
00606 s_names().clear();
00607 s_warned_same_name = false;
00608 s_warned_anonymous = false;
00609 s_has_anonymous_generator = false;
00610 }
00611 if (s_store) {
00612 s_store = false;
00613 if (s_exclusive_seed_file) fclose(s_seed_file_ptr);
00614 s_seed_file_name() = "";
00615 }
00616 if (s_retrieve) {
00617 string dummyName;
00618 unsigned long long dummy_seed;
00619 s_retrieve = false;
00620 if (s_seed_file_ptr && readname_and_seed(dummyName,dummy_seed)) {
00621 scv_random_error::seed_not_exhausted(s_seed_file_name());
00622 }
00623 if (s_numOutstanding_seeds>0) {
00624 scv_random_error::seed_not_exhausted(s_seed_file_name());
00625 }
00626 if (s_exclusive_seed_file && s_seed_file_ptr) fclose(s_seed_file_ptr);
00627 s_seed_file_name() = "";
00628 s_seed_file_ptr = NULL;
00629 s_numOutstanding_seeds = 0;
00630 s_outstanding_seeds().clear();
00631 s_warnedOutOfOrder = false;
00632 }
00633 }
00634
00635 int scv_random::get_debug() {
00636 return _scv_random_impl::get_debug();
00637 }
00638
00639 const char *scv_random::kind() const {
00640 static const char *name = "scv_random";
00641 return name;
00642 }
00643
00644 void scv_random::print(ostream& o, int details, int indent) const {
00645 char algorithm[100];
00646
00647 o << "scv_random Name: " << get_name() << endl;
00648 switch(_coreP->_alg_type) {
00649 case scv_random::RAND48 :
00650 strcpy(algorithm, "jrand48");
00651 break;
00652 case scv_random::RAND:
00653 strcpy(algorithm, "rand");
00654 break;
00655 case scv_random::RAND32:
00656 strcpy(algorithm, "rand32");
00657 break;
00658 case scv_random::CUSTOM:
00659 strcpy(algorithm, "custom");
00660 break;
00661 default:
00662 break;
00663 }
00664 o << "\talgorithm: " << algorithm << endl;
00665 o << "\tseed: " << _coreP->_seed << endl;
00666 o << "\tnext: " << get_current_seed() << endl;
00667 o << "\tnext value: " << _coreP->testNext() << endl;
00668 }
00669
00670 void scv_random::set_debug(int debug) {
00671 _scv_random_impl::set_debug(debug);
00672 }
00673
00674 void scv_random::show(int details, int indent) const {
00675 print(scv_out, details, indent);
00676 }
00677
00679
00680
00681
00682
00683
00684
00685
00686
00687
00688
00689
00690
00692
00693 extern const char *scv_get_process_name(sc_process_b*) ;
00694
00695 static void _scv_update_current_thread_info(const string& name)
00696 {
00697 sc_process_b * handle = sc_get_curr_process_handle();
00698 if (handle) {
00699 s_current_thread_name = scv_get_process_name(handle);
00700 } else {
00701 s_current_thread_name = "scv_main_thread";
00702 }
00703 string thread_based_name = s_current_thread_name + name;
00704 s_inst_num = unique_name_hash.getValue(thread_based_name);
00705 if (s_inst_num == 0) {
00706 sprintf(s_current_inst_num, "<noappend>");
00707 } else {
00708 sprintf(s_current_inst_num, "%d", s_inst_num);
00709 }
00710 unique_name_hash.insert(thread_based_name, (s_inst_num+1));
00711 }
00712
00713 static unsigned long long _scv_generate_seed(const string& name)
00714 {
00715 #ifdef OLD_SEED_GENERATION_SEMANTICS
00716 return s_seed_generator->next();
00717 #else
00718 string thread_based_name = s_current_thread_name + name;
00719 return _scv_get_seed_from_name(thread_based_name.c_str(), s_inst_num);
00720 #endif
00721 }
00722
00723 static void
00724 _scv_set_algorithm(scv_random::value_generation_algorithm alg,
00725 scv_random::alg_func custom_alg,
00726 scv_random::alg_func * scv_be_set,
00727 const string & algorithm_name) {
00728 switch(alg) {
00729 case scv_random::RAND48:
00730 case scv_random::RAND:
00731 case scv_random::RAND32:
00732 *scv_be_set = NULL; break;
00733 case scv_random::CUSTOM:
00734 if (custom_alg==NULL) {
00735 scv_random_error::missing_algorithm(algorithm_name);
00736 *scv_be_set = NULL; break;
00737 } else {
00738 *scv_be_set = custom_alg; break;
00739 }
00740 }
00741 }
00742
00743 static string& s_seed_file_name() {
00744 static string seed_file_name;
00745 return seed_file_name;
00746 }
00747
00748 static _scv_associative_array<string,list<unsigned long long> >&
00749 s_outstanding_seeds() {
00750 static _scv_associative_array<string,list<unsigned long long> >
00751 outstanding_seeds("outstanding_seeds",list<unsigned long long>());
00752 return outstanding_seeds;
00753 }
00754
00755 static _scv_associative_array<string,int>&
00756 s_names() {
00757 static _scv_associative_array<string,int>
00758 names("_generator Name Data Base",0);
00759 return names;
00760 }
00761
00762 static list<scv_random *> *_list_of_generators = NULL;
00763
00764 static list<scv_random *>& s_list_of_generators() {
00765 if (!_list_of_generators) {
00766 _list_of_generators = new list<scv_random*>;
00767 }
00768 return *(_list_of_generators);
00769 }
00770
00771 static bool readname_and_seed(string& nextName, unsigned long long & next_seed) {
00772 char nextChar;
00773 string name;
00774 name.reserve(60);
00775
00776 if (s_exclusive_seed_file) {
00777 do {
00778 nextChar = getc(s_seed_file_ptr);
00779 if (nextChar == EOF) return false;
00780 } while (nextChar != '\"');
00781 } else {
00782 bool done = false;
00783
00784 while (!done) {
00785 do {
00786 nextChar = getc(s_seed_file_ptr);
00787 if (nextChar == EOF) return false;
00788 } while (nextChar != '<');
00789 do {
00790 nextChar = getc(s_seed_file_ptr);
00791 if (nextChar == EOF) return false;
00792 if (nextChar != '>') name = name.append(1,nextChar);
00793 } while (nextChar != '>');
00794 if (name == s_seed_file_name())
00795 done = true;
00796 else
00797 name = "";
00798 }
00799 do {
00800 nextChar = getc(s_seed_file_ptr);
00801 if (nextChar == EOF) return false;
00802 } while (nextChar != '\"');
00803 }
00804
00805 name = "";
00806
00807
00808 do {
00809 nextChar = getc(s_seed_file_ptr);
00810 if (nextChar == EOF) return false;
00811 if (nextChar != '\"') name = name.append(1,nextChar);
00812 } while (nextChar != '\"');
00813 nextName = name.c_str();
00814
00815 int result = fscanf(s_seed_file_ptr," :: %llu", &next_seed);
00816
00817 return result != EOF;
00818 }
00819
00820 static void retrieve_seed(const string & name, unsigned long long * seed) {
00821 string s = name;
00822
00823 if (s == string("")) s = string("<anonymous>");
00824 if (s_numOutstanding_seeds>0 && s_outstanding_seeds()[s].size()>0) {
00825 *seed = s_outstanding_seeds()[s].front();
00826 s_outstanding_seeds()[s].pop_front();
00827 --s_numOutstanding_seeds;
00828 return;
00829 }
00830
00831 if (s_seed_file_ptr) {
00832 string nextName;
00833 unsigned long long next_seed;
00834 bool done = false;
00835
00836 while (!done && readname_and_seed(nextName,next_seed)) {
00837 if (nextName == s ||
00838 (nextName == string("<anonymous>") && s == string("")) ) {
00839 *seed = next_seed;
00840 done = true;
00841 } else {
00842 ++s_numOutstanding_seeds;
00843 s_outstanding_seeds()[nextName].push_back(next_seed);
00844 if (!s_warnedOutOfOrder) {
00845 s_warnedOutOfOrder = true;
00846 scv_random_error::out_of_order_seed(s, s_seed_file_name());
00847 }
00848 }
00849 }
00850
00851 if (!done) {
00852 scv_random_error::cannot_match_seed(s, s_seed_file_name());
00853 fclose(s_seed_file_ptr);
00854 s_seed_file_ptr = NULL;
00855 }
00856 } else {
00857 scv_random_error::cannot_match_seed(s, s_seed_file_name());
00858 }
00859 }
00860
00861 static void addSelf(scv_random * self) {
00862 s_list_of_generators().push_back(self);
00863 if (s_store || s_retrieve) {
00864 string s = self->get_name();
00865
00866 if (s!="") {
00867 if (++s_names()[s]>1) {
00868 if (!s_warned_same_name) {
00869 s_warned_same_name = true;
00870 if (s_store) scv_random_error::storing_with_same_name(s, s_seed_file_name());
00871 else scv_random_error::retrieving_with_same_name(s, s_seed_file_name());
00872 }
00873 }
00874 } else {
00875 if (s_has_anonymous_generator && !s_warned_anonymous) {
00876 s_warned_anonymous = true;
00877 if (s_store) scv_random_error::storing_with_same_name("", s_seed_file_name());
00878 else scv_random_error::retrieving_with_same_name("", s_seed_file_name());
00879 } else {
00880 s_has_anonymous_generator = true;
00881 }
00882 }
00883
00884 if (s_store) {
00885 if (s_exclusive_seed_file) {
00886 if (s!="") {
00887 fprintf(s_seed_file_ptr,"\"%s\" :: %llu\n",self->get_name(),self->get_initial_seed());
00888 } else {
00889 fprintf(s_seed_file_ptr,"\"<anonymous>\" :: %llu\n",self->get_initial_seed());
00890 }
00891 } else {
00892 if (s!="") {
00893 fprintf(s_seed_file_ptr,"<%s> \"%s\" :: %llu\n",s_seed_file_name().c_str(),self->get_name(),self->get_initial_seed());
00894 } else {
00895 fprintf(s_seed_file_ptr,"<%s> \"<anonymous>\" :: %llu\n",s_seed_file_name().c_str(),self->get_initial_seed());
00896 }
00897 }
00898 }
00899 }
00900 }
00901
00902 unsigned long long _scv_get_global_seed(void) {
00903 return scv_random::get_global_seed();
00904 }
00905
00906 static string _scv_get_unique_name(const string & name) {
00907 #ifndef DONT_UNIQUIFY_NAMES
00908 string hier_object_name;
00909 if (!strcmp(s_current_inst_num,"<noappend>")) {
00910 hier_object_name = s_current_thread_name + "." + name;
00911 } else {
00912 hier_object_name = s_current_thread_name + "." + name +
00913 "_" + s_current_inst_num;
00914 }
00915 return hier_object_name;
00916 #else
00917 return name;
00918 #endif
00919 }
00920
00921 static string _scv_extract_name(const char * str) {
00922 if (!str || 0==strcmp("",str)) return string("<anonymous>");
00923 string s(str);
00924 return s;
00925 }
00926
00928
00929
00930
00931
00932
00933
00935
00936 #if defined(__linux__) || defined(_MSC_VER)
00937
00938 struct _scv_linux_drand48_data
00939 {
00940 unsigned short int __x[3];
00941 unsigned short int __old_x[3];
00942 unsigned short int __c;
00943 unsigned short int __init;
00944 unsigned long long int __a;
00945 };
00946
00947 static struct _scv_linux_drand48_data drand48_data_glbl;
00948
00949 static int _scv_linux_drand48_iterate(unsigned short int xsubi[3],
00950 struct _scv_linux_drand48_data *buffer)
00951 {
00952 unsigned long long X;
00953 unsigned long long result;
00954
00955 if (!buffer->__init)
00956 {
00957 buffer->__a = 0x5deece66dull;
00958 buffer->__c = 0xb;
00959 buffer->__init = 1;
00960 }
00961
00962 X = ((unsigned long long) xsubi[2]) << 32 | ((unsigned long) xsubi[1]) << 16 | xsubi[0];
00963
00964 result = X * buffer->__a + buffer->__c;
00965
00966 xsubi[0] = (unsigned short) (result & 0xffff);
00967 xsubi[1] = (unsigned short) (result >> 16) & 0xffff;
00968 xsubi[2] = (unsigned short) (result >> 32) & 0xffff;
00969
00970 return 0;
00971 }
00972
00973 static int _scv_linux_jrand48_r(unsigned short int xsubi[3],
00974 struct _scv_linux_drand48_data *buffer,
00975 long int *result)
00976 {
00977 if (_scv_linux_drand48_iterate (xsubi, buffer) < 0)
00978 return -1;
00979
00980 *result = ((xsubi[2] << 16) | xsubi[1]) & 0xffffffffl;
00981
00982 return 0;
00983 }
00984
00985 static long int _scv_linux_jrand48(unsigned short xsubi[3])
00986 {
00987 long int result;
00988
00989 (void) _scv_linux_jrand48_r(xsubi, &drand48_data_glbl, &result);
00990
00991 return result;
00992 }
00993
00994 #endif
00995
00996 static inline unsigned int _scv_jrand48(unsigned short next[3]) {
00997 #if defined(__linux__) || defined(_MSC_VER)
00998 return (unsigned int) _scv_linux_jrand48(next);
00999 #else
01000 return (unsigned int) jrand48(next);
01001 #endif
01002 }
01003