<commit_before>/**
 * \file
 * \brief DynamicThreadBase class header
 *
 * \author Copyright (C) 2015-2017 Kamil Szczygiel http://www.distortec.com http://www.freddiechopin.info
 *
 * \par License
 * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not
 * distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

#ifndef INCLUDE_DISTORTOS_INTERNAL_SCHEDULER_DYNAMICTHREADBASE_HPP_
#define INCLUDE_DISTORTOS_INTERNAL_SCHEDULER_DYNAMICTHREADBASE_HPP_

#include "distortos/DynamicSignalsReceiver.hpp"
#include "distortos/DynamicThreadParameters.hpp"
#include "distortos/ThreadCommon.hpp"

#include "distortos/internal/memory/storageDeleter.hpp"

namespace distortos
{

#ifdef CONFIG_THREAD_DETACH_ENABLE

class DynamicThread;

#endif	// def CONFIG_THREAD_DETACH_ENABLE

namespace internal
{

/**
 * \brief DynamicThreadBase class is a type-erased interface for thread that has dynamic storage for bound function,
 * stack and internal DynamicSignalsReceiver object.
 *
 * If thread detachment is enabled (CONFIG_THREAD_DETACH_ENABLE is defined) then this class is dynamically allocated by
 * DynamicThread - which allows it to be "detached". Otherwise - if thread detachment is disabled
 * (CONFIG_THREAD_DETACH_ENABLE is not defined) - DynamicThread just inherits from this class.
 */

class DynamicThreadBase : public ThreadCommon
{
public:

#ifdef CONFIG_THREAD_DETACH_ENABLE

	/**
	 * \brief DynamicThreadBase's constructor
	 *
	 * \tparam Function is the function that will be executed in separate thread
	 * \tparam Args are the arguments for \a Function
	 *
	 * \param [in] stackSize is the size of stack, bytes
	 * \param [in] canReceiveSignals selects whether reception of signals is enabled (true) or disabled (false) for this
	 * thread
	 * \param [in] queuedSignals is the max number of queued signals for this thread, relevant only if
	 * \a canReceiveSignals == true, 0 to disable queuing of signals for this thread
	 * \param [in] signalActions is the max number of different SignalAction objects for this thread, relevant only if
	 * \a canReceiveSignals == true, 0 to disable catching of signals for this thread
	 * \param [in] priority is the thread's priority, 0 - lowest, UINT8_MAX - highest
	 * \param [in] schedulingPolicy is the scheduling policy of the thread
	 * \param [in] owner is a reference to owner DynamicThread object
	 * \param [in] function is a function that will be executed in separate thread
	 * \param [in] args are arguments for \a function
	 */

	template<typename Function, typename... Args>
	DynamicThreadBase(size_t stackSize, bool canReceiveSignals, size_t queuedSignals, size_t signalActions,
			uint8_t priority, SchedulingPolicy schedulingPolicy, DynamicThread& owner, Function&& function,
			Args&&... args);

#else	// !def CONFIG_THREAD_DETACH_ENABLE

	/**
	 * \brief DynamicThreadBase's constructor
	 *
	 * \tparam Function is the function that will be executed in separate thread
	 * \tparam Args are the arguments for \a Function
	 *
	 * \param [in] stackSize is the size of stack, bytes
	 * \param [in] canReceiveSignals selects whether reception of signals is enabled (true) or disabled (false) for this
	 * thread
	 * \param [in] queuedSignals is the max number of queued signals for this thread, relevant only if
	 * \a canReceiveSignals == true, 0 to disable queuing of signals for this thread
	 * \param [in] signalActions is the max number of different SignalAction objects for this thread, relevant only if
	 * \a canReceiveSignals == true, 0 to disable catching of signals for this thread
	 * \param [in] priority is the thread's priority, 0 - lowest, UINT8_MAX - highest
	 * \param [in] schedulingPolicy is the scheduling policy of the thread
	 * \param [in] function is a function that will be executed in separate thread
	 * \param [in] args are arguments for \a function
	 */

	template<typename Function, typename... Args>
	DynamicThreadBase(size_t stackSize, bool canReceiveSignals, size_t queuedSignals, size_t signalActions,
			uint8_t priority, SchedulingPolicy schedulingPolicy, Function&& function, Args&&... args);

	/**
	 * \brief DynamicThreadBase's constructor
	 *
	 * \tparam Function is the function that will be executed in separate thread
	 * \tparam Args are the arguments for \a Function
	 *
	 * \param [in] parameters is a DynamicThreadParameters struct with thread parameters
	 * \param [in] function is a function that will be executed in separate thread
	 * \param [in] args are arguments for \a function
	 */

	template<typename Function, typename... Args>
	DynamicThreadBase(const DynamicThreadParameters parameters, Function&& function, Args&&... args) :
			DynamicThreadBase{parameters.stackSize, parameters.canReceiveSignals, parameters.queuedSignals,
					parameters.signalActions, parameters.priority, parameters.schedulingPolicy,
					std::forward<Function>(function), std::forward<Args>(args)...}
	{

	}

#endif	// !def CONFIG_THREAD_DETACH_ENABLE

#ifdef CONFIG_THREAD_DETACH_ENABLE

	/**
	 * \brief Detaches the thread.
	 *
	 * Similar to std::thread::detach() - http://en.cppreference.com/w/cpp/thread/thread/detach
	 * Similar to POSIX pthread_detach() - http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_detach.html
	 *
	 * Detaches the executing thread from the Thread object, allowing execution to continue independently. All resources
	 * allocated for the thread will be deallocated when the thread terminates.
	 *
	 * \return 0 on success, error code otherwise:
	 * - EINVAL - this thread is already detached;
	 */

	int detach() override;

#endif	// def CONFIG_THREAD_DETACH_ENABLE

	/**
	 * \brief Starts the thread.
	 *
	 * This operation can be performed on threads in "New" state only.
	 *
	 * \return 0 on success, error code otherwise:
	 * - error codes returned by ThreadCommon::startInternal();
	 */

	int start()
	{
#ifdef CONFIG_THREAD_DETACH_ENABLE
		return ThreadCommon::startInternal(run, preTerminationHook, terminationHook);
#else	// !def CONFIG_THREAD_DETACH_ENABLE
		return ThreadCommon::startInternal(run, nullptr, terminationHook);
#endif	// !def CONFIG_THREAD_DETACH_ENABLE
	}

	DynamicThreadBase(const DynamicThreadBase&) = delete;
	DynamicThreadBase(DynamicThreadBase&&) = default;
	const DynamicThreadBase& operator=(const DynamicThreadBase&) = delete;
	DynamicThreadBase& operator=(DynamicThreadBase&&) = delete;

protected:

#ifdef CONFIG_THREAD_DETACH_ENABLE

	/**
	 * \brief Pre-termination hook function of thread
	 *
	 * If thread is detached, locks object used for deferred deletion.
	 *
	 * \param [in] thread is a reference to Thread object, this must be DynamicThreadBase!
	 */

	static void preTerminationHook(Thread& thread);

	/**
	 * \brief Termination hook function of thread
	 *
	 * Calls ThreadCommon::terminationHook() and - if thread is detached - schedules itself for deferred deletion.
	 *
	 * \param [in] thread is a reference to Thread object, this must be DynamicThreadBase!
	 */

	static void terminationHook(Thread& thread);

#endif	// def CONFIG_THREAD_DETACH_ENABLE

private:

	/**
	 * \brief Thread's "run" function.
	 *
	 * Executes bound function object.
	 *
	 * \param [in] thread is a reference to Thread object, this must be DynamicThreadBase!
	 */

	static void run(Thread& thread);

	/// internal DynamicSignalsReceiver object
	DynamicSignalsReceiver dynamicSignalsReceiver_;

	/// bound function object
	std::function<void()> boundFunction_;

#ifdef CONFIG_THREAD_DETACH_ENABLE

	/// pointer to owner DynamicThread object, nullptr if thread is detached
	DynamicThread* owner_;

#endif	// def CONFIG_THREAD_DETACH_ENABLE
};

#ifdef CONFIG_THREAD_DETACH_ENABLE

template<typename Function, typename... Args>
DynamicThreadBase::DynamicThreadBase(const size_t stackSize, const bool canReceiveSignals, const size_t queuedSignals,
		const size_t signalActions, const uint8_t priority, const SchedulingPolicy schedulingPolicy,
		DynamicThread& owner, Function&& function, Args&&... args) :
				ThreadCommon{{{new uint8_t[stackSize + stackGuardSize], storageDeleter<uint8_t>},
						stackSize + stackGuardSize}, priority, schedulingPolicy, nullptr,
						canReceiveSignals == true ? &dynamicSignalsReceiver_ : nullptr},
				dynamicSignalsReceiver_{canReceiveSignals == true ? queuedSignals : 0,
						canReceiveSignals == true ? signalActions : 0},
				boundFunction_{std::bind(std::forward<Function>(function), std::forward<Args>(args)...)},
				owner_{&owner}
{

}

#else	// !def CONFIG_THREAD_DETACH_ENABLE

template<typename Function, typename... Args>
DynamicThreadBase::DynamicThreadBase(const size_t stackSize, const bool canReceiveSignals, const size_t queuedSignals,
		const size_t signalActions, const uint8_t priority, const SchedulingPolicy schedulingPolicy,
		Function&& function, Args&&... args) :
				ThreadCommon{{{new uint8_t[stackSize + stackGuardSize], storageDeleter<uint8_t>},
						stackSize + stackGuardSize}, priority, schedulingPolicy, nullptr,
						canReceiveSignals == true ? &dynamicSignalsReceiver_ : nullptr},
				dynamicSignalsReceiver_{canReceiveSignals == true ? queuedSignals : 0,
						canReceiveSignals == true ? signalActions : 0},
				boundFunction_{std::bind(std::forward<Function>(function), std::forward<Args>(args)...)}
{

}

#endif	// !def CONFIG_THREAD_DETACH_ENABLE

}	// namespace internal

}	// namespace distortos

#endif	// INCLUDE_DISTORTOS_INTERNAL_SCHEDULER_DYNAMICTHREADBASE_HPP_
<commit_msg>Add static_assert() to check alignment of dynamically allocated memory<commit_after>/**
 * \file
 * \brief DynamicThreadBase class header
 *
 * \author Copyright (C) 2015-2017 Kamil Szczygiel http://www.distortec.com http://www.freddiechopin.info
 *
 * \par License
 * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not
 * distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

#ifndef INCLUDE_DISTORTOS_INTERNAL_SCHEDULER_DYNAMICTHREADBASE_HPP_
#define INCLUDE_DISTORTOS_INTERNAL_SCHEDULER_DYNAMICTHREADBASE_HPP_

#include "distortos/DynamicSignalsReceiver.hpp"
#include "distortos/DynamicThreadParameters.hpp"
#include "distortos/ThreadCommon.hpp"

#include "distortos/internal/memory/storageDeleter.hpp"

namespace distortos
{

#ifdef CONFIG_THREAD_DETACH_ENABLE

class DynamicThread;

#endif	// def CONFIG_THREAD_DETACH_ENABLE

namespace internal
{

/**
 * \brief DynamicThreadBase class is a type-erased interface for thread that has dynamic storage for bound function,
 * stack and internal DynamicSignalsReceiver object.
 *
 * If thread detachment is enabled (CONFIG_THREAD_DETACH_ENABLE is defined) then this class is dynamically allocated by
 * DynamicThread - which allows it to be "detached". Otherwise - if thread detachment is disabled
 * (CONFIG_THREAD_DETACH_ENABLE is not defined) - DynamicThread just inherits from this class.
 */

class DynamicThreadBase : public ThreadCommon
{
public:

#ifdef CONFIG_THREAD_DETACH_ENABLE

	/**
	 * \brief DynamicThreadBase's constructor
	 *
	 * \tparam Function is the function that will be executed in separate thread
	 * \tparam Args are the arguments for \a Function
	 *
	 * \param [in] stackSize is the size of stack, bytes
	 * \param [in] canReceiveSignals selects whether reception of signals is enabled (true) or disabled (false) for this
	 * thread
	 * \param [in] queuedSignals is the max number of queued signals for this thread, relevant only if
	 * \a canReceiveSignals == true, 0 to disable queuing of signals for this thread
	 * \param [in] signalActions is the max number of different SignalAction objects for this thread, relevant only if
	 * \a canReceiveSignals == true, 0 to disable catching of signals for this thread
	 * \param [in] priority is the thread's priority, 0 - lowest, UINT8_MAX - highest
	 * \param [in] schedulingPolicy is the scheduling policy of the thread
	 * \param [in] owner is a reference to owner DynamicThread object
	 * \param [in] function is a function that will be executed in separate thread
	 * \param [in] args are arguments for \a function
	 */

	template<typename Function, typename... Args>
	DynamicThreadBase(size_t stackSize, bool canReceiveSignals, size_t queuedSignals, size_t signalActions,
			uint8_t priority, SchedulingPolicy schedulingPolicy, DynamicThread& owner, Function&& function,
			Args&&... args);

#else	// !def CONFIG_THREAD_DETACH_ENABLE

	/**
	 * \brief DynamicThreadBase's constructor
	 *
	 * \tparam Function is the function that will be executed in separate thread
	 * \tparam Args are the arguments for \a Function
	 *
	 * \param [in] stackSize is the size of stack, bytes
	 * \param [in] canReceiveSignals selects whether reception of signals is enabled (true) or disabled (false) for this
	 * thread
	 * \param [in] queuedSignals is the max number of queued signals for this thread, relevant only if
	 * \a canReceiveSignals == true, 0 to disable queuing of signals for this thread
	 * \param [in] signalActions is the max number of different SignalAction objects for this thread, relevant only if
	 * \a canReceiveSignals == true, 0 to disable catching of signals for this thread
	 * \param [in] priority is the thread's priority, 0 - lowest, UINT8_MAX - highest
	 * \param [in] schedulingPolicy is the scheduling policy of the thread
	 * \param [in] function is a function that will be executed in separate thread
	 * \param [in] args are arguments for \a function
	 */

	template<typename Function, typename... Args>
	DynamicThreadBase(size_t stackSize, bool canReceiveSignals, size_t queuedSignals, size_t signalActions,
			uint8_t priority, SchedulingPolicy schedulingPolicy, Function&& function, Args&&... args);

	/**
	 * \brief DynamicThreadBase's constructor
	 *
	 * \tparam Function is the function that will be executed in separate thread
	 * \tparam Args are the arguments for \a Function
	 *
	 * \param [in] parameters is a DynamicThreadParameters struct with thread parameters
	 * \param [in] function is a function that will be executed in separate thread
	 * \param [in] args are arguments for \a function
	 */

	template<typename Function, typename... Args>
	DynamicThreadBase(const DynamicThreadParameters parameters, Function&& function, Args&&... args) :
			DynamicThreadBase{parameters.stackSize, parameters.canReceiveSignals, parameters.queuedSignals,
					parameters.signalActions, parameters.priority, parameters.schedulingPolicy,
					std::forward<Function>(function), std::forward<Args>(args)...}
	{

	}

#endif	// !def CONFIG_THREAD_DETACH_ENABLE

#ifdef CONFIG_THREAD_DETACH_ENABLE

	/**
	 * \brief Detaches the thread.
	 *
	 * Similar to std::thread::detach() - http://en.cppreference.com/w/cpp/thread/thread/detach
	 * Similar to POSIX pthread_detach() - http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_detach.html
	 *
	 * Detaches the executing thread from the Thread object, allowing execution to continue independently. All resources
	 * allocated for the thread will be deallocated when the thread terminates.
	 *
	 * \return 0 on success, error code otherwise:
	 * - EINVAL - this thread is already detached;
	 */

	int detach() override;

#endif	// def CONFIG_THREAD_DETACH_ENABLE

	/**
	 * \brief Starts the thread.
	 *
	 * This operation can be performed on threads in "New" state only.
	 *
	 * \return 0 on success, error code otherwise:
	 * - error codes returned by ThreadCommon::startInternal();
	 */

	int start()
	{
#ifdef CONFIG_THREAD_DETACH_ENABLE
		return ThreadCommon::startInternal(run, preTerminationHook, terminationHook);
#else	// !def CONFIG_THREAD_DETACH_ENABLE
		return ThreadCommon::startInternal(run, nullptr, terminationHook);
#endif	// !def CONFIG_THREAD_DETACH_ENABLE
	}

	DynamicThreadBase(const DynamicThreadBase&) = delete;
	DynamicThreadBase(DynamicThreadBase&&) = default;
	const DynamicThreadBase& operator=(const DynamicThreadBase&) = delete;
	DynamicThreadBase& operator=(DynamicThreadBase&&) = delete;

protected:

#ifdef CONFIG_THREAD_DETACH_ENABLE

	/**
	 * \brief Pre-termination hook function of thread
	 *
	 * If thread is detached, locks object used for deferred deletion.
	 *
	 * \param [in] thread is a reference to Thread object, this must be DynamicThreadBase!
	 */

	static void preTerminationHook(Thread& thread);

	/**
	 * \brief Termination hook function of thread
	 *
	 * Calls ThreadCommon::terminationHook() and - if thread is detached - schedules itself for deferred deletion.
	 *
	 * \param [in] thread is a reference to Thread object, this must be DynamicThreadBase!
	 */

	static void terminationHook(Thread& thread);

#endif	// def CONFIG_THREAD_DETACH_ENABLE

private:

	/**
	 * \brief Thread's "run" function.
	 *
	 * Executes bound function object.
	 *
	 * \param [in] thread is a reference to Thread object, this must be DynamicThreadBase!
	 */

	static void run(Thread& thread);

	/// internal DynamicSignalsReceiver object
	DynamicSignalsReceiver dynamicSignalsReceiver_;

	/// bound function object
	std::function<void()> boundFunction_;

#ifdef CONFIG_THREAD_DETACH_ENABLE

	/// pointer to owner DynamicThread object, nullptr if thread is detached
	DynamicThread* owner_;

#endif	// def CONFIG_THREAD_DETACH_ENABLE
};

static_assert(alignof(max_align_t) >= CONFIG_ARCHITECTURE_STACK_ALIGNMENT,
		"Alignment of dynamically allocated memory is too low!");

#ifdef CONFIG_THREAD_DETACH_ENABLE

template<typename Function, typename... Args>
DynamicThreadBase::DynamicThreadBase(const size_t stackSize, const bool canReceiveSignals, const size_t queuedSignals,
		const size_t signalActions, const uint8_t priority, const SchedulingPolicy schedulingPolicy,
		DynamicThread& owner, Function&& function, Args&&... args) :
				ThreadCommon{{{new uint8_t[stackSize + stackGuardSize], storageDeleter<uint8_t>},
						stackSize + stackGuardSize}, priority, schedulingPolicy, nullptr,
						canReceiveSignals == true ? &dynamicSignalsReceiver_ : nullptr},
				dynamicSignalsReceiver_{canReceiveSignals == true ? queuedSignals : 0,
						canReceiveSignals == true ? signalActions : 0},
				boundFunction_{std::bind(std::forward<Function>(function), std::forward<Args>(args)...)},
				owner_{&owner}
{

}

#else	// !def CONFIG_THREAD_DETACH_ENABLE

template<typename Function, typename... Args>
DynamicThreadBase::DynamicThreadBase(const size_t stackSize, const bool canReceiveSignals, const size_t queuedSignals,
		const size_t signalActions, const uint8_t priority, const SchedulingPolicy schedulingPolicy,
		Function&& function, Args&&... args) :
				ThreadCommon{{{new uint8_t[stackSize + stackGuardSize], storageDeleter<uint8_t>},
						stackSize + stackGuardSize}, priority, schedulingPolicy, nullptr,
						canReceiveSignals == true ? &dynamicSignalsReceiver_ : nullptr},
				dynamicSignalsReceiver_{canReceiveSignals == true ? queuedSignals : 0,
						canReceiveSignals == true ? signalActions : 0},
				boundFunction_{std::bind(std::forward<Function>(function), std::forward<Args>(args)...)}
{

}

#endif	// !def CONFIG_THREAD_DETACH_ENABLE

}	// namespace internal

}	// namespace distortos

#endif	// INCLUDE_DISTORTOS_INTERNAL_SCHEDULER_DYNAMICTHREADBASE_HPP_
<|endoftext|>


<commit_before>#include "aes.hpp"

int     aes::setKey(char *_key)
{

    for(int i = 0; i < Nk; i++)
    {
        for(int j = 0; j < 4; j++)
        {
            key[i*4+(3-j)] = _key[i*4+j];
        }
    }

    return expandKey();
}

int     aes::expandKey()
{
    for(int i = 0; i < Nk; i++)
    {
        roundKey[i] = (key[4*i]) | (key[4*i+1] << 8) | (key[4*i+2] << 16) | (key[4*i+3] << 24);
    }

    for(int i = Nk; i < (Nb*(Nr+1)); i++)
    {
        uint32_t temp = roundKey[i-1];
        if( i % Nk == 0 )
        {
            printf("\n");
            printf("\t %08x -> %08x -> %08x", temp, rotWord(temp, 1), subWord(rotWord(temp, 1)));
            temp = subWord(rotWord(temp, 1)) ^ (rcon[i/Nk] << 24);
            printf(" -> %08x\n", temp);
        }
        roundKey[i] = roundKey[i-Nk] ^ temp;
    }

    return 0;
}

uint8_t aes::rotByte(uint8_t input, int n)
{
    return __rolb(input, n);
}

uint32_t    aes::rotWord(uint32_t input, int n)
{
    uint32_t output = (input << 8) | ((input >> 24) & 0xff);
    return output;
}

uint32_t    aes::subWord(uint32_t input)
{
    uint8_t byte;
    uint32_t output = 0;
    for(int i = 0; i < 4; i++)
    {
        byte = 0xff & ( input >> (i*8) );
        output |= (s_fwd_aes[byte] << (i*8));
    }
    return output;
}

std::string aes::printRoundKeys(void)
{
    std::string output;
    for(int i = 0; i < (Nr+1); i++)
    {
        for(int j = 0; j < Nb; j++)
        {
            output.push_back(printf("%d : %08x ", i*Nb+j, roundKey[i*Nb + j]));
        }
        output.push_back(printf("\n"));
    }
    return output;
}

std::string aes::printKey(void)
{
    std::string output;
    for(int i = 0; i < Nk*4; i++)
    {
        output.push_back(printf("%02x ", key[i]));
    }

    return output;
}

int     aes::shiftRow(uint32_t *msg)
{
    uint32_t tmp[4];
    for(int i = 1; i < 4; i++)
    {
        for(int j = 0; j < i; j++)
        {
            tmp[j] = msg[4*i+j];
        }

        for(int j = 0; j < 4-i; j++)
        {
            msg[4*i+j] = msg[4*i+j+i];
        }

        for(int j = 4-i; j < 4; j++)
        {
            msg[4*i+j] = tmp[j-4+i];
        }
    }
    return 0;
}

int     aes::encryptBlock(uint32_t *msg)
{
    for(int j = 0; j < Nb; j++)
    {
        msg[j] = (msg[j] ^ roundKey[j]);
    }

    for(int i = 1; i < Nr; i++)
    {
        for(int j = 0; j < Nb; j++)
        {
            msg[j] = subWord(msg[j]);
        }

        shiftRow(msg);
        mixCol(msg);

        for(int j = 0; j < Nb; j++)
        {
            msg[j] = msg[j] ^ roundKey[j];
        }

    }

    return 0;
}
<commit_msg>shiftRow was wrong<commit_after>#include "aes.hpp"

int     aes::setKey(char *_key)
{

    for(int i = 0; i < Nk; i++)
    {
        for(int j = 0; j < 4; j++)
        {
            key[i*4+(3-j)] = _key[i*4+j];
        }
    }

    return expandKey();
}

int     aes::expandKey()
{
    for(int i = 0; i < Nk; i++)
    {
        roundKey[i] = (key[4*i]) | (key[4*i+1] << 8) | (key[4*i+2] << 16) | (key[4*i+3] << 24);
    }

    for(int i = Nk; i < (Nb*(Nr+1)); i++)
    {
        uint32_t temp = roundKey[i-1];
        if( i % Nk == 0 )
        {
            printf("\n");
            printf("\t %08x -> %08x -> %08x", temp, rotWord(temp, 1), subWord(rotWord(temp, 1)));
            temp = subWord(rotWord(temp, 1)) ^ (rcon[i/Nk] << 24);
            printf(" -> %08x\n", temp);
        }
        roundKey[i] = roundKey[i-Nk] ^ temp;
    }

    return 0;
}

uint8_t aes::rotByte(uint8_t input, int n)
{
    return __rolb(input, n);
}

uint32_t    aes::rotWord(uint32_t input, int n)
{
    uint32_t output = (input << 8) | ((input >> 24) & 0xff);
    return output;
}

uint32_t    aes::subWord(uint32_t input)
{
    uint8_t byte;
    uint32_t output = 0;
    for(int i = 0; i < 4; i++)
    {
        byte = 0xff & ( input >> (i*8) );
        output |= (s_fwd_aes[byte] << (i*8));
    }
    return output;
}

std::string aes::printRoundKeys(void)
{
    std::string output;
    for(int i = 0; i < (Nr+1); i++)
    {
        for(int j = 0; j < Nb; j++)
        {
            output.push_back(printf("%d : %08x ", i*Nb+j, roundKey[i*Nb + j]));
        }
        output.push_back(printf("\n"));
    }
    return output;
}

std::string aes::printKey(void)
{
    std::string output;
    for(int i = 0; i < Nk*4; i++)
    {
        output.push_back(printf("%02x ", key[i]));
    }

    return output;
}

int     aes::shiftRow(uint32_t *msg)
{
}

int     aes::encryptBlock(uint32_t *msg)
{
    for(int j = 0; j < Nb; j++)
    {
        msg[j] = (msg[j] ^ roundKey[j]);
    }

    for(int i = 1; i < Nr; i++)
    {
        for(int j = 0; j < Nb; j++)
        {
            msg[j] = subWord(msg[j]);
        }

        shiftRow(msg);
        mixCol(msg);

        for(int j = 0; j < Nb; j++)
        {
            msg[j] = msg[j] ^ roundKey[j];
        }

    }

    return 0;
}
<|endoftext|>


<commit_before>#include"all_defines.hpp"

#include"aio.hpp"
#include"heaps.hpp"
#include"types.hpp"
#include"objects.hpp"
#include"processes.hpp"
#include"workers.hpp"
#include"bytecodes.hpp"
#include"symbols.hpp"

/*Generic code for AIO*/
/*This contains code that is shared across AIO implementations*/

/*internal function for sending a message to a process*/
/*
preconditions:
	stack.top() = message to send
postconditions:
	stack.top() has been popped
*/
static inline void send_message_to(Process* P, ProcessStack& stack) {
	/*prepare message*/
	ValueHolderRef m;
	ValueHolder::copy_object(m, stack.top());
	stack.pop();

	bool is_waiting = 0;
	/*keep sending until we definitely go through any locks or whatnot*/
	while(!P->receive_message(m, is_waiting)) /*do nothing*/;
	if(is_waiting) {
		workers->workqueue_push(P);
	}
}

ProcessInvoker::ProcessInvoker(Process* nP) : P(nP) {
}
ProcessInvoker::~ProcessInvoker() {
}

void ProcessInvoker::io_respond(
		Process& host,
		boost::shared_ptr<Event>& event,
		boost::shared_ptr<std::vector<unsigned char> >& dat) {
	Heap& hp = host; ProcessStack& stack = host.stack;
	/*build objects*/
	HlEvent* ev = hp.create<HlEvent>();
	ev->p = event;
	stack.push(Object::to_ref<Generic*>(ev));
	/*any data?*/
	if(!dat || dat->size() == 0) {
		stack.push(Object::nil());
	} else {
		BinObj* e = BinObj::create(hp, dat);
		stack.push(Object::to_ref<Generic*>(e));
	}
	bytecode_cons(host, stack);

	send_message_to(P, stack);

}

void ProcessInvoker::nil_respond(
		Process& host,
		boost::shared_ptr<Event>& event) {
	Heap& hp = host; ProcessStack& stack = host.stack;
	/*build objects*/
	HlEvent* ev = hp.create<HlEvent>();
	ev->p = event;
	stack.push(Object::to_ref<Generic*>(ev));
	stack.push(Object::nil());
	bytecode_cons(host, stack);

	send_message_to(P, stack);

}

void ProcessInvoker::accept_respond(
		Process& host,
		boost::shared_ptr<Event>& event,
		boost::shared_ptr<IOPort>& new_socket){
	Heap& hp = host; ProcessStack& stack = host.stack;
	/*build objects*/
	HlEvent* ev = hp.create<HlEvent>();
	ev->p = event;
	stack.push(Object::to_ref<Generic*>(ev));
	HlIOPort* io = hp.create<HlIOPort>();
	io->p = new_socket;
	stack.push(Object::to_ref<Generic*>(io));
	bytecode_cons(host, stack);

	send_message_to(P, stack);

}

void ProcessInvoker::connect_respond(
		Process& host,
		boost::shared_ptr<Event>& event,
		boost::shared_ptr<IOPort>& new_socket) {
	Heap& hp = host; ProcessStack& stack = host.stack;
	/*build objects*/
	HlEvent* ev = hp.create<HlEvent>();
	ev->p = event;
	stack.push(Object::to_ref<Generic*>(ev));
	HlIOPort* io = hp.create<HlIOPort>();
	io->p = new_socket;
	stack.push(Object::to_ref<Generic*>(io));
	bytecode_cons(host, stack);

	send_message_to(P, stack);

}

void ProcessInvoker::sleep_respond(
		Process& host,
		boost::shared_ptr<Event>& event,
		size_t time) {
	Heap& hp = host; ProcessStack& stack = host.stack;
	/*build objects*/
	HlEvent* ev = hp.create<HlEvent>();
	ev->p = event;
	stack.push(Object::to_ref<Generic*>(ev));
	stack.push(Object::to_ref<int>(time));
	bytecode_cons(host, stack);

	send_message_to(P, stack);

}

void ProcessInvoker::error_respond(
		Process& host,
		boost::shared_ptr<Event>& event,
		std::string const& msg) {
	Heap& hp = host; ProcessStack& stack = host.stack;
	/*build objects*/
	HlEvent* ev = hp.create<HlEvent>();
	ev->p = event;
	stack.push(Object::to_ref<Generic*>(ev));
	/*slow lookup is OK, we don't expect error handling
	to be fast.
	*/
	stack.push(Object::to_ref(symbols->lookup("<hl>i/o")));
	/*assume ASCII string for now*/
	for(size_t i = 0; i < msg.size(); ++i) {
		stack.push(Object::to_ref(UnicodeChar(msg[i])));
	}
	HlString::stack_create(hp, stack, msg.size());

	bytecode_tag(host, stack);
	bytecode_cons(host, stack);

	send_message_to(P, stack);
}

<commit_msg>src/aio.cpp: notes on problem with process-level GC and arbitrarily pushing a process onto the workqueue<commit_after>#include"all_defines.hpp"

#include"aio.hpp"
#include"heaps.hpp"
#include"types.hpp"
#include"objects.hpp"
#include"processes.hpp"
#include"workers.hpp"
#include"bytecodes.hpp"
#include"symbols.hpp"

/*Generic code for AIO*/
/*This contains code that is shared across AIO implementations*/

/*internal function for sending a message to a process*/
/*
preconditions:
	stack.top() = message to send
postconditions:
	stack.top() has been popped
*/
static inline void send_message_to(Process* P, ProcessStack& stack) {
	/*prepare message*/
	ValueHolderRef m;
	ValueHolder::copy_object(m, stack.top());
	stack.pop();

	bool is_waiting = 0;
	/*keep sending until we definitely go through any locks or whatnot*/
	while(!P->receive_message(m, is_waiting)) /*do nothing*/;
	if(is_waiting) {
		/*TODO: must have a way of determining if we are
		in process-level GC.  The process-level GC must
		first blacken the process before it can be safely
		pushed on the workqueue.
		*/
		workers->workqueue_push(P);
	}
}

ProcessInvoker::ProcessInvoker(Process* nP) : P(nP) {
}
ProcessInvoker::~ProcessInvoker() {
}

void ProcessInvoker::io_respond(
		Process& host,
		boost::shared_ptr<Event>& event,
		boost::shared_ptr<std::vector<unsigned char> >& dat) {
	Heap& hp = host; ProcessStack& stack = host.stack;
	/*build objects*/
	HlEvent* ev = hp.create<HlEvent>();
	ev->p = event;
	stack.push(Object::to_ref<Generic*>(ev));
	/*any data?*/
	if(!dat || dat->size() == 0) {
		stack.push(Object::nil());
	} else {
		BinObj* e = BinObj::create(hp, dat);
		stack.push(Object::to_ref<Generic*>(e));
	}
	bytecode_cons(host, stack);

	send_message_to(P, stack);

}

void ProcessInvoker::nil_respond(
		Process& host,
		boost::shared_ptr<Event>& event) {
	Heap& hp = host; ProcessStack& stack = host.stack;
	/*build objects*/
	HlEvent* ev = hp.create<HlEvent>();
	ev->p = event;
	stack.push(Object::to_ref<Generic*>(ev));
	stack.push(Object::nil());
	bytecode_cons(host, stack);

	send_message_to(P, stack);

}

void ProcessInvoker::accept_respond(
		Process& host,
		boost::shared_ptr<Event>& event,
		boost::shared_ptr<IOPort>& new_socket){
	Heap& hp = host; ProcessStack& stack = host.stack;
	/*build objects*/
	HlEvent* ev = hp.create<HlEvent>();
	ev->p = event;
	stack.push(Object::to_ref<Generic*>(ev));
	HlIOPort* io = hp.create<HlIOPort>();
	io->p = new_socket;
	stack.push(Object::to_ref<Generic*>(io));
	bytecode_cons(host, stack);

	send_message_to(P, stack);

}

void ProcessInvoker::connect_respond(
		Process& host,
		boost::shared_ptr<Event>& event,
		boost::shared_ptr<IOPort>& new_socket) {
	Heap& hp = host; ProcessStack& stack = host.stack;
	/*build objects*/
	HlEvent* ev = hp.create<HlEvent>();
	ev->p = event;
	stack.push(Object::to_ref<Generic*>(ev));
	HlIOPort* io = hp.create<HlIOPort>();
	io->p = new_socket;
	stack.push(Object::to_ref<Generic*>(io));
	bytecode_cons(host, stack);

	send_message_to(P, stack);

}

void ProcessInvoker::sleep_respond(
		Process& host,
		boost::shared_ptr<Event>& event,
		size_t time) {
	Heap& hp = host; ProcessStack& stack = host.stack;
	/*build objects*/
	HlEvent* ev = hp.create<HlEvent>();
	ev->p = event;
	stack.push(Object::to_ref<Generic*>(ev));
	stack.push(Object::to_ref<int>(time));
	bytecode_cons(host, stack);

	send_message_to(P, stack);

}

void ProcessInvoker::error_respond(
		Process& host,
		boost::shared_ptr<Event>& event,
		std::string const& msg) {
	Heap& hp = host; ProcessStack& stack = host.stack;
	/*build objects*/
	HlEvent* ev = hp.create<HlEvent>();
	ev->p = event;
	stack.push(Object::to_ref<Generic*>(ev));
	/*slow lookup is OK, we don't expect error handling
	to be fast.
	*/
	stack.push(Object::to_ref(symbols->lookup("<hl>i/o")));
	/*assume ASCII string for now*/
	for(size_t i = 0; i < msg.size(); ++i) {
		stack.push(Object::to_ref(UnicodeChar(msg[i])));
	}
	HlString::stack_create(hp, stack, msg.size());

	bytecode_tag(host, stack);
	bytecode_cons(host, stack);

	send_message_to(P, stack);
}

<|endoftext|>


<commit_before>#include"all_defines.hpp"

#include"aio.hpp"
#include"heaps.hpp"
#include"types.hpp"
#include"objects.hpp"
#include"processes.hpp"
#include"workers.hpp"
#include"bytecodes.hpp"
#include"symbols.hpp"

/*Generic code for AIO*/
/*This contains code that is shared across AIO implementations*/

/*internal function for sending a message to a process*/
/*
preconditions:
	stack.top() = message to send
postconditions:
	stack.top() has been popped
*/
static inline void send_message_to(Process& host, Process* P, ProcessStack& stack) {
	/*prepare message*/
	ValueHolderRef m;
	ValueHolder::copy_object(m, stack.top());
	stack.pop();

	bool is_waiting = 0;
	/*keep sending until we definitely go through any locks or whatnot*/
	while(!P->receive_message(m, is_waiting)) /*do nothing*/;
	if(is_waiting) {
		/*Use multipush on the hosting process to
		push the processes on the workqueue when
		the hosting process' timeslice expires.
		*/
		host.add_to_multipush(P);
	}
}

ProcessInvoker::ProcessInvoker(Process* nP) : P(nP) {
}
ProcessInvoker::~ProcessInvoker() {
}

void ProcessInvoker::io_respond(
		Process& host,
		boost::shared_ptr<Event>& event,
		boost::shared_ptr<std::vector<unsigned char> >& dat) {
	Heap& hp = host; ProcessStack& stack = host.stack;
	/*build objects*/
	HlEvent* ev = hp.create<HlEvent>();
	ev->p = event;
	stack.push(Object::to_ref<Generic*>(ev));
	/*any data?*/
	if(!dat || dat->size() == 0) {
		stack.push(Object::nil());
	} else {
		BinObj* e = BinObj::create(hp, dat);
		stack.push(Object::to_ref<Generic*>(e));
	}
	bytecode_cons(host, stack);

	send_message_to(host, P, stack);

}

void ProcessInvoker::nil_respond(
		Process& host,
		boost::shared_ptr<Event>& event) {
	Heap& hp = host; ProcessStack& stack = host.stack;
	/*build objects*/
	HlEvent* ev = hp.create<HlEvent>();
	ev->p = event;
	stack.push(Object::to_ref<Generic*>(ev));
	stack.push(Object::nil());
	bytecode_cons(host, stack);

	send_message_to(host, P, stack);

}

void ProcessInvoker::accept_respond(
		Process& host,
		boost::shared_ptr<Event>& event,
		boost::shared_ptr<IOPort>& new_socket) {
	Heap& hp = host; ProcessStack& stack = host.stack;
	/*build objects*/
	HlEvent* ev = hp.create<HlEvent>();
	ev->p = event;
	stack.push(Object::to_ref<Generic*>(ev));
	HlIOPort* io = hp.create<HlIOPort>();
	io->p = new_socket;
	stack.push(Object::to_ref<Generic*>(io));
	bytecode_cons(host, stack);

	send_message_to(host, P, stack);

}

void ProcessInvoker::connect_respond(
		Process& host,
		boost::shared_ptr<Event>& event,
		boost::shared_ptr<IOPort>& new_socket) {
	Heap& hp = host; ProcessStack& stack = host.stack;
	/*build objects*/
	HlEvent* ev = hp.create<HlEvent>();
	ev->p = event;
	stack.push(Object::to_ref<Generic*>(ev));
	HlIOPort* io = hp.create<HlIOPort>();
	io->p = new_socket;
	stack.push(Object::to_ref<Generic*>(io));
	bytecode_cons(host, stack);

	send_message_to(host, P, stack);

}

void ProcessInvoker::sleep_respond(
		Process& host,
		boost::shared_ptr<Event>& event,
		size_t time) {
	Heap& hp = host; ProcessStack& stack = host.stack;
	/*build objects*/
	HlEvent* ev = hp.create<HlEvent>();
	ev->p = event;
	stack.push(Object::to_ref<Generic*>(ev));
	stack.push(Object::to_ref<int>(time));
	bytecode_cons(host, stack);

	send_message_to(host, P, stack);

}

void ProcessInvoker::error_respond(
		Process& host,
		boost::shared_ptr<Event>& event,
		std::string const& msg) {
	Heap& hp = host; ProcessStack& stack = host.stack;
	/*build objects*/
	HlEvent* ev = hp.create<HlEvent>();
	ev->p = event;
	stack.push(Object::to_ref<Generic*>(ev));
	/*slow lookup is OK, we don't expect error handling
	to be fast.
	*/
	stack.push(Object::to_ref(symbols->lookup("<hl>i/o")));
	/*assume ASCII string for now*/
	for(size_t i = 0; i < msg.size(); ++i) {
		stack.push(Object::to_ref(UnicodeChar(msg[i])));
	}
	HlString::stack_create(hp, stack, msg.size());

	bytecode_tag(host, stack);
	bytecode_cons(host, stack);

	send_message_to(host, P, stack);
}

<commit_msg>src/aio.cpp: Changed to properly create the HlEvent by also binding the process to send to<commit_after>#include"all_defines.hpp"

#include"aio.hpp"
#include"heaps.hpp"
#include"types.hpp"
#include"objects.hpp"
#include"processes.hpp"
#include"workers.hpp"
#include"bytecodes.hpp"
#include"symbols.hpp"

/*Generic code for AIO*/
/*This contains code that is shared across AIO implementations*/

/*internal function for sending a message to a process*/
/*
preconditions:
	stack.top() = message to send
postconditions:
	stack.top() has been popped
*/
static inline void send_message_to(Process& host, Process* P, ProcessStack& stack) {
	/*prepare message*/
	ValueHolderRef m;
	ValueHolder::copy_object(m, stack.top());
	stack.pop();

	bool is_waiting = 0;
	/*keep sending until we definitely go through any locks or whatnot*/
	while(!P->receive_message(m, is_waiting)) /*do nothing*/;
	if(is_waiting) {
		/*Use multipush on the hosting process to
		push the processes on the workqueue when
		the hosting process' timeslice expires.
		*/
		host.add_to_multipush(P);
	}
}

ProcessInvoker::ProcessInvoker(Process* nP) : P(nP) {
}
ProcessInvoker::~ProcessInvoker() {
}

static inline void recreate_event_push(
		Heap& hp,
		ProcessStack& stack,
		boost::shared_ptr<Event>& event,
		Process* P) {
	{
		HlPid *pid = hp.create<HlPid>();
		pid->process = P;
		stack.push(Object::to_ref<Generic*>(pid));
	}
	HlEvent* ev = hp.create<HlEvent>();
	ev->p = event;
	ev->hl_pid = stack.top(); stack.pop();
	stack.push(Object::to_ref<Generic*>(ev));
}

void ProcessInvoker::io_respond(
		Process& host,
		boost::shared_ptr<Event>& event,
		boost::shared_ptr<std::vector<unsigned char> >& dat) {
	Heap& hp = host; ProcessStack& stack = host.stack;
	/*build objects*/
	recreate_event_push(hp, stack, event, P);
	/*any data?*/
	if(!dat || dat->size() == 0) {
		stack.push(Object::nil());
	} else {
		BinObj* e = BinObj::create(hp, dat);
		stack.push(Object::to_ref<Generic*>(e));
	}
	bytecode_cons(host, stack);

	send_message_to(host, P, stack);

}

void ProcessInvoker::nil_respond(
		Process& host,
		boost::shared_ptr<Event>& event) {
	Heap& hp = host; ProcessStack& stack = host.stack;
	/*build objects*/
	recreate_event_push(hp, stack, event, P);
	stack.push(Object::nil());
	bytecode_cons(host, stack);

	send_message_to(host, P, stack);

}

void ProcessInvoker::accept_respond(
		Process& host,
		boost::shared_ptr<Event>& event,
		boost::shared_ptr<IOPort>& new_socket) {
	Heap& hp = host; ProcessStack& stack = host.stack;
	/*build objects*/
	recreate_event_push(hp, stack, event, P);
	HlIOPort* io = hp.create<HlIOPort>();
	io->p = new_socket;
	stack.push(Object::to_ref<Generic*>(io));
	bytecode_cons(host, stack);

	send_message_to(host, P, stack);

}

void ProcessInvoker::connect_respond(
		Process& host,
		boost::shared_ptr<Event>& event,
		boost::shared_ptr<IOPort>& new_socket) {
	Heap& hp = host; ProcessStack& stack = host.stack;
	/*build objects*/
	recreate_event_push(hp, stack, event, P);
	HlIOPort* io = hp.create<HlIOPort>();
	io->p = new_socket;
	stack.push(Object::to_ref<Generic*>(io));
	bytecode_cons(host, stack);

	send_message_to(host, P, stack);

}

void ProcessInvoker::sleep_respond(
		Process& host,
		boost::shared_ptr<Event>& event,
		size_t time) {
	Heap& hp = host; ProcessStack& stack = host.stack;
	/*build objects*/
	recreate_event_push(hp, stack, event, P);
	stack.push(Object::to_ref<int>(time));
	bytecode_cons(host, stack);

	send_message_to(host, P, stack);

}

void ProcessInvoker::error_respond(
		Process& host,
		boost::shared_ptr<Event>& event,
		std::string const& msg) {
	Heap& hp = host; ProcessStack& stack = host.stack;
	/*build objects*/
	recreate_event_push(hp, stack, event, P);
	/*slow lookup is OK, we don't expect error handling
	to be fast.
	*/
	stack.push(Object::to_ref(symbols->lookup("<hl>i/o")));
	/*assume ASCII string for now*/
	for(size_t i = 0; i < msg.size(); ++i) {
		stack.push(Object::to_ref(UnicodeChar(msg[i])));
	}
	HlString::stack_create(hp, stack, msg.size());

	bytecode_tag(host, stack);
	bytecode_cons(host, stack);

	send_message_to(host, P, stack);
}

<|endoftext|>


<commit_before>#include "ant.hpp"

extern int debug;

Ant::Ant(Graph *graph, double alpha, double beta, double gamma, unsigned max_solution_length)
: graph(graph)
, alpha(alpha)
, beta(beta)
, gamma(gamma)
, max_solution_length(max_solution_length)
, solution(NULL)
, generator()
{}

void Ant::traverse_graph() {
  bool term_condition = true;
  set_beginning_position();

  while(term_condition) {
    term_condition = term_condition && move();
    if (debug >= 5) { cout << *solution << endl; }
  }
}

void Ant::free_solution() {
  if (solution) {
    delete solution;
    solution = NULL;
  }
}

void Ant::set_beginning_position() {
  vector<Node*> nodes = graph->get_nodes();
  vector<double> distribution;
  distribution.reserve(nodes.size());
  for(unsigned i = 0; i < nodes.size(); ++i) {
    distribution.push_back(graph->rate_node_as_first(nodes[i]));
  }
  for (unsigned i = 1; i < nodes.size(); ++i) {
    distribution[i] += distribution[i - 1];
  }

  int choice = generator.roulette(distribution);
  current_node = nodes[choice];
  solution = new Solution(graph->get_size(), current_node);
}

bool Ant::move() {
  Edge *chosen_edge = choose_edge();
  if (chosen_edge == NULL) return false;

  step(chosen_edge);
  return true;
}

void Ant::step(Edge *edge) {
  this->current_node = solution->add_edge(edge);
}

double Ant::heuristic_attrictiveness(Edge *choice) {
  unsigned no_visits = solution->get_no_visits(current_node);
  return max(0.0, 1 + choice->get_weight() - gamma * no_visits);
}

double Ant::probability_of_choice(Edge *choice) {
  return pow(choice->get_pheromones(), alpha) * pow(heuristic_attrictiveness(choice), beta);
}

bool Ant::can_choose_edge(Edge *edge) {
  return (solution->get_cummulated_length(edge) <= this->max_solution_length);
}

void Ant::filter_choices(vector<Edge *> &potential_choices) {
  unsigned i = this->current_node->get_index();
  for (unsigned j = 0, len = graph->get_size(); j < len; ++j) {
    Edge *edge = graph->get_edge(i, j);
    if ((i != j) && can_choose_edge(edge)) {
      potential_choices.push_back(edge);
    }
  }
}

Edge* Ant::choose_edge() {
  vector<Edge *> potential_choices;
  filter_choices(potential_choices);

  unsigned size = potential_choices.size();
  if (size == 0) return NULL;

  vector<double> distribution;
  distribution.reserve(size);
  for (unsigned i = 0; i < size; ++i) {
    distribution.push_back(probability_of_choice(potential_choices[i]));
  }

  if (debug >= 5) {
    cout << "distribution:\t";
    for (unsigned i = 0, len = potential_choices.size(); i < len; ++i) {
      Edge *choice = potential_choices[i];
      cout << choice->get_n2()->get_index() << " => (" << distribution[i] << ", ";
      cout << "ph: " << choice->get_pheromones() << ", ";
      cout << "h: " << heuristic_attrictiveness(choice) << ")\t";
    }
    cout << endl;
  }

  for (unsigned i = 1; i < size; ++i) {
    distribution[i] += distribution[i - 1];
  }

  int choice = generator.roulette(distribution);
  return potential_choices[choice];
}
<commit_msg>Critical bug<commit_after>#include "ant.hpp"

extern int debug;

Ant::Ant(Graph *graph, double alpha, double beta, double gamma, unsigned max_solution_length)
: graph(graph)
, alpha(alpha)
, beta(beta)
, gamma(gamma)
, max_solution_length(max_solution_length)
, solution(NULL)
, generator()
{}

void Ant::traverse_graph() {
  bool term_condition = true;
  set_beginning_position();

  while(term_condition) {
    term_condition = term_condition && move();
    if (debug >= 5) { cout << *solution << endl; }
  }
}

void Ant::free_solution() {
  if (solution) {
    delete solution;
    solution = NULL;
  }
}

void Ant::set_beginning_position() {
  vector<Node*> nodes = graph->get_nodes();
  vector<double> distribution;
  distribution.reserve(nodes.size());
  for(unsigned i = 0; i < nodes.size(); ++i) {
    distribution.push_back(graph->rate_node_as_first(nodes[i]));
  }
  for (unsigned i = 1; i < nodes.size(); ++i) {
    distribution[i] += distribution[i - 1];
  }

  int choice = generator.roulette(distribution);
  current_node = nodes[choice];
  solution = new Solution(graph->get_size(), current_node);
}

bool Ant::move() {
  Edge *chosen_edge = choose_edge();
  if (chosen_edge == NULL) return false;

  step(chosen_edge);
  return true;
}

void Ant::step(Edge *edge) {
  this->current_node = solution->add_edge(edge);
}

double Ant::heuristic_attrictiveness(Edge *choice) {
  unsigned no_visits = solution->get_no_visits(choice->get_n2());
  return max(0.0, 1 + choice->get_normalized_weight() - gamma * no_visits);
}

double Ant::probability_of_choice(Edge *choice) {
  return pow(choice->get_pheromones(), alpha) * pow(heuristic_attrictiveness(choice), beta);
}

bool Ant::can_choose_edge(Edge *edge) {
  return (solution->get_cummulated_length(edge) <= this->max_solution_length);
}

void Ant::filter_choices(vector<Edge *> &potential_choices) {
  unsigned i = this->current_node->get_index();
  for (unsigned j = 0, len = graph->get_size(); j < len; ++j) {
    Edge *edge = graph->get_edge(i, j);
    if ((i != j) && can_choose_edge(edge)) {
      potential_choices.push_back(edge);
    }
  }
}

Edge* Ant::choose_edge() {
  vector<Edge *> potential_choices;
  filter_choices(potential_choices);

  unsigned size = potential_choices.size();
  if (size == 0) return NULL;

  vector<double> distribution;
  distribution.reserve(size);
  for (unsigned i = 0; i < size; ++i) {
    distribution.push_back(probability_of_choice(potential_choices[i]));
  }

  if (debug >= 5) {
    cout << "distribution:\t";
    for (unsigned i = 0, len = potential_choices.size(); i < len; ++i) {
      Edge *choice = potential_choices[i];
      cout << choice->get_n2()->get_index() << " => (" << distribution[i] << ", ";
      cout << "ph: " << choice->get_pheromones() << ", ";
      cout << "h: " << heuristic_attrictiveness(choice) << ")\t";
    }
    cout << endl;
  }

  for (unsigned i = 1; i < size; ++i) {
    distribution[i] += distribution[i - 1];
  }

  int choice = generator.roulette(distribution);
  return potential_choices[choice];
}
<|endoftext|>


<commit_before>#include "app.h"

#include <memory>
#include <utility>
#include <cmath>

#include "platform.h"
#include "view/view.h"

#include "GLES2/gl2.h"
#include "EGL/egl.h"
#include "EGL/eglext.h"

std::shared_ptr<View> m_view;

void initialize() {
    logMsg("%s\n", "initialize");

    // Create view
    m_view = std::make_shared<View>();

    //
    //

    // Set up openGL state
    glDisable(GL_BLEND);
    glDisable(GL_STENCIL_TEST);
    glEnable(GL_DEPTH_TEST);
    glClearDepthf(1.0);
    glDepthRangef(0.0, 1.0);
    glDepthMask(GL_TRUE);
    glDepthFunc(GL_LEQUAL);
    glEnable(GL_CULL_FACE);
    glFrontFace(GL_CCW);
    glCullFace(GL_BACK);
    glClearColor(0.3f, 0.3f, 0.3f, 1.0f);

    logMsg("%s\n", "finish initialize");
}

void resize(int _newWidth, int _newHeight) {
    logMsg("%s\n", "resize");

    glViewport(0, 0, _newWidth, _newHeight);

    if (m_view) {
        m_view->setAspect(_newWidth, _newHeight);
    }
}

void update(float _dt) {

}

void render() {
    // Set up openGL for new frame
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glm::dmat4 view = m_view->getViewMatrix();
    glm::dmat4 viewProj = m_view->getViewProjectionMatrix();

    //
    //

    // TODO: This error checking is incomplete and only marginally useful
    // 1. We need to continue calling glGetError until no error states remain
    // 2. Repeating an error message 60 times per second is not useful, try to consolidate
    GLenum glError = glGetError();
    if (glError) {
        logMsg("GL Error %d!!!\n", glError);
    }
}

void teardown() {
    // TODO: Release resources!
}<commit_msg>view issue<commit_after>#include "app.h"

#include "GLES2/gl2.h"
#include "EGL/egl.h"
#include "EGL/eglext.h"

#include <memory>
#include <utility>
#include <cmath>

#include "platform.h"
#include "view/view.h"

std::shared_ptr<View> m_view;

void initialize() {
    logMsg("%s\n", "initialize");

    // Create view
    m_view = std::make_shared<View>();

    //
    //

    // Set up openGL state
    glDisable(GL_BLEND);
    glDisable(GL_STENCIL_TEST);
    glEnable(GL_DEPTH_TEST);
    glClearDepthf(1.0);
    glDepthRangef(0.0, 1.0);
    glDepthMask(GL_TRUE);
    glDepthFunc(GL_LEQUAL);
    glEnable(GL_CULL_FACE);
    glFrontFace(GL_CCW);
    glCullFace(GL_BACK);
    glClearColor(0.3f, 0.3f, 0.3f, 1.0f);

    logMsg("%s\n", "finish initialize");
}

void resize(int _newWidth, int _newHeight) {
    logMsg("%s\n", "resize");

    glViewport(0, 0, _newWidth, _newHeight);

    if (m_view) {
        m_view->setAspect(_newWidth, _newHeight);
    }
}

void update(float _dt) {

}

void render() {
    // Set up openGL for new frame
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    // glm::dmat4 view = m_view->getViewMatrix();
    // glm::dmat4 viewProj = m_view->getViewProjectionMatrix();

    //
    //

    // TODO: This error checking is incomplete and only marginally useful
    // 1. We need to continue calling glGetError until no error states remain
    // 2. Repeating an error message 60 times per second is not useful, try to consolidate
    GLenum glError = glGetError();
    if (glError) {
        logMsg("GL Error %d!!!\n", glError);
    }
}

void teardown() {
    // TODO: Release resources!
}<|endoftext|>


<commit_before>/*
 * Copyright (c) 2000-2005 The Regents of The University of Michigan
 * 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;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * 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
 * OWNER 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.
 *
 * Authors: Steve Raasch
 *          Nathan Binkert
 *          Steve Reinhardt
 */

///
/// @file sim/main.cc
///
#include <Python.h>	// must be before system headers... see Python docs

#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <libgen.h>
#include <stdlib.h>
#include <signal.h>
#include <getopt.h>

#include <list>
#include <string>
#include <vector>

#include "base/callback.hh"
#include "base/inifile.hh"
#include "base/misc.hh"
#include "base/output.hh"
#include "base/pollevent.hh"
#include "base/statistics.hh"
#include "base/str.hh"
#include "base/time.hh"
#include "cpu/base.hh"
#include "cpu/smt.hh"
#include "mem/mem_object.hh"
#include "mem/port.hh"
#include "sim/async.hh"
#include "sim/builder.hh"
#include "sim/host.hh"
#include "sim/serialize.hh"
#include "sim/sim_events.hh"
#include "sim/sim_exit.hh"
#include "sim/sim_object.hh"
#include "sim/stat_control.hh"
#include "sim/stats.hh"
#include "sim/root.hh"

using namespace std;

// See async.h.
volatile bool async_event = false;
volatile bool async_dump = false;
volatile bool async_dumpreset = false;
volatile bool async_exit = false;
volatile bool async_io = false;
volatile bool async_alarm = false;

/// Stats signal handler.
void
dumpStatsHandler(int sigtype)
{
    async_event = true;
    async_dump = true;
}

void
dumprstStatsHandler(int sigtype)
{
    async_event = true;
    async_dumpreset = true;
}

/// Exit signal handler.
void
exitNowHandler(int sigtype)
{
    async_event = true;
    async_exit = true;
}

/// Abort signal handler.
void
abortHandler(int sigtype)
{
    cerr << "Program aborted at cycle " << curTick << endl;

#if TRACING_ON
    // dump trace buffer, if there is one
    Trace::theLog.dump(cerr);
#endif
}

extern "C" { void init_cc_main(); }

int
main(int argc, char **argv)
{
    signal(SIGFPE, SIG_IGN);		// may occur on misspeculated paths
    signal(SIGTRAP, SIG_IGN);
    signal(SIGUSR1, dumpStatsHandler);		// dump intermediate stats
    signal(SIGUSR2, dumprstStatsHandler);	// dump and reset stats
    signal(SIGINT, exitNowHandler);		// dump final stats and exit
    signal(SIGABRT, abortHandler);

    Py_SetProgramName(argv[0]);

    // default path to m5 python code is the currently executing
    // file... Python ZipImporter will find embedded zip archive.
    // The M5_ARCHIVE environment variable can be used to override this.
    char *m5_archive = getenv("M5_ARCHIVE");
    string pythonpath = m5_archive ? m5_archive : argv[0];

    char *oldpath = getenv("PYTHONPATH");
    if (oldpath != NULL) {
        pythonpath += ":";
        pythonpath += oldpath;
    }

    if (setenv("PYTHONPATH", pythonpath.c_str(), true) == -1)
        fatal("setenv: %s\n", strerror(errno));

    // initialize embedded Python interpreter
    Py_Initialize();
    PySys_SetArgv(argc, argv);

    // initialize SWIG 'cc_main' module
    init_cc_main();

    PyRun_SimpleString("import m5");
    PyRun_SimpleString("m5.main()");

    // clean up Python intepreter.
    Py_Finalize();
}

void
setOutputDir(const string &dir)
{
    simout.setDirectory(dir);
}

IniFile inifile;

SimObject *
createSimObject(const string &name)
{
    return SimObjectClass::createObject(inifile, name);
}

/**
 * Pointer to the Python function that maps names to SimObjects.
 */
PyObject *resolveFunc = NULL;

/**
 * Convert a pointer to the Python object that SWIG wraps around a C++
 * SimObject pointer back to the actual C++ pointer.  See main.i.
 */
extern "C" SimObject *convertSwigSimObjectPtr(PyObject *);

SimObject *
resolveSimObject(const string &name)
{
    PyObject *pyPtr = PyEval_CallFunction(resolveFunc, "(s)", name.c_str());
    if (pyPtr == NULL) {
        PyErr_Print();
        panic("resolveSimObject: failure on call to Python for %s", name);
    }

    SimObject *simObj = convertSwigSimObjectPtr(pyPtr);
    if (simObj == NULL)
        panic("resolveSimObject: failure on pointer conversion for %s", name);

    return simObj;
}

/**
 * Load config.ini into C++ database.  Exported to Python via SWIG;
 * invoked from m5.instantiate().
 */
void
loadIniFile(PyObject *_resolveFunc)
{
    resolveFunc = _resolveFunc;
    configStream = simout.find("config.out");

    // The configuration database is now complete; start processing it.
    inifile.load("config.ini");

    // Initialize statistics database
    Stats::InitSimStats();
}

/**
 * Look up a MemObject port.  Helper function for connectPorts().
 */
Port *
lookupPort(SimObject *so, const std::string &name, int i)
{
    MemObject *mo = dynamic_cast<MemObject *>(so);
    if (mo == NULL) {
        warn("error casting SimObject %s to MemObject", so->name());
        return NULL;
    }

    Port *p = mo->getPort(name, i);
    if (p == NULL)
        warn("error looking up port %s on object %s", name, so->name());
    return p;
}

/**
 * Connect the described MemObject ports.  Called from Python via SWIG.
 */
int
connectPorts(SimObject *o1, const std::string &name1, int i1,
             SimObject *o2, const std::string &name2, int i2)
{
    Port *p1 = lookupPort(o1, name1, i1);
    Port *p2 = lookupPort(o2, name2, i2);

    if (p1 == NULL || p2 == NULL) {
        warn("connectPorts: port lookup error");
        return 0;
    }

    p1->setPeer(p2);
    p2->setPeer(p1);

    return 1;
}

/**
 * Do final initialization steps after object construction but before
 * start of simulation.
 */
void
finalInit()
{
    // Parse and check all non-config-hierarchy parameters.
    ParamContext::parseAllContexts(inifile);
    ParamContext::checkAllContexts();

    // Echo all parameter settings to stats file as well.
    ParamContext::showAllContexts(*configStream);

    // Do a second pass to finish initializing the sim objects
    SimObject::initAll();

    // Restore checkpointed state, if any.
#if 0
    configHierarchy.unserializeSimObjects();
#endif

    SimObject::regAllStats();

    // Check to make sure that the stats package is properly initialized
    Stats::check();

    // Reset to put the stats in a consistent state.
    Stats::reset();

    SimStartup();
}

/** Simulate for num_cycles additional cycles.  If num_cycles is -1
 * (the default), do not limit simulation; some other event must
 * terminate the loop.  Exported to Python via SWIG.
 * @return The SimLoopExitEvent that caused the loop to exit.
 */
SimLoopExitEvent *
simulate(Tick num_cycles = -1)
{
    warn("Entering event queue @ %d.  Starting simulation...\n", curTick);

    // Fix up num_cycles.  Special default value -1 means simulate
    // "forever"... schedule event at MaxTick just to be safe.
    // Otherwise it's a delta for additional cycles to simulate past
    // curTick, and thus must be non-negative.
    if (num_cycles == -1)
        num_cycles = MaxTick;
    else if (num_cycles < 0)
        fatal("simulate: num_cycles must be >= 0 (was %d)\n", num_cycles);
    else
        num_cycles = curTick + num_cycles;

    Event *limit_event = new SimLoopExitEvent(num_cycles,
                                              "simulate() limit reached");

    while (1) {
        // there should always be at least one event (the SimLoopExitEvent
        // we just scheduled) in the queue
        assert(!mainEventQueue.empty());
        assert(curTick <= mainEventQueue.nextTick() &&
               "event scheduled in the past");

        // forward current cycle to the time of the first event on the
        // queue
        curTick = mainEventQueue.nextTick();
        Event *exit_event = mainEventQueue.serviceOne();
        if (exit_event != NULL) {
            // hit some kind of exit event; return to Python
            // event must be subclass of SimLoopExitEvent...
            SimLoopExitEvent *se_event = dynamic_cast<SimLoopExitEvent *>(exit_event);
            if (se_event == NULL)
                panic("Bogus exit event class!");

            // if we didn't hit limit_event, delete it
            if (se_event != limit_event) {
                assert(limit_event->scheduled());
                limit_event->deschedule();
                delete limit_event;
            }

            return se_event;
        }

        if (async_event) {
            async_event = false;
            if (async_dump) {
                async_dump = false;

                using namespace Stats;
                SetupEvent(Dump, curTick);
            }

            if (async_dumpreset) {
                async_dumpreset = false;

                using namespace Stats;
                SetupEvent(Dump | Reset, curTick);
            }

            if (async_exit) {
                async_exit = false;
                exitSimLoop("user interrupt received");
            }

            if (async_io || async_alarm) {
                async_io = false;
                async_alarm = false;
                pollQueue.service();
            }
        }
    }

    // not reached... only exit is return on SimLoopExitEvent
}

Event *
createCountedDrain()
{
    return new CountedDrainEvent();
}

void
cleanupCountedDrain(Event *counted_drain)
{
    CountedDrainEvent *event =
        dynamic_cast<CountedDrainEvent *>(counted_drain);
    if (event == NULL) {
        fatal("Called cleanupCountedDrain() on an event that was not "
              "a CountedDrainEvent.");
    }
    assert(event->getCount() == 0);
    delete event;
}

void
serializeAll(const std::string &cpt_dir)
{
    Serializable::serializeAll(cpt_dir);
}

void
unserializeAll(const std::string &cpt_dir)
{
    Serializable::unserializeAll(cpt_dir);
}

/**
 * Queue of C++ callbacks to invoke on simulator exit.
 */
CallbackQueue exitCallbacks;

/**
 * Register an exit callback.
 */
void
registerExitCallback(Callback *callback)
{
    exitCallbacks.add(callback);
}

BaseCPU *
convertToBaseCPUPtr(SimObject *obj)
{
    BaseCPU *ptr = dynamic_cast<BaseCPU *>(obj);

    if (ptr == NULL)
        warn("Casting to BaseCPU pointer failed");
    return ptr;
}

/**
 * Do C++ simulator exit processing.  Exported to SWIG to be invoked
 * when simulator terminates via Python's atexit mechanism.
 */
void
doExitCleanup()
{
    exitCallbacks.process();
    exitCallbacks.clear();

    cout.flush();

    ParamContext::cleanupAllContexts();

    // print simulation stats
    Stats::DumpNow();
}
<commit_msg>Get the path to load the ini file from.  I'm not sure if this fix is needed in other places as well.<commit_after>/*
 * Copyright (c) 2000-2005 The Regents of The University of Michigan
 * 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;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * 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
 * OWNER 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.
 *
 * Authors: Steve Raasch
 *          Nathan Binkert
 *          Steve Reinhardt
 */

///
/// @file sim/main.cc
///
#include <Python.h>	// must be before system headers... see Python docs

#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <libgen.h>
#include <stdlib.h>
#include <signal.h>
#include <getopt.h>

#include <list>
#include <string>
#include <vector>

#include "base/callback.hh"
#include "base/inifile.hh"
#include "base/misc.hh"
#include "base/output.hh"
#include "base/pollevent.hh"
#include "base/statistics.hh"
#include "base/str.hh"
#include "base/time.hh"
#include "cpu/base.hh"
#include "cpu/smt.hh"
#include "mem/mem_object.hh"
#include "mem/port.hh"
#include "sim/async.hh"
#include "sim/builder.hh"
#include "sim/host.hh"
#include "sim/serialize.hh"
#include "sim/sim_events.hh"
#include "sim/sim_exit.hh"
#include "sim/sim_object.hh"
#include "sim/stat_control.hh"
#include "sim/stats.hh"
#include "sim/root.hh"

using namespace std;

// See async.h.
volatile bool async_event = false;
volatile bool async_dump = false;
volatile bool async_dumpreset = false;
volatile bool async_exit = false;
volatile bool async_io = false;
volatile bool async_alarm = false;

/// Stats signal handler.
void
dumpStatsHandler(int sigtype)
{
    async_event = true;
    async_dump = true;
}

void
dumprstStatsHandler(int sigtype)
{
    async_event = true;
    async_dumpreset = true;
}

/// Exit signal handler.
void
exitNowHandler(int sigtype)
{
    async_event = true;
    async_exit = true;
}

/// Abort signal handler.
void
abortHandler(int sigtype)
{
    cerr << "Program aborted at cycle " << curTick << endl;

#if TRACING_ON
    // dump trace buffer, if there is one
    Trace::theLog.dump(cerr);
#endif
}

extern "C" { void init_cc_main(); }

int
main(int argc, char **argv)
{
    signal(SIGFPE, SIG_IGN);		// may occur on misspeculated paths
    signal(SIGTRAP, SIG_IGN);
    signal(SIGUSR1, dumpStatsHandler);		// dump intermediate stats
    signal(SIGUSR2, dumprstStatsHandler);	// dump and reset stats
    signal(SIGINT, exitNowHandler);		// dump final stats and exit
    signal(SIGABRT, abortHandler);

    Py_SetProgramName(argv[0]);

    // default path to m5 python code is the currently executing
    // file... Python ZipImporter will find embedded zip archive.
    // The M5_ARCHIVE environment variable can be used to override this.
    char *m5_archive = getenv("M5_ARCHIVE");
    string pythonpath = m5_archive ? m5_archive : argv[0];

    char *oldpath = getenv("PYTHONPATH");
    if (oldpath != NULL) {
        pythonpath += ":";
        pythonpath += oldpath;
    }

    if (setenv("PYTHONPATH", pythonpath.c_str(), true) == -1)
        fatal("setenv: %s\n", strerror(errno));

    // initialize embedded Python interpreter
    Py_Initialize();
    PySys_SetArgv(argc, argv);

    // initialize SWIG 'cc_main' module
    init_cc_main();

    PyRun_SimpleString("import m5");
    PyRun_SimpleString("m5.main()");

    // clean up Python intepreter.
    Py_Finalize();
}

void
setOutputDir(const string &dir)
{
    simout.setDirectory(dir);
}

IniFile inifile;

SimObject *
createSimObject(const string &name)
{
    return SimObjectClass::createObject(inifile, name);
}

/**
 * Pointer to the Python function that maps names to SimObjects.
 */
PyObject *resolveFunc = NULL;

/**
 * Convert a pointer to the Python object that SWIG wraps around a C++
 * SimObject pointer back to the actual C++ pointer.  See main.i.
 */
extern "C" SimObject *convertSwigSimObjectPtr(PyObject *);

SimObject *
resolveSimObject(const string &name)
{
    PyObject *pyPtr = PyEval_CallFunction(resolveFunc, "(s)", name.c_str());
    if (pyPtr == NULL) {
        PyErr_Print();
        panic("resolveSimObject: failure on call to Python for %s", name);
    }

    SimObject *simObj = convertSwigSimObjectPtr(pyPtr);
    if (simObj == NULL)
        panic("resolveSimObject: failure on pointer conversion for %s", name);

    return simObj;
}

/**
 * Load config.ini into C++ database.  Exported to Python via SWIG;
 * invoked from m5.instantiate().
 */
void
loadIniFile(PyObject *_resolveFunc)
{
    resolveFunc = _resolveFunc;
    configStream = simout.find("config.out");

    // The configuration database is now complete; start processing it.
    inifile.load(simout.resolve("config.ini"));

    // Initialize statistics database
    Stats::InitSimStats();
}

/**
 * Look up a MemObject port.  Helper function for connectPorts().
 */
Port *
lookupPort(SimObject *so, const std::string &name, int i)
{
    MemObject *mo = dynamic_cast<MemObject *>(so);
    if (mo == NULL) {
        warn("error casting SimObject %s to MemObject", so->name());
        return NULL;
    }

    Port *p = mo->getPort(name, i);
    if (p == NULL)
        warn("error looking up port %s on object %s", name, so->name());
    return p;
}

/**
 * Connect the described MemObject ports.  Called from Python via SWIG.
 */
int
connectPorts(SimObject *o1, const std::string &name1, int i1,
             SimObject *o2, const std::string &name2, int i2)
{
    Port *p1 = lookupPort(o1, name1, i1);
    Port *p2 = lookupPort(o2, name2, i2);

    if (p1 == NULL || p2 == NULL) {
        warn("connectPorts: port lookup error");
        return 0;
    }

    p1->setPeer(p2);
    p2->setPeer(p1);

    return 1;
}

/**
 * Do final initialization steps after object construction but before
 * start of simulation.
 */
void
finalInit()
{
    // Parse and check all non-config-hierarchy parameters.
    ParamContext::parseAllContexts(inifile);
    ParamContext::checkAllContexts();

    // Echo all parameter settings to stats file as well.
    ParamContext::showAllContexts(*configStream);

    // Do a second pass to finish initializing the sim objects
    SimObject::initAll();

    // Restore checkpointed state, if any.
#if 0
    configHierarchy.unserializeSimObjects();
#endif

    SimObject::regAllStats();

    // Check to make sure that the stats package is properly initialized
    Stats::check();

    // Reset to put the stats in a consistent state.
    Stats::reset();

    SimStartup();
}

/** Simulate for num_cycles additional cycles.  If num_cycles is -1
 * (the default), do not limit simulation; some other event must
 * terminate the loop.  Exported to Python via SWIG.
 * @return The SimLoopExitEvent that caused the loop to exit.
 */
SimLoopExitEvent *
simulate(Tick num_cycles = -1)
{
    warn("Entering event queue @ %d.  Starting simulation...\n", curTick);

    // Fix up num_cycles.  Special default value -1 means simulate
    // "forever"... schedule event at MaxTick just to be safe.
    // Otherwise it's a delta for additional cycles to simulate past
    // curTick, and thus must be non-negative.
    if (num_cycles == -1)
        num_cycles = MaxTick;
    else if (num_cycles < 0)
        fatal("simulate: num_cycles must be >= 0 (was %d)\n", num_cycles);
    else
        num_cycles = curTick + num_cycles;

    Event *limit_event = new SimLoopExitEvent(num_cycles,
                                              "simulate() limit reached");

    while (1) {
        // there should always be at least one event (the SimLoopExitEvent
        // we just scheduled) in the queue
        assert(!mainEventQueue.empty());
        assert(curTick <= mainEventQueue.nextTick() &&
               "event scheduled in the past");

        // forward current cycle to the time of the first event on the
        // queue
        curTick = mainEventQueue.nextTick();
        Event *exit_event = mainEventQueue.serviceOne();
        if (exit_event != NULL) {
            // hit some kind of exit event; return to Python
            // event must be subclass of SimLoopExitEvent...
            SimLoopExitEvent *se_event = dynamic_cast<SimLoopExitEvent *>(exit_event);
            if (se_event == NULL)
                panic("Bogus exit event class!");

            // if we didn't hit limit_event, delete it
            if (se_event != limit_event) {
                assert(limit_event->scheduled());
                limit_event->deschedule();
                delete limit_event;
            }

            return se_event;
        }

        if (async_event) {
            async_event = false;
            if (async_dump) {
                async_dump = false;

                using namespace Stats;
                SetupEvent(Dump, curTick);
            }

            if (async_dumpreset) {
                async_dumpreset = false;

                using namespace Stats;
                SetupEvent(Dump | Reset, curTick);
            }

            if (async_exit) {
                async_exit = false;
                exitSimLoop("user interrupt received");
            }

            if (async_io || async_alarm) {
                async_io = false;
                async_alarm = false;
                pollQueue.service();
            }
        }
    }

    // not reached... only exit is return on SimLoopExitEvent
}

Event *
createCountedDrain()
{
    return new CountedDrainEvent();
}

void
cleanupCountedDrain(Event *counted_drain)
{
    CountedDrainEvent *event =
        dynamic_cast<CountedDrainEvent *>(counted_drain);
    if (event == NULL) {
        fatal("Called cleanupCountedDrain() on an event that was not "
              "a CountedDrainEvent.");
    }
    assert(event->getCount() == 0);
    delete event;
}

void
serializeAll(const std::string &cpt_dir)
{
    Serializable::serializeAll(cpt_dir);
}

void
unserializeAll(const std::string &cpt_dir)
{
    Serializable::unserializeAll(cpt_dir);
}

/**
 * Queue of C++ callbacks to invoke on simulator exit.
 */
CallbackQueue exitCallbacks;

/**
 * Register an exit callback.
 */
void
registerExitCallback(Callback *callback)
{
    exitCallbacks.add(callback);
}

BaseCPU *
convertToBaseCPUPtr(SimObject *obj)
{
    BaseCPU *ptr = dynamic_cast<BaseCPU *>(obj);

    if (ptr == NULL)
        warn("Casting to BaseCPU pointer failed");
    return ptr;
}

/**
 * Do C++ simulator exit processing.  Exported to SWIG to be invoked
 * when simulator terminates via Python's atexit mechanism.
 */
void
doExitCleanup()
{
    exitCallbacks.process();
    exitCallbacks.clear();

    cout.flush();

    ParamContext::cleanupAllContexts();

    // print simulation stats
    Stats::DumpNow();
}
<|endoftext|>


<commit_before>/******************************************************************************
 * Copyright (c) 2016 Sergey Alexandrov
 *
 * 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.
 ******************************************************************************/

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>

// In OpenCV 3 imwrite has been moved to imgcodecs module
#if CV_MAJOR_VERSION >= 3
#include <opencv2/imgcodecs/imgcodecs.hpp>
#endif

#include <radical/radiometric_response.h>

#include "utils/plot_radiometric_response.h"
#include "utils/program_options.h"

class Options : public OptionsBase {
 public:
  std::string r_response;
  bool save = false;

 protected:
  virtual void addOptions(boost::program_options::options_description& desc) override {
    namespace po = boost::program_options;
    desc.add_options()("save,s", po::bool_switch(&save), "Save to PNG file");
  }

  virtual void addPositional(boost::program_options::options_description& desc,
                             boost::program_options::positional_options_description& positional) override {
    namespace po = boost::program_options;
    desc.add_options()("crf", po::value<std::string>(&r_response), "Calibration file with radiometric response");
    positional.add("crf", 1);
  }

  virtual void printHelp() override {
    std::cout << "Usage: display_radiometric_response [options] <radiometric-response>" << std::endl;
    std::cout << "" << std::endl;
    std::cout << "Visualizes radiometric response stored in a calibration file." << std::endl;
    std::cout << "" << std::endl;
    std::cout << "With the --save option the displayed image will also be written to the disk." << std::endl;
    std::cout << "File name is constructed by appending \".png\" to the input file path." << std::endl;
    std::cout << "" << std::endl;
  }
};

int main(int argc, const char** argv) {
  Options options;
  if (!options.parse(argc, argv))
    return 1;

  radical::RadiometricResponse rr(options.r_response);
  auto min_radiance = rr.inverseMap(cv::Vec3b(0, 0, 0));
  auto max_radiance = rr.inverseMap(cv::Vec3b(255, 255, 255));

  std::cout << "Loaded radiometric response from file \"" << options.r_response << "\"" << std::endl;
  std::cout << "Irradiance range: " << min_radiance << " - " << max_radiance << std::endl;

  auto plot = utils::plotRadiometricResponse(rr);

  if (options.save) {
    auto output = options.r_response + ".png";
    cv::imwrite(output, plot);
    std::cout << "Saved radiometric response visualization to file \"" << output << "\"" << std::endl;
  }

  cv::imshow("Radiometric response", plot);
  cv::waitKey(-1);

  return 0;
}
<commit_msg>With --save option do not show radiometric response on the screen<commit_after>/******************************************************************************
 * Copyright (c) 2016 Sergey Alexandrov
 *
 * 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.
 ******************************************************************************/

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>

// In OpenCV 3 imwrite has been moved to imgcodecs module
#if CV_MAJOR_VERSION >= 3
#include <opencv2/imgcodecs/imgcodecs.hpp>
#endif

#include <radical/radiometric_response.h>

#include "utils/plot_radiometric_response.h"
#include "utils/program_options.h"

class Options : public OptionsBase {
 public:
  std::string r_response;
  bool save = false;

 protected:
  virtual void addOptions(boost::program_options::options_description& desc) override {
    namespace po = boost::program_options;
    desc.add_options()("save,s", po::bool_switch(&save), "Save to PNG file and exit");
  }

  virtual void addPositional(boost::program_options::options_description& desc,
                             boost::program_options::positional_options_description& positional) override {
    namespace po = boost::program_options;
    desc.add_options()("crf", po::value<std::string>(&r_response), "Calibration file with radiometric response");
    positional.add("crf", 1);
  }

  virtual void printHelp() override {
    std::cout << "Usage: display_radiometric_response [options] <radiometric-response>" << std::endl;
    std::cout << "" << std::endl;
    std::cout << "Plots radiometric response stored in a calibration file and displays it on the screen." << std::endl;
    std::cout << "" << std::endl;
    std::cout << "With the --save option the plot will be written to the disk instead of showing on the screen." << std::endl;
    std::cout << "Output file name is constructed by appending \".png\" to the input file path." << std::endl;
    std::cout << "" << std::endl;
  }
};

int main(int argc, const char** argv) {
  Options options;
  if (!options.parse(argc, argv))
    return 1;

  radical::RadiometricResponse rr(options.r_response);
  auto min_radiance = rr.inverseMap(cv::Vec3b(0, 0, 0));
  auto max_radiance = rr.inverseMap(cv::Vec3b(255, 255, 255));

  std::cout << "Loaded radiometric response from file \"" << options.r_response << "\"" << std::endl;
  std::cout << "Irradiance range: " << min_radiance << " - " << max_radiance << std::endl;

  auto plot = utils::plotRadiometricResponse(rr);

  if (options.save) {
    auto output = options.r_response + ".png";
    cv::imwrite(output, plot);
    std::cout << "Saved radiometric response visualization to file \"" << output << "\"" << std::endl;
  } else {
    cv::imshow("Radiometric response", plot);
    cv::waitKey(-1);
  }

  return 0;
}
<|endoftext|>


<commit_before>//
//  SString.cpp
//  DataStruct
//
//  Created by haozhu on 2017/6/10.
//  Copyright © 2017年 neu. All rights reserved.
//

//串采用定长顺序存储结构
//SString是数组类型，故不需引用类型

#include "SString.hpp"
<commit_msg>完成串的部分操作方法<commit_after>//
//  SString.cpp
//  DataStruct
//
//  Created by haozhu on 2017/6/10.
//  Copyright © 2017年 neu. All rights reserved.
//

//串采用定长顺序存储结构
//SString是数组类型，故不需引用类型

#include "SString.hpp"

//生成一个其值等于chars的串T
Status StrAssign(SString T, char *chars){
    if (strlen(chars)>MAXSTRLEN) { //要保存的串超过了T的长度
        return ERROR;
    }else{
        T[0] = strlen(chars);  //串T的第一个位置保存字符串的长度
        for (int i=1; i<=T[0]; i++) {
            T[i] = *(chars+i-1);
        }
        return OK;
    }
}

//由串S复制得串T
Status StrCopy(SString T, SString S){
    for (int i=0; i<S[0]; i++) {
        T[i] = S[i];
    }
    return OK;
}

//若串为空串则返回True，否则返回False
Status StrEmpty(SString T){
    if (T[0]) {
        return FALSE;
    }else{
        return TRUE;
    }
}

//返回串T的长度
int StrLength(SString T){
    return T[0];
}

//若串T,S存在，若T>S, 返回值>0，T=S,返回值=0，T<S，返回值<0
int StrCompare(SString T, SString S){
    for (int i=1; i<=T[0]&&i<=S[0]; i++) {
        if (T[i]!=S[i]) {
            return T[i]-S[i];
        }
    }
    return T[0]-S[0];
}

//将S清为空串
Status CleanStr(SString T){
    T[0] = 0; //令串长等于0
    return OK;
}

//用T返回由S1和S2联结而成的新串，若未截断，返回True，否则返回False
Status Concat(SString T, SString S1, SString S2){
    if (S1[0]+S2[0]<=MAXSTRLEN) { //字符串未截断
        T[0] = S1[0]+S2[0];
        for (int i=1; i<=S1[0]; i++) {
            T[i] = S1[i];
        }
        for (int i=1; i<=S2[0]; i++) {
            T[S1[0]+i] = S2[i];
        }
        return OK;
    }else{  //字符串截断
        T[0] = MAXSTRLEN;
        for (int i=1; i<=S1[0]&&i<=MAXSTRLEN; i++) {
            T[i] = S1[i];
        }
        for (int i=1; i<=MAXSTRLEN-S1[0]; i++) {
            T[S1[0]+i] = S2[i];  //进入了这个循环说明MAXSTRLEN-S1[0]>=1
        }
        return FALSE;
    }
}

//用sub串返回串T的第pos个字符起长度为len的子串
Status SubString(SString T, SString sub, int pos, int len){

    if (pos<1||pos>T[0]||len<0||pos+len-1>T[0]) {
        return ERROR;
    }
    for (int i=1; i<=len; i++) {
        sub[i] = T[pos+len-1];
    }
    sub[0] = len;
    return OK;

    //我的写法
    int to;
    if (pos+len-1>MAXSTRLEN) {
        to = MAXSTRLEN;
    }else{
        to = pos+len-1;
    }
    for (int i=pos,j=1; i<=to&&j<=MAXSTRLEN; i++,j++) {
        sub[j] = T[i];
    }
    return OK;
}

<|endoftext|>