rng_queue_pool.cpp 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. //
  2. // C++ Implementation: rng_queue_pool
  3. //
  4. // Description:
  5. //
  6. //
  7. // Author: Frank Michler,,, <frank@pc13365>, (C) 2010
  8. //
  9. // Copyright: See COPYING file that comes with this distribution
  10. //
  11. //
  12. #include <iostream>
  13. #include <QSemaphore>
  14. #include <QMutex>
  15. #include <QThread>
  16. #include "rng_queue_pool.hpp"
  17. #include "rngqueue.hpp"
  18. using namespace std;
  19. RngQueuePool::RngQueuePool(): mSemFreshNumbers(0), mSemUsedNumbers(mNRndVectors), mIsDead(false)
  20. {
  21. cout << "Singleton-Constructor: RngQueuePool::RngQueuePool()\n";
  22. // initialize global random generator
  23. const gsl_rng_type * T;
  24. gsl_rng_env_setup();
  25. T = gsl_rng_default;
  26. gslr = gsl_rng_alloc (T);
  27. #ifdef SEED_RNG_WITH_42
  28. unsigned long int seed = (long)(42);
  29. #else
  30. unsigned long int seed = (long)(time( NULL ));
  31. #endif
  32. gsl_rng_set(gslr, seed);
  33. mRNVectorPool = vector<vector<double> >(mNRndVectors, vector<double>(mkNumbersPerVector, 0));
  34. for (int i=0; i<mNRndVectors; ++i) {
  35. mUsedNumbers.push_back(i);
  36. }
  37. }
  38. RngQueuePool::~RngQueuePool()
  39. {
  40. cout << "\n Destructor\n";
  41. mIsDead=true;
  42. cout << "available UsedNumbers=" << mSemUsedNumbers.available() << "\n";
  43. mSemUsedNumbers.release();
  44. wait();
  45. }
  46. IRngQueuePool* RngQueuePool::getRngQueuePool()
  47. {
  48. cout << "Singleton-Request\n";
  49. static RngQueuePool instanz;
  50. if (!instanz.isRunning()) {
  51. cout << "Starting random number generator thread\n";
  52. instanz.start();
  53. }
  54. return &instanz;
  55. }
  56. IRngQueue* RngQueuePool::getRngQueue()
  57. {
  58. mSemFreshNumbers.acquire();
  59. mMutFreshNumbers.lock();
  60. int FreshVectorNum = mFreshNumbers.front();
  61. mFreshNumbers.pop_front();
  62. mMutFreshNumbers.unlock();
  63. RngQueue* NewQueue = new RngQueue(this, &(mRNVectorPool[FreshVectorNum]));
  64. mLeasedNumbers[NewQueue]=FreshVectorNum;
  65. cout << "new queue with fresh vector num=" << FreshVectorNum << "\n";
  66. return NewQueue;
  67. }
  68. IRngQueue* RngQueuePool::getRngQueue(RngType _RType, double _Parameter, int NVectors, int NumbersPerVector)
  69. {
  70. cerr << "NOT SUPPORTED\n";
  71. }
  72. vector<double>* RngQueuePool::getRandomNumberVector(IRngQueue* _RngQueue)
  73. {
  74. map<IRngQueue*,int>::iterator it = mLeasedNumbers.find(_RngQueue);
  75. if (it!=mLeasedNumbers.end()) {
  76. if (!mSemFreshNumbers.tryAcquire()) {
  77. //cout << "getRandomNumberVector waiting for fresh numbers\n";
  78. //cout << "-";
  79. mSemFreshNumbers.acquire();
  80. }
  81. mMutFreshNumbers.lock();
  82. int FreshVectorNum = mFreshNumbers.front();
  83. mFreshNumbers.pop_front();
  84. mMutFreshNumbers.unlock();
  85. mMutUsedNumbers.lock();
  86. mUsedNumbers.push_back((*it).second);
  87. mMutUsedNumbers.unlock();
  88. (*it).second = FreshVectorNum;
  89. mSemUsedNumbers.release();
  90. // cout << "leased fresh Vector Num=" << FreshVectorNum << "\n";
  91. return &(mRNVectorPool[FreshVectorNum]);
  92. }
  93. cout << "RngQueuePool::getRandomNumberVector failed\n";
  94. return 0;
  95. }
  96. void RngQueuePool::refreshRandomNumbers(vector<double>& rnVect)
  97. {
  98. // cout << "RngQueuePool::refreshRandomNumbers\n";
  99. const double PoissonLambda=0.3;
  100. for(vector<double>::iterator it=rnVect.begin();it!=rnVect.end();++it) {
  101. (*it) = gsl_ran_poisson(gslr, PoissonLambda);
  102. }
  103. }
  104. void RngQueuePool::refillRNumberPool()
  105. {
  106. while (!mIsDead) {
  107. if (!mSemUsedNumbers.tryAcquire()) {
  108. // cout << "\nRngQueuePool::refillRNumberPool waiting for used numbers\n";
  109. //cout << "+";
  110. mSemUsedNumbers.acquire();
  111. }
  112. mMutUsedNumbers.lock();
  113. int VectorNum = mUsedNumbers.front();
  114. mUsedNumbers.pop_front();
  115. mMutUsedNumbers.unlock();
  116. refreshRandomNumbers(mRNVectorPool[VectorNum]);
  117. mMutFreshNumbers.lock();
  118. mFreshNumbers.push_back(VectorNum);
  119. mMutFreshNumbers.unlock();
  120. mSemFreshNumbers.release();
  121. }
  122. cout << "finish thread loop \n";
  123. }
  124. void RngQueuePool::run()
  125. {
  126. refillRNumberPool();
  127. }