void Sampler::recordingStarted() {
	printf("Record start\n");
	controlMutex.lock();
	recording = true;
	recordPos = 0;
	controlMutex.unlock();
}
void Sampler::recordingEnded() {
	printf("Record end\n");
	controlMutex.lock();
	recording = false;
	sample.load(recordBuffer, recordPos);
	printf("Loaded sample of %d length\n", recordPos);
	controlMutex.unlock();
	noteOffset = -12;
}
void Sampler::soundChanged() {

	controlMutex.lock();
	string sndUrl = "";//AppSettings::soundFile;
	if(sndUrl=="") {
		sndUrl = ofToDataPath("sounds/harp.wav");
	}
	sample.loadFromFile(sndUrl);
	controlMutex.unlock();
}
    void DoSomethingConcurrently()
    {
        // Declares a mutex (mutual exclusion)
        Poco::Mutex mutex;
        
        // No other thread will be able to execute the next line until the mutex is unlocked by a previous thread
        mutex.lock();

        ::OutputDebugStringW(L"Something done.\n");

        mutex.unlock();
    }
Beispiel #5
0
  operator TextCache::Result() const {
#ifdef ENABLE_OPENGL
    return texture;
#else
    return { data, width, width, height };
#endif
  }
void Sampler::audioRequested (float * output, int bufferSize, int nChannels) {
	controlMutex.lock();
	// if we're recording, we want silence!!
	if(recording) {
		memset(output, 0, bufferSize*nChannels*sizeof(float));
	} else {
	//	printf("Sound %f\n", playbackSpeed);
		// otherwise, maybe we want playback
		for(int i = 0; i < bufferSize; i++) {
			float s = sample.getSample(playbackSpeed);
			for(int channel = 0; channel < nChannels; channel++) {
				output[i*nChannels + channel] = s;
			}
		}
	}
	controlMutex.unlock();
}
//--------------------------------------------------------------
void Sampler::audioReceived 	(float * input, int bufferSize, int nChannels){

	//if(recording) printf("We're recording\n");
	//else printf("Not record\n");
	controlMutex.lock();
	for(int i = 0; i < bufferSize; i++) {

		float inp = input[i*nChannels];

		// do the recording
		if(recording && recordPos<recordBufferSize) {
			recordBuffer[recordPos++] = inp;
		}
		// do a level meter
		if(inputLevel<inp) {
			inputLevel = inp;
		} else {
			inputLevel *= 0.99995;
		}
	}
	controlMutex.unlock();

}
Beispiel #8
0
 void Unlock() { text_cache_mutex.unlock(); }
Beispiel #9
0
 void Lock() { text_cache_mutex.lock(); }
//--------------------------------------------------------------
void Sampler::init(){
	
	currTouchId = -1;
	//AppSettings::addListener(this);
	movementThreshold = 0.02;
	//Particle::color = &AppSettings::color3;

	recordBufferSize = SAMPLERATE*MAX_RECORD_SECONDS;
	recordBuffer = new float[recordBufferSize];
	recordPos = 0;
	recording = false;
	inputLevel = 0;
	playbackSpeed = 1;
	lastSound = -1;


	ofDirectory DIR;

	int numFiles = DIR.listDir("sounds");
	for(int i = 0; i < numFiles; i++) {
		sounds.push_back(DIR.getName(i));
	}


	// this is the last time that there was a note
	noteLastTime = -10;
	lastNote = 0;


	scales.push_back(PENTATONIC);
	scales.push_back(MAJOR);
	scales.push_back(MINOR);
	scales.push_back(CHROMATIC);


	memset(recordBuffer, 0, recordBufferSize*sizeof(float));
	// 1 output channels,
	// 2 input channels
	// 44100 samples per second
	// 256 samples per buffer
	// 1 num buffers (latency)


 
	controlMutex.lock();
	sample.loadFromFile(ofToDataPath("sounds/harp.wav"));
	controlMutex.unlock();


	//--------- PANEL 1

	video.listDevices();
	#ifdef TARGET_OF_IPHONE
	video.setDeviceID(1);
	#endif
	video.initGrabber(VISION_WIDTH, VISION_HEIGHT, OF_PIXELS_BGRA);
	vision.setup();
	gui.setup();
	
	gui.recordButton->recListener = this;
}
Beispiel #11
0
void Message::Unlock() {
  CritSec_Messages.unlock();
}
Beispiel #12
0
void LockComm() {
  CritSec_Comm.lock();
}
namespace rrllvm
{

typedef cxx11_ns::weak_ptr<ModelResources> WeakModelPtr;
typedef cxx11_ns::shared_ptr<ModelResources> SharedModelPtr;
typedef cxx11_ns::unordered_map<std::string, WeakModelPtr> ModelPtrMap;

static Poco::Mutex cachedModelsMutex;
static ModelPtrMap cachedModels;


/**
 * copy the cached model fields between a cached model, and a
 * executable model.
 *
 * We don't want to have ExecutableModel inherit from CahcedModel
 * because they do compleltly different things, and have completly
 * differnt deletion semantics
 */
template <typename a_type, typename b_type>
void copyCachedModel(a_type* src, b_type* dst)
{
    dst->symbols = src->symbols;
    dst->context = src->context;
    dst->executionEngine = src->executionEngine;
    dst->errStr = src->errStr;

    dst->evalInitialConditionsPtr = src->evalInitialConditionsPtr;
    dst->evalReactionRatesPtr = src->evalReactionRatesPtr;
    dst->getBoundarySpeciesAmountPtr = src->getBoundarySpeciesAmountPtr;
    dst->getFloatingSpeciesAmountPtr = src->getFloatingSpeciesAmountPtr;
    dst->getBoundarySpeciesConcentrationPtr = src->getBoundarySpeciesConcentrationPtr;
    dst->getFloatingSpeciesConcentrationPtr = src->getFloatingSpeciesConcentrationPtr;
    dst->getCompartmentVolumePtr = src->getCompartmentVolumePtr;
    dst->getGlobalParameterPtr = src->getGlobalParameterPtr;
    dst->evalRateRuleRatesPtr = src->evalRateRuleRatesPtr;
    dst->getEventTriggerPtr = src->getEventTriggerPtr;
    dst->getEventPriorityPtr = src->getEventPriorityPtr;
    dst->getEventDelayPtr = src->getEventDelayPtr;
    dst->eventTriggerPtr = src->eventTriggerPtr;
    dst->eventAssignPtr = src->eventAssignPtr;
    dst->evalVolatileStoichPtr = src->evalVolatileStoichPtr;
    dst->evalConversionFactorPtr = src->evalConversionFactorPtr;
}


ExecutableModel* LLVMModelGenerator::createModel(const std::string& sbml,
        uint options)
{
    bool forceReCompile = options & LoadSBMLOptions::RECOMPILE;

    string md5;

    if (!forceReCompile)
    {
        // check for a chached copy
        md5 = rr::getMD5(sbml);

        if (options & LoadSBMLOptions::CONSERVED_MOIETIES)
        {
            md5 += "_conserved";
        }

        ModelPtrMap::const_iterator i;

        SharedModelPtr sp;

        cachedModelsMutex.lock();

        if ((i = cachedModels.find(md5)) != cachedModels.end())
        {
            sp = i->second.lock();
        }

        cachedModelsMutex.unlock();

        // we could have recieved a bad ptr, a model could have been deleted,
        // in which case, we should have a bad ptr.

        if (sp)
        {
            Log(Logger::LOG_DEBUG) << "found a cached model for " << md5;
            return new LLVMExecutableModel(sp, createModelData(*sp->symbols, sp->random));
        }
        else
        {
            Log(Logger::LOG_TRACE) << "no cached model found for " << md5
                    << ", creating new one";
        }
    }

    SharedModelPtr rc(new ModelResources());

    ModelGeneratorContext context(sbml, options);

    rc->evalInitialConditionsPtr =
            EvalInitialConditionsCodeGen(context).createFunction();

    rc->evalReactionRatesPtr =
            EvalReactionRatesCodeGen(context).createFunction();

    rc->getBoundarySpeciesAmountPtr =
            GetBoundarySpeciesAmountCodeGen(context).createFunction();

    rc->getFloatingSpeciesAmountPtr =
            GetFloatingSpeciesAmountCodeGen(context).createFunction();

    rc->getBoundarySpeciesConcentrationPtr =
            GetBoundarySpeciesConcentrationCodeGen(context).createFunction();

    rc->getFloatingSpeciesConcentrationPtr =
            GetFloatingSpeciesConcentrationCodeGen(context).createFunction();

    rc->getCompartmentVolumePtr =
            GetCompartmentVolumeCodeGen(context).createFunction();

    rc->getGlobalParameterPtr =
            GetGlobalParameterCodeGen(context).createFunction();

    rc->evalRateRuleRatesPtr =
            EvalRateRuleRatesCodeGen(context).createFunction();

    rc->getEventTriggerPtr =
            GetEventTriggerCodeGen(context).createFunction();

    rc->getEventPriorityPtr =
            GetEventPriorityCodeGen(context).createFunction();

    rc->getEventDelayPtr =
            GetEventDelayCodeGen(context).createFunction();

    rc->eventTriggerPtr =
            EventTriggerCodeGen(context).createFunction();

    rc->eventAssignPtr =
            EventAssignCodeGen(context).createFunction();

    rc->evalVolatileStoichPtr =
            EvalVolatileStoichCodeGen(context).createFunction();

    rc->evalConversionFactorPtr =
            EvalConversionFactorCodeGen(context).createFunction();

    if (options & LoadSBMLOptions::READ_ONLY)
    {
        rc->setBoundarySpeciesAmountPtr = 0;
        rc->setBoundarySpeciesConcentrationPtr = 0;
        rc->setFloatingSpeciesConcentrationPtr = 0;
        rc->setCompartmentVolumePtr = 0;
        rc->setFloatingSpeciesAmountPtr = 0;
        rc->setGlobalParameterPtr = 0;
    }
    else
    {
        rc->setBoundarySpeciesAmountPtr = SetBoundarySpeciesAmountCodeGen(
                context).createFunction();

        rc->setBoundarySpeciesConcentrationPtr =
                SetBoundarySpeciesConcentrationCodeGen(context).createFunction();

        rc->setFloatingSpeciesConcentrationPtr =
                SetFloatingSpeciesConcentrationCodeGen(context).createFunction();

        rc->setCompartmentVolumePtr =
                SetCompartmentVolumeCodeGen(context).createFunction();

        rc->setFloatingSpeciesAmountPtr = SetFloatingSpeciesAmountCodeGen(
                context).createFunction();

        rc->setGlobalParameterPtr =
                SetGlobalParameterCodeGen(context).createFunction();
    }

    if (options & LoadSBMLOptions::MUTABLE_INITIAL_CONDITIONS)
    {
        rc->getFloatingSpeciesInitConcentrationsPtr =
                GetFloatingSpeciesInitConcentrationCodeGen(context).createFunction();
        rc->setFloatingSpeciesInitConcentrationsPtr =
                SetFloatingSpeciesInitConcentrationCodeGen(context).createFunction();

        rc->getFloatingSpeciesInitAmountsPtr =
                GetFloatingSpeciesInitAmountCodeGen(context).createFunction();
        rc->setFloatingSpeciesInitAmountsPtr =
                SetFloatingSpeciesInitAmountCodeGen(context).createFunction();

        rc->getCompartmentInitVolumesPtr =
                GetCompartmentInitVolumeCodeGen(context).createFunction();
        rc->setCompartmentInitVolumesPtr =
                SetCompartmentInitVolumeCodeGen(context).createFunction();

        rc->getGlobalParameterInitValuePtr =
                GetGlobalParameterInitValueCodeGen(context).createFunction();
        rc->setGlobalParameterInitValuePtr =
                SetGlobalParameterInitValueCodeGen(context).createFunction();
    }
    else
    {
        rc->getFloatingSpeciesInitConcentrationsPtr = 0;
        rc->setFloatingSpeciesInitConcentrationsPtr = 0;

        rc->getFloatingSpeciesInitAmountsPtr = 0;
        rc->setFloatingSpeciesInitAmountsPtr = 0;

        rc->getCompartmentInitVolumesPtr = 0;
        rc->setCompartmentInitVolumesPtr = 0;

        rc->getGlobalParameterInitValuePtr = 0;
        rc->setGlobalParameterInitValuePtr = 0;
    }


    // if anything up to this point throws an exception, thats OK, because
    // we have not allocated any memory yet that is not taken care of by
    // something else.
    // Now that everything that could have thrown would have thrown, we
    // can now create the model and set its fields.

    LLVMModelData *modelData = createModelData(context.getModelDataSymbols(),
            context.getRandom());

    uint llvmsize = ModelDataIRBuilder::getModelDataSize(context.getModule(),
            &context.getExecutionEngine());

    if (llvmsize != modelData->size)
    {
        std::stringstream s;

        s << "LLVM Model Data size " << llvmsize << " is different from " <<
                "C++ size of LLVM ModelData, " << modelData->size;

        LLVMModelData_free(modelData);

        Log(Logger::LOG_FATAL) << s.str();

        throw_llvm_exception(s.str());
    }

    // * MOVE * the bits over from the context to the exe model.
    context.stealThePeach(&rc->symbols, &rc->context,
            &rc->executionEngine, &rc->random, &rc->errStr);


    if (!forceReCompile)
    {
        // check for a chached copy, another thread could have
        // created one while we were making ours...

        ModelPtrMap::const_iterator i;

        SharedModelPtr sp;

        cachedModelsMutex.lock();

        // whilst we have it locked, clear any expired ptrs
        for (ModelPtrMap::const_iterator j = cachedModels.begin();
                j != cachedModels.end();)
        {
            if (j->second.expired())
            {
                Log(Logger::LOG_DEBUG) <<
                        "removing expired model resource for hash " << md5;

                j = cachedModels.erase(j);
            }
            else
            {
                ++j;
            }
        }

        if ((i = cachedModels.find(md5)) == cachedModels.end())
        {
            Log(Logger::LOG_DEBUG) << "could not find existing cached resource "
                    "resources, for hash " << md5 <<
                    ", inserting new resources into cache";

            cachedModels[md5] = rc;
        }

        cachedModelsMutex.unlock();
    }

    return new LLVMExecutableModel(rc, modelData);
}



/************ LLVM Utility Functions, TODO: Move To Separate File ************/

/**
 * C++ 11 style to_string for LLVM types
 */
std::string to_string(const llvm::Value *value)
{
    std::string str;
    llvm::raw_string_ostream stream(str);
    value->print(stream);
    return str;
}

LLVMModelData *createModelData(const rrllvm::LLVMModelDataSymbols &symbols,
        const Random *random)
{
    uint modelDataBaseSize = sizeof(LLVMModelData);

    uint numIndCompartments = symbols.getIndependentCompartmentSize();
    uint numIndFloatingSpecies = symbols.getIndependentFloatingSpeciesSize();
    uint numIndBoundarySpecies = symbols.getIndependentBoundarySpeciesSize();
    uint numIndGlobalParameters = symbols.getIndependentGlobalParameterSize();

    uint numInitCompartments = symbols.getInitCompartmentSize();
    uint numInitFloatingSpecies = symbols.getInitFloatingSpeciesSize();
    uint numInitBoundarySpecies = symbols.getInitBoundarySpeciesSize();
    uint numInitGlobalParameters = symbols.getInitGlobalParameterSize();

    // no initial conditions for these
    uint numRateRules = symbols.getRateRuleSize();
    uint numReactions = symbols.getReactionSize();

    uint modelDataSize = modelDataBaseSize +
        sizeof(double) * (
            numIndCompartments +
            numInitCompartments +
            numInitFloatingSpecies +
            numIndBoundarySpecies +
            numInitBoundarySpecies +
            numIndGlobalParameters +
            numInitGlobalParameters +
            numReactions +
            numRateRules +
            numIndFloatingSpecies
            );

    LLVMModelData *modelData = (LLVMModelData*)calloc(
            modelDataSize, sizeof(unsigned char));

    modelData->size = modelDataSize;
    modelData->numIndCompartments = numIndCompartments;
    modelData->numIndFloatingSpecies = numIndFloatingSpecies;
    modelData->numIndBoundarySpecies = numIndBoundarySpecies;
    modelData->numIndGlobalParameters = numIndGlobalParameters;

    modelData->numInitCompartments = numInitCompartments;
    modelData->numInitFloatingSpecies = numInitFloatingSpecies;
    modelData->numInitBoundarySpecies = numInitBoundarySpecies;
    modelData->numInitBoundarySpecies = numInitGlobalParameters;

    modelData->numRateRules = numRateRules;
    modelData->numReactions = numReactions;
    modelData->numEvents = symbols.getEventAttributes().size();

    // set the aliases to the offsets
    uint offset = 0;

    modelData->compartmentVolumesAlias = &modelData->data[offset];
    offset += numIndCompartments;

    modelData->initCompartmentVolumesAlias = &modelData->data[offset];
    offset += numInitCompartments;

    modelData->initFloatingSpeciesAmountsAlias = &modelData->data[offset];
    offset += numInitFloatingSpecies;

    modelData->boundarySpeciesAmountsAlias = &modelData->data[offset];
    offset += numIndBoundarySpecies;

    modelData->initBoundarySpeciesAmountsAlias = &modelData->data[offset];
    offset += numInitBoundarySpecies;

    modelData->globalParametersAlias = &modelData->data[offset];
    offset += numIndGlobalParameters;

    modelData->initGlobalParametersAlias = &modelData->data[offset];
    offset += numInitGlobalParameters;

    modelData->reactionRatesAlias = &modelData->data[offset];
    offset += numReactions;

    modelData->rateRuleValuesAlias = &modelData->data[offset];
    offset += numRateRules;

    modelData->floatingSpeciesAmountsAlias = &modelData->data[offset];
    offset += numIndFloatingSpecies;

    assert (modelDataBaseSize + offset * sizeof(double) == modelDataSize  &&
            "LLVMModelData size not equal to base size + data");

    // allocate the stoichiometry matrix
    const std::vector<uint> &stoichRowIndx = symbols.getStoichRowIndx();
    const std::vector<uint> &stoichColIndx = symbols.getStoichColIndx();
    std::vector<double> stoichValues(stoichRowIndx.size(), 0);

    modelData->stoichiometry = rr::csr_matrix_new(numIndFloatingSpecies, numReactions,
            stoichRowIndx, stoichColIndx, stoichValues);

    // make a copy of the random object
    modelData->random = random ? new Random(*random) : 0;

    return modelData;
}

} /* namespace rrllvm */
Beispiel #14
0
void Message::Lock() {
  CritSec_Messages.lock();
}
void Sampler::update() {

	if(!wasRecording && gui.recording) {
		// recording just started.
		//ofSoundStreamStop();
		//ofSoundStreamSetup(0, 1, ofGetAppPtr(), 44100, 512, 4);

	}
	
	wasRecording = gui.recording;
	if(gui.input==INPUT_ACCELEROMETER) {
		#ifdef TARGET_OF_IPHONE
		ofPoint a = ofxAccelerometer.getOrientation();
		float ax = a.x;// + a.y;
	//	printf("%f\n", ax);
		float pitch = ofMap(ax, -45, 45, 1, 0);
		float vol = 0.8;
		if(gui.useYAxisAsVolume) {
			vol = ofMap(a.y, -45, 45, 1, 0);
		}
		
		if(ax<-45) pitch = 1;
		else if(ax>45) {
			pitch = 0;
//			pitch = ofMap(ax, 45, 135, 0, 1, true);
		}
		int currNote = pitch*vision.levels.size();
		if(currNote!=lastNote) {
			
			playSound(vol, pitch);
		}
		#endif
	}
	ofBackground(0,0,0);
	vision.numLevels = gui.noteRange;
	vision.video = &video;
	// the vision code works out how much average change there is in each of
	// either vertical or horizontal strips across the screen.
	// this bit of code finds out if the strip with the most change
	// is a different strip from the last strip, and then triggers that note.
	float max = 0;
	int currMaxLevel = -1;
	for(int i = 0; i < vision.levels.size(); i++) {

		if(max<vision.levels[i].second) {
			max = vision.levels[i].second;
			currMaxLevel = i;
		}
	}

	if(lastMaxLevel!=currMaxLevel) {
		//printf("Playing note %d %f\n", currMaxLevel, max);
		float volume = ofMap(max, 0, 0.5, 0, 1);
		if(volume>1) volume = 1;
		if(volume>movementThreshold) { // some threshold
			lastMaxLevel = currMaxLevel;
			if(gui.input==INPUT_CAMERA) playSound(volume, 1.f - (float)currMaxLevel/vision.levels.size());
		} else {
			currMaxLevel = -1;
		}
	}

	lastMaxLevel = currMaxLevel;



	vision.update();
	
	
	if(gui.mustLoadSound) {
		controlMutex.lock();
		sample.loadFromFile(gui.soundFile);

		controlMutex.unlock();
		gui.mustLoadSound = false;
		noteOffset = 0;
	}
	
	
	/*for(int i = 0; i < particles.size(); i++) {
		particles[i].update();
		if(!particles[i].alive) {
			particles.erase(particles.begin()+i);
			i--;
		}
	}*/
}
Beispiel #16
0
	void unlock() { _mutex.unlock(); }
Beispiel #17
0
	bool try_lock() { return _mutex.tryLock(); }
Beispiel #18
0
	void lock() { _mutex.lock(); }
Beispiel #19
0
void UnlockComm() {
  CritSec_Comm.unlock();
}
ExecutableModel* LLVMModelGenerator::createModel(const std::string& sbml,
        uint options)
{
    bool computeAndAssignConsevationLaws =
            options & ModelGenerator::ComputeAndAssignConsevationLaws;

    bool forceReCompile = options & ModelGenerator::ForceReCompile;

    string md5;

    if (!forceReCompile)
    {
        // check for a chached copy
        md5 = rr::getMD5(sbml);

        ModelPtrMap::const_iterator i;

        SharedModelPtr sp;

        cachedModelsMutex.lock();

        if ((i = cachedModels.find(md5)) != cachedModels.end())
        {
            sp = i->second.lock();
        }

        cachedModelsMutex.unlock();

        // we could have recieved a bad ptr, a model could have been deleted,
        // in which case, we should have a bad ptr.

        if (sp)
        {
            Log(Logger::PRIO_DEBUG) << "found a cached model for " << md5;
            return new LLVMExecutableModel(sp);
        }
        else
        {
            Log(Logger::PRIO_TRACE) << "no cached model found for " << md5
                    << ", creating new one";
        }
    }

    SharedModelPtr rc(new ModelResources());

    ModelGeneratorContext context(sbml, computeAndAssignConsevationLaws);

    rc->evalInitialConditionsPtr =
            EvalInitialConditionsCodeGen(context).createFunction();

    rc->evalReactionRatesPtr =
            EvalReactionRatesCodeGen(context).createFunction();

    rc->getBoundarySpeciesAmountPtr =
            GetBoundarySpeciesAmountCodeGen(context).createFunction();

    rc->getFloatingSpeciesAmountPtr =
            GetFloatingSpeciesAmountCodeGen(context).createFunction();

    rc->getBoundarySpeciesConcentrationPtr =
            GetBoundarySpeciesConcentrationCodeGen(context).createFunction();

    rc->getFloatingSpeciesConcentrationPtr =
            GetFloatingSpeciesConcentrationCodeGen(context).createFunction();

    rc->getCompartmentVolumePtr =
            GetCompartmentVolumeCodeGen(context).createFunction();

    rc->getGlobalParameterPtr =
            GetGlobalParameterCodeGen(context).createFunction();

    rc->evalRateRuleRatesPtr =
            EvalRateRuleRatesCodeGen(context).createFunction();

    rc->getEventTriggerPtr =
            GetEventTriggerCodeGen(context).createFunction();

    rc->getEventPriorityPtr =
            GetEventPriorityCodeGen(context).createFunction();

    rc->getEventDelayPtr =
            GetEventDelayCodeGen(context).createFunction();

    rc->eventTriggerPtr =
            EventTriggerCodeGen(context).createFunction();

    rc->eventAssignPtr =
            EventAssignCodeGen(context).createFunction();

    rc->evalVolatileStoichPtr =
            EvalVolatileStoichCodeGen(context).createFunction();

    rc->evalConversionFactorPtr =
            EvalConversionFactorCodeGen(context).createFunction();

    if (options & ModelGenerator::ReadOnlyModel)
    {
        rc->setBoundarySpeciesAmountPtr = 0;
        rc->setBoundarySpeciesConcentrationPtr = 0;
        rc->setFloatingSpeciesConcentrationPtr = 0;
        rc->setCompartmentVolumePtr = 0;
        rc->setFloatingSpeciesAmountPtr = 0;
        rc->setGlobalParameterPtr = 0;
    }
    else
    {
        rc->setBoundarySpeciesAmountPtr = SetBoundarySpeciesAmountCodeGen(
                context).createFunction();

        rc->setBoundarySpeciesConcentrationPtr =
                SetBoundarySpeciesConcentrationCodeGen(context).createFunction();

        rc->setFloatingSpeciesConcentrationPtr =
                SetFloatingSpeciesConcentrationCodeGen(context).createFunction();

        rc->setCompartmentVolumePtr =
                SetCompartmentVolumeCodeGen(context).createFunction();

        rc->setFloatingSpeciesAmountPtr = SetFloatingSpeciesAmountCodeGen(
                context).createFunction();

        rc->setGlobalParameterPtr =
                SetGlobalParameterCodeGen(context).createFunction();
    }


    // if anything up to this point throws an exception, thats OK, because
    // we have not allocated any memory yet that is not taken care of by
    // something else.
    // Now that everything that could have thrown would have thrown, we
    // can now create the model and set its fields.

    // * MOVE * the bits over from the context to the exe model.
    context.stealThePeach(&rc->symbols, &rc->context,
            &rc->executionEngine, &rc->errStr);

    if (!forceReCompile)
    {
        // check for a chached copy, another thread could have
        // created one while we were making ours...

        ModelPtrMap::const_iterator i;

        SharedModelPtr sp;

        cachedModelsMutex.lock();

        // whilst we have it locked, clear any expired ptrs
        for (ModelPtrMap::const_iterator j = cachedModels.begin();
                j != cachedModels.end();)
        {
            if (j->second.expired())
            {
                Log(Logger::PRIO_INFORMATION) <<
                        "removing expired model resource for hash " << md5;

                j = cachedModels.erase(j);
            }
            else
            {
                ++j;
            }
        }

        if ((i = cachedModels.find(md5)) == cachedModels.end())
        {
            Log(Logger::PRIO_INFORMATION) << "could not find existing cached resource "
                    "resources, for hash " << md5 <<
                    ", inserting new resources into cache";

            cachedModels[md5] = rc;
        }

        cachedModelsMutex.unlock();
    }

    return new LLVMExecutableModel(rc);
}
namespace rrllvm
{

typedef std::tr1::weak_ptr<ModelResources> WeakModelPtr;
typedef std::tr1::shared_ptr<ModelResources> SharedModelPtr;
typedef std::tr1::unordered_map<std::string, WeakModelPtr> ModelPtrMap;

static Poco::Mutex cachedModelsMutex;
static ModelPtrMap cachedModels;

/**
 * copy the cached model fields between a cached model, and a
 * executable model.
 *
 * We don't want to have ExecutableModel inherit from CahcedModel
 * because they do compleltly different things, and have completly
 * differnt deletion semantics
 */
template <typename a_type, typename b_type>
void copyCachedModel(a_type* src, b_type* dst)
{
    dst->symbols = src->symbols;
    dst->context = src->context;
    dst->executionEngine = src->executionEngine;
    dst->errStr = src->errStr;

    dst->evalInitialConditionsPtr = src->evalInitialConditionsPtr;
    dst->evalReactionRatesPtr = src->evalReactionRatesPtr;
    dst->getBoundarySpeciesAmountPtr = src->getBoundarySpeciesAmountPtr;
    dst->getFloatingSpeciesAmountPtr = src->getFloatingSpeciesAmountPtr;
    dst->getBoundarySpeciesConcentrationPtr = src->getBoundarySpeciesConcentrationPtr;
    dst->getFloatingSpeciesConcentrationPtr = src->getFloatingSpeciesConcentrationPtr;
    dst->getCompartmentVolumePtr = src->getCompartmentVolumePtr;
    dst->getGlobalParameterPtr = src->getGlobalParameterPtr;
    dst->evalRateRuleRatesPtr = src->evalRateRuleRatesPtr;
    dst->getEventTriggerPtr = src->getEventTriggerPtr;
    dst->getEventPriorityPtr = src->getEventPriorityPtr;
    dst->getEventDelayPtr = src->getEventDelayPtr;
    dst->eventTriggerPtr = src->eventTriggerPtr;
    dst->eventAssignPtr = src->eventAssignPtr;
    dst->evalVolatileStoichPtr = src->evalVolatileStoichPtr;
    dst->evalConversionFactorPtr = src->evalConversionFactorPtr;
}


LLVMModelGenerator::LLVMModelGenerator()
{
    Log(Logger::PRIO_TRACE) << __FUNC__;
}

LLVMModelGenerator::~LLVMModelGenerator()
{
    Log(Logger::PRIO_TRACE) << __FUNC__;

}

bool LLVMModelGenerator::setTemporaryDirectory(const string& path)
{
    return true;
}

string LLVMModelGenerator::getTemporaryDirectory()
{
    return LLVMCompiler::gurgle();
}

class test
{
public:
    const int* p;
};

void testt(const int** p)
{
    *p = 0;
}

void testtt()
{
    test *t = new test();

    testt(&t->p);
}




ExecutableModel* LLVMModelGenerator::createModel(const std::string& sbml,
        uint options)
{
    bool computeAndAssignConsevationLaws =
            options & ModelGenerator::ComputeAndAssignConsevationLaws;

    bool forceReCompile = options & ModelGenerator::ForceReCompile;

    string md5;

    if (!forceReCompile)
    {
        // check for a chached copy
        md5 = rr::getMD5(sbml);

        ModelPtrMap::const_iterator i;

        SharedModelPtr sp;

        cachedModelsMutex.lock();

        if ((i = cachedModels.find(md5)) != cachedModels.end())
        {
            sp = i->second.lock();
        }

        cachedModelsMutex.unlock();

        // we could have recieved a bad ptr, a model could have been deleted,
        // in which case, we should have a bad ptr.

        if (sp)
        {
            Log(Logger::PRIO_DEBUG) << "found a cached model for " << md5;
            return new LLVMExecutableModel(sp);
        }
        else
        {
            Log(Logger::PRIO_TRACE) << "no cached model found for " << md5
                    << ", creating new one";
        }
    }

    SharedModelPtr rc(new ModelResources());

    ModelGeneratorContext context(sbml, computeAndAssignConsevationLaws);

    rc->evalInitialConditionsPtr =
            EvalInitialConditionsCodeGen(context).createFunction();

    rc->evalReactionRatesPtr =
            EvalReactionRatesCodeGen(context).createFunction();

    rc->getBoundarySpeciesAmountPtr =
            GetBoundarySpeciesAmountCodeGen(context).createFunction();

    rc->getFloatingSpeciesAmountPtr =
            GetFloatingSpeciesAmountCodeGen(context).createFunction();

    rc->getBoundarySpeciesConcentrationPtr =
            GetBoundarySpeciesConcentrationCodeGen(context).createFunction();

    rc->getFloatingSpeciesConcentrationPtr =
            GetFloatingSpeciesConcentrationCodeGen(context).createFunction();

    rc->getCompartmentVolumePtr =
            GetCompartmentVolumeCodeGen(context).createFunction();

    rc->getGlobalParameterPtr =
            GetGlobalParameterCodeGen(context).createFunction();

    rc->evalRateRuleRatesPtr =
            EvalRateRuleRatesCodeGen(context).createFunction();

    rc->getEventTriggerPtr =
            GetEventTriggerCodeGen(context).createFunction();

    rc->getEventPriorityPtr =
            GetEventPriorityCodeGen(context).createFunction();

    rc->getEventDelayPtr =
            GetEventDelayCodeGen(context).createFunction();

    rc->eventTriggerPtr =
            EventTriggerCodeGen(context).createFunction();

    rc->eventAssignPtr =
            EventAssignCodeGen(context).createFunction();

    rc->evalVolatileStoichPtr =
            EvalVolatileStoichCodeGen(context).createFunction();

    rc->evalConversionFactorPtr =
            EvalConversionFactorCodeGen(context).createFunction();

    if (options & ModelGenerator::ReadOnlyModel)
    {
        rc->setBoundarySpeciesAmountPtr = 0;
        rc->setBoundarySpeciesConcentrationPtr = 0;
        rc->setFloatingSpeciesConcentrationPtr = 0;
        rc->setCompartmentVolumePtr = 0;
        rc->setFloatingSpeciesAmountPtr = 0;
        rc->setGlobalParameterPtr = 0;
    }
    else
    {
        rc->setBoundarySpeciesAmountPtr = SetBoundarySpeciesAmountCodeGen(
                context).createFunction();

        rc->setBoundarySpeciesConcentrationPtr =
                SetBoundarySpeciesConcentrationCodeGen(context).createFunction();

        rc->setFloatingSpeciesConcentrationPtr =
                SetFloatingSpeciesConcentrationCodeGen(context).createFunction();

        rc->setCompartmentVolumePtr =
                SetCompartmentVolumeCodeGen(context).createFunction();

        rc->setFloatingSpeciesAmountPtr = SetFloatingSpeciesAmountCodeGen(
                context).createFunction();

        rc->setGlobalParameterPtr =
                SetGlobalParameterCodeGen(context).createFunction();
    }


    // if anything up to this point throws an exception, thats OK, because
    // we have not allocated any memory yet that is not taken care of by
    // something else.
    // Now that everything that could have thrown would have thrown, we
    // can now create the model and set its fields.

    // * MOVE * the bits over from the context to the exe model.
    context.stealThePeach(&rc->symbols, &rc->context,
            &rc->executionEngine, &rc->errStr);

    if (!forceReCompile)
    {
        // check for a chached copy, another thread could have
        // created one while we were making ours...

        ModelPtrMap::const_iterator i;

        SharedModelPtr sp;

        cachedModelsMutex.lock();

        // whilst we have it locked, clear any expired ptrs
        for (ModelPtrMap::const_iterator j = cachedModels.begin();
                j != cachedModels.end();)
        {
            if (j->second.expired())
            {
                Log(Logger::PRIO_INFORMATION) <<
                        "removing expired model resource for hash " << md5;

                j = cachedModels.erase(j);
            }
            else
            {
                ++j;
            }
        }

        if ((i = cachedModels.find(md5)) == cachedModels.end())
        {
            Log(Logger::PRIO_INFORMATION) << "could not find existing cached resource "
                    "resources, for hash " << md5 <<
                    ", inserting new resources into cache";

            cachedModels[md5] = rc;
        }

        cachedModelsMutex.unlock();
    }

    return new LLVMExecutableModel(rc);
}

Compiler* LLVMModelGenerator::getCompiler()
{
    return &compiler;
}

bool LLVMModelGenerator::setCompiler(const string& compiler)
{
    return true;
}

/************ LLVM Utility Functions, TODO: Move To Separate File ************/

/**
 * C++ 11 style to_string for LLVM types
 */
std::string to_string(const llvm::Value *value)
{
    std::string str;
    llvm::raw_string_ostream stream(str);
    value->print(stream);
    return str;
}

} /* namespace rr */
ExecutableModel* LLVMModelGenerator::createModel(const std::string& sbml,
        uint options)
{
    bool forceReCompile = options & LoadSBMLOptions::RECOMPILE;

    string md5;

    if (!forceReCompile)
    {
        // check for a chached copy
        md5 = rr::getMD5(sbml);

        if (options & LoadSBMLOptions::CONSERVED_MOIETIES)
        {
            md5 += "_conserved";
        }

        ModelPtrMap::const_iterator i;

        SharedModelPtr sp;

        cachedModelsMutex.lock();

        if ((i = cachedModels.find(md5)) != cachedModels.end())
        {
            sp = i->second.lock();
        }

        cachedModelsMutex.unlock();

        // we could have recieved a bad ptr, a model could have been deleted,
        // in which case, we should have a bad ptr.

        if (sp)
        {
            Log(Logger::LOG_DEBUG) << "found a cached model for " << md5;
            return new LLVMExecutableModel(sp, createModelData(*sp->symbols, sp->random));
        }
        else
        {
            Log(Logger::LOG_TRACE) << "no cached model found for " << md5
                    << ", creating new one";
        }
    }

    SharedModelPtr rc(new ModelResources());

    ModelGeneratorContext context(sbml, options);

    rc->evalInitialConditionsPtr =
            EvalInitialConditionsCodeGen(context).createFunction();

    rc->evalReactionRatesPtr =
            EvalReactionRatesCodeGen(context).createFunction();

    rc->getBoundarySpeciesAmountPtr =
            GetBoundarySpeciesAmountCodeGen(context).createFunction();

    rc->getFloatingSpeciesAmountPtr =
            GetFloatingSpeciesAmountCodeGen(context).createFunction();

    rc->getBoundarySpeciesConcentrationPtr =
            GetBoundarySpeciesConcentrationCodeGen(context).createFunction();

    rc->getFloatingSpeciesConcentrationPtr =
            GetFloatingSpeciesConcentrationCodeGen(context).createFunction();

    rc->getCompartmentVolumePtr =
            GetCompartmentVolumeCodeGen(context).createFunction();

    rc->getGlobalParameterPtr =
            GetGlobalParameterCodeGen(context).createFunction();

    rc->evalRateRuleRatesPtr =
            EvalRateRuleRatesCodeGen(context).createFunction();

    rc->getEventTriggerPtr =
            GetEventTriggerCodeGen(context).createFunction();

    rc->getEventPriorityPtr =
            GetEventPriorityCodeGen(context).createFunction();

    rc->getEventDelayPtr =
            GetEventDelayCodeGen(context).createFunction();

    rc->eventTriggerPtr =
            EventTriggerCodeGen(context).createFunction();

    rc->eventAssignPtr =
            EventAssignCodeGen(context).createFunction();

    rc->evalVolatileStoichPtr =
            EvalVolatileStoichCodeGen(context).createFunction();

    rc->evalConversionFactorPtr =
            EvalConversionFactorCodeGen(context).createFunction();

    if (options & LoadSBMLOptions::READ_ONLY)
    {
        rc->setBoundarySpeciesAmountPtr = 0;
        rc->setBoundarySpeciesConcentrationPtr = 0;
        rc->setFloatingSpeciesConcentrationPtr = 0;
        rc->setCompartmentVolumePtr = 0;
        rc->setFloatingSpeciesAmountPtr = 0;
        rc->setGlobalParameterPtr = 0;
    }
    else
    {
        rc->setBoundarySpeciesAmountPtr = SetBoundarySpeciesAmountCodeGen(
                context).createFunction();

        rc->setBoundarySpeciesConcentrationPtr =
                SetBoundarySpeciesConcentrationCodeGen(context).createFunction();

        rc->setFloatingSpeciesConcentrationPtr =
                SetFloatingSpeciesConcentrationCodeGen(context).createFunction();

        rc->setCompartmentVolumePtr =
                SetCompartmentVolumeCodeGen(context).createFunction();

        rc->setFloatingSpeciesAmountPtr = SetFloatingSpeciesAmountCodeGen(
                context).createFunction();

        rc->setGlobalParameterPtr =
                SetGlobalParameterCodeGen(context).createFunction();
    }

    if (options & LoadSBMLOptions::MUTABLE_INITIAL_CONDITIONS)
    {
        rc->getFloatingSpeciesInitConcentrationsPtr =
                GetFloatingSpeciesInitConcentrationCodeGen(context).createFunction();
        rc->setFloatingSpeciesInitConcentrationsPtr =
                SetFloatingSpeciesInitConcentrationCodeGen(context).createFunction();

        rc->getFloatingSpeciesInitAmountsPtr =
                GetFloatingSpeciesInitAmountCodeGen(context).createFunction();
        rc->setFloatingSpeciesInitAmountsPtr =
                SetFloatingSpeciesInitAmountCodeGen(context).createFunction();

        rc->getCompartmentInitVolumesPtr =
                GetCompartmentInitVolumeCodeGen(context).createFunction();
        rc->setCompartmentInitVolumesPtr =
                SetCompartmentInitVolumeCodeGen(context).createFunction();

        rc->getGlobalParameterInitValuePtr =
                GetGlobalParameterInitValueCodeGen(context).createFunction();
        rc->setGlobalParameterInitValuePtr =
                SetGlobalParameterInitValueCodeGen(context).createFunction();
    }
    else
    {
        rc->getFloatingSpeciesInitConcentrationsPtr = 0;
        rc->setFloatingSpeciesInitConcentrationsPtr = 0;

        rc->getFloatingSpeciesInitAmountsPtr = 0;
        rc->setFloatingSpeciesInitAmountsPtr = 0;

        rc->getCompartmentInitVolumesPtr = 0;
        rc->setCompartmentInitVolumesPtr = 0;

        rc->getGlobalParameterInitValuePtr = 0;
        rc->setGlobalParameterInitValuePtr = 0;
    }


    // if anything up to this point throws an exception, thats OK, because
    // we have not allocated any memory yet that is not taken care of by
    // something else.
    // Now that everything that could have thrown would have thrown, we
    // can now create the model and set its fields.

    LLVMModelData *modelData = createModelData(context.getModelDataSymbols(),
            context.getRandom());

    uint llvmsize = ModelDataIRBuilder::getModelDataSize(context.getModule(),
            &context.getExecutionEngine());

    if (llvmsize != modelData->size)
    {
        std::stringstream s;

        s << "LLVM Model Data size " << llvmsize << " is different from " <<
                "C++ size of LLVM ModelData, " << modelData->size;

        LLVMModelData_free(modelData);

        Log(Logger::LOG_FATAL) << s.str();

        throw_llvm_exception(s.str());
    }

    // * MOVE * the bits over from the context to the exe model.
    context.stealThePeach(&rc->symbols, &rc->context,
            &rc->executionEngine, &rc->random, &rc->errStr);


    if (!forceReCompile)
    {
        // check for a chached copy, another thread could have
        // created one while we were making ours...

        ModelPtrMap::const_iterator i;

        SharedModelPtr sp;

        cachedModelsMutex.lock();

        // whilst we have it locked, clear any expired ptrs
        for (ModelPtrMap::const_iterator j = cachedModels.begin();
                j != cachedModels.end();)
        {
            if (j->second.expired())
            {
                Log(Logger::LOG_DEBUG) <<
                        "removing expired model resource for hash " << md5;

                j = cachedModels.erase(j);
            }
            else
            {
                ++j;
            }
        }

        if ((i = cachedModels.find(md5)) == cachedModels.end())
        {
            Log(Logger::LOG_DEBUG) << "could not find existing cached resource "
                    "resources, for hash " << md5 <<
                    ", inserting new resources into cache";

            cachedModels[md5] = rc;
        }

        cachedModelsMutex.unlock();
    }

    return new LLVMExecutableModel(rc, modelData);
}