123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151 |
- //
- // C++ Implementation: rng_queue_pool
- //
- // Description:
- //
- //
- // Author: Frank Michler,,, <frank@pc13365>, (C) 2010
- //
- // Copyright: See COPYING file that comes with this distribution
- //
- //
- #include <iostream>
- #include <QSemaphore>
- #include <QMutex>
- #include <QThread>
- #include "rng_queue_pool.hpp"
- #include "rngqueue.hpp"
- using namespace std;
- RngQueuePool::RngQueuePool(): mSemFreshNumbers(0), mSemUsedNumbers(mNRndVectors), mIsDead(false)
- {
- cout << "Singleton-Constructor: RngQueuePool::RngQueuePool()\n";
- // initialize global random generator
- const gsl_rng_type * T;
- gsl_rng_env_setup();
- T = gsl_rng_default;
- gslr = gsl_rng_alloc (T);
- #ifdef SEED_RNG_WITH_42
- unsigned long int seed = (long)(42);
- #else
- unsigned long int seed = (long)(time( NULL ));
- #endif
- gsl_rng_set(gslr, seed);
-
- mRNVectorPool = vector<vector<double> >(mNRndVectors, vector<double>(mkNumbersPerVector, 0));
- for (int i=0; i<mNRndVectors; ++i) {
- mUsedNumbers.push_back(i);
- }
- }
- RngQueuePool::~RngQueuePool()
- {
- cout << "\n Destructor\n";
- mIsDead=true;
- cout << "available UsedNumbers=" << mSemUsedNumbers.available() << "\n";
- mSemUsedNumbers.release();
- wait();
- }
- IRngQueuePool* RngQueuePool::getRngQueuePool()
- {
- cout << "Singleton-Request\n";
- static RngQueuePool instanz;
- if (!instanz.isRunning()) {
- cout << "Starting random number generator thread\n";
- instanz.start();
- }
- return &instanz;
- }
-
- IRngQueue* RngQueuePool::getRngQueue()
- {
- mSemFreshNumbers.acquire();
- mMutFreshNumbers.lock();
- int FreshVectorNum = mFreshNumbers.front();
- mFreshNumbers.pop_front();
- mMutFreshNumbers.unlock();
-
- RngQueue* NewQueue = new RngQueue(this, &(mRNVectorPool[FreshVectorNum]));
- mLeasedNumbers[NewQueue]=FreshVectorNum;
- cout << "new queue with fresh vector num=" << FreshVectorNum << "\n";
- return NewQueue;
- }
- IRngQueue* RngQueuePool::getRngQueue(RngType _RType, double _Parameter, int NVectors, int NumbersPerVector)
- {
- cerr << "NOT SUPPORTED\n";
- }
-
- vector<double>* RngQueuePool::getRandomNumberVector(IRngQueue* _RngQueue)
- {
- map<IRngQueue*,int>::iterator it = mLeasedNumbers.find(_RngQueue);
- if (it!=mLeasedNumbers.end()) {
- if (!mSemFreshNumbers.tryAcquire()) {
- //cout << "getRandomNumberVector waiting for fresh numbers\n";
- //cout << "-";
- mSemFreshNumbers.acquire();
- }
- mMutFreshNumbers.lock();
- int FreshVectorNum = mFreshNumbers.front();
- mFreshNumbers.pop_front();
- mMutFreshNumbers.unlock();
- mMutUsedNumbers.lock();
- mUsedNumbers.push_back((*it).second);
- mMutUsedNumbers.unlock();
-
- (*it).second = FreshVectorNum;
- mSemUsedNumbers.release();
- // cout << "leased fresh Vector Num=" << FreshVectorNum << "\n";
- return &(mRNVectorPool[FreshVectorNum]);
- }
- cout << "RngQueuePool::getRandomNumberVector failed\n";
- return 0;
- }
- void RngQueuePool::refreshRandomNumbers(vector<double>& rnVect)
- {
- // cout << "RngQueuePool::refreshRandomNumbers\n";
- const double PoissonLambda=0.3;
- for(vector<double>::iterator it=rnVect.begin();it!=rnVect.end();++it) {
- (*it) = gsl_ran_poisson(gslr, PoissonLambda);
- }
- }
-
- void RngQueuePool::refillRNumberPool()
- {
- while (!mIsDead) {
- if (!mSemUsedNumbers.tryAcquire()) {
- // cout << "\nRngQueuePool::refillRNumberPool waiting for used numbers\n";
- //cout << "+";
- mSemUsedNumbers.acquire();
- }
-
- mMutUsedNumbers.lock();
- int VectorNum = mUsedNumbers.front();
- mUsedNumbers.pop_front();
- mMutUsedNumbers.unlock();
-
- refreshRandomNumbers(mRNVectorPool[VectorNum]);
-
- mMutFreshNumbers.lock();
- mFreshNumbers.push_back(VectorNum);
- mMutFreshNumbers.unlock();
-
- mSemFreshNumbers.release();
- }
- cout << "finish thread loop \n";
- }
- void RngQueuePool::run()
- {
- refillRNumberPool();
- }
|