<commit_before>#ifndef __EXTENSION_INTERACTIVE_STRATEGY_HPP
#define __EXTENSION_INTERACTIVE_STRATEGY_HPP

#include <boost/algorithm/string.hpp>

/**
 * A class that opens an interactive shell to allow examining the property of strategies computed
 *
 */
template<class T> class XInteractiveStrategy : public T {
protected:
    XInteractiveStrategy<T>(std::list<std::string> &filenames) : T(filenames) {}

    using T::checkRealizability;
    using T::realizable;
    using T::variables;
    using T::variableNames;
    using T::variableTypes;
    using T::mgr;
    using T::winningPositions;
    using T::livenessAssumptions;
    using T::livenessGuarantees;
    using T::safetyEnv;
    using T::safetySys;
    using T::strategyDumpingData;
    using T::varCubePostOutput;
    using T::postOutputVars;
    using T::determinize;

public:
    static GR1Context* makeInstance(std::list<std::string> &filenames) {
        return new XInteractiveStrategy<T>(filenames);
    }

    void execute() {
        checkRealizability();

        std::vector<BF> positionalStrategiesForTheIndividualGoals(livenessGuarantees.size());
        for (unsigned int i=0;i<livenessGuarantees.size();i++) {
            BF casesCovered = mgr.constantFalse();
            BF strategy = mgr.constantFalse();
            for (auto it = strategyDumpingData.begin();it!=strategyDumpingData.end();it++) {
                if (it->first == i) {
                    BF newCases = it->second.ExistAbstract(varCubePostOutput) & !casesCovered;
                    strategy |= newCases & it->second;
                    casesCovered |= newCases;
                }
            }
            positionalStrategiesForTheIndividualGoals[i] = strategy;
            //BF_newDumpDot(*this,strategy,"PreInput PreOutput PostInput PostOutput","/tmp/generalStrategy.dot");
        }

        if (realizable) {

            BF currentPosition = mgr.constantFalse();

            while(true) {

                // The prompt
                std::cout << "> ";
                std::cout.flush();
                std::string command;
                std::getline(std::cin,command);

                // Check the command
                boost::trim(command);
                boost::to_upper(command);

                if ((command=="QUIT") || (command=="EXIT")) {
                    return;
                } else if (command=="CHECKTRANS") {

                    std::cout << "From: \n";
                    BF from = mgr.constantTrue();
                    for (unsigned int i=0;i<variables.size();i++) {
                        if ((variableTypes[i]==PreInput) || (variableTypes[i]==PreOutput)) {
                            std::cout << " - " << variableNames[i] << ": ";
                            std::cout.flush();
                            int value;
                            std::cin >> value;
                            if (std::cin.fail()) {
                                std::cout << "    -> Error reading value. Assuming 0.\n";
                                value = 0;
                            }
                            if (value==0) {
                                from &= !variables[i];
                            } else if (value==1) {
                                from &= variables[i];
                            } else {
                                std::cout << "    -> Value != 0 or 1. Assuming 1.\n";
                                from &= variables[i];
                            }
                        }
                    }

                    std::cout << "To: \n";
                    BF to = mgr.constantTrue();
                    for (unsigned int i=0;i<variables.size();i++) {
                        if ((variableTypes[i]==PostInput) || (variableTypes[i]==PostOutput)) {
                            std::cout << " - " << variableNames[i] << ": ";
                            std::cout.flush();
                            int value;
                            std::cin >> value;
                            if (std::cin.fail()) {
                                std::cout << "    -> Error reading value. Assuming 0.\n";
                                value = 0;
                            }
                            if (value==0) {
                                from &= !variables[i];
                            } else if (value==1) {
                                from &= variables[i];
                            } else {
                                std::cout << "    -> Value != 0 or 1. Assuming 1.\n";
                                from &= variables[i];
                            }
                        }
                    }

                    std::cout << "Result: \n";
                    if ((from & winningPositions).isFalse()) {
                        std::cout << "- The pre-position is not winning.\n";
                    } else {
                        std::cout << "- The pre-position is winning.\n";
                    }
                    if ((from & to & safetyEnv).isFalse()) {
                        std::cout << "- The transition VIOLATES the SAFETY ASSUMPTIONS\n";
                    } else {
                        std::cout << "- The transition SATISFIES the SAFETY ASSUMPTIONS\n";
                    }
                    if ((from & to & safetySys).isFalse()) {
                        std::cout << "- The transition VIOLATES the SAFETY GUARANTEES\n";
                    } else {
                        std::cout << "- The transition SATISFIES the SAFETY GUARANTEES\n";
                    }
                    std::cout << "- The transition is a goal transition for the following liveness assumptions: ";
                    bool foundOne = false;
                    for (uint i=0;i<livenessAssumptions.size();i++) {
                        if (!(livenessAssumptions[i] & from & to).isFalse()) {
                            if (foundOne) std::cout << ", ";
                            foundOne = true;
                            std::cout << i;
                        }
                    }
                    if (!foundOne) std::cout << "none";
                    std::cout << std::endl;
                    std::cout << "- The transition is a goal transition for the following liveness guarantees: ";
                    foundOne = false;
                    for (uint i=0;i<livenessGuarantees.size();i++) {
                        if (!(livenessGuarantees[i] & from & to).isFalse()) {
                            if (foundOne) std::cout << ", ";
                            foundOne = true;
                            std::cout << i;
                        }
                    }
                    if (!foundOne) std::cout << "none";
                    std::cout << std::endl;

                    // Analyse if it is part of a possible strategy
                    std::cout << "- The transition is a possible transition in a strategy for the following goals: ";
                    foundOne = false;
                    for (uint i=0;i<livenessGuarantees.size();i++) {
                        if (!(positionalStrategiesForTheIndividualGoals[i] & from & to).isFalse()) {
                            if (foundOne) std::cout << ", ";
                            foundOne = true;
                            std::cout << i;
                        }
                    }
                    if (!foundOne) std::cout << "none";
                    std::cout << std::endl;

                } else if (command=="SETPOS") {

                    std::cout << "Position: \n";
                    BF from = mgr.constantTrue();
                    for (unsigned int i=0;i<variables.size();i++) {
                        if ((variableTypes[i]==PreInput) || (variableTypes[i]==PreOutput)) {
                            std::cout << " - " << variableNames[i] << ": ";
                            std::cout.flush();
                            int value;
                            std::cin >> value;
                            if (std::cin.fail()) {
                                std::cout << "    -> Error reading value. Assuming 0.\n";
                                value = 0;
                            }
                            if (value==0) {
                                from &= !variables[i];
                            } else if (value==1) {
                                from &= variables[i];
                            } else {
                                std::cout << "    -> Value != 0 or 1. Assuming 1.\n";
                                from &= variables[i];
                            }
                        }
                    }
                    currentPosition = from;
                } else if (command=="MOVE") {

                    std::cout << "Guarantee No.: ";
                    std::cout.flush();
                    unsigned int guarantee;
                    std::cin >> guarantee;
                    if (std::cin.fail()) {
                        std::cout << "    -> Error reading value. Aborting \n";
                    } else if (guarantee>=livenessGuarantees.size()) {
                        std::cout << "    -> Number too large. Aborting \n";
                    } else {

                        BF allowedInputs = (currentPosition & safetyEnv);
                        BF_newDumpDot(*this,allowedInputs,NULL,"/tmp/allowedInputs.dot");

                        std::cout << "To: \n";
                        BF to = mgr.constantTrue();
                        for (unsigned int i=0;i<variables.size();i++) {
                            if ((variableTypes[i]==PostInput)) {
                                std::cout << " - " << variableNames[i] << ": ";
                                std::cout.flush();
                                int value;
                                std::cin >> value;
                                if (std::cin.fail()) {
                                    std::cout << "    -> Error reading value. Assuming 0.\n";
                                    value = 0;
                                }
                                if (value==0) {
                                    to &= !variables[i];
                                } else if (value==1) {
                                    to &= variables[i];
                                } else {
                                    std::cout << "    -> Value != 0 or 1. Assuming 1.\n";
                                    to &= variables[i];
                                }
                            }
                        }

                        BF transition = currentPosition & to & positionalStrategiesForTheIndividualGoals[guarantee];

                        if (transition.isFalse()) {
                            std::cout << "    -> Error: Input not allowed here.\n";
                            if (!(currentPosition & to & safetyEnv).isFalse()) {
                                std::cout << "       -> Actually, that's an internal error!\n";
                            }
                        } else {

                            transition = determinize(transition,postOutputVars);

                            for (unsigned int i=0;i<variables.size();i++) {
                                if ((variableTypes[i]==PostOutput)) {
                                    if ((variables[i] & transition).isFalse()) {
                                        std::cout << " - " << variableNames[i] << " = 0\n";
                                    } else {
                                        std::cout << " - " << variableNames[i] << " = 1\n";
                                    }
                                }
                            }

                            std::cout << "- The transition is a goal transition for the following liveness assumptions: ";
                            bool foundOne = false;
                            for (uint i=0;i<livenessAssumptions.size();i++) {
                                if (!(livenessAssumptions[i] & transition).isFalse()) {
                                    if (foundOne) std::cout << ", ";
                                    foundOne = true;
                                    std::cout << i;
                                }
                            }
                            if (!foundOne) std::cout << "none";
                            std::cout << std::endl;
                            std::cout << "- The transition is a goal transition for the following liveness guarantees: ";
                            foundOne = false;
                            for (uint i=0;i<livenessGuarantees.size();i++) {
                                if (!(livenessGuarantees[i] & transition).isFalse()) {
                                    if (foundOne) std::cout << ", ";
                                    foundOne = true;
                                    std::cout << i;
                                }
                            }
                            if (!foundOne) std::cout << "none";
                            std::cout << std::endl;

                            // Analyse if it is part of a possible strategy
                            std::cout << "- The transition is a possible transition in a strategy for the following goals: ";
                            foundOne = false;
                            for (uint i=0;i<livenessGuarantees.size();i++) {
                                if (!(positionalStrategiesForTheIndividualGoals[i] & transition).isFalse()) {
                                    if (foundOne) std::cout << ", ";
                                    foundOne = true;
                                    std::cout << i;
                                }
                            }
                            if (!foundOne) std::cout << "none";
                            std::cout << std::endl;

                        }
                    }

                }
            }

        }

    }

};

#endif
<commit_msg>uint to unsigned int<commit_after>#ifndef __EXTENSION_INTERACTIVE_STRATEGY_HPP
#define __EXTENSION_INTERACTIVE_STRATEGY_HPP

#include <boost/algorithm/string.hpp>

/**
 * A class that opens an interactive shell to allow examining the property of strategies computed
 *
 */
template<class T> class XInteractiveStrategy : public T {
protected:
    XInteractiveStrategy<T>(std::list<std::string> &filenames) : T(filenames) {}

    using T::checkRealizability;
    using T::realizable;
    using T::variables;
    using T::variableNames;
    using T::variableTypes;
    using T::mgr;
    using T::winningPositions;
    using T::livenessAssumptions;
    using T::livenessGuarantees;
    using T::safetyEnv;
    using T::safetySys;
    using T::strategyDumpingData;
    using T::varCubePostOutput;
    using T::postOutputVars;
    using T::determinize;

public:
    static GR1Context* makeInstance(std::list<std::string> &filenames) {
        return new XInteractiveStrategy<T>(filenames);
    }

    void execute() {
        checkRealizability();

        std::vector<BF> positionalStrategiesForTheIndividualGoals(livenessGuarantees.size());
        for (unsigned int i=0;i<livenessGuarantees.size();i++) {
            BF casesCovered = mgr.constantFalse();
            BF strategy = mgr.constantFalse();
            for (auto it = strategyDumpingData.begin();it!=strategyDumpingData.end();it++) {
                if (it->first == i) {
                    BF newCases = it->second.ExistAbstract(varCubePostOutput) & !casesCovered;
                    strategy |= newCases & it->second;
                    casesCovered |= newCases;
                }
            }
            positionalStrategiesForTheIndividualGoals[i] = strategy;
            //BF_newDumpDot(*this,strategy,"PreInput PreOutput PostInput PostOutput","/tmp/generalStrategy.dot");
        }

        if (realizable) {

            BF currentPosition = mgr.constantFalse();

            while(true) {

                // The prompt
                std::cout << "> ";
                std::cout.flush();
                std::string command;
                std::getline(std::cin,command);

                // Check the command
                boost::trim(command);
                boost::to_upper(command);

                if ((command=="QUIT") || (command=="EXIT")) {
                    return;
                } else if (command=="CHECKTRANS") {

                    std::cout << "From: \n";
                    BF from = mgr.constantTrue();
                    for (unsigned int i=0;i<variables.size();i++) {
                        if ((variableTypes[i]==PreInput) || (variableTypes[i]==PreOutput)) {
                            std::cout << " - " << variableNames[i] << ": ";
                            std::cout.flush();
                            int value;
                            std::cin >> value;
                            if (std::cin.fail()) {
                                std::cout << "    -> Error reading value. Assuming 0.\n";
                                value = 0;
                            }
                            if (value==0) {
                                from &= !variables[i];
                            } else if (value==1) {
                                from &= variables[i];
                            } else {
                                std::cout << "    -> Value != 0 or 1. Assuming 1.\n";
                                from &= variables[i];
                            }
                        }
                    }

                    std::cout << "To: \n";
                    BF to = mgr.constantTrue();
                    for (unsigned int i=0;i<variables.size();i++) {
                        if ((variableTypes[i]==PostInput) || (variableTypes[i]==PostOutput)) {
                            std::cout << " - " << variableNames[i] << ": ";
                            std::cout.flush();
                            int value;
                            std::cin >> value;
                            if (std::cin.fail()) {
                                std::cout << "    -> Error reading value. Assuming 0.\n";
                                value = 0;
                            }
                            if (value==0) {
                                from &= !variables[i];
                            } else if (value==1) {
                                from &= variables[i];
                            } else {
                                std::cout << "    -> Value != 0 or 1. Assuming 1.\n";
                                from &= variables[i];
                            }
                        }
                    }

                    std::cout << "Result: \n";
                    if ((from & winningPositions).isFalse()) {
                        std::cout << "- The pre-position is not winning.\n";
                    } else {
                        std::cout << "- The pre-position is winning.\n";
                    }
                    if ((from & to & safetyEnv).isFalse()) {
                        std::cout << "- The transition VIOLATES the SAFETY ASSUMPTIONS\n";
                    } else {
                        std::cout << "- The transition SATISFIES the SAFETY ASSUMPTIONS\n";
                    }
                    if ((from & to & safetySys).isFalse()) {
                        std::cout << "- The transition VIOLATES the SAFETY GUARANTEES\n";
                    } else {
                        std::cout << "- The transition SATISFIES the SAFETY GUARANTEES\n";
                    }
                    std::cout << "- The transition is a goal transition for the following liveness assumptions: ";
                    bool foundOne = false;
                    for (unsigned int i=0;i<livenessAssumptions.size();i++) {
                        if (!(livenessAssumptions[i] & from & to).isFalse()) {
                            if (foundOne) std::cout << ", ";
                            foundOne = true;
                            std::cout << i;
                        }
                    }
                    if (!foundOne) std::cout << "none";
                    std::cout << std::endl;
                    std::cout << "- The transition is a goal transition for the following liveness guarantees: ";
                    foundOne = false;
                    for (unsigned int i=0;i<livenessGuarantees.size();i++) {
                        if (!(livenessGuarantees[i] & from & to).isFalse()) {
                            if (foundOne) std::cout << ", ";
                            foundOne = true;
                            std::cout << i;
                        }
                    }
                    if (!foundOne) std::cout << "none";
                    std::cout << std::endl;

                    // Analyse if it is part of a possible strategy
                    std::cout << "- The transition is a possible transition in a strategy for the following goals: ";
                    foundOne = false;
                    for (unsigned int i=0;i<livenessGuarantees.size();i++) {
                        if (!(positionalStrategiesForTheIndividualGoals[i] & from & to).isFalse()) {
                            if (foundOne) std::cout << ", ";
                            foundOne = true;
                            std::cout << i;
                        }
                    }
                    if (!foundOne) std::cout << "none";
                    std::cout << std::endl;

                } else if (command=="SETPOS") {

                    std::cout << "Position: \n";
                    BF from = mgr.constantTrue();
                    for (unsigned int i=0;i<variables.size();i++) {
                        if ((variableTypes[i]==PreInput) || (variableTypes[i]==PreOutput)) {
                            std::cout << " - " << variableNames[i] << ": ";
                            std::cout.flush();
                            int value;
                            std::cin >> value;
                            if (std::cin.fail()) {
                                std::cout << "    -> Error reading value. Assuming 0.\n";
                                value = 0;
                            }
                            if (value==0) {
                                from &= !variables[i];
                            } else if (value==1) {
                                from &= variables[i];
                            } else {
                                std::cout << "    -> Value != 0 or 1. Assuming 1.\n";
                                from &= variables[i];
                            }
                        }
                    }
                    currentPosition = from;
                } else if (command=="MOVE") {

                    std::cout << "Guarantee No.: ";
                    std::cout.flush();
                    unsigned int guarantee;
                    std::cin >> guarantee;
                    if (std::cin.fail()) {
                        std::cout << "    -> Error reading value. Aborting \n";
                    } else if (guarantee>=livenessGuarantees.size()) {
                        std::cout << "    -> Number too large. Aborting \n";
                    } else {

                        BF allowedInputs = (currentPosition & safetyEnv);
                        BF_newDumpDot(*this,allowedInputs,NULL,"/tmp/allowedInputs.dot");

                        std::cout << "To: \n";
                        BF to = mgr.constantTrue();
                        for (unsigned int i=0;i<variables.size();i++) {
                            if ((variableTypes[i]==PostInput)) {
                                std::cout << " - " << variableNames[i] << ": ";
                                std::cout.flush();
                                int value;
                                std::cin >> value;
                                if (std::cin.fail()) {
                                    std::cout << "    -> Error reading value. Assuming 0.\n";
                                    value = 0;
                                }
                                if (value==0) {
                                    to &= !variables[i];
                                } else if (value==1) {
                                    to &= variables[i];
                                } else {
                                    std::cout << "    -> Value != 0 or 1. Assuming 1.\n";
                                    to &= variables[i];
                                }
                            }
                        }

                        BF transition = currentPosition & to & positionalStrategiesForTheIndividualGoals[guarantee];

                        if (transition.isFalse()) {
                            std::cout << "    -> Error: Input not allowed here.\n";
                            if (!(currentPosition & to & safetyEnv).isFalse()) {
                                std::cout << "       -> Actually, that's an internal error!\n";
                            }
                        } else {

                            transition = determinize(transition,postOutputVars);

                            for (unsigned int i=0;i<variables.size();i++) {
                                if ((variableTypes[i]==PostOutput)) {
                                    if ((variables[i] & transition).isFalse()) {
                                        std::cout << " - " << variableNames[i] << " = 0\n";
                                    } else {
                                        std::cout << " - " << variableNames[i] << " = 1\n";
                                    }
                                }
                            }

                            std::cout << "- The transition is a goal transition for the following liveness assumptions: ";
                            bool foundOne = false;
                            for (unsigned int i=0;i<livenessAssumptions.size();i++) {
                                if (!(livenessAssumptions[i] & transition).isFalse()) {
                                    if (foundOne) std::cout << ", ";
                                    foundOne = true;
                                    std::cout << i;
                                }
                            }
                            if (!foundOne) std::cout << "none";
                            std::cout << std::endl;
                            std::cout << "- The transition is a goal transition for the following liveness guarantees: ";
                            foundOne = false;
                            for (unsigned int i=0;i<livenessGuarantees.size();i++) {
                                if (!(livenessGuarantees[i] & transition).isFalse()) {
                                    if (foundOne) std::cout << ", ";
                                    foundOne = true;
                                    std::cout << i;
                                }
                            }
                            if (!foundOne) std::cout << "none";
                            std::cout << std::endl;

                            // Analyse if it is part of a possible strategy
                            std::cout << "- The transition is a possible transition in a strategy for the following goals: ";
                            foundOne = false;
                            for (unsigned int i=0;i<livenessGuarantees.size();i++) {
                                if (!(positionalStrategiesForTheIndividualGoals[i] & transition).isFalse()) {
                                    if (foundOne) std::cout << ", ";
                                    foundOne = true;
                                    std::cout << i;
                                }
                            }
                            if (!foundOne) std::cout << "none";
                            std::cout << std::endl;

                        }
                    }

                }
            }

        }

    }

};

#endif
<|endoftext|>


<commit_before>/*
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License along
    with this program; if not, write to the Free Software Foundation, Inc.,
    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

#include "World.h"
#include "Hatchery.h"

Hatchery::Hatchery(QWidget *parent) : QDialog(parent) {
	setWindowTitle(tr("Hatchery"));
	setAttribute(Qt::WA_QuitOnClose, false);

	std::string hatcherybgfile = world.findFile("hatchery/hatchery.bmp");
	if (hatcherybgfile.empty()) return;
	QPixmap hatcherybg(QString(hatcherybgfile.c_str()));

	resize(hatcherybg.width() + 6, hatcherybg.height() + 6);

	graphicsScene = new QGraphicsScene();
	graphicsView = new QGraphicsView(graphicsScene, this);
	QHBoxLayout *layout = new QHBoxLayout(this);
	layout->addWidget(graphicsView);
	layout->setContentsMargins(0, 0, 0, 0);

	graphicsScene->addPixmap(hatcherybg);
}

Hatchery::~Hatchery() {
}

<commit_msg>Hatchery: add mask, comments<commit_after>/*
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License along
    with this program; if not, write to the Free Software Foundation, Inc.,
    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

#include "World.h"
#include "Hatchery.h"

/*
  C1 hatchery resources:
  hatchery.bmp and htchmask.bmp used for the background/foreground
  SCAN*.BMP and hdsk.wav used for egg disk animation
  EGG*.BMP and hegg.wav used for egg movement animation
  FAN*.BMP and hfan.wav used for the fan animation
  lightoff.bmp and hlgt.wav used for the light flickering
  GENSPIN.BMP, and hmle.wav/hfml.wav used for male/female animation (male.bmp and female.bmp also present)
 */

Hatchery::Hatchery(QWidget *parent) : QDialog(parent) {
	setWindowTitle(tr("Hatchery"));
	setAttribute(Qt::WA_QuitOnClose, false);

	/* hatchery background */
	std::string hatcherybgfile = world.findFile("hatchery/hatchery.bmp");
	if (hatcherybgfile.empty()) return;
	QPixmap hatcherybg(QString(hatcherybgfile.c_str()));

	resize(hatcherybg.width() + 6, hatcherybg.height() + 6);

	/* create the widgets/layout */
	graphicsScene = new QGraphicsScene();
	graphicsView = new QGraphicsView(graphicsScene, this);
	QHBoxLayout *layout = new QHBoxLayout(this);
	layout->addWidget(graphicsView);
	layout->setContentsMargins(0, 0, 0, 0);

	graphicsScene->addPixmap(hatcherybg);

	/* mask which goes over the eggs */
	std::string hatcherymaskfile = world.findFile("hatchery/htchmask.bmp");
	if (hatcherymaskfile.size()) {
		QPixmap hatcherymask(QString(hatcherymaskfile.c_str()));
		QColor maskcolour(0xff, 0x00, 0x80);
		hatcherymask.setMask(hatcherymask.createMaskFromColor(maskcolour));

		QGraphicsPixmapItem *maskitem = graphicsScene->addPixmap(hatcherymask);
		maskitem->setPos(0, 168);
	}

	/* fan animation */
	for (unsigned int i = 0; i < 4; i++) {
		// TODO
	}

	/* 'off' state for the light */
	// TODO

	/* eggs */
	// TODO

	/* gender marker animation */
	// TODO
}

Hatchery::~Hatchery() {
}

<|endoftext|>


<commit_before>#include "std_incl.h"
#include "ResultManager.h"
#include "utils.h"

ResultManager::ResultManager(const char *outfile, const char* frameInfoFile, ResultManagerConfig *cfg)
{
	config = *cfg;
	outputFile = outfile;
	this->frameInfoFile = frameInfoFile;

	startFrame = 0;
	lastSaveFrame = 0;
	processedFrames = 0;
	capturedFrames = 0;
	localizationsDone = 0;

	qtrk = 0;

	thread = Threads::Create(ThreadLoop, this);
	quit=false;

	remove(outfile);
	remove(frameInfoFile);

	if(config.binaryOutput) {
		FILE *f = fopen(outfile, "w");
		fwrite(&cfg->numBeads, sizeof(int), 1, f);
		fclose(f);
	}

	dbgprintf("Allocating ResultManager with %d beads and writeinterval %d\n", cfg->numBeads, cfg->writeInterval);
}

ResultManager::~ResultManager()
{
	quit = true;
	Threads::WaitAndClose(thread);

	DeleteAllElems(frameResults);
}

void ResultManager::StoreResult(LocalizationResult *r)
{
	int index = r->job.frame - startFrame;

	if (index >= frameResults.size()) {
		dbgprintf("dropping result. Result provided for unregistered frame %d. Current frames registered: %d\n",
			r->job.frame, startFrame + frameResults.size());
		return; // add errors?
	}

	LocalizationResult scaled = *r;
	// Make roi-centered pos
	scaled.pos = scaled.pos - vector3f( qtrk->cfg.width*0.5f, qtrk->cfg.height*0.5f, 0);
	scaled.pos = ( scaled.pos + config.offset ) * config.scaling;
	FrameResult* fr = frameResults[index];
	fr->results[r->job.zlutIndex] = scaled;
	fr->count++;

	// Advance fullFrames
	frameCountMutex.lock();
	while (processedFrames - startFrame < frameResults.size() && frameResults[processedFrames-startFrame]->count == config.numBeads)
		processedFrames ++;
	localizationsDone ++;
	frameCountMutex.unlock();
}

void ResultManager::Write()
{
	FILE* f = outputFile.empty () ? 0 : fopen(outputFile.c_str(), "a");
	FILE* finfo = frameInfoFile.empty() ? 0 : fopen(frameInfoFile.c_str(), "a");

	resultMutex.lock();
	if (config.binaryOutput) {
		for (uint j=lastSaveFrame; j<processedFrames;j++)
		{
			auto fr = frameResults[j-startFrame];
			if (f) {
				fwrite(&j, sizeof(uint), 1, f);
				fwrite(&fr->timestamp, sizeof(double), 1, f);
				for (int i=0;i<config.numBeads;i++)
				{
					LocalizationResult *r = &fr->results[i];
					fwrite(&r->pos, sizeof(vector3f), 1, f);
				}
			}
			if (finfo)
				fwrite(&fr->timestamp, sizeof(double), 1, finfo);
		}
	}
	else {
		for (uint k=lastSaveFrame; k<processedFrames;k++)
		{
			auto fr = frameResults[k-startFrame];
			if (f) {
				fprintf(f,"%d\t%f\t", k, fr->timestamp);
				for (int i=0;i<config.numBeads;i++)
				{
					LocalizationResult *r = &fr->results[i];
					fprintf(f, "%.5f\t%.5f\t%.5f\t", r->pos.x,r->pos.y,r->pos.z);
				}
				fputs("\n", f);
			}
			if (finfo) {
				fprintf(finfo,"%d\t%f\t", k, fr->timestamp);
				for (int i=0;i<config.numFrameInfoColumns;i++)
					fprintf(finfo, "%.5f\t", fr->frameInfo[i]);
				fputs("\n", finfo);
			}
		}
	}

	dbgprintf("Saved frame %d to %d\n", lastSaveFrame, processedFrames);

	if(f) fclose(f);
	if(finfo) fclose(finfo);
	frameCountMutex.lock();
	lastSaveFrame = processedFrames;
	frameCountMutex.unlock();

	resultMutex.unlock();
}

void ResultManager::SetTracker(QueuedTracker *qtrk)
{
	trackerMutex.lock();
	this->qtrk = qtrk;
	trackerMutex.unlock();
}

bool ResultManager::Update()
{
	trackerMutex.lock();

	if (!qtrk) {
		trackerMutex.unlock();
		return 0;
	}

	const int NResultBuf = 40;
	LocalizationResult resultbuf[NResultBuf];

	int count = qtrk->PollFinished( resultbuf, NResultBuf );

	resultMutex.lock();
	for (int i=0;i<count;i++)
		StoreResult(&resultbuf[i]);
	resultMutex.unlock();

	trackerMutex.unlock();

	if (processedFrames - lastSaveFrame >= config.writeInterval) {
		Write();
	}

	if (config.maxFramesInMemory>0 && frameResults.size () > config.maxFramesInMemory) {
		int del = frameResults.size()-config.maxFramesInMemory;
		dbgprintf("Removing %d frames from memory\n", del);

		for (int i=0;i<del;i++)
			delete frameResults[i];
		frameResults.erase(frameResults.begin(), frameResults.begin()+del);

		frameCountMutex.lock();
		startFrame += del;
		frameCountMutex.unlock();
	}

	return count>0;
}

void ResultManager::ThreadLoop(void *param)
{
	ResultManager* rm = (ResultManager*)param;

	while(true) {
		if (!rm->Update())
			Threads::Sleep(20);

		if (rm->quit)
			break;
	}
}

int ResultManager::GetBeadPositions(int startFrame, int endFrame, int bead, LocalizationResult* results)
{
	frameCountMutex.lock();
	int start = startFrame - this->startFrame;

	if (endFrame > processedFrames)
		endFrame = processedFrames;

	int end = endFrame - this->startFrame;
	frameCountMutex.unlock();

	if (start < 0)
		return 0;

	resultMutex.lock();
	for (int i=start;i<end;i++){
		results[i-start] = frameResults[i]->results[bead];
	}
	resultMutex.unlock();

	return end-start;
}

void ResultManager::Flush()
{
	Write();

	resultMutex.lock();

	// Dump stats about unfinished frames for debugging
	for (int i=0;i<frameResults.size();i++) {
		FrameResult *fr = frameResults[i];
		dbgprintf("Frame %d. TS: %f, Count: %d\n", i, fr->timestamp, fr->count);
		if (fr->count != config.numBeads) {
			for (int j=0;j<fr->results.size();j++) {
				if( fr->results[j].job.locType == 0 )
					dbgprintf("%d, ", j );
			}
			dbgprintf("\n");
		}
	}

	resultMutex.unlock();
}

void ResultManager::GetFrameCounters(int* startFrame, int *processedFrames, int *lastSaveFrame, int *capturedFrames, int *localizationsDone)
{
	frameCountMutex.lock();
	if (startFrame) *startFrame = this->startFrame;
	if (processedFrames) *processedFrames = this->processedFrames;
	if (lastSaveFrame) *lastSaveFrame = this->lastSaveFrame;
	if (localizationsDone) *localizationsDone = this->localizationsDone;
	frameCountMutex.unlock();

	if (capturedFrames) {
		resultMutex.lock();
		*capturedFrames = this->capturedFrames;
		resultMutex.unlock();
	}
}

int ResultManager::GetResults(LocalizationResult* results, int startFrame, int numFrames)
{
	frameCountMutex.lock();

	if (startFrame >= this->startFrame && numFrames+startFrame <= processedFrames)  {
		resultMutex.lock();
		for (int f=0;f<numFrames;f++) {
			int index = f + startFrame - this->startFrame;
			for (int j=0;j<config.numBeads;j++)
				results[config.numBeads*f+j] = frameResults[index]->results[j];
		}

		resultMutex.unlock();
	}
	frameCountMutex.unlock();

	return numFrames;
}

int ResultManager::StoreFrameInfo(double timestamp, float* columns)
{
	resultMutex.lock();
	auto fr = new FrameResult( config.numBeads, config.numFrameInfoColumns);
	fr->timestamp = timestamp;
	for(int i=0;i<config.numFrameInfoColumns;i++)
		fr->frameInfo[i]=columns[i];
	frameResults.push_back (fr);
	int nfr = ++capturedFrames;
	resultMutex.unlock();
	return nfr;
}

int ResultManager::GetFrameCount()
{
	resultMutex.lock();
	int nfr = capturedFrames;
	resultMutex.unlock();
	return nfr;
}

<commit_msg>* return partial GetBeadPositions() if range is too large<commit_after>#include "std_incl.h"
#include "ResultManager.h"
#include "utils.h"

ResultManager::ResultManager(const char *outfile, const char* frameInfoFile, ResultManagerConfig *cfg)
{
	config = *cfg;
	outputFile = outfile;
	this->frameInfoFile = frameInfoFile;

	startFrame = 0;
	lastSaveFrame = 0;
	processedFrames = 0;
	capturedFrames = 0;
	localizationsDone = 0;

	qtrk = 0;

	thread = Threads::Create(ThreadLoop, this);
	quit=false;

	remove(outfile);
	remove(frameInfoFile);

	dbgprintf("Allocating ResultManager with %d beads and writeinterval %d\n", cfg->numBeads, cfg->writeInterval);
}

ResultManager::~ResultManager()
{
	quit = true;
	Threads::WaitAndClose(thread);

	DeleteAllElems(frameResults);
}

void ResultManager::StoreResult(LocalizationResult *r)
{
	int index = r->job.frame - startFrame;

	if (index >= frameResults.size()) {
		dbgprintf("dropping result. Result provided for unregistered frame %d. Current frames registered: %d\n",
			r->job.frame, startFrame + frameResults.size());
		return; // add errors?
	}

	LocalizationResult scaled = *r;
	// Make roi-centered pos
	scaled.pos = scaled.pos - vector3f( qtrk->cfg.width*0.5f, qtrk->cfg.height*0.5f, 0);
	scaled.pos = ( scaled.pos + config.offset ) * config.scaling;
	FrameResult* fr = frameResults[index];
	fr->results[r->job.zlutIndex] = scaled;
	fr->count++;

	// Advance fullFrames
	frameCountMutex.lock();
	while (processedFrames - startFrame < frameResults.size() && frameResults[processedFrames-startFrame]->count == config.numBeads)
		processedFrames ++;
	localizationsDone ++;
	frameCountMutex.unlock();
}

void ResultManager::Write()
{
	FILE* f = outputFile.empty () ? 0 : fopen(outputFile.c_str(), "a");
	FILE* finfo = frameInfoFile.empty() ? 0 : fopen(frameInfoFile.c_str(), "a");

	resultMutex.lock();
	if (config.binaryOutput) {
		if (lastSaveFrame == 0) {
			fwrite(&config.numBeads, sizeof(int), 1, f);
			dbgprintf("writing %d beads into file %s\n", config.numBeads, outputFile.c_str());
		}

		for (uint j=lastSaveFrame; j<processedFrames;j++)
		{
			auto fr = frameResults[j-startFrame];
			if (f) {
				fwrite(&j, sizeof(uint), 1, f);
				fwrite(&fr->timestamp, sizeof(double), 1, f);
				for (int i=0;i<config.numBeads;i++)
				{
					LocalizationResult *r = &fr->results[i];
					fwrite(&r->pos, sizeof(vector3f), 1, f);
				}
			}
			if (finfo)
				fwrite(&fr->timestamp, sizeof(double), 1, finfo);
		}
	}
	else {
		for (uint k=lastSaveFrame; k<processedFrames;k++)
		{
			auto fr = frameResults[k-startFrame];
			if (f) {
				fprintf(f,"%d\t%f\t", k, fr->timestamp);
				for (int i=0;i<config.numBeads;i++)
				{
					LocalizationResult *r = &fr->results[i];
					fprintf(f, "%.5f\t%.5f\t%.5f\t", r->pos.x,r->pos.y,r->pos.z);
				}
				fputs("\n", f);
			}
			if (finfo) {
				fprintf(finfo,"%d\t%f\t", k, fr->timestamp);
				for (int i=0;i<config.numFrameInfoColumns;i++)
					fprintf(finfo, "%.5f\t", fr->frameInfo[i]);
				fputs("\n", finfo);
			}
		}
	}

	dbgprintf("Saved frame %d to %d\n", lastSaveFrame, processedFrames);

	if(f) fclose(f);
	if(finfo) fclose(finfo);
	frameCountMutex.lock();
	lastSaveFrame = processedFrames;
	frameCountMutex.unlock();

	resultMutex.unlock();
}

void ResultManager::SetTracker(QueuedTracker *qtrk)
{
	trackerMutex.lock();
	this->qtrk = qtrk;
	trackerMutex.unlock();
}

bool ResultManager::Update()
{
	trackerMutex.lock();

	if (!qtrk) {
		trackerMutex.unlock();
		return 0;
	}

	const int NResultBuf = 40;
	LocalizationResult resultbuf[NResultBuf];

	int count = qtrk->PollFinished( resultbuf, NResultBuf );

	resultMutex.lock();
	for (int i=0;i<count;i++)
		StoreResult(&resultbuf[i]);
	resultMutex.unlock();

	trackerMutex.unlock();

	if (processedFrames - lastSaveFrame >= config.writeInterval) {
		Write();
	}

	if (config.maxFramesInMemory>0 && frameResults.size () > config.maxFramesInMemory) {
		int del = frameResults.size()-config.maxFramesInMemory;
		dbgprintf("Removing %d frames from memory\n", del);

		for (int i=0;i<del;i++)
			delete frameResults[i];
		frameResults.erase(frameResults.begin(), frameResults.begin()+del);

		frameCountMutex.lock();
		startFrame += del;
		frameCountMutex.unlock();
	}

	return count>0;
}

void ResultManager::ThreadLoop(void *param)
{
	ResultManager* rm = (ResultManager*)param;

	while(true) {
		if (!rm->Update())
			Threads::Sleep(20);

		if (rm->quit)
			break;
	}
}

int ResultManager::GetBeadPositions(int startFrame, int endFrame, int bead, LocalizationResult* results)
{
	int count = endFrame-startFrame;

	frameCountMutex.lock();
	if (endFrame > processedFrames)
		endFrame = processedFrames;

	int start = startFrame - this->startFrame;
	if (start < 0) start = 0;
	if (count > processedFrames-this->startFrame)
		count = processedFrames-this->startFrame;

	frameCountMutex.unlock();

	resultMutex.lock();
	for (int i=0;i<count;i++){
		results[i] = frameResults[i+start]->results[bead];
	}
	resultMutex.unlock();

	return count;
}

void ResultManager::Flush()
{
	Write();

	resultMutex.lock();

	// Dump stats about unfinished frames for debugging
	for (int i=0;i<frameResults.size();i++) {
		FrameResult *fr = frameResults[i];
		dbgprintf("Frame %d. TS: %f, Count: %d\n", i, fr->timestamp, fr->count);
		if (fr->count != config.numBeads) {
			for (int j=0;j<fr->results.size();j++) {
				if( fr->results[j].job.locType == 0 )
					dbgprintf("%d, ", j );
			}
			dbgprintf("\n");
		}
	}

	resultMutex.unlock();
}

void ResultManager::GetFrameCounters(int* startFrame, int *processedFrames, int *lastSaveFrame, int *capturedFrames, int *localizationsDone)
{
	frameCountMutex.lock();
	if (startFrame) *startFrame = this->startFrame;
	if (processedFrames) *processedFrames = this->processedFrames;
	if (lastSaveFrame) *lastSaveFrame = this->lastSaveFrame;
	if (localizationsDone) *localizationsDone = this->localizationsDone;
	frameCountMutex.unlock();

	if (capturedFrames) {
		resultMutex.lock();
		*capturedFrames = this->capturedFrames;
		resultMutex.unlock();
	}
}

int ResultManager::GetResults(LocalizationResult* results, int startFrame, int numFrames)
{
	frameCountMutex.lock();

	if (startFrame >= this->startFrame && numFrames+startFrame <= processedFrames)  {
		resultMutex.lock();
		for (int f=0;f<numFrames;f++) {
			int index = f + startFrame - this->startFrame;
			for (int j=0;j<config.numBeads;j++)
				results[config.numBeads*f+j] = frameResults[index]->results[j];
		}

		resultMutex.unlock();
	}
	frameCountMutex.unlock();

	return numFrames;
}

int ResultManager::StoreFrameInfo(double timestamp, float* columns)
{
	resultMutex.lock();
	auto fr = new FrameResult( config.numBeads, config.numFrameInfoColumns);
	fr->timestamp = timestamp;
	for(int i=0;i<config.numFrameInfoColumns;i++)
		fr->frameInfo[i]=columns[i];
	frameResults.push_back (fr);
	int nfr = ++capturedFrames;
	resultMutex.unlock();
	return nfr;
}

int ResultManager::GetFrameCount()
{
	resultMutex.lock();
	int nfr = capturedFrames;
	resultMutex.unlock();
	return nfr;
}

<|endoftext|>


<commit_before>/*
Copyright (c) 2015-2016 Advanced Micro Devices, Inc. All rights reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/

/* HIT_START
 * BUILD: %t %s ../../test_common.cpp
 * RUN: %t
 * HIT_END
 */

// Test under-development. Call hipStreamAddCallback function and see if it works as expected.

#include "hip/hip_runtime.h"
#include "test_common.h"
#define HIPRT_CB
const int NN = 1 << 21;

__global__ void kernel(hipLaunchParm lp, float *x, float *y, int n){
	int tid = hipThreadIdx_x;
	if(tid < 1){
		for(int i=0;i<n;i++){
			x[i] = sqrt(pow(3.14159,i));
		}
		y[tid] = y[tid] + 1.0f;
	}
}
__global__ void nKernel(hipLaunchParm lp, float *y){
	int tid = hipThreadIdx_x;
	y[tid] = y[tid] + 1.0f;
}

class CallbackClass
{
public:
    static void HIPRT_CB Callback(hipStream_t stream, hipError_t status, void *userData);

private:
    void callbackFunc(hipError_t status);
};

void HIPRT_CB CallbackClass::Callback(hipStream_t stream, hipError_t status, void *userData)
{
    CallbackClass* obj = (CallbackClass*) userData;
    obj->callbackFunc(status);
}

void CallbackClass::callbackFunc(hipError_t status)
{
     HIPASSERT(status==hipSuccess);
}

int main(){
	const int num_streams = 8;
	hipStream_t streams[num_streams];
   /* float *data[num_streams], *yd, *xd;*/
	//float y = 1.0f, x = 1.0f;
	//HIPCHECK(hipMalloc((void**)&yd, sizeof(float)));
	//HIPCHECK(hipMalloc((void**)&xd, sizeof(float)));
	//HIPCHECK(hipMemcpy(yd, &y, sizeof(float), hipMemcpyHostToDevice));
	//HIPCHECK(hipMemcpy(xd, &x, sizeof(float), hipMemcpyHostToDevice));
	//for(int i=0;i<num_streams;i++){
		//HIPCHECK(hipStreamCreate(&streams[i]));
		//HIPCHECK(hipMalloc(&data[i], NN * sizeof(float)));
		//hipLaunchKernel(HIP_KERNEL_NAME(kernel), dim3(1), dim3(1), 0, streams[i], data[i], xd, N);
		//hipLaunchKernel(HIP_KERNEL_NAME(nKernel), dim3(1), dim3(1), 0, 0, yd);
	//}

	//HIPCHECK(hipMemcpy(&x, xd, sizeof(float), hipMemcpyDeviceToHost));
	//HIPCHECK(hipMemcpy(&y, yd, sizeof(float), hipMemcpyDeviceToHost));
	//std::cout<<x<<" "<<y<<std::endl;
	//HIPASSERT(x<y);

    //hipStream_t mystream = streams[0];
    hipStream_t mystream = NULL;
     CallbackClass* obj = new CallbackClass;
     hipStreamAddCallback(mystream, CallbackClass::Callback, obj, 0);

	passed();
}
<commit_msg>Modify hipStreamAddCallback test case to consider both NULL stream and stream<commit_after>/*
Copyright (c) 2015-2016 Advanced Micro Devices, Inc. All rights reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/

/* HIT_START
 * BUILD: %t %s ../../test_common.cpp
 * RUN: %t
 * HIT_END
 */

// Test under-development. Call hipStreamAddCallback function and see if it works as expected.

#include "hip/hip_runtime.h"
#include "test_common.h"
#define HIPRT_CB

class CallbackClass
{
public:
    static void HIPRT_CB Callback(hipStream_t stream, hipError_t status, void *userData);

private:
    void callbackFunc(hipError_t status);
};

void HIPRT_CB CallbackClass::Callback(hipStream_t stream, hipError_t status, void *userData)
{
    CallbackClass* obj = (CallbackClass*) userData;
    obj->callbackFunc(status);
}

void CallbackClass::callbackFunc(hipError_t status)
{
     HIPASSERT(status==hipSuccess);
}

int main(){
    hipStream_t mystream;
    HIPCHECK(hipStreamCreate(&mystream));
    CallbackClass* obj = new CallbackClass;
    HIPCHECK(hipStreamAddCallback(mystream, CallbackClass::Callback, obj, 0));
    HIPCHECK(hipStreamAddCallback(NULL, CallbackClass::Callback, obj, 0));

	passed();
}
<|endoftext|>


<commit_before>/** \copyright
 * Copyright (c) 2015, Stuart W Baker
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are  permitted provided that the following conditions are met:
 *
 *  - Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 *
 *  - Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 * \file Pipe.cxx
 * This file imlements POSIX pipe().
 *
 * @author Stuart W. Baker
 * @date 27 January 2015
 */

#include <sys/select.h>
#include <unistd.h>
#include <fcntl.h>

#include "Devtab.hxx"
#include "utils/constants.hxx"
#include "utils/RingBuffer.hxx"

const size_t DEFAULT_PIPE_SIZE = 256;

/** Private data for a can device */
class Pipe : public Node
{
public:
    /** Constructor
     * @param name device name in file system
     */
    Pipe(const char *name)
        : Node(name)
        , selInfoRd()
        , selInfoWr()
        , ring(NULL)
        , size(DEFAULT_PIPE_SIZE)
    {
    }

    /** Destructor.
     */
    ~Pipe()
    {
        if (ring)
        {
            ring->destroy();
        }
    }

    /** Create a Unix style pipe.
     * @param pipefds index 0, file descriptor open for reading.
     *                index 1, file descriptor open for writing.
     * @return 0 upon success, -1 on errer with errno set appropriately
     */
    static int pipe(int pipefds[2]);

private:
    /** Close method. Returns negative errno on failure.
     * @param file reference to close
     * @return 0 upon success or negative error number upon error.
     */
    int close(File *file) OVERRIDE;

    /** Read from a file or device.
    * @param file file reference for this device
    * @param buf location to place read data
    * @param count number of bytes to read
    * @return number of bytes read upon success, -1 upon failure with errno containing the cause
    */
    ssize_t read(File *file, void *buf, size_t count) OVERRIDE;

    /** Write to a file or device.
    * @param file file reference for this device
    * @param buf location to find write data
    * @param count number of bytes to write
    * @return number of bytes written upon success, -1 upon failure with errno containing the cause
    */
    ssize_t write(File *file, const void *buf, size_t count) OVERRIDE;

    /** Manipulate a file descriptor.
     * @param file file reference for this device
     * @param cmd operation to perform
     * @param data parameter to the cmd operation
     * @return dependent on the operation (POSIX compliant where applicable)
     *         or negative error number upon error.
     */
    int fcntl(File *file, int cmd, unsigned long data) OVERRIDE;

    /** Device select method. Default impementation returns true.
     * @param file reference to the file
     * @param mode FREAD for read active, FWRITE for write active, 0 for
     *        exceptions
     * @return true if active, false if inactive
     */
    bool select(File* file, int mode) OVERRIDE;

    void enable() OVERRIDE {} /**< function to enable device */
    void disable() OVERRIDE {}; /**< function to disable device */
    void flush_buffers() OVERRIDE {}; /**< called after disable */

    SelectInfo selInfoRd; /**< select wakeup metadata for read active */
    SelectInfo selInfoWr; /**< select wakeup metadata for write active */

    RingBuffer<uint8_t> *ring; /**< ring buffer for storing the data */

    size_t size; /**< pipe size */

    DISALLOW_COPY_AND_ASSIGN(Pipe);
};

/** Read from a file or device.
 * @param file file reference for this device
 * @param buf location to place read data
 * @param count number of bytes to read
 * @return number of bytes read upon success, -1 upon failure with errno containing the cause
 */
ssize_t Pipe::read(File *file, void *buf, size_t count)
{
    if ((file->flags & O_ACCMODE) == O_WRONLY)
    {
        return -EBADF;
    }

    uint8_t *data = (uint8_t*)buf;
    ssize_t result = 0;

    while (count)
    {
        size_t bytes;
        {
            OSMutexLock locker(&lock_);
            if (ring == NULL)
            {
                ring = RingBuffer<uint8_t>::create(size);
            }
            bytes = ring->get(data, count);

            count -= bytes;
            result += bytes;
            data += bytes;
        }

        if (bytes)
        {
            select_wakeup(&selInfoWr);
        }

        if (count)
        {
            /* no more data to receive */
            if (file->flags & O_NONBLOCK || result > 0)
            {
                break;
            }
            else
            {
                /* blocking mode, wait for writer */
                fd_set rdfds;
                FD_ZERO(&rdfds);
                int fd = fd_lookup(file);
                FD_SET(fd, &rdfds);
                ::select(fd + 1, &rdfds, NULL, NULL, NULL);
            }
        }
    }

    return result;
}

/** Write to a file or device.
 * @param file file reference for this device
 * @param buf location to find write data
 * @param count number of bytes to write
 * @return number of bytes written upon success, -1 upon failure with errno containing the cause
 */
ssize_t Pipe::write(File *file, const void *buf, size_t count)
{
    if ((file->flags & O_ACCMODE) == O_RDONLY)
    {
        return -EBADF;
    }

    const uint8_t *data = (const uint8_t*)buf;
    ssize_t result = 0;

    while (count)
    {
        size_t bytes;
        {
            OSMutexLock locker(&lock_);
            if (ring == NULL)
            {
                ring = RingBuffer<uint8_t>::create(size);
            }
            bytes = ring->put(data, count);

            count -= bytes;
            result += bytes;
            data += bytes;
        }

        if (bytes)
        {
            select_wakeup(&selInfoRd);
        }

        if (count)
        {
            /* no more room left */
            if (file->flags & O_NONBLOCK || result > 0)
            {
                break;
            }
            else
            {
                /* blocking mode, wait for reader */
                fd_set wrfds;
                FD_ZERO(&wrfds);
                int fd = fd_lookup(file);
                FD_SET(fd, &wrfds);
                ::select(fd + 1, NULL, &wrfds, NULL, NULL);
            }
        }
    }

    return result;
}

/** Close method. Returns negative errno on failure.
 * @param file reference to close
 * @return 0 upon success or negative error number upon error.
 */
int Pipe::close(File *file)
{
    mutex.lock();
    if (--references_ == 0)
    {
        mutex.unlock();
        delete file->dev;
    }
    else
    {
        mutex.unlock();
    }

    return 0;
}

/** Manipulate a file descriptor.
 * @param file file reference for this device
 * @param cmd operation to perform
 * @param data parameter to the cmd operation
 * @return dependent on the operation (POSIX compliant where applicable)
 *         or negative error number upon error.
 */
int Pipe::fcntl(File *file, int cmd, unsigned long data)
{
    switch (cmd)
    {
        default:
            return 0;
        case F_SETPIPE_SZ:
            size = data;
            return 0;
    }
}

/** Device select method. Default impementation returns true.
 * @param file reference to the file
 * @param mode FREAD for read active, FWRITE for write active, 0 for
 *        exceptions
 * @return true if active, false if inactive
 */
bool Pipe::select(File* file, int mode)
{
    bool retval = false;
    switch (mode)
    {
        case FREAD:
            portENTER_CRITICAL();
            if (ring->items())
            {
                retval = true;
            }
            else
            {
                select_insert(&selInfoRd);
            }
            portEXIT_CRITICAL();
            break;
        case FWRITE:
            portENTER_CRITICAL();
            if (ring->space())
            {
                retval = true;
            }
            else
            {
                select_insert(&selInfoWr);
            }
            portEXIT_CRITICAL();
            break;
        default:
        case 0:
            /* we don't support any exceptions */
            break;
    }
    return retval;
}

/** Create a Unix style pipe.
 * @param pipefds index 0, file descriptor open for reading.
 *                index 1, file descriptor open for writing.
 * @return 0 upon success, -1 on errer with errno set appropriately
 */
int Pipe::pipe(int pipefds[2])
{
    Pipe *new_pipe = new Pipe(NULL);

    mutex.lock();
    pipefds[0] = fd_alloc();
    if (pipefds[0] < 0)
    {
        mutex.unlock();
        errno = EMFILE;
        return -1;
    }
    pipefds[1] = fd_alloc();
    mutex.unlock();
    if (pipefds[1] < 0)
    {
        fd_free(pipefds[0]);
        errno = EMFILE;
        return -1;
    }

    File *files[2] = {file_lookup(pipefds[0]), file_lookup(pipefds[1])};

    files[0]->dev = new_pipe;
    files[1]->dev = new_pipe;
    files[0]->flags = O_RDONLY;
    files[1]->flags = O_WRONLY;

    new_pipe->references_ = 2;
    new_pipe->enable();

    return 0;
}

/** Create a Unix style pipe.
 * @param pipefds index 0, file descriptor open for reading.
 *                index 1, file descriptor open for writing.
 * @return 0 upon success, -1 on errer with errno set appropriately
 */
int pipe(int pipefds[2])
{
    return Pipe::pipe(pipefds);
}
<commit_msg>Trivial comment update<commit_after>/** \copyright
 * Copyright (c) 2015, Stuart W Baker
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are  permitted provided that the following conditions are met:
 *
 *  - Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 *
 *  - Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 * \file Pipe.cxx
 * This file implements POSIX pipe().
 *
 * @author Stuart W. Baker
 * @date 27 January 2015
 */

#include <sys/select.h>
#include <unistd.h>
#include <fcntl.h>

#include "Devtab.hxx"
#include "utils/constants.hxx"
#include "utils/RingBuffer.hxx"

const size_t DEFAULT_PIPE_SIZE = 256;

/** Private data for a can device */
class Pipe : public Node
{
public:
    /** Constructor
     * @param name device name in file system
     */
    Pipe(const char *name)
        : Node(name)
        , selInfoRd()
        , selInfoWr()
        , ring(NULL)
        , size(DEFAULT_PIPE_SIZE)
    {
    }

    /** Destructor.
     */
    ~Pipe()
    {
        if (ring)
        {
            ring->destroy();
        }
    }

    /** Create a Unix style pipe.
     * @param pipefds index 0, file descriptor open for reading.
     *                index 1, file descriptor open for writing.
     * @return 0 upon success, -1 on errer with errno set appropriately
     */
    static int pipe(int pipefds[2]);

private:
    /** Close method. Returns negative errno on failure.
     * @param file reference to close
     * @return 0 upon success or negative error number upon error.
     */
    int close(File *file) OVERRIDE;

    /** Read from a file or device.
    * @param file file reference for this device
    * @param buf location to place read data
    * @param count number of bytes to read
    * @return number of bytes read upon success, -1 upon failure with errno containing the cause
    */
    ssize_t read(File *file, void *buf, size_t count) OVERRIDE;

    /** Write to a file or device.
    * @param file file reference for this device
    * @param buf location to find write data
    * @param count number of bytes to write
    * @return number of bytes written upon success, -1 upon failure with errno containing the cause
    */
    ssize_t write(File *file, const void *buf, size_t count) OVERRIDE;

    /** Manipulate a file descriptor.
     * @param file file reference for this device
     * @param cmd operation to perform
     * @param data parameter to the cmd operation
     * @return dependent on the operation (POSIX compliant where applicable)
     *         or negative error number upon error.
     */
    int fcntl(File *file, int cmd, unsigned long data) OVERRIDE;

    /** Device select method. Default impementation returns true.
     * @param file reference to the file
     * @param mode FREAD for read active, FWRITE for write active, 0 for
     *        exceptions
     * @return true if active, false if inactive
     */
    bool select(File* file, int mode) OVERRIDE;

    void enable() OVERRIDE {} /**< function to enable device */
    void disable() OVERRIDE {}; /**< function to disable device */
    void flush_buffers() OVERRIDE {}; /**< called after disable */

    SelectInfo selInfoRd; /**< select wakeup metadata for read active */
    SelectInfo selInfoWr; /**< select wakeup metadata for write active */

    RingBuffer<uint8_t> *ring; /**< ring buffer for storing the data */

    size_t size; /**< pipe size */

    DISALLOW_COPY_AND_ASSIGN(Pipe);
};

/** Read from a file or device.
 * @param file file reference for this device
 * @param buf location to place read data
 * @param count number of bytes to read
 * @return number of bytes read upon success, -1 upon failure with errno containing the cause
 */
ssize_t Pipe::read(File *file, void *buf, size_t count)
{
    if ((file->flags & O_ACCMODE) == O_WRONLY)
    {
        return -EBADF;
    }

    uint8_t *data = (uint8_t*)buf;
    ssize_t result = 0;

    while (count)
    {
        size_t bytes;
        {
            OSMutexLock locker(&lock_);
            if (ring == NULL)
            {
                ring = RingBuffer<uint8_t>::create(size);
            }
            bytes = ring->get(data, count);

            count -= bytes;
            result += bytes;
            data += bytes;
        }

        if (bytes)
        {
            select_wakeup(&selInfoWr);
        }

        if (count)
        {
            /* no more data to receive */
            if (file->flags & O_NONBLOCK || result > 0)
            {
                break;
            }
            else
            {
                /* blocking mode, wait for writer */
                fd_set rdfds;
                FD_ZERO(&rdfds);
                int fd = fd_lookup(file);
                FD_SET(fd, &rdfds);
                ::select(fd + 1, &rdfds, NULL, NULL, NULL);
            }
        }
    }

    return result;
}

/** Write to a file or device.
 * @param file file reference for this device
 * @param buf location to find write data
 * @param count number of bytes to write
 * @return number of bytes written upon success, -1 upon failure with errno containing the cause
 */
ssize_t Pipe::write(File *file, const void *buf, size_t count)
{
    if ((file->flags & O_ACCMODE) == O_RDONLY)
    {
        return -EBADF;
    }

    const uint8_t *data = (const uint8_t*)buf;
    ssize_t result = 0;

    while (count)
    {
        size_t bytes;
        {
            OSMutexLock locker(&lock_);
            if (ring == NULL)
            {
                ring = RingBuffer<uint8_t>::create(size);
            }
            bytes = ring->put(data, count);

            count -= bytes;
            result += bytes;
            data += bytes;
        }

        if (bytes)
        {
            select_wakeup(&selInfoRd);
        }

        if (count)
        {
            /* no more room left */
            if (file->flags & O_NONBLOCK || result > 0)
            {
                break;
            }
            else
            {
                /* blocking mode, wait for reader */
                fd_set wrfds;
                FD_ZERO(&wrfds);
                int fd = fd_lookup(file);
                FD_SET(fd, &wrfds);
                ::select(fd + 1, NULL, &wrfds, NULL, NULL);
            }
        }
    }

    return result;
}

/** Close method. Returns negative errno on failure.
 * @param file reference to close
 * @return 0 upon success or negative error number upon error.
 */
int Pipe::close(File *file)
{
    mutex.lock();
    if (--references_ == 0)
    {
        mutex.unlock();
        delete file->dev;
    }
    else
    {
        mutex.unlock();
    }

    return 0;
}

/** Manipulate a file descriptor.
 * @param file file reference for this device
 * @param cmd operation to perform
 * @param data parameter to the cmd operation
 * @return dependent on the operation (POSIX compliant where applicable)
 *         or negative error number upon error.
 */
int Pipe::fcntl(File *file, int cmd, unsigned long data)
{
    switch (cmd)
    {
        default:
            return 0;
        case F_SETPIPE_SZ:
            size = data;
            return 0;
    }
}

/** Device select method. Default impementation returns true.
 * @param file reference to the file
 * @param mode FREAD for read active, FWRITE for write active, 0 for
 *        exceptions
 * @return true if active, false if inactive
 */
bool Pipe::select(File* file, int mode)
{
    bool retval = false;
    switch (mode)
    {
        case FREAD:
            portENTER_CRITICAL();
            if (ring->items())
            {
                retval = true;
            }
            else
            {
                select_insert(&selInfoRd);
            }
            portEXIT_CRITICAL();
            break;
        case FWRITE:
            portENTER_CRITICAL();
            if (ring->space())
            {
                retval = true;
            }
            else
            {
                select_insert(&selInfoWr);
            }
            portEXIT_CRITICAL();
            break;
        default:
        case 0:
            /* we don't support any exceptions */
            break;
    }
    return retval;
}

/** Create a Unix style pipe.
 * @param pipefds index 0, file descriptor open for reading.
 *                index 1, file descriptor open for writing.
 * @return 0 upon success, -1 on errer with errno set appropriately
 */
int Pipe::pipe(int pipefds[2])
{
    Pipe *new_pipe = new Pipe(NULL);

    mutex.lock();
    pipefds[0] = fd_alloc();
    if (pipefds[0] < 0)
    {
        mutex.unlock();
        errno = EMFILE;
        return -1;
    }
    pipefds[1] = fd_alloc();
    mutex.unlock();
    if (pipefds[1] < 0)
    {
        fd_free(pipefds[0]);
        errno = EMFILE;
        return -1;
    }

    File *files[2] = {file_lookup(pipefds[0]), file_lookup(pipefds[1])};

    files[0]->dev = new_pipe;
    files[1]->dev = new_pipe;
    files[0]->flags = O_RDONLY;
    files[1]->flags = O_WRONLY;

    new_pipe->references_ = 2;
    new_pipe->enable();

    return 0;
}

/** Create a Unix style pipe.
 * @param pipefds index 0, file descriptor open for reading.
 *                index 1, file descriptor open for writing.
 * @return 0 upon success, -1 on errer with errno set appropriately
 */
int pipe(int pipefds[2])
{
    return Pipe::pipe(pipefds);
}
<|endoftext|>


<commit_before>/*******************************************************************************
* ALMA - Atacama Large Millimiter Array
* Copyright (c) European Southern Observatory, 2012
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
*
* "@(#) $Id: AlarmSourceThread.cpp,v 1.1 2012/04/26 12:35:42 acaproni Exp $"
*
* who       when      what
* --------  --------  ----------------------------------------------
* acaproni  2012-04-24  created
*/

#include <ace/Guard_T.h>
#include <ace/Time_Value.h>
#include <ace/OS.h>

#include <ACSErrTypeCommon.h>
#include <acstimeTimeUtil.h>
#include "AlarmSourceThread.h"

using namespace acsalarm;
using namespace acsthreadErrType;

AlarmSourceThread::AlarmSourceThread():
	ACS::Thread("AlarmSourceThread", 10000000),
	m_alarmSources()
{
	// Start the thread
	resume();
}

AlarmSourceThread::~AlarmSourceThread()
{
	ACE_Guard<ACE_Recursive_Thread_Mutex> guard(m_mutex);
	m_alarmSources.clear();
	// Stop the thread
	terminate();
}

void AlarmSourceThread::runLoop()
{
	ACE_Guard<ACE_Recursive_Thread_Mutex> guard(m_mutex);
	 std::set<AlarmSource*>::iterator it;
	 for (it=m_alarmSources.begin(); it!=m_alarmSources.end() && check(); ++it)
	 {
		 ACE_Time_Value nowAceTime=ACE_OS::gettimeofday();
		 acstime::Epoch now=TimeUtil::ace2epoch(nowAceTime);
		 try {
			 (*it)->update(now.value);
		 } catch (...) {
			 ACS_SHORT_LOG((LM_CRITICAL,"Exception caught callin AlarmSource->update()"));
			 ACSErrTypeCommon::UnexpectedExceptionExImpl uex(__FILE__, __LINE__, "AlarmSourceThread::runLoop");
			 ExceptionInRunLoopExImpl ex(uex, __FILE__, __LINE__, "ACS::Thread::runLoop");
			 ex.setThreadName(getName());
			 throw ex;
		 }
	 }
}

bool AlarmSourceThread::registerForUpdating(AlarmSource* src)
{
	if (src==NULL) {
		return false;
	}
	ACE_Guard<ACE_Recursive_Thread_Mutex> guard(m_mutex);
	std::pair<std::set<AlarmSource*>::iterator,bool> ret= m_alarmSources.insert(src);
	return ret.second;
}

bool AlarmSourceThread::unregisterFromUpdating(AlarmSource* src)
{
	if (src==NULL) {
		return false;
	}
	ACE_Guard<ACE_Recursive_Thread_Mutex> guard(m_mutex);
	return m_alarmSources.erase(src)==1;
}

/*___oOo___*/
<commit_msg>Removed the dependency from acstime. The actual time passed in update() is in msec.<commit_after>/*******************************************************************************
* ALMA - Atacama Large Millimiter Array
* Copyright (c) European Southern Observatory, 2012
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
*
* "@(#) $Id: AlarmSourceThread.cpp,v 1.2 2012/04/27 09:10:28 acaproni Exp $"
*
* who       when      what
* --------  --------  ----------------------------------------------
* acaproni  2012-04-24  created
*/

#include <ace/Guard_T.h>
#include <ace/Time_Value.h>
#include <ace/OS.h>

#include <ACSErrTypeCommon.h>
#include "AlarmSourceThread.h"

using namespace acsalarm;
using namespace acsthreadErrType;

AlarmSourceThread::AlarmSourceThread():
	ACS::Thread("AlarmSourceThread", 1000000),
	m_alarmSources()
{
	// Start the thread
	resume();
}

AlarmSourceThread::~AlarmSourceThread()
{
	ACE_Guard<ACE_Recursive_Thread_Mutex> guard(m_mutex);
	m_alarmSources.clear();
	// Stop the thread
	terminate();
}

void AlarmSourceThread::runLoop()
{
	ACE_Guard<ACE_Recursive_Thread_Mutex> guard(m_mutex);
	 std::set<AlarmSource*>::iterator it;
	 for (it=m_alarmSources.begin(); it!=m_alarmSources.end() && check(); ++it)
	 {
		 ACE_Time_Value nowAceTime=ACE_OS::gettimeofday();
		 try {
			 (*it)->update(nowAceTime.msec());
		 } catch (...) {
			 ACS_SHORT_LOG((LM_CRITICAL,"Exception caught callin AlarmSource->update()"));
			 ACSErrTypeCommon::UnexpectedExceptionExImpl uex(__FILE__, __LINE__, "AlarmSourceThread::runLoop");
			 ExceptionInRunLoopExImpl ex(uex, __FILE__, __LINE__, "ACS::Thread::runLoop");
			 ex.setThreadName(getName());
			 throw ex;
		 }
	 }
}

bool AlarmSourceThread::registerForUpdating(AlarmSource* src)
{
	if (src==NULL) {
		return false;
	}
	ACE_Guard<ACE_Recursive_Thread_Mutex> guard(m_mutex);
	std::pair<std::set<AlarmSource*>::iterator,bool> ret= m_alarmSources.insert(src);
	return ret.second;
}

bool AlarmSourceThread::unregisterFromUpdating(AlarmSource* src)
{
	if (src==NULL) {
		return false;
	}
	ACE_Guard<ACE_Recursive_Thread_Mutex> guard(m_mutex);
	return m_alarmSources.erase(src)==1;
}

/*___oOo___*/
<|endoftext|>


<commit_before>/*
 * Copyright(c) Sophist Solutions, Inc. 1990-2013.  All rights reserved
 */
#ifndef _Stroika_Foundation_Memory_Optional_inl_
#define _Stroika_Foundation_Memory_Optional_inl_    1

/*
 ********************************************************************************
 ***************************** Implementation Details ***************************
 ********************************************************************************
 */
#include   "../Debug/Assertions.h"

namespace   Stroika {
    namespace   Foundation {
        namespace   Memory {

            /*
             ********************************************************************************
             ********************************** Optional<T> *********************************
             ********************************************************************************
             */
            template    <typename T>
            inline  Optional<T>::Optional ()
                : fValue_ (nullptr)
            {
            }
            template    <typename T>
            inline  Optional<T>::Optional (const T& from)
                : fValue_ (new BlockAllocated<T> (from))
            {
            }
            template    <typename T>
            inline  Optional<T>::Optional (T && from)
                : fValue_ (new BlockAllocated<T> (std::move (from)))
            {
            }
            template    <typename T>
            inline  Optional<T>::Optional (const Optional<T>& from)
                : fValue_ (from.fValue_ == nullptr ? nullptr : new BlockAllocated<T> (*from.fValue_))
            {
            }
            template    <typename T>
            inline  Optional<T>::Optional (Optional<T> && from)
                : fValue_ (from.fValue_)
            {
                from.fValue_ = nullptr;
            }
            template    <typename T>
            inline  Optional<T>::~Optional ()
            {
                delete fValue_;
            }
            template    <typename T>
            inline  Optional<T>&   Optional<T>::operator= (const T& from)
            {
                delete fValue_;
                fValue_ = nullptr;
                fValue_ = new BlockAllocated<T> (from);
                return *this;
            }
            template    <typename T>
            inline  Optional<T>&   Optional<T>::operator= (T && from)
            {
                fValue_ = new BlockAllocated<T> (std::move (from));
                return *this;
            }
            template    <typename T>
            inline  Optional<T>&   Optional<T>::operator= (const Optional<T>& from)
            {
                delete fValue_;
                fValue_ = nullptr;
                if (from.fValue_ != nullptr) {
                    fValue_ = new BlockAllocated<T> (*from.fValue_);
                }
                return *this;
            }
            template    <typename T>
            inline  Optional<T>&   Optional<T>::operator= (Optional<T> && from)
            {
                fValue_ = from.fValue_;
                from.fValue_ = nullptr;
                return *this;
            }
            template    <typename T>
            inline  void    Optional<T>::clear ()
            {
                delete fValue_;
                fValue_ = nullptr;
            }
            template    <typename T>
            inline  const T*    Optional<T>::get () const
            {
                return fValue_;
            }
            template    <typename T>
            inline  bool    Optional<T>::empty () const
            {
                return fValue_ == nullptr;
            }
            template    <typename T>
            inline  const T* Optional<T>::operator-> () const
            {
                Require (not empty ())
                AssertNotNull (fValue_);
                return fValue_;
            }
            template    <typename T>
            inline  T* Optional<T>::operator-> ()
            {
                Require (not empty ());
                AssertNotNull (fValue_);
                return fValue_->get ();
            }
            template    <typename T>
            inline  const T& Optional<T>::operator* () const
            {
                Require (not empty ())
                return *fValue_->get ();
            }
            template    <typename T>
            inline  T& Optional<T>::operator* ()
            {
                Require (not empty ())
                return *fValue_->get ();
            }
            template    <typename T>
            inline  Optional<T>::operator T () const
            {
                Require (not empty ())
                return *fValue_;
            }
            template    <typename T>
            bool    Optional<T>::operator< (const Optional<T>& rhs) const
            {
                if (fValue_ == nullptr) {
                    return (rhs.fValue_ == nullptr) ? false : true; // arbitrary choice - but assume if lhs is empty thats less than any T value
                }
                if (rhs.fValue_ == nullptr) {
                    return false;
                }
                return *fValue_ < *rhs.fValue_;
            }
            template    <typename T>
            bool    Optional<T>::operator<= (const Optional<T>& rhs) const
            {
                return *this < rhs or * this == rhs;
            }
            template    <typename T>
            inline  bool    Optional<T>::operator> (const Optional<T>& rhs) const
            {
                return rhs < *this;
            }
            template    <typename T>
            bool    Optional<T>::operator>= (const Optional<T>& rhs) const
            {
                return *this > rhs or * this == rhs;
            }
            template    <typename T>
            bool    Optional<T>::operator== (const Optional<T>& rhs) const
            {
                if (fValue_ == nullptr) {
                    return rhs.fValue_ == nullptr;
                }
                if (rhs.fValue_ == nullptr) {
                    return false;
                }
                return *fValue_ == *rhs.fValue_;
            }
            template    <typename T>
            inline  bool    Optional<T>::operator!= (const Optional<T>& rhs) const
            {
                return not (*this == rhs);
            }

        }
    }
}
#endif  /*_Stroika_Foundation_Memory_Optional_inl_*/
<commit_msg>small bugs with Optional<T> fixed<commit_after>/*
 * Copyright(c) Sophist Solutions, Inc. 1990-2013.  All rights reserved
 */
#ifndef _Stroika_Foundation_Memory_Optional_inl_
#define _Stroika_Foundation_Memory_Optional_inl_    1

/*
 ********************************************************************************
 ***************************** Implementation Details ***************************
 ********************************************************************************
 */
#include   "../Debug/Assertions.h"

namespace   Stroika {
    namespace   Foundation {
        namespace   Memory {

            /*
             ********************************************************************************
             ********************************** Optional<T> *********************************
             ********************************************************************************
             */
            template    <typename T>
            inline  Optional<T>::Optional ()
                : fValue_ (nullptr)
            {
            }
            template    <typename T>
            inline  Optional<T>::Optional (const T& from)
                : fValue_ (new BlockAllocated<T> (from))
            {
            }
            template    <typename T>
            inline  Optional<T>::Optional (T && from)
                : fValue_ (new BlockAllocated<T> (std::move (from)))
            {
            }
            template    <typename T>
            inline  Optional<T>::Optional (const Optional<T>& from)
                : fValue_ (from.fValue_ == nullptr ? nullptr : new BlockAllocated<T> (*from.fValue_))
            {
            }
            template    <typename T>
            inline  Optional<T>::Optional (Optional<T> && from)
                : fValue_ (from.fValue_)
            {
                from.fValue_ = nullptr;
            }
            template    <typename T>
            inline  Optional<T>::~Optional ()
            {
                delete fValue_;
            }
            template    <typename T>
            inline  Optional<T>&   Optional<T>::operator= (const T& from)
            {
                delete fValue_;
                fValue_ = nullptr;
                fValue_ = new BlockAllocated<T> (from);
                return *this;
            }
            template    <typename T>
            inline  Optional<T>&   Optional<T>::operator= (T && from)
            {
                fValue_ = new BlockAllocated<T> (std::move (from));
                return *this;
            }
            template    <typename T>
            inline  Optional<T>&   Optional<T>::operator= (const Optional<T>& from)
            {
                delete fValue_;
                fValue_ = nullptr;
                if (from.fValue_ != nullptr) {
                    fValue_ = new BlockAllocated<T> (*from.fValue_);
                }
                return *this;
            }
            template    <typename T>
            inline  Optional<T>&   Optional<T>::operator= (Optional<T> && from)
            {
                fValue_ = from.fValue_;
                from.fValue_ = nullptr;
                return *this;
            }
            template    <typename T>
            inline  void    Optional<T>::clear ()
            {
                delete fValue_;
                fValue_ = nullptr;
            }
            template    <typename T>
            inline  const T*    Optional<T>::get () const
            {
                return fValue_;
            }
            template    <typename T>
            inline  bool    Optional<T>::empty () const
            {
                return fValue_ == nullptr;
            }
            template    <typename T>
            inline  const T* Optional<T>::operator-> () const
            {
                Require (not empty ())
                AssertNotNull (fValue_);
                EnsureNotNull (fValue_->get ());
                return fValue_->get ();
            }
            template    <typename T>
            inline  T* Optional<T>::operator-> ()
            {
                Require (not empty ());
                AssertNotNull (fValue_);
                EnsureNotNull (fValue_->get ());
                return fValue_->get ();
            }
            template    <typename T>
            inline  const T& Optional<T>::operator* () const
            {
                Require (not empty ())
                AssertNotNull (fValue_);
                EnsureNotNull (fValue_->get ());
                return *fValue_->get ();
            }
            template    <typename T>
            inline  T& Optional<T>::operator* ()
            {
                Require (not empty ())
                AssertNotNull (fValue_);
                EnsureNotNull (fValue_->get ());
                return *fValue_->get ();
            }
            template    <typename T>
            inline  Optional<T>::operator T () const
            {
                Require (not empty ())
                AssertNotNull (fValue_);
                return *fValue_;
            }
            template    <typename T>
            bool    Optional<T>::operator< (const Optional<T>& rhs) const
            {
                if (fValue_ == nullptr) {
                    return (rhs.fValue_ == nullptr) ? false : true; // arbitrary choice - but assume if lhs is empty thats less than any T value
                }
                if (rhs.fValue_ == nullptr) {
                    return false;
                }
                return *fValue_ < *rhs.fValue_;
            }
            template    <typename T>
            bool    Optional<T>::operator<= (const Optional<T>& rhs) const
            {
                return *this < rhs or * this == rhs;
            }
            template    <typename T>
            inline  bool    Optional<T>::operator> (const Optional<T>& rhs) const
            {
                return rhs < *this;
            }
            template    <typename T>
            bool    Optional<T>::operator>= (const Optional<T>& rhs) const
            {
                return *this > rhs or * this == rhs;
            }
            template    <typename T>
            bool    Optional<T>::operator== (const Optional<T>& rhs) const
            {
                if (fValue_ == nullptr) {
                    return rhs.fValue_ == nullptr;
                }
                if (rhs.fValue_ == nullptr) {
                    return false;
                }
                return *fValue_ == *rhs.fValue_;
            }
            template    <typename T>
            inline  bool    Optional<T>::operator!= (const Optional<T>& rhs) const
            {
                return not (*this == rhs);
            }

        }
    }
}
#endif  /*_Stroika_Foundation_Memory_Optional_inl_*/
<|endoftext|>


<commit_before>#include "details/compiler/compile.h"
#include "details/compiler/compiler.h"
#include "details/program/program.h"
#include "details/reporting/report.h"
#include "details/errors/errors.h"
#include "details/pass/a-src2ast/ast-from-source.h"
#include <yuni/io/file.h>
#include <libnanyc.h>
#include <utility>
#include <memory>

namespace ny {
namespace compiler {

namespace {

constexpr uint32_t memoryHardlimit = 64 * 1024 * 1024;

Logs::Report buildGenerateReport(void* ptr, Logs::Level level) {
	return (*((ny::Logs::Report*) ptr)).fromErrLevel(level);
}

nyprogram_t* complainNoSource(ny::Logs::Report& report) {
	report.error() << "no input source code";
	return nullptr;
}

void copySourceOpts(ny::compiler::Source& source, const nysource_opts_t& opts) {
	if (opts.filename.len != 0) {
		if (unlikely(opts.filename.len > memoryHardlimit))
			throw "input filename bigger than internal limit";
		yuni::IO::Canonicalize(source.filename, AnyString{opts.filename.c_str, static_cast<uint32_t>(opts.filename.len)});
	}
	if (opts.content.len != 0) {
		if (unlikely(opts.content.len > memoryHardlimit))
			throw "input source content bigger than internal limit";
		source.content.assign(opts.content.c_str, static_cast<uint32_t>(opts.content.len));
	}
}

void compileSource(ny::compiler::Source& source) {
	bool compiled = true;
	compiled &= makeASTFromSource(source);
	return compiled;
}

bool importSourceAndCompile(ny::compiler::Source& source, const nysource_opts_t& opts) {
	copySourceOpts(source, opts);
	return compileSource(source);
}

} // namespace

inline Compiler::Compiler(const nycompile_opts_t& opts)
	: opts(opts) {
}

inline nyprogram_t* Compiler::compile() {
	ny::Logs::Report report{messages};
	Logs::Handler errorHandler{&report, &buildGenerateReport};
	try {
		uint32_t scount = opts.sources.count;
		if (unlikely(scount == 0))
			return complainNoSource(report);
		sources.count = scount;
		sources.items = std::make_unique<Source[]>(scount);
		for (uint32_t i = 0; i != opts.sources.count; ++i)
			importSourceAndCompile(sources[i], opts.sources.items[i]);
		auto program = std::make_unique<ny::Program>();
		return ny::Program::pointer(program.release());
	}
	catch (const std::bad_alloc& e) {
		report.ice() << "not enough memory when compiling";
	}
	catch (const std::exception& e) {
		report.ice() << "exception: " << e.what();
	}
	catch (const char* e) {
		report.error() << e;
	}
	catch (...) {
		report.ice() << "uncaught exception when compiling";
	}
	return nullptr;
}

nyprogram_t* compile(nycompile_opts_t& opts) {
	try {
		if (opts.on_build_start)
			opts.userdata = opts.on_build_start(opts.userdata);
		auto* program = Compiler{opts}.compile();
		if (opts.on_build_stop)
			opts.on_build_stop(opts.userdata, (program ? nytrue : nyfalse));
		return program;
	}
	catch (...) {
	}
	if (opts.on_build_stop)
		opts.on_build_stop(opts.userdata, nyfalse);
	return nullptr;
}

} // namespace compiler
} // namespace ny
<commit_msg>compiler: add error report per source<commit_after>#include "details/compiler/compile.h"
#include "details/compiler/compiler.h"
#include "details/program/program.h"
#include "details/reporting/report.h"
#include "details/errors/errors.h"
#include "details/pass/a-src2ast/ast-from-source.h"
#include <yuni/io/file.h>
#include <libnanyc.h>
#include <utility>
#include <memory>

namespace ny {
namespace compiler {

namespace {

constexpr uint32_t memoryHardlimit = 64 * 1024 * 1024;

Logs::Report buildGenerateReport(void* ptr, Logs::Level level) {
	return (*((ny::Logs::Report*) ptr)).fromErrLevel(level);
}

nyprogram_t* complainNoSource(ny::Logs::Report& report) {
	report.error() << "no input source code";
	return nullptr;
}

void copySourceOpts(ny::compiler::Source& source, const nysource_opts_t& opts) {
	if (opts.filename.len != 0) {
		if (unlikely(opts.filename.len > memoryHardlimit))
			throw "input filename bigger than internal limit";
		yuni::IO::Canonicalize(source.filename, AnyString{opts.filename.c_str, static_cast<uint32_t>(opts.filename.len)});
	}
	if (opts.content.len != 0) {
		if (unlikely(opts.content.len > memoryHardlimit))
			throw "input source content bigger than internal limit";
		source.content.assign(opts.content.c_str, static_cast<uint32_t>(opts.content.len));
	}
}

bool compileSource(ny::Logs::Report& mainreport, ny::compiler::Source& source) {
	auto report = mainreport.subgroup();
	report.data().origins.location.filename = source.filename;
	report.data().origins.location.target.clear();
	bool compiled = true;
	compiled &= makeASTFromSource(source);
	return compiled;
}

bool importSourceAndCompile(ny::Logs::Report& mainreport, ny::compiler::Source& source, const nysource_opts_t& opts) {
	copySourceOpts(source, opts);
	return compileSource(mainreport, source);
}

} // namespace

inline Compiler::Compiler(const nycompile_opts_t& opts)
	: opts(opts) {
}

inline nyprogram_t* Compiler::compile() {
	ny::Logs::Report report{messages};
	Logs::Handler errorHandler{&report, &buildGenerateReport};
	try {
		uint32_t scount = opts.sources.count;
		if (unlikely(scount == 0))
			return complainNoSource(report);
		sources.count = scount;
		sources.items = std::make_unique<Source[]>(scount);
		bool compiled = true;
		for (uint32_t i = 0; i != opts.sources.count; ++i)
			compiled &= importSourceAndCompile(report, sources[i], opts.sources.items[i]);
		if (compiled) {
			auto program = std::make_unique<ny::Program>();
			return ny::Program::pointer(program.release());
		}
	}
	catch (const std::bad_alloc& e) {
		report.ice() << "not enough memory when compiling";
	}
	catch (const std::exception& e) {
		report.ice() << "exception: " << e.what();
	}
	catch (const char* e) {
		report.error() << e;
	}
	catch (...) {
		report.ice() << "uncaught exception when compiling";
	}
	return nullptr;
}

nyprogram_t* compile(nycompile_opts_t& opts) {
	try {
		if (opts.on_build_start)
			opts.userdata = opts.on_build_start(opts.userdata);
		auto* program = Compiler{opts}.compile();
		if (opts.on_build_stop)
			opts.on_build_stop(opts.userdata, (program ? nytrue : nyfalse));
		return program;
	}
	catch (...) {
	}
	if (opts.on_build_stop)
		opts.on_build_stop(opts.userdata, nyfalse);
	return nullptr;
}

} // namespace compiler
} // namespace ny
<|endoftext|>


<commit_before>#include <iostream>

class Point
{
    public:

        Point();
        Point(double , double);
        double x();
        void set_x(double);
        double y();
        void set_y(double);

    private:
        double m_x;
        double m_y;

};

void Point::set_x(double x)
{
     m_x = x;
}
void Point::set_y(double y)
{
    m_y = y;

}
Point::Point()
{
    set_x(0);
    set_y(0);

}
Point::Point( double x, double y)
{
    set_x(x);
    set_y(y);

}

<commit_msg> created point. closes<commit_after>#include <iostream>

class Point
{
    public:

        Point();
        Point(double , double);
        double x();
        void set_x(double);
        double y();
        void set_y(double);

    private:
        double m_x;
        double m_y;

};

void Point::set_x(double x)
{
     m_x = x;
}

void Point::set_y(double y)
{
    m_y = y;

}

Point::Point()
{
    set_x(0);
    set_y(0);

}

Point::Point( double x, double y)
{
    set_x(x);
    set_y(y);

}

int main (int argc, char* argv[])
{
    Point p1;
    p1.set_x(4);
    p1.set_y(6);

    std::cout << " Point x is: " << p1.set_x <<std::endl;
    std::cout << " Point y is: " << p1.set_y << std::endl;
}

<|endoftext|>


<commit_before>#ifndef __SEVMGR_SEVMGR_TYPES_HPP
#define __SEVMGR_SEVMGR_TYPES_HPP

// //////////////////////////////////////////////////////////////////////
// Import section
// //////////////////////////////////////////////////////////////////////
// Sevmgr
#include <sevmgr/SEVMGR_Exceptions.hpp>

namespace SEVMGR {

  // //////// Type definitions specific to Sevmgr /////////
  // No specific type for now

}
#endif // __SEVMGR_SEVMGR_TYPES_HPP

<commit_msg>[dev] Added the pointer on SEvMgr service handler.<commit_after>#ifndef __SEVMGR_SEVMGR_TYPES_HPP
#define __SEVMGR_SEVMGR_TYPES_HPP

// //////////////////////////////////////////////////////////////////////
// Import section
// //////////////////////////////////////////////////////////////////////
// Boost
#include <boost/shared_ptr.hpp>
// Sevmgr
#include <sevmgr/SEVMGR_Exceptions.hpp>

namespace SEVMGR {

  // Forward declarations
  class SEVMGR_Service;

  // //////// Type definitions specific to to Sevmgr /////////
  /**
   * (Smart) Pointer on the SEvMgr service handler.
   */
  typedef boost::shared_ptr<SEVMGR_Service> SEVMGR_ServicePtr_T;

}
#endif // __SEVMGR_SEVMGR_TYPES_HPP

<|endoftext|>