<commit_before>/*  Sirikata -- Platform Dependent Definitions
 *  Platform.hpp
 *
 *  Copyright (c) 2009, Ewen Cheslack-Postava and Daniel Reiter Horn
 *  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 Sirikata 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.
 */

#ifndef _SIRIKATA_PLATFORM_HPP_
#define _SIRIKATA_PLATFORM_HPP_

#define PLATFORM_WINDOWS 0
#define PLATFORM_LINUX   1
#define PLATFORM_MAC     2

#if defined(__WIN32__) || defined(_WIN32)
// disable type needs to have dll-interface to be used byu clients due to STL member variables which are not public
#pragma warning (disable: 4251)
//disable warning about no suitable definition provided for explicit template instantiation request which seems to have no resolution nor cause any problems
#pragma warning (disable: 4661)
//disable non dll-interface class used as base for dll-interface class when deriving from singleton
#pragma warning (disable : 4275)
#  define SIRIKATA_PLATFORM PLATFORM_WINDOWS
#elif defined(__APPLE_CC__) || defined(__APPLE__)
#  define SIRIKATA_PLATFORM PLATFORM_MAC
#  ifndef __MACOSX__
#    define __MACOSX__
#  endif
#else
#  define SIRIKATA_PLATFORM PLATFORM_LINUX
#endif

#ifdef NDEBUG
#define SIRIKATA_DEBUG 0
#else
#define SIRIKATA_DEBUG 1
#endif

#ifndef SIRIKATA_EXPORT
# if SIRIKATA_PLATFORM == PLATFORM_WINDOWS
#   if defined(STATIC_LINKED)
#     define SIRIKATA_EXPORT
#   else
#     if defined(SIRIKATA_BUILD)
#       define SIRIKATA_EXPORT __declspec(dllexport)
#     else
#       define SIRIKATA_EXPORT __declspec(dllimport)
#     endif
#   endif
#   define SIRIKATA_PLUGIN_EXPORT __declspec(dllexport)
# else
#   if defined(__GNUC__) && __GNUC__ >= 4
#     define SIRIKATA_EXPORT __attribute__ ((visibility("default")))
#     define SIRIKATA_PLUGIN_EXPORT __attribute__ ((visibility("default")))
#   else
#     define SIRIKATA_EXPORT
#     define SIRIKATA_PLUGIN_EXPORT
#   endif
# endif
#endif

#ifndef SIRIKATA_FUNCTION_EXPORT
# if SIRIKATA_PLATFORM == PLATFORM_WINDOWS
#   if defined(STATIC_LINKED)
#     define SIRIKATA_FUNCTION_EXPORT
#   else
#     if defined(SIRIKATA_BUILD)
#       define SIRIKATA_FUNCTION_EXPORT __declspec(dllexport)
#     else
#       define SIRIKATA_FUNCTION_EXPORT __declspec(dllimport)
#     endif
#   endif
# else
#   define SIRIKATA_FUNCTION_EXPORT
# endif
#endif

#ifndef SIRIKATA_EXPORT_C
# define SIRIKATA_EXPORT_C extern "C" SIRIKATA_EXPORT
#endif

#ifndef SIRIKATA_PLUGIN_EXPORT_C
# define SIRIKATA_PLUGIN_EXPORT_C extern "C" SIRIKATA_PLUGIN_EXPORT
#endif

#ifdef __GLIBC__
# include <endian.h>
# define SIRIKATA_LITTLE_ENDIAN __LITTLE_ENDIAN
# define SIRIKATA_BIG_ENDIAN    __BIG_ENDIAN
# define SIRIKATA_BYTE_ORDER    __BYTE_ORDER
#elif defined(__APPLE__) || defined(MACOSX) || defined(BSD) || defined(__FreeBSD__)
# include<machine/endian.h>
# ifdef BYTE_ORDER
#  define SIRIKATA_LITTLE_ENDIAN LITTLE_ENDIAN
#  define SIRIKATA_BIG_ENDIAN    BIG_ENDIAN
#  define SIRIKATA_BYTE_ORDER    BYTE_ORDER
# else
#  error "MACINTOSH DOES NOT DEFINE ENDIANNESS"
# endif
#else
# define SIRIKATA_LITTLE_ENDIAN 1234
# define SIRIKATA_BIG_ENDIAN    4321
# ifdef _BIG_ENDIAN
#  define SIRIKATA_BYTE_ORDER SIRIKATA_BIG_ENDIAN
#  ifdef _LITTLE_ENDIAN
#   error "BOTH little and big endian defined"
#  endif
# else
#  ifdef _LITTLE_ENDIAN
#   define SIRIKATA_BYTE_ORDER SIRIKATA_LITTLE_ENDIAN
#  elif defined(__sparc) || defined(__sparc__) \
   ||   defined(_POWER) || defined(__powerpc__) \
   ||   defined(__ppc__) || defined(__hpux) \
   ||   defined(_MIPSEB) || defined(_POWER) \
   ||   defined(__s390__)
#   define SIRIKATA_BYTE_ORDER SIRIKATA_BIG_ENDIAN
#  elif defined(__i386__) || defined(__alpha__) \
   ||   defined(__ia64) || defined(__ia64__) \
   ||   defined(_M_IX86) || defined(_M_IA64) \
   ||   defined(_M_ALPHA) || defined(__amd64) \
   ||   defined(__amd64__) || defined(_M_AMD64) \
   ||   defined(__x86_64) || defined(__x86_64__) \
   ||   defined(_M_X64)
#   define SIRIKATA_BYTE_ORDER SIRIKATA_LITTLE_ENDIAN
#  else
#   error "Not a known CPU type"
#  endif
# endif
#endif

#if SIRIKATA_PLATFORM == PLATFORM_WINDOWS
#ifndef NOMINMAX
#define NOMINMAX
#endif
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
//need to get rid of GetMessage for protocol buffer compatibility
#undef GetMessage
#endif

#include <assert.h>
#include <cstddef>
#include <cstring>
#include <cmath>
#include <fstream>
#include <iostream>
#include <string>
#include <sstream>
#include <vector>
#include <list>
#include <queue>
#include <deque>
#include <set>
#include <map>
#include <algorithm>

#ifdef __GNUC__
// Required for OGRE.
#if (__GNUC__ == 4 && __GNUC_MINOR__ >= 3) || __GNUC__ > 4
#define BOOST_HAS_GCC_TR1

// #include_next is broken: it does not search default include paths!
#define BOOST_TR1_DISABLE_INCLUDE_NEXT
// config_all.hpp reads this variable, then sets BOOST_HAS_INCLUDE_NEXT anyway
#include <boost/tr1/detail/config_all.hpp>
#ifdef BOOST_HAS_INCLUDE_NEXT
// This behavior has existed since boost 1.34, unlikely to change.
#undef BOOST_HAS_INCLUDE_NEXT
#endif

#endif
#endif

#include <boost/tr1/memory.hpp>
#include <boost/tr1/array.hpp>
#include <boost/tr1/functional.hpp>
#include <boost/tr1/unordered_set.hpp>
#include <boost/tr1/unordered_map.hpp>

namespace Sirikata {

// numeric typedefs to get standardized types
typedef unsigned char uchar;
#if SIRIKATA_PLATFORM == PLATFORM_WINDOWS
#ifndef NOMINMAX
#define NOMINMAX
#endif
typedef __int8 int8;
typedef unsigned __int8 uint8;
typedef __int16 int16;
typedef unsigned __int16 uint16;
typedef __int32 int32;
typedef unsigned __int32 uint32;
typedef __int64 int64;
typedef unsigned __int64 uint64;

#else
# include <stdint.h>
typedef int8_t int8;
typedef uint8_t uint8;
typedef int16_t int16;
typedef uint16_t uint16;
typedef int32_t int32;
typedef uint32_t uint32;
typedef int64_t int64;
typedef uint64_t uint64;
#endif

typedef float float32;
typedef double float64;

typedef uchar byte;
typedef std::string String;
typedef std::vector<uint8> MemoryBuffer;

namespace Network {
class IOService;
class Stream;
class Address;
typedef std::vector<uint8> Chunk;
}
#ifdef NDEBUG
class ThreadIdCheck{};
#else
class ThreadIdCheck { public:
    unsigned int mThreadId;
};
#endif
class RoutableMessageHeader;
class RoutableMessage;
class RoutableMessageBody;
} // namespace Sirikata
#include "MemoryReference.hpp"
#include "MessageService.hpp"
#include "TotallyOrdered.hpp"
#include "Singleton.hpp"
#include "Factory.hpp"
#include "Vector2.hpp"
#include "Vector3.hpp"
#include "Vector4.hpp"
#include "Matrix3x3.hpp"
#include "Quaternion.hpp"
#include "SolidAngle.hpp"
#include "SelfWeakPtr.hpp"
#include "Noncopyable.hpp"
#include "Array.hpp"
#include "options/OptionValue.hpp"
#include "Logging.hpp"
#include "Location.hpp"
#include "VInt.hpp"
namespace Sirikata {
template<class T>T*aligned_malloc(size_t num_bytes, const unsigned char alignment) {
    unsigned char *data=(unsigned char*)malloc(num_bytes+alignment);
    if (data!=NULL) {
        size_t remainder=((size_t)data)%alignment;
        size_t offset=alignment-remainder;
        data+=offset;
        data[-1]=offset;
        return (T*)(data);
    }
    return (T*)NULL;
}
template<class T>T*aligned_new(const unsigned char alignment) {
    return aligned_malloc<T>(sizeof(T),alignment);
}
template<class T> void aligned_free(T* data) {
    if (data!=NULL) {
        unsigned char *bloc=(unsigned char*)data;
        unsigned char offset=bloc[-1];
        free(bloc-offset);
    }
}
namespace Task {
class LocalTime;
class DeltaTime;
}
class Time;
typedef Task::DeltaTime Duration;
typedef Vector2<float32> Vector2f;
typedef Vector2<float64> Vector2d;
typedef Vector3<float32> Vector3f;
typedef Vector3<float64> Vector3d;
typedef Vector4<float32> Vector4f;
typedef Vector4<float64> Vector4d;
typedef VInt<uint32> vuint32;
typedef VInt<uint64> vuint64;
using std::tr1::placeholders::_1;
using std::tr1::placeholders::_2;
using std::tr1::placeholders::_3;
using std::tr1::placeholders::_4;
using std::tr1::placeholders::_5;
using std::tr1::placeholders::_6;
using std::tr1::placeholders::_7;
using std::tr1::placeholders::_8;
using std::tr1::placeholders::_9;
}
#include "BoundingSphere.hpp"
#include "BoundingBox.hpp"
namespace Sirikata {
typedef BoundingBox<float32> BoundingBox3f3f;
typedef BoundingBox<float64> BoundingBox3d3f;
typedef BoundingSphere<float32> BoundingSphere3f;
typedef BoundingSphere<float64> BoundingSphere3d;
}
#if 0
template class std::tr1::unordered_map<Sirikata::int32, Sirikata::int32>;
template class std::tr1::unordered_map<Sirikata::uint32, Sirikata::uint32>;
template class std::tr1::unordered_map<Sirikata::uint64, Sirikata::uint64>;
template class std::tr1::unordered_map<Sirikata::int64, Sirikata::int64>;
template class std::tr1::unordered_map<Sirikata::String, Sirikata::String>;

template class std::tr1::unordered_map<Sirikata::int32, void*>;
template class std::tr1::unordered_map<Sirikata::uint32, void*>;
template class std::tr1::unordered_map<Sirikata::uint64, void*>;
template class std::tr1::unordered_map<Sirikata::int64, void*>;
template class std::tr1::unordered_map<Sirikata::String, void*>;
template class std::map<Sirikata::int32, Sirikata::int32>;
template class std::map<Sirikata::uint32, Sirikata::uint32>;
template class std::map<Sirikata::uint64, Sirikata::uint64>;
template class std::map<Sirikata::int64, Sirikata::int64>;
template class std::map<Sirikata::String, Sirikata::String>;
template class std::map<Sirikata::int32, void*>;
template class std::map<Sirikata::uint32, void*>;
template class std::map<Sirikata::uint64, void*>;
template class std::map<Sirikata::int64, void*>;
template class std::map<Sirikata::String, void*>;
template class std::vector<Sirikata::String>;
template class std::vector<void*>;
template class std::vector<Sirikata::int8>;
template class std::vector<Sirikata::uint8>;
#endif

#endif //_SIRIKATA_PLATFORM_HPP_
<commit_msg>Fixing buildbot by removing SolidAngle from .pch<commit_after>/*  Sirikata -- Platform Dependent Definitions
 *  Platform.hpp
 *
 *  Copyright (c) 2009, Ewen Cheslack-Postava and Daniel Reiter Horn
 *  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 Sirikata 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.
 */

#ifndef _SIRIKATA_PLATFORM_HPP_
#define _SIRIKATA_PLATFORM_HPP_

#define PLATFORM_WINDOWS 0
#define PLATFORM_LINUX   1
#define PLATFORM_MAC     2

#if defined(__WIN32__) || defined(_WIN32)
// disable type needs to have dll-interface to be used byu clients due to STL member variables which are not public
#pragma warning (disable: 4251)
//disable warning about no suitable definition provided for explicit template instantiation request which seems to have no resolution nor cause any problems
#pragma warning (disable: 4661)
//disable non dll-interface class used as base for dll-interface class when deriving from singleton
#pragma warning (disable : 4275)
#  define SIRIKATA_PLATFORM PLATFORM_WINDOWS
#elif defined(__APPLE_CC__) || defined(__APPLE__)
#  define SIRIKATA_PLATFORM PLATFORM_MAC
#  ifndef __MACOSX__
#    define __MACOSX__
#  endif
#else
#  define SIRIKATA_PLATFORM PLATFORM_LINUX
#endif

#ifdef NDEBUG
#define SIRIKATA_DEBUG 0
#else
#define SIRIKATA_DEBUG 1
#endif

#ifndef SIRIKATA_EXPORT
# if SIRIKATA_PLATFORM == PLATFORM_WINDOWS
#   if defined(STATIC_LINKED)
#     define SIRIKATA_EXPORT
#   else
#     if defined(SIRIKATA_BUILD)
#       define SIRIKATA_EXPORT __declspec(dllexport)
#     else
#       define SIRIKATA_EXPORT __declspec(dllimport)
#     endif
#   endif
#   define SIRIKATA_PLUGIN_EXPORT __declspec(dllexport)
# else
#   if defined(__GNUC__) && __GNUC__ >= 4
#     define SIRIKATA_EXPORT __attribute__ ((visibility("default")))
#     define SIRIKATA_PLUGIN_EXPORT __attribute__ ((visibility("default")))
#   else
#     define SIRIKATA_EXPORT
#     define SIRIKATA_PLUGIN_EXPORT
#   endif
# endif
#endif

#ifndef SIRIKATA_FUNCTION_EXPORT
# if SIRIKATA_PLATFORM == PLATFORM_WINDOWS
#   if defined(STATIC_LINKED)
#     define SIRIKATA_FUNCTION_EXPORT
#   else
#     if defined(SIRIKATA_BUILD)
#       define SIRIKATA_FUNCTION_EXPORT __declspec(dllexport)
#     else
#       define SIRIKATA_FUNCTION_EXPORT __declspec(dllimport)
#     endif
#   endif
# else
#   define SIRIKATA_FUNCTION_EXPORT
# endif
#endif

#ifndef SIRIKATA_EXPORT_C
# define SIRIKATA_EXPORT_C extern "C" SIRIKATA_EXPORT
#endif

#ifndef SIRIKATA_PLUGIN_EXPORT_C
# define SIRIKATA_PLUGIN_EXPORT_C extern "C" SIRIKATA_PLUGIN_EXPORT
#endif

#ifdef __GLIBC__
# include <endian.h>
# define SIRIKATA_LITTLE_ENDIAN __LITTLE_ENDIAN
# define SIRIKATA_BIG_ENDIAN    __BIG_ENDIAN
# define SIRIKATA_BYTE_ORDER    __BYTE_ORDER
#elif defined(__APPLE__) || defined(MACOSX) || defined(BSD) || defined(__FreeBSD__)
# include<machine/endian.h>
# ifdef BYTE_ORDER
#  define SIRIKATA_LITTLE_ENDIAN LITTLE_ENDIAN
#  define SIRIKATA_BIG_ENDIAN    BIG_ENDIAN
#  define SIRIKATA_BYTE_ORDER    BYTE_ORDER
# else
#  error "MACINTOSH DOES NOT DEFINE ENDIANNESS"
# endif
#else
# define SIRIKATA_LITTLE_ENDIAN 1234
# define SIRIKATA_BIG_ENDIAN    4321
# ifdef _BIG_ENDIAN
#  define SIRIKATA_BYTE_ORDER SIRIKATA_BIG_ENDIAN
#  ifdef _LITTLE_ENDIAN
#   error "BOTH little and big endian defined"
#  endif
# else
#  ifdef _LITTLE_ENDIAN
#   define SIRIKATA_BYTE_ORDER SIRIKATA_LITTLE_ENDIAN
#  elif defined(__sparc) || defined(__sparc__) \
   ||   defined(_POWER) || defined(__powerpc__) \
   ||   defined(__ppc__) || defined(__hpux) \
   ||   defined(_MIPSEB) || defined(_POWER) \
   ||   defined(__s390__)
#   define SIRIKATA_BYTE_ORDER SIRIKATA_BIG_ENDIAN
#  elif defined(__i386__) || defined(__alpha__) \
   ||   defined(__ia64) || defined(__ia64__) \
   ||   defined(_M_IX86) || defined(_M_IA64) \
   ||   defined(_M_ALPHA) || defined(__amd64) \
   ||   defined(__amd64__) || defined(_M_AMD64) \
   ||   defined(__x86_64) || defined(__x86_64__) \
   ||   defined(_M_X64)
#   define SIRIKATA_BYTE_ORDER SIRIKATA_LITTLE_ENDIAN
#  else
#   error "Not a known CPU type"
#  endif
# endif
#endif

#if SIRIKATA_PLATFORM == PLATFORM_WINDOWS
#ifndef NOMINMAX
#define NOMINMAX
#endif
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
//need to get rid of GetMessage for protocol buffer compatibility
#undef GetMessage
#endif

#include <assert.h>
#include <cstddef>
#include <cstring>
#include <cmath>
#include <fstream>
#include <iostream>
#include <string>
#include <sstream>
#include <vector>
#include <list>
#include <queue>
#include <deque>
#include <set>
#include <map>
#include <algorithm>

#ifdef __GNUC__
// Required for OGRE.
#if (__GNUC__ == 4 && __GNUC_MINOR__ >= 3) || __GNUC__ > 4
#define BOOST_HAS_GCC_TR1

// #include_next is broken: it does not search default include paths!
#define BOOST_TR1_DISABLE_INCLUDE_NEXT
// config_all.hpp reads this variable, then sets BOOST_HAS_INCLUDE_NEXT anyway
#include <boost/tr1/detail/config_all.hpp>
#ifdef BOOST_HAS_INCLUDE_NEXT
// This behavior has existed since boost 1.34, unlikely to change.
#undef BOOST_HAS_INCLUDE_NEXT
#endif

#endif
#endif

#include <boost/tr1/memory.hpp>
#include <boost/tr1/array.hpp>
#include <boost/tr1/functional.hpp>
#include <boost/tr1/unordered_set.hpp>
#include <boost/tr1/unordered_map.hpp>

namespace Sirikata {

// numeric typedefs to get standardized types
typedef unsigned char uchar;
#if SIRIKATA_PLATFORM == PLATFORM_WINDOWS
#ifndef NOMINMAX
#define NOMINMAX
#endif
typedef __int8 int8;
typedef unsigned __int8 uint8;
typedef __int16 int16;
typedef unsigned __int16 uint16;
typedef __int32 int32;
typedef unsigned __int32 uint32;
typedef __int64 int64;
typedef unsigned __int64 uint64;

#else
# include <stdint.h>
typedef int8_t int8;
typedef uint8_t uint8;
typedef int16_t int16;
typedef uint16_t uint16;
typedef int32_t int32;
typedef uint32_t uint32;
typedef int64_t int64;
typedef uint64_t uint64;
#endif

typedef float float32;
typedef double float64;

typedef uchar byte;
typedef std::string String;
typedef std::vector<uint8> MemoryBuffer;

namespace Network {
class IOService;
class Stream;
class Address;
typedef std::vector<uint8> Chunk;
}
#ifdef NDEBUG
class ThreadIdCheck{};
#else
class ThreadIdCheck { public:
    unsigned int mThreadId;
};
#endif
class RoutableMessageHeader;
class RoutableMessage;
class RoutableMessageBody;
} // namespace Sirikata
#include "MemoryReference.hpp"
#include "MessageService.hpp"
#include "TotallyOrdered.hpp"
#include "Singleton.hpp"
#include "Factory.hpp"
#include "Vector2.hpp"
#include "Vector3.hpp"
#include "Vector4.hpp"
#include "Matrix3x3.hpp"
#include "Quaternion.hpp"
#include "SelfWeakPtr.hpp"
#include "Noncopyable.hpp"
#include "Array.hpp"
#include "options/OptionValue.hpp"
#include "Logging.hpp"
#include "Location.hpp"
#include "VInt.hpp"
namespace Sirikata {
template<class T>T*aligned_malloc(size_t num_bytes, const unsigned char alignment) {
    unsigned char *data=(unsigned char*)malloc(num_bytes+alignment);
    if (data!=NULL) {
        size_t remainder=((size_t)data)%alignment;
        size_t offset=alignment-remainder;
        data+=offset;
        data[-1]=offset;
        return (T*)(data);
    }
    return (T*)NULL;
}
template<class T>T*aligned_new(const unsigned char alignment) {
    return aligned_malloc<T>(sizeof(T),alignment);
}
template<class T> void aligned_free(T* data) {
    if (data!=NULL) {
        unsigned char *bloc=(unsigned char*)data;
        unsigned char offset=bloc[-1];
        free(bloc-offset);
    }
}
namespace Task {
class LocalTime;
class DeltaTime;
}
class Time;
typedef Task::DeltaTime Duration;
typedef Vector2<float32> Vector2f;
typedef Vector2<float64> Vector2d;
typedef Vector3<float32> Vector3f;
typedef Vector3<float64> Vector3d;
typedef Vector4<float32> Vector4f;
typedef Vector4<float64> Vector4d;
typedef VInt<uint32> vuint32;
typedef VInt<uint64> vuint64;
using std::tr1::placeholders::_1;
using std::tr1::placeholders::_2;
using std::tr1::placeholders::_3;
using std::tr1::placeholders::_4;
using std::tr1::placeholders::_5;
using std::tr1::placeholders::_6;
using std::tr1::placeholders::_7;
using std::tr1::placeholders::_8;
using std::tr1::placeholders::_9;
}
#include "BoundingSphere.hpp"
#include "BoundingBox.hpp"
namespace Sirikata {
typedef BoundingBox<float32> BoundingBox3f3f;
typedef BoundingBox<float64> BoundingBox3d3f;
typedef BoundingSphere<float32> BoundingSphere3f;
typedef BoundingSphere<float64> BoundingSphere3d;
}
#if 0
template class std::tr1::unordered_map<Sirikata::int32, Sirikata::int32>;
template class std::tr1::unordered_map<Sirikata::uint32, Sirikata::uint32>;
template class std::tr1::unordered_map<Sirikata::uint64, Sirikata::uint64>;
template class std::tr1::unordered_map<Sirikata::int64, Sirikata::int64>;
template class std::tr1::unordered_map<Sirikata::String, Sirikata::String>;

template class std::tr1::unordered_map<Sirikata::int32, void*>;
template class std::tr1::unordered_map<Sirikata::uint32, void*>;
template class std::tr1::unordered_map<Sirikata::uint64, void*>;
template class std::tr1::unordered_map<Sirikata::int64, void*>;
template class std::tr1::unordered_map<Sirikata::String, void*>;
template class std::map<Sirikata::int32, Sirikata::int32>;
template class std::map<Sirikata::uint32, Sirikata::uint32>;
template class std::map<Sirikata::uint64, Sirikata::uint64>;
template class std::map<Sirikata::int64, Sirikata::int64>;
template class std::map<Sirikata::String, Sirikata::String>;
template class std::map<Sirikata::int32, void*>;
template class std::map<Sirikata::uint32, void*>;
template class std::map<Sirikata::uint64, void*>;
template class std::map<Sirikata::int64, void*>;
template class std::map<Sirikata::String, void*>;
template class std::vector<Sirikata::String>;
template class std::vector<void*>;
template class std::vector<Sirikata::int8>;
template class std::vector<Sirikata::uint8>;
#endif

#endif //_SIRIKATA_PLATFORM_HPP_
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2014 Pavel Kirienko <pavel.kirienko@gmail.com>
 */

#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <board.hpp>
#include <chip.h>
#include <uavcan_lpc11c24/uavcan_lpc11c24.hpp>
#include <uavcan/protocol/global_time_sync_slave.hpp>
#include <uavcan/protocol/dynamic_node_id_client.hpp>
#include <uavcan/protocol/logger.hpp>

/**
 * This function re-defines the standard ::rand(), which is used by the class uavcan::DynamicNodeIDClient.
 * Redefinition is normally not needed, but GCC 4.9 tends to generate broken binaries if it is not redefined.
 */
int rand()
{
    static int x = 1;
    x = x * 48271 % 2147483647;
    return x;
}

namespace
{

static constexpr unsigned NodeMemoryPoolSize = 2800;

/**
 * This is a compact, reentrant and thread-safe replacement to standard llto().
 * It returns the string by value, no extra storage is needed.
 */
typename uavcan::MakeString<22>::Type intToString(long long n)
{
    char buf[24] = {};
    const short sign = (n < 0) ? -1 : 1;
    if (sign < 0)
    {
        n = -n;
    }
    unsigned pos = 0;
    do
    {
        buf[pos++] = char(n % 10 + '0');
    }
    while ((n /= 10) > 0);
    if (sign < 0)
    {
        buf[pos++] = '-';
    }
    buf[pos] = '\0';
    for (unsigned i = 0, j = pos - 1U; i < j; i++, j--)
    {
        std::swap(buf[i], buf[j]);
    }
    return static_cast<const char*>(buf);
}

uavcan::Node<NodeMemoryPoolSize>& getNode()
{
    static uavcan::Node<NodeMemoryPoolSize> node(uavcan_lpc11c24::CanDriver::instance(),
                                                 uavcan_lpc11c24::SystemClock::instance());
    return node;
}

uavcan::GlobalTimeSyncSlave& getTimeSyncSlave()
{
    static uavcan::GlobalTimeSyncSlave tss(getNode());
    return tss;
}

uavcan::Logger& getLogger()
{
    static uavcan::Logger logger(getNode());
    return logger;
}

uavcan::NodeID performDynamicNodeIDAllocation()
{
    uavcan::DynamicNodeIDClient client(getNode());

    const int client_start_res = client.start(getNode().getHardwareVersion().unique_id);
    if (client_start_res < 0)
    {
        board::die();
    }

    while (!client.isAllocationComplete())
    {
        board::resetWatchdog();
        (void)getNode().spin(uavcan::MonotonicDuration::fromMSec(100));
    }

    return client.getAllocatedNodeID();
}

#if __GNUC__
__attribute__((noinline, optimize(2)))  // Higher optimization breaks the code.
#endif
void init()
{
    board::resetWatchdog();
    board::syslog("Boot\r\n");

    board::setErrorLed(false);
    board::setStatusLed(true);

    /*
     * Configuring the clock - this must be done before the CAN controller is initialized
     */
    uavcan_lpc11c24::clock::init();

    /*
     * Configuring the CAN controller
     */
    std::uint32_t bit_rate = 0;
    while (bit_rate == 0)
    {
        board::syslog("CAN auto bitrate...\r\n");
        bit_rate = uavcan_lpc11c24::CanDriver::detectBitRate(&board::resetWatchdog);
    }
    board::syslog("Bitrate: ");
    board::syslog(intToString(bit_rate).c_str());
    board::syslog("\r\n");

    if (uavcan_lpc11c24::CanDriver::instance().init(bit_rate) < 0)
    {
        board::die();
    }

    board::syslog("CAN init ok\r\n");

    board::resetWatchdog();

    /*
     * Configuring the node
     */
    getNode().setName("org.uavcan.lpc11c24_test");

    uavcan::protocol::SoftwareVersion swver;
    swver.major = FW_VERSION_MAJOR;
    swver.minor = FW_VERSION_MINOR;
    swver.vcs_commit = GIT_HASH;
    swver.optional_field_flags = swver.OPTIONAL_FIELD_FLAG_VCS_COMMIT;
    getNode().setSoftwareVersion(swver);

    uavcan::protocol::HardwareVersion hwver;
    std::uint8_t uid[board::UniqueIDSize] = {};
    board::readUniqueID(uid);
    std::copy(std::begin(uid), std::end(uid), std::begin(hwver.unique_id));
    getNode().setHardwareVersion(hwver);

    board::resetWatchdog();

    /*
     * Starting the node and performing dynamic node ID allocation
     */
    if (getNode().start() < 0)
    {
        board::die();
    }

    board::syslog("Node ID allocation...\r\n");

    getNode().setNodeID(performDynamicNodeIDAllocation());

    board::syslog("Node ID ");
    board::syslog(intToString(getNode().getNodeID().get()).c_str());
    board::syslog("\r\n");

    board::resetWatchdog();

    /*
     * Example filter configuration.
     * Can be removed safely.
     */
    {
        constexpr unsigned NumFilters = 3;
        uavcan::CanFilterConfig filters[NumFilters];

        // Acepting all service transfers addressed to us
        filters[0].id   = (unsigned(getNode().getNodeID().get()) << 8) | (1U << 7) | uavcan::CanFrame::FlagEFF;
        filters[0].mask = 0x7F80 | uavcan::CanFrame::FlagEFF;

        // Accepting time sync messages
        filters[1].id   = (4U << 8) | uavcan::CanFrame::FlagEFF;
        filters[1].mask = 0xFFFF80 | uavcan::CanFrame::FlagEFF;

        // Accepting zero CAN ID (just for the sake of testing)
        filters[2].id   = 0 | uavcan::CanFrame::FlagEFF;
        filters[2].mask = uavcan::CanFrame::MaskExtID | uavcan::CanFrame::FlagEFF;

        const auto before = uavcan_lpc11c24::clock::getMonotonic();
        if (uavcan_lpc11c24::CanDriver::instance().configureFilters(filters, NumFilters) < 0)
        {
            board::syslog("Filter init failed\r\n");
            board::die();
        }
        const auto duration = uavcan_lpc11c24::clock::getMonotonic() - before;
        board::syslog("CAN filter configuration took ");
        board::syslog(intToString(duration.toUSec()).c_str());
        board::syslog(" usec\r\n");
    }

    /*
     * Initializing other libuavcan-related objects
     */
    if (getTimeSyncSlave().start() < 0)
    {
        board::die();
    }

    if (getLogger().init() < 0)
    {
        board::die();
    }

    getLogger().setLevel(uavcan::protocol::debug::LogLevel::DEBUG);

    board::resetWatchdog();
}

}

int main()
{
    init();

    getNode().setModeOperational();

    uavcan::MonotonicTime prev_log_at;

    while (true)
    {
        const int res = getNode().spin(uavcan::MonotonicDuration::fromMSec(25));
        board::setErrorLed(res < 0);
        board::setStatusLed(uavcan_lpc11c24::CanDriver::instance().hadActivity());

        const auto ts = uavcan_lpc11c24::clock::getMonotonic();
        if ((ts - prev_log_at).toMSec() >= 1000)
        {
            prev_log_at = ts;

            /*
             * CAN bus off state monitoring
             */
            if (uavcan_lpc11c24::CanDriver::instance().isInBusOffState())
            {
                board::syslog("CAN BUS OFF\r\n");
            }

            /*
             * CAN error counter, for debugging purposes
             */
            board::syslog("CAN errors: ");
            board::syslog(intToString(static_cast<long long>(uavcan_lpc11c24::CanDriver::instance().getErrorCount())).c_str());
            board::syslog(" ");
            board::syslog(intToString(uavcan_lpc11c24::CanDriver::instance().getRxQueueOverflowCount()).c_str());
            board::syslog("\r\n");

            /*
             * We don't want to use formatting functions provided by libuavcan because they rely on std::snprintf(),
             * so we need to construct the message manually:
             */
            uavcan::protocol::debug::LogMessage logmsg;
            logmsg.level.value = uavcan::protocol::debug::LogLevel::INFO;
            logmsg.source = "app";
            logmsg.text = intToString(uavcan_lpc11c24::clock::getPrevUtcAdjustment().toUSec()).c_str();
            (void)getLogger().log(logmsg);
        }

        board::resetWatchdog();
    }
}
<commit_msg>LPC11C24 demo optimization<commit_after>/*
 * Copyright (C) 2014 Pavel Kirienko <pavel.kirienko@gmail.com>
 */

#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <board.hpp>
#include <chip.h>
#include <uavcan_lpc11c24/uavcan_lpc11c24.hpp>
#include <uavcan/protocol/global_time_sync_slave.hpp>
#include <uavcan/protocol/dynamic_node_id_client.hpp>
#include <uavcan/protocol/logger.hpp>

/*
 * GCC 4.9 cannot generate a working binary with higher optimization levels, although
 *         rest of the firmware can be compiled with -Os.
 * GCC 4.8 and earlier don't work at all on this firmware.
 */
#if __GNUC__
# pragma GCC optimize 1
#endif

/**
 * This function re-defines the standard ::rand(), which is used by the class uavcan::DynamicNodeIDClient.
 * Redefinition is normally not needed, but GCC 4.9 tends to generate broken binaries if it is not redefined.
 */
int rand()
{
    static int x = 1;
    x = x * 48271 % 2147483647;
    return x;
}

namespace
{

static constexpr unsigned NodeMemoryPoolSize = 2800;

/**
 * This is a compact, reentrant and thread-safe replacement to standard llto().
 * It returns the string by value, no extra storage is needed.
 */
typename uavcan::MakeString<22>::Type intToString(long long n)
{
    char buf[24] = {};
    const short sign = (n < 0) ? -1 : 1;
    if (sign < 0)
    {
        n = -n;
    }
    unsigned pos = 0;
    do
    {
        buf[pos++] = char(n % 10 + '0');
    }
    while ((n /= 10) > 0);
    if (sign < 0)
    {
        buf[pos++] = '-';
    }
    buf[pos] = '\0';
    for (unsigned i = 0, j = pos - 1U; i < j; i++, j--)
    {
        std::swap(buf[i], buf[j]);
    }
    return static_cast<const char*>(buf);
}

uavcan::Node<NodeMemoryPoolSize>& getNode()
{
    static uavcan::Node<NodeMemoryPoolSize> node(uavcan_lpc11c24::CanDriver::instance(),
                                                 uavcan_lpc11c24::SystemClock::instance());
    return node;
}

uavcan::GlobalTimeSyncSlave& getTimeSyncSlave()
{
    static uavcan::GlobalTimeSyncSlave tss(getNode());
    return tss;
}

uavcan::Logger& getLogger()
{
    static uavcan::Logger logger(getNode());
    return logger;
}

uavcan::NodeID performDynamicNodeIDAllocation()
{
    uavcan::DynamicNodeIDClient client(getNode());

    const int client_start_res = client.start(getNode().getHardwareVersion().unique_id);
    if (client_start_res < 0)
    {
        board::die();
    }

    while (!client.isAllocationComplete())
    {
        board::resetWatchdog();
        (void)getNode().spin(uavcan::MonotonicDuration::fromMSec(100));
    }

    return client.getAllocatedNodeID();
}

void init()
{
    board::resetWatchdog();
    board::syslog("Boot\r\n");

    board::setErrorLed(false);
    board::setStatusLed(true);

    /*
     * Configuring the clock - this must be done before the CAN controller is initialized
     */
    uavcan_lpc11c24::clock::init();

    /*
     * Configuring the CAN controller
     */
    std::uint32_t bit_rate = 0;
    while (bit_rate == 0)
    {
        board::syslog("CAN auto bitrate...\r\n");
        bit_rate = uavcan_lpc11c24::CanDriver::detectBitRate(&board::resetWatchdog);
    }
    board::syslog("Bitrate: ");
    board::syslog(intToString(bit_rate).c_str());
    board::syslog("\r\n");

    if (uavcan_lpc11c24::CanDriver::instance().init(bit_rate) < 0)
    {
        board::die();
    }

    board::syslog("CAN init ok\r\n");

    board::resetWatchdog();

    /*
     * Configuring the node
     */
    getNode().setName("org.uavcan.lpc11c24_test");

    uavcan::protocol::SoftwareVersion swver;
    swver.major = FW_VERSION_MAJOR;
    swver.minor = FW_VERSION_MINOR;
    swver.vcs_commit = GIT_HASH;
    swver.optional_field_flags = swver.OPTIONAL_FIELD_FLAG_VCS_COMMIT;
    getNode().setSoftwareVersion(swver);

    uavcan::protocol::HardwareVersion hwver;
    std::uint8_t uid[board::UniqueIDSize] = {};
    board::readUniqueID(uid);
    std::copy(std::begin(uid), std::end(uid), std::begin(hwver.unique_id));
    getNode().setHardwareVersion(hwver);

    board::resetWatchdog();

    /*
     * Starting the node and performing dynamic node ID allocation
     */
    if (getNode().start() < 0)
    {
        board::die();
    }

    board::syslog("Node ID allocation...\r\n");

    getNode().setNodeID(performDynamicNodeIDAllocation());

    board::syslog("Node ID ");
    board::syslog(intToString(getNode().getNodeID().get()).c_str());
    board::syslog("\r\n");

    board::resetWatchdog();

    /*
     * Example filter configuration.
     * Can be removed safely.
     */
    {
        constexpr unsigned NumFilters = 3;
        uavcan::CanFilterConfig filters[NumFilters];

        // Acepting all service transfers addressed to us
        filters[0].id   = (unsigned(getNode().getNodeID().get()) << 8) | (1U << 7) | uavcan::CanFrame::FlagEFF;
        filters[0].mask = 0x7F80 | uavcan::CanFrame::FlagEFF;

        // Accepting time sync messages
        filters[1].id   = (4U << 8) | uavcan::CanFrame::FlagEFF;
        filters[1].mask = 0xFFFF80 | uavcan::CanFrame::FlagEFF;

        // Accepting zero CAN ID (just for the sake of testing)
        filters[2].id   = 0 | uavcan::CanFrame::FlagEFF;
        filters[2].mask = uavcan::CanFrame::MaskExtID | uavcan::CanFrame::FlagEFF;

        if (uavcan_lpc11c24::CanDriver::instance().configureFilters(filters, NumFilters) < 0)
        {
            board::syslog("Filter init failed\r\n");
            board::die();
        }
    }

    /*
     * Initializing other libuavcan-related objects
     */
    if (getTimeSyncSlave().start() < 0)
    {
        board::die();
    }

    if (getLogger().init() < 0)
    {
        board::die();
    }

    getLogger().setLevel(uavcan::protocol::debug::LogLevel::DEBUG);

    board::resetWatchdog();
}

}

int main()
{
    init();

    getNode().setModeOperational();

    uavcan::MonotonicTime prev_log_at;

    while (true)
    {
        const int res = getNode().spin(uavcan::MonotonicDuration::fromMSec(25));
        board::setErrorLed(res < 0);
        board::setStatusLed(uavcan_lpc11c24::CanDriver::instance().hadActivity());

        const auto ts = uavcan_lpc11c24::clock::getMonotonic();
        if ((ts - prev_log_at).toMSec() >= 1000)
        {
            prev_log_at = ts;

            /*
             * CAN bus off state monitoring
             */
            if (uavcan_lpc11c24::CanDriver::instance().isInBusOffState())
            {
                board::syslog("CAN BUS OFF\r\n");
            }

            /*
             * CAN error counter, for debugging purposes
             */
            board::syslog("CAN errors: ");
            board::syslog(intToString(static_cast<long long>(uavcan_lpc11c24::CanDriver::instance().getErrorCount())).c_str());
            board::syslog(" ");
            board::syslog(intToString(uavcan_lpc11c24::CanDriver::instance().getRxQueueOverflowCount()).c_str());
            board::syslog("\r\n");

            /*
             * We don't want to use formatting functions provided by libuavcan because they rely on std::snprintf(),
             * so we need to construct the message manually:
             */
            uavcan::protocol::debug::LogMessage logmsg;
            logmsg.level.value = uavcan::protocol::debug::LogLevel::INFO;
            logmsg.source = "app";
            logmsg.text = intToString(uavcan_lpc11c24::clock::getPrevUtcAdjustment().toUSec()).c_str();
            (void)getLogger().log(logmsg);
        }

        board::resetWatchdog();
    }
}
<|endoftext|>


<commit_before>#include "ExecutionEngine.h"

#include <chrono>

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-parameter"

#include <llvm/IR/LLVMContext.h>
#include <llvm/IR/Module.h>
#include <llvm/ADT/Triple.h>
#include <llvm/ExecutionEngine/ExecutionEngine.h>
#include <llvm/ExecutionEngine/SectionMemoryManager.h>
#include <llvm/ExecutionEngine/GenericValue.h>
#include <llvm/ExecutionEngine/MCJIT.h>
#include <llvm/Support/TargetSelect.h>
#include <llvm/Support/Signals.h>
#include <llvm/Support/PrettyStackTrace.h>
#include <llvm/Support/Host.h>

#pragma GCC diagnostic pop

#include "Runtime.h"
#include "Memory.h"
#include "Stack.h"
#include "Type.h"
#include "Compiler.h"
#include "Cache.h"

namespace dev
{
namespace eth
{
namespace jit
{

ReturnCode ExecutionEngine::run(bytes const& _code, RuntimeData* _data, Env* _env)
{
	std::string key{reinterpret_cast<char const*>(_code.data()), _code.size()};
	/*if (auto cachedExec = Cache::findExec(key))
	{
		return run(*cachedExec, _data, _env);
	}*/

	auto module = Compiler({}).compile(_code);
	//module->dump();
	return run(std::move(module), _data, _env, _code);
}

namespace
{
ReturnCode runEntryFunc(ExecBundle const& _exec, Runtime* _runtime)
{
	// That function uses long jumps to handle "execeptions".
	// Do not create any non-POD objects here

	typedef ReturnCode(*EntryFuncPtr)(Runtime*);
	auto entryFuncPtr = (EntryFuncPtr)_exec.engine->getFunctionAddress(_exec.mainFuncName);

	//std::cerr << _exec.mainFuncName << "  F: " << entryFuncPtr << "\n";
	ReturnCode returnCode{};
	//std::cerr << _exec.mainFuncName << " +S: " << &returnCode << "\n";
	auto sj = setjmp(_runtime->getJmpBuf());
	if (sj == 0)
		returnCode = entryFuncPtr(_runtime);
	else
		returnCode = static_cast<ReturnCode>(sj);

	//std::cerr << _exec.mainFuncName << " -S: " << &returnCode << "\n";
	return returnCode;
}
}

ReturnCode ExecutionEngine::run(std::unique_ptr<llvm::Module> _module, RuntimeData* _data, Env* _env, bytes const& _code)
{
	// TODO: Use it in evmcc
	//llvm::sys::PrintStackTraceOnErrorSignal();
	//static const auto program = "EVM JIT";
	//llvm::PrettyStackTraceProgram X(1, &program);

	static std::unique_ptr<llvm::ExecutionEngine> ee;  // TODO: Use Managed Objects from LLVM?

	typedef ReturnCode(*EntryFuncPtr)(Runtime*);
	EntryFuncPtr entryFuncPtr{};

	ExecBundle exec;
	exec.mainFuncName = _module->getModuleIdentifier();

	if (!ee)
	{
		llvm::InitializeNativeTarget();
		llvm::InitializeNativeTargetAsmPrinter();

		llvm::EngineBuilder builder(_module.get());
		builder.setEngineKind(llvm::EngineKind::JIT);
		builder.setUseMCJIT(true);
		std::unique_ptr<llvm::SectionMemoryManager> memoryManager(new llvm::SectionMemoryManager);
		builder.setMCJITMemoryManager(memoryManager.get());
		builder.setOptLevel(llvm::CodeGenOpt::None);

		auto triple = llvm::Triple(llvm::sys::getProcessTriple());
		if (triple.getOS() == llvm::Triple::OSType::Win32)
			triple.setObjectFormat(llvm::Triple::ObjectFormatType::ELF);  // MCJIT does not support COFF format
		_module->setTargetTriple(triple.str());

		ee.reset(builder.create());
		if (!ee)
			return ReturnCode::LLVMConfigError;

		_module.release();        // Successfully created llvm::ExecutionEngine takes ownership of the module
		memoryManager.release();  // and memory manager

		//ee->setObjectCache(Cache::getObjectCache());
	}
	else
	{
		if (entryFuncPtr = (EntryFuncPtr)ee->getFunctionAddress(_module->getModuleIdentifier()))
		{
			entryFuncPtr = nullptr;
		}
		else
		{
			ee->addModule(_module.get());
			//std::cerr << _module->getModuleIdentifier() << "\n";
			_module.release();
		}
	}

	assert(ee);

	//ExecBundle exec;
	//exec.engine.reset(builder.create());
	//if (!exec.engine)
	//	return ReturnCode::LLVMConfigError;

	exec.engine = ee.get();

	// TODO: Finalization not needed when llvm::ExecutionEngine::getFunctionAddress used
	//auto finalizationStartTime = std::chrono::high_resolution_clock::now();
	//exec.engine->finalizeObject();
	//auto finalizationEndTime = std::chrono::high_resolution_clock::now();
	//clog(JIT) << " + " << std::chrono::duration_cast<std::chrono::milliseconds>(finalizationEndTime - finalizationStartTime).count();

	auto executionStartTime = std::chrono::high_resolution_clock::now();

	std::string key{reinterpret_cast<char const*>(_code.data()), _code.size()};
	//auto& cachedExec = Cache::registerExec(key, std::move(exec));
	Runtime runtime(_data, _env);
	auto returnCode = runEntryFunc(exec, &runtime);
	if (returnCode == ReturnCode::Return)
		this->returnData = runtime.getReturnData();

	auto executionEndTime = std::chrono::high_resolution_clock::now();
	clog(JIT) << " + " << std::chrono::duration_cast<std::chrono::milliseconds>(executionEndTime - executionStartTime).count() << " ms ";
	//clog(JIT) << "Max stack size: " << Stack::maxStackSize;

	clog(JIT) << "\n";

	return returnCode;
}

}
}
}
<commit_msg>Clean up ExecutionEngine<commit_after>#include "ExecutionEngine.h"

#include <chrono>

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-parameter"

#include <llvm/IR/LLVMContext.h>
#include <llvm/IR/Module.h>
#include <llvm/ADT/Triple.h>
#include <llvm/ExecutionEngine/ExecutionEngine.h>
#include <llvm/ExecutionEngine/SectionMemoryManager.h>
#include <llvm/ExecutionEngine/GenericValue.h>
#include <llvm/ExecutionEngine/MCJIT.h>
#include <llvm/Support/TargetSelect.h>
#include <llvm/Support/Signals.h>
#include <llvm/Support/PrettyStackTrace.h>
#include <llvm/Support/Host.h>

#pragma GCC diagnostic pop

#include "Runtime.h"
#include "Memory.h"
#include "Stack.h"
#include "Type.h"
#include "Compiler.h"
#include "Cache.h"

namespace dev
{
namespace eth
{
namespace jit
{

ReturnCode ExecutionEngine::run(bytes const& _code, RuntimeData* _data, Env* _env)
{
	std::string key{reinterpret_cast<char const*>(_code.data()), _code.size()};
	/*if (auto cachedExec = Cache::findExec(key))
	{
		return run(*cachedExec, _data, _env);
	}*/

	auto module = Compiler({}).compile(_code);
	//module->dump();
	return run(std::move(module), _data, _env, _code);
}

namespace
{

typedef ReturnCode(*EntryFuncPtr)(Runtime*);

ReturnCode runEntryFunc(EntryFuncPtr _mainFunc, Runtime* _runtime)
{
	// That function uses long jumps to handle "execeptions".
	// Do not create any non-POD objects here

	ReturnCode returnCode{};
	auto sj = setjmp(_runtime->getJmpBuf());
	if (sj == 0)
		returnCode = _mainFunc(_runtime);
	else
		returnCode = static_cast<ReturnCode>(sj);

	return returnCode;
}

}

ReturnCode ExecutionEngine::run(std::unique_ptr<llvm::Module> _module, RuntimeData* _data, Env* _env, bytes const& _code)
{
	// TODO: Use it in evmcc
	//llvm::sys::PrintStackTraceOnErrorSignal();
	//static const auto program = "EVM JIT";
	//llvm::PrettyStackTraceProgram X(1, &program);

	static std::unique_ptr<llvm::ExecutionEngine> ee;  // TODO: Use Managed Objects from LLVM?

	typedef ReturnCode(*EntryFuncPtr)(Runtime*);
	EntryFuncPtr entryFuncPtr{};

	auto&& mainFuncName = _module->getModuleIdentifier();

	if (!ee)
	{
		llvm::InitializeNativeTarget();
		llvm::InitializeNativeTargetAsmPrinter();

		llvm::EngineBuilder builder(_module.get());
		builder.setEngineKind(llvm::EngineKind::JIT);
		builder.setUseMCJIT(true);
		std::unique_ptr<llvm::SectionMemoryManager> memoryManager(new llvm::SectionMemoryManager);
		builder.setMCJITMemoryManager(memoryManager.get());
		builder.setOptLevel(llvm::CodeGenOpt::None);

		auto triple = llvm::Triple(llvm::sys::getProcessTriple());
		if (triple.getOS() == llvm::Triple::OSType::Win32)
			triple.setObjectFormat(llvm::Triple::ObjectFormatType::ELF);  // MCJIT does not support COFF format
		_module->setTargetTriple(triple.str());

		ee.reset(builder.create());
		if (!ee)
			return ReturnCode::LLVMConfigError;

		_module.release();        // Successfully created llvm::ExecutionEngine takes ownership of the module
		memoryManager.release();  // and memory manager

		//ee->setObjectCache(Cache::getObjectCache());
	}
	else
	{
		if (entryFuncPtr = (EntryFuncPtr)ee->getFunctionAddress(_module->getModuleIdentifier()))
		{
			entryFuncPtr = nullptr;
		}
		else
		{
			ee->addModule(_module.get());
			//std::cerr << _module->getModuleIdentifier() << "\n";
			_module.release();
		}
	}

	assert(ee);

	//ExecBundle exec;
	//exec.engine.reset(builder.create());
	//if (!exec.engine)
	//	return ReturnCode::LLVMConfigError;

	// TODO: Finalization not needed when llvm::ExecutionEngine::getFunctionAddress used
	//auto finalizationStartTime = std::chrono::high_resolution_clock::now();
	//exec.engine->finalizeObject();
	//auto finalizationEndTime = std::chrono::high_resolution_clock::now();
	//clog(JIT) << " + " << std::chrono::duration_cast<std::chrono::milliseconds>(finalizationEndTime - finalizationStartTime).count();

	auto executionStartTime = std::chrono::high_resolution_clock::now();

	std::string key{reinterpret_cast<char const*>(_code.data()), _code.size()};
	//auto& cachedExec = Cache::registerExec(key, std::move(exec));
	Runtime runtime(_data, _env);
	auto mainFunc = (EntryFuncPtr)ee->getFunctionAddress(mainFuncName);
	auto returnCode = runEntryFunc(mainFunc, &runtime);
	if (returnCode == ReturnCode::Return)
		this->returnData = runtime.getReturnData();

	auto executionEndTime = std::chrono::high_resolution_clock::now();
	clog(JIT) << " + " << std::chrono::duration_cast<std::chrono::milliseconds>(executionEndTime - executionStartTime).count() << " ms ";
	//clog(JIT) << "Max stack size: " << Stack::maxStackSize;

	clog(JIT) << "\n";

	return returnCode;
}

}
}
}
<|endoftext|>


<commit_before>#include "replayState.h"

#include <deque>
#include <boost/bind.hpp>
#include <boost/thread.hpp>

#include "libwatcher/message.h"
#include "serverConnection.h"
#include "Assert.h"
#include "database.h"
#include "watcherd.h"

using namespace util;
using namespace watcher;
using namespace watcher::event;

//< default value for number of events to prefetch from the database
const unsigned int DEFAULT_BUFFER_SIZE = 10U; /* db rows */
const unsigned int DEFAULT_STEP = 250U /* ms */;

/** Internal structure used for implementing the class.  Used to avoid
 * dependencies for the user of the class.  These would normally be private
 * members of ReplayState.
 */
struct ReplayState::impl {
    boost::weak_ptr<ServerConnection> conn;
    std::deque<MessagePtr> events;
    boost::asio::deadline_timer timer;
    Timestamp ts; // the current effective time
    Timestamp last_event; // timestamp of last event retrieved from db
    float speed; //< playback speed
    unsigned int bufsiz; //< number of database rows to prefetch
    Timestamp step;
    enum run_state { paused, running } state;

    /*
     * Lock used for event queue.  This is required due to the seek() member
     * function, which can be called from a different thread.
     */
    boost::mutex lock;

    impl(ServerConnectionPtr& ptr) :
        conn(ptr), timer(ptr->io_service()), ts(0), last_event(0), bufsiz(DEFAULT_BUFFER_SIZE),
        step(DEFAULT_STEP), state(paused)
    {
        TRACE_ENTER();
        TRACE_EXIT();
    }
};

ReplayState::ReplayState(ServerConnectionPtr ptr, Timestamp t, float playback_speed) :
    impl_(new impl(ptr))
{
    TRACE_ENTER();
    Assert<Bad_arg>(t >= 0);
    impl_->ts = t;
    impl_->last_event = t;

    speed(playback_speed);
    TRACE_EXIT();
}

Timestamp ReplayState::tell() const
{
    TRACE_ENTER();
    TRACE_EXIT_RET(impl_->ts);
    return impl_->ts;
}

ReplayState& ReplayState::pause()
{
    TRACE_ENTER();
    LOG_DEBUG("cancelling timer");
    impl_->timer.cancel();
    impl_->state = impl::paused;
    TRACE_EXIT();
    return *this;
}

ReplayState& ReplayState::seek(Timestamp t)
{
    TRACE_ENTER();

    impl::run_state oldstate;
    {
        boost::mutex::scoped_lock L(impl_->lock);
        oldstate = impl_->state;
        pause();
        impl_->events.clear();
        impl_->ts = t;
        if (t == -1)
            impl_->last_event = std::numeric_limits<Timestamp>::max();
        else
            impl_->last_event = t;
    }
    if (oldstate == impl::running)
        run();
    TRACE_EXIT();
    return *this;
}

ReplayState& ReplayState::speed(float f)
{
    TRACE_ENTER();
    Assert<Bad_arg>(f != 0);
    /* If speed changes direction, need to clear the event list.
     * Check for sign change by noting that positive*negative==negative
     */
    if (impl_->speed * f < 0) {
        impl::run_state oldstate;
        {
            boost::mutex::scoped_lock L(impl_->lock);

            oldstate = impl_->state;
            pause();

            impl_->events.clear();

            /*
             * Avoid setting .last_event when SpeedMessage is received
             * prior to the first StartMessage.
             */
            if (impl_->ts != 0 && impl_->ts != -1)
                impl_->last_event = impl_->ts;

            impl_->speed = f;
        }
        if (oldstate == impl::running)
            run();
    } else
        impl_->speed = f;
    LOG_DEBUG("ts=" << impl_->ts << " last_event=" << impl_->last_event);
    TRACE_EXIT();
    return *this;
}

ReplayState& ReplayState::buffer_size(unsigned int n)
{
    TRACE_ENTER();
    Assert<Bad_arg>(n != 0);
    impl_->bufsiz = n;
    TRACE_EXIT();
    return *this;
}

ReplayState& ReplayState::time_step(unsigned int n)
{
    TRACE_ENTER();
    Assert<Bad_arg>(n != 0);
    impl_->step = n;
    TRACE_EXIT();
    return *this;
}

/* function object for accepting events output from Database::getEvents() */
struct event_output {
    std::deque<MessagePtr>& q;
    event_output(std::deque<MessagePtr>& qq) : q(qq) {}
    void operator() (MessagePtr m) { q.push_back(m); }
};

/** Schedule an asynchronous task to replay events from the database to a GUI
 * client.  If the local cache of upcoming events is empty, prefetch a block of
 * events from the database.
 *
 * The code is written such that it will work when playing events forward or in
 * reverse.
 */
void ReplayState::run()
{
    TRACE_ENTER();
    boost::mutex::scoped_lock L(impl_->lock);

    if (impl_->events.empty()) {
        // queue is empty, pre-fetch more items from the DB

        boost::function<void(MessagePtr)> cb(event_output(impl_->events));
        LOG_DEBUG("fetching events " << (impl_->speed > 0 ? "> " : "< ") << impl_->last_event);
        get_db_handle().getEvents(cb,
                                  impl_->last_event,
                                  (impl_->speed >= 0) ? Database::forward : Database::reverse,
                                  impl_->bufsiz);

        if (!impl_->events.empty()) {
            /* When starting to replay, assume that time T=0 is the time of the
             * first event in the stream.
             * T= -1 is EOF.
             * Convert to timestamp of first item in the returned events.
             *
             * When playing in reverse, the first item in the list is the last event in the database.
             */
            if (impl_->ts == 0 || impl_->ts == -1)
                impl_->ts = impl_->events.front()->timestamp;

            // save timestamp of last event retrieved to avoid duplication
            impl_->last_event = impl_->events.back()->timestamp;
        }
    }

    if (! impl_->events.empty()) {
        // time until next event
        Timestamp delta = impl_->events.front()->timestamp - impl_->ts;
        LOG_DEBUG("Next event in " << delta << " ms");

        // update our notion of the current time after the timer expires
        impl_->ts = impl_->events.front()->timestamp;

        /* Adjust for playback speed.  Note that when playing events in reverse, both speed
         * delta will be negative, which will turn delta into a positive value for the
         * async_wait() call, which is exactly what is required.  */
        delta /= impl_->speed;

        impl_->timer.expires_from_now(boost::posix_time::millisec(delta));
        impl_->timer.async_wait(boost::bind(&ReplayState::timer_handler, shared_from_this(), boost::asio::placeholders::error));
        impl_->state = impl::running;
    } else {
        /*
         * FIXME what should happen when the end of the event stream is reached?
         * One option would be to convert to live stream at this point.
         */
        impl_->state = impl::paused;
    }
    TRACE_EXIT();
}

/** Replay events to a GUI client when a timer expires.
 *
 * The run() member function is reponsible for prefetching events from the
 * database and storing them in the class object.  When a timer expires, run
 * through the locally stored events and send those that occurred within the
 * last time slice.  The task is then rescheduled when the next most recent
 * event needs to be transmitted.
 */
void ReplayState::timer_handler(const boost::system::error_code& ec)
{
    TRACE_ENTER();
    if (ec == boost::asio::error::operation_aborted)
        LOG_DEBUG("timer was cancelled");
    else if (impl_->state == impl::paused) {
        LOG_DEBUG("timer expired but state is paused!");
    } else {
        std::vector<MessagePtr> msgs;
        {
            boost::mutex::scoped_lock L(impl_->lock);

            while (! impl_->events.empty()) {
                MessagePtr m = impl_->events.front();
                /* Replay all events in the current time step.  Use the absolute value
                 * of the difference in order for forward and reverse replay to work
                 * properly. */
                if (abs(m->timestamp - impl_->ts) >= impl_->step)
                    break;
                msgs.push_back(m);
                impl_->events.pop_front();
            }
        }

        ServerConnectionPtr srv = impl_->conn.lock();
        if (srv) { /* connection is still alive */
            srv->sendMessage(msgs);
            run(); // reschedule this task
        }
    }
    TRACE_EXIT();
}

/* This is required to be defined, otherwise a the default dtor will cause a
 * compiler error due to use of scoped_ptr with an incomplete type.
 */
ReplayState::~ReplayState()
{
    TRACE_ENTER();
    TRACE_EXIT();
}

float ReplayState::speed() const
{
    return impl_->speed;
}
<commit_msg>add debug message when last row of db is fetched<commit_after>#include "replayState.h"

#include <deque>
#include <boost/bind.hpp>
#include <boost/thread.hpp>

#include "libwatcher/message.h"
#include "serverConnection.h"
#include "Assert.h"
#include "database.h"
#include "watcherd.h"

using namespace util;
using namespace watcher;
using namespace watcher::event;

//< default value for number of events to prefetch from the database
const unsigned int DEFAULT_BUFFER_SIZE = 10U; /* db rows */
const unsigned int DEFAULT_STEP = 250U /* ms */;

/** Internal structure used for implementing the class.  Used to avoid
 * dependencies for the user of the class.  These would normally be private
 * members of ReplayState.
 */
struct ReplayState::impl {
    boost::weak_ptr<ServerConnection> conn;
    std::deque<MessagePtr> events;
    boost::asio::deadline_timer timer;
    Timestamp ts; // the current effective time
    Timestamp last_event; // timestamp of last event retrieved from db
    float speed; //< playback speed
    unsigned int bufsiz; //< number of database rows to prefetch
    Timestamp step;
    enum run_state { paused, running } state;

    /*
     * Lock used for event queue.  This is required due to the seek() member
     * function, which can be called from a different thread.
     */
    boost::mutex lock;

    impl(ServerConnectionPtr& ptr) :
        conn(ptr), timer(ptr->io_service()), ts(0), last_event(0), bufsiz(DEFAULT_BUFFER_SIZE),
        step(DEFAULT_STEP), state(paused)
    {
        TRACE_ENTER();
        TRACE_EXIT();
    }
};

ReplayState::ReplayState(ServerConnectionPtr ptr, Timestamp t, float playback_speed) :
    impl_(new impl(ptr))
{
    TRACE_ENTER();
    Assert<Bad_arg>(t >= 0);
    impl_->ts = t;
    impl_->last_event = t;

    speed(playback_speed);
    TRACE_EXIT();
}

Timestamp ReplayState::tell() const
{
    TRACE_ENTER();
    TRACE_EXIT_RET(impl_->ts);
    return impl_->ts;
}

ReplayState& ReplayState::pause()
{
    TRACE_ENTER();
    LOG_DEBUG("cancelling timer");
    impl_->timer.cancel();
    impl_->state = impl::paused;
    TRACE_EXIT();
    return *this;
}

ReplayState& ReplayState::seek(Timestamp t)
{
    TRACE_ENTER();

    impl::run_state oldstate;
    {
        boost::mutex::scoped_lock L(impl_->lock);
        oldstate = impl_->state;
        pause();
        impl_->events.clear();
        impl_->ts = t;
        if (t == -1)
            impl_->last_event = std::numeric_limits<Timestamp>::max();
        else
            impl_->last_event = t;
    }
    if (oldstate == impl::running)
        run();
    TRACE_EXIT();
    return *this;
}

ReplayState& ReplayState::speed(float f)
{
    TRACE_ENTER();
    Assert<Bad_arg>(f != 0);
    /* If speed changes direction, need to clear the event list.
     * Check for sign change by noting that positive*negative==negative
     */
    if (impl_->speed * f < 0) {
        impl::run_state oldstate;
        {
            boost::mutex::scoped_lock L(impl_->lock);

            oldstate = impl_->state;
            pause();

            impl_->events.clear();

            /*
             * Avoid setting .last_event when SpeedMessage is received
             * prior to the first StartMessage.
             */
            if (impl_->ts != 0 && impl_->ts != -1)
                impl_->last_event = impl_->ts;

            impl_->speed = f;
        }
        if (oldstate == impl::running)
            run();
    } else
        impl_->speed = f;
    LOG_DEBUG("ts=" << impl_->ts << " last_event=" << impl_->last_event);
    TRACE_EXIT();
    return *this;
}

ReplayState& ReplayState::buffer_size(unsigned int n)
{
    TRACE_ENTER();
    Assert<Bad_arg>(n != 0);
    impl_->bufsiz = n;
    TRACE_EXIT();
    return *this;
}

ReplayState& ReplayState::time_step(unsigned int n)
{
    TRACE_ENTER();
    Assert<Bad_arg>(n != 0);
    impl_->step = n;
    TRACE_EXIT();
    return *this;
}

/* function object for accepting events output from Database::getEvents() */
struct event_output {
    std::deque<MessagePtr>& q;
    event_output(std::deque<MessagePtr>& qq) : q(qq) {}
    void operator() (MessagePtr m) { q.push_back(m); }
};

/** Schedule an asynchronous task to replay events from the database to a GUI
 * client.  If the local cache of upcoming events is empty, prefetch a block of
 * events from the database.
 *
 * The code is written such that it will work when playing events forward or in
 * reverse.
 */
void ReplayState::run()
{
    TRACE_ENTER();
    boost::mutex::scoped_lock L(impl_->lock);

    if (impl_->events.empty()) {
        // queue is empty, pre-fetch more items from the DB

        boost::function<void(MessagePtr)> cb(event_output(impl_->events));
        LOG_DEBUG("fetching events " << (impl_->speed > 0 ? "> " : "< ") << impl_->last_event);
        get_db_handle().getEvents(cb,
                                  impl_->last_event,
                                  (impl_->speed >= 0) ? Database::forward : Database::reverse,
                                  impl_->bufsiz);

        if (!impl_->events.empty()) {
            /* When starting to replay, assume that time T=0 is the time of the
             * first event in the stream.
             * T= -1 is EOF.
             * Convert to timestamp of first item in the returned events.
             *
             * When playing in reverse, the first item in the list is the last event in the database.
             */
            if (impl_->ts == 0 || impl_->ts == -1)
                impl_->ts = impl_->events.front()->timestamp;

            // save timestamp of last event retrieved to avoid duplication
            impl_->last_event = impl_->events.back()->timestamp;
        }
    }

    if (! impl_->events.empty()) {
        // time until next event
        Timestamp delta = impl_->events.front()->timestamp - impl_->ts;
        LOG_DEBUG("Next event in " << delta << " ms");

        // update our notion of the current time after the timer expires
        impl_->ts = impl_->events.front()->timestamp;

        /* Adjust for playback speed.  Note that when playing events in reverse, both speed
         * delta will be negative, which will turn delta into a positive value for the
         * async_wait() call, which is exactly what is required.  */
        delta /= impl_->speed;

        impl_->timer.expires_from_now(boost::posix_time::millisec(delta));
        impl_->timer.async_wait(boost::bind(&ReplayState::timer_handler, shared_from_this(), boost::asio::placeholders::error));
        impl_->state = impl::running;
    } else {
        /*
         * FIXME what should happen when the end of the event stream is reached?
         * One option would be to convert to live stream at this point.
         */
        LOG_DEBUG("reached end of database, pausing playback");
        impl_->state = impl::paused;
    }
    TRACE_EXIT();
}

/** Replay events to a GUI client when a timer expires.
 *
 * The run() member function is reponsible for prefetching events from the
 * database and storing them in the class object.  When a timer expires, run
 * through the locally stored events and send those that occurred within the
 * last time slice.  The task is then rescheduled when the next most recent
 * event needs to be transmitted.
 */
void ReplayState::timer_handler(const boost::system::error_code& ec)
{
    TRACE_ENTER();
    if (ec == boost::asio::error::operation_aborted)
        LOG_DEBUG("timer was cancelled");
    else if (impl_->state == impl::paused) {
        LOG_DEBUG("timer expired but state is paused!");
    } else {
        std::vector<MessagePtr> msgs;
        {
            boost::mutex::scoped_lock L(impl_->lock);

            while (! impl_->events.empty()) {
                MessagePtr m = impl_->events.front();
                /* Replay all events in the current time step.  Use the absolute value
                 * of the difference in order for forward and reverse replay to work
                 * properly. */
                if (abs(m->timestamp - impl_->ts) >= impl_->step)
                    break;
                msgs.push_back(m);
                impl_->events.pop_front();
            }
        }

        ServerConnectionPtr srv = impl_->conn.lock();
        if (srv) { /* connection is still alive */
            srv->sendMessage(msgs);
            run(); // reschedule this task
        }
    }
    TRACE_EXIT();
}

/* This is required to be defined, otherwise a the default dtor will cause a
 * compiler error due to use of scoped_ptr with an incomplete type.
 */
ReplayState::~ReplayState()
{
    TRACE_ENTER();
    TRACE_EXIT();
}

float ReplayState::speed() const
{
    return impl_->speed;
}
<|endoftext|>


<commit_before>//-----------------------------------------------------------------------bl-
//--------------------------------------------------------------------------
//
// QUESO - a library to support the Quantification of Uncertainty
// for Estimation, Simulation and Optimization
//
// Copyright (C) 2008-2015 The PECOS Development Team
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the Version 2.1 GNU Lesser General
// Public License as published by the Free Software Foundation.
//
// 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. 51 Franklin Street, Fifth Floor,
// Boston, MA  02110-1301  USA
//
//-----------------------------------------------------------------------el-

#include <queso/UniformJointPdf.h>
#include <queso/GslVector.h>
#include <queso/GslMatrix.h>

namespace QUESO {

// Constructor -------------------------------------
template<class V,class M>
UniformJointPdf<V,M>::UniformJointPdf(
  const char*                  prefix,
  const VectorSet<V,M>& domainSet)
  :
  BaseJointPdf<V,M>(((std::string)(prefix)+"uni").c_str(),
                            domainSet)
{
  if ((m_env.subDisplayFile()) && (m_env.displayVerbosity() >= 54)) {
    *m_env.subDisplayFile() << "Entering UniformJointPdf<V,M>::constructor()"
                            << ": prefix = " << m_prefix
                            << std::endl;
  }

  if ((m_env.subDisplayFile()) && (m_env.displayVerbosity() >= 54)) {
    *m_env.subDisplayFile() << "Leaving UniformJointPdf<V,M>::constructor()"
                            << ": prefix = " << m_prefix
                            << std::endl;
  }
}
// Destructor --------------------------------------
template<class V,class M>
UniformJointPdf<V,M>::~UniformJointPdf()
{
}
// Math methods-------------------------------------
template<class V, class M>
double
UniformJointPdf<V,M>::actualValue(
  const V& domainVector,
  const V* domainDirection,
        V* gradVector,
        M* hessianMatrix,
        V* hessianEffect) const
{
  UQ_FATAL_TEST_MACRO(domainVector.sizeLocal() != this->m_domainSet.vectorSpace().dimLocal(),
                      m_env.worldRank(),
                      "UniformJointPdf<V,M>::actualValue()",
                      "invalid input");

  if (gradVector   ) *gradVector     = m_domainSet.vectorSpace().zeroVector();
  if (hessianMatrix) *hessianMatrix *= 0.;
  if (hessianEffect) *hessianEffect  = m_domainSet.vectorSpace().zeroVector();

  if (domainDirection) {}; // just to remove compiler warning

  double volume = m_domainSet.volume();
  if (((boost::math::isnan)(volume)) ||
      (volume == -INFINITY         ) ||
      (volume ==  INFINITY         ) ||
      (volume <= 0.                ) ||
      (m_normalizationStyle != 0   )) {
    volume = 1.;
  }

  return 1./volume; // No need to multiply by exp(m_logOfNormalizationFactor) [PDF-04]
}
//--------------------------------------------------
template<class V, class M>
double
UniformJointPdf<V,M>::lnValue(
  const V& domainVector,
  const V* domainDirection,
        V* gradVector,
        M* hessianMatrix,
        V* hessianEffect) const
{
  if (gradVector   ) *gradVector     = m_domainSet.vectorSpace().zeroVector();
  if (hessianMatrix) *hessianMatrix *= 0.;
  if (hessianEffect) *hessianEffect  = m_domainSet.vectorSpace().zeroVector();

  if (domainVector[0]) {}; // just to remove compiler warning
  if (domainDirection) {}; // just to remove compiler warning

  double volume = m_domainSet.volume();
  if (((boost::math::isnan)(volume)) ||
      (volume == -INFINITY         ) ||
      (volume ==  INFINITY         ) ||
      (volume <= 0.                ) ||
      (m_normalizationStyle != 0   )) {
    volume = 1.;
  }

  return log(volume); // No need to add m_logOfNormalizationFactor [PDF-04]
}
//--------------------------------------------------
template<class V, class M>
double
UniformJointPdf<V,M>::computeLogOfNormalizationFactor(unsigned int numSamples, bool updateFactorInternally) const
{
  double value = 0.;

  if ((m_env.subDisplayFile()) && (m_env.displayVerbosity() >= 2)) {
    *m_env.subDisplayFile() << "Entering UniformJointPdf<V,M>::computeLogOfNormalizationFactor()"
                            << std::endl;
  }
  value = BaseJointPdf<V,M>::commonComputeLogOfNormalizationFactor(numSamples, updateFactorInternally);
  if ((m_env.subDisplayFile()) && (m_env.displayVerbosity() >= 2)) {
    *m_env.subDisplayFile() << "Leaving UniformJointPdf<V,M>::computeLogOfNormalizationFactor()"
                            << ", m_logOfNormalizationFactor = " << m_logOfNormalizationFactor
                            << std::endl;
  }

  return value;
}

}  // End namespace QUESO

template class QUESO::UniformJointPdf<QUESO::GslVector, QUESO::GslMatrix>;
<commit_msg>Fix sign in log uniform pdf<commit_after>//-----------------------------------------------------------------------bl-
//--------------------------------------------------------------------------
//
// QUESO - a library to support the Quantification of Uncertainty
// for Estimation, Simulation and Optimization
//
// Copyright (C) 2008-2015 The PECOS Development Team
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the Version 2.1 GNU Lesser General
// Public License as published by the Free Software Foundation.
//
// 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. 51 Franklin Street, Fifth Floor,
// Boston, MA  02110-1301  USA
//
//-----------------------------------------------------------------------el-

#include <queso/UniformJointPdf.h>
#include <queso/GslVector.h>
#include <queso/GslMatrix.h>

namespace QUESO {

// Constructor -------------------------------------
template<class V,class M>
UniformJointPdf<V,M>::UniformJointPdf(
  const char*                  prefix,
  const VectorSet<V,M>& domainSet)
  :
  BaseJointPdf<V,M>(((std::string)(prefix)+"uni").c_str(),
                            domainSet)
{
  if ((m_env.subDisplayFile()) && (m_env.displayVerbosity() >= 54)) {
    *m_env.subDisplayFile() << "Entering UniformJointPdf<V,M>::constructor()"
                            << ": prefix = " << m_prefix
                            << std::endl;
  }

  if ((m_env.subDisplayFile()) && (m_env.displayVerbosity() >= 54)) {
    *m_env.subDisplayFile() << "Leaving UniformJointPdf<V,M>::constructor()"
                            << ": prefix = " << m_prefix
                            << std::endl;
  }
}
// Destructor --------------------------------------
template<class V,class M>
UniformJointPdf<V,M>::~UniformJointPdf()
{
}
// Math methods-------------------------------------
template<class V, class M>
double
UniformJointPdf<V,M>::actualValue(
  const V& domainVector,
  const V* domainDirection,
        V* gradVector,
        M* hessianMatrix,
        V* hessianEffect) const
{
  UQ_FATAL_TEST_MACRO(domainVector.sizeLocal() != this->m_domainSet.vectorSpace().dimLocal(),
                      m_env.worldRank(),
                      "UniformJointPdf<V,M>::actualValue()",
                      "invalid input");

  if (gradVector   ) *gradVector     = m_domainSet.vectorSpace().zeroVector();
  if (hessianMatrix) *hessianMatrix *= 0.;
  if (hessianEffect) *hessianEffect  = m_domainSet.vectorSpace().zeroVector();

  if (domainDirection) {}; // just to remove compiler warning

  double volume = m_domainSet.volume();
  if (((boost::math::isnan)(volume)) ||
      (volume == -INFINITY         ) ||
      (volume ==  INFINITY         ) ||
      (volume <= 0.                ) ||
      (m_normalizationStyle != 0   )) {
    volume = 1.;
  }

  return 1./volume; // No need to multiply by exp(m_logOfNormalizationFactor) [PDF-04]
}
//--------------------------------------------------
template<class V, class M>
double
UniformJointPdf<V,M>::lnValue(
  const V& domainVector,
  const V* domainDirection,
        V* gradVector,
        M* hessianMatrix,
        V* hessianEffect) const
{
  if (gradVector   ) *gradVector     = m_domainSet.vectorSpace().zeroVector();
  if (hessianMatrix) *hessianMatrix *= 0.;
  if (hessianEffect) *hessianEffect  = m_domainSet.vectorSpace().zeroVector();

  if (domainVector[0]) {}; // just to remove compiler warning
  if (domainDirection) {}; // just to remove compiler warning

  double volume = m_domainSet.volume();
  if (((boost::math::isnan)(volume)) ||
      (volume == -INFINITY         ) ||
      (volume ==  INFINITY         ) ||
      (volume <= 0.                ) ||
      (m_normalizationStyle != 0   )) {
    volume = 1.;
  }

  return -log(volume);
}
//--------------------------------------------------
template<class V, class M>
double
UniformJointPdf<V,M>::computeLogOfNormalizationFactor(unsigned int numSamples, bool updateFactorInternally) const
{
  double value = 0.;

  if ((m_env.subDisplayFile()) && (m_env.displayVerbosity() >= 2)) {
    *m_env.subDisplayFile() << "Entering UniformJointPdf<V,M>::computeLogOfNormalizationFactor()"
                            << std::endl;
  }
  value = BaseJointPdf<V,M>::commonComputeLogOfNormalizationFactor(numSamples, updateFactorInternally);
  if ((m_env.subDisplayFile()) && (m_env.displayVerbosity() >= 2)) {
    *m_env.subDisplayFile() << "Leaving UniformJointPdf<V,M>::computeLogOfNormalizationFactor()"
                            << ", m_logOfNormalizationFactor = " << m_logOfNormalizationFactor
                            << std::endl;
  }

  return value;
}

}  // End namespace QUESO

template class QUESO::UniformJointPdf<QUESO::GslVector, QUESO::GslMatrix>;
<|endoftext|>


<commit_before>/*
 * Copyright 2006-2008 The FLWOR Foundation.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <sstream>

#include "store/api/item.h"
#include "store/naive/item_vector.h"

namespace zorba { namespace simplestore {

ItemVector::ItemVector(std::vector<store::Item_t>& items)
{
  ulong numItems = items.size();

  theItems.resize(numItems);

  for (ulong i = 0; i < numItems; i++)
    theItems[i].transfer(items[i]);
}

xqpStringStore_t ItemVector::getStringValue() const
{
  std::ostringstream ostr;
  ulong numItems = theItems.size();

  for (ulong i = 0; i < numItems; i++)
  {
    ostr << theItems[i]->getStringValue()->c_str() << " ";
  }

  return new xqpStringStore(ostr.str());
}

void ItemVector::getStringValue(xqpStringStore_t& strval) const
{
  strval = new xqpStringStore("");
  getStringValue(strval->str());
}

void ItemVector::getStringValue(std::string& buf) const
{
  ulong numItems = theItems.size();

  if (numItems > 0)
  {
    theItems[0]->getStringValue(buf);

    for (ulong i = 1; i < numItems; i++)
    {
      buf += " ";
      theItems[i]->getStringValue(buf);
    }
  }
}

} // namespace store
} // namespace zorba
<commit_msg>fixed bug in ItemVector::getStringValue()<commit_after>/*
 * Copyright 2006-2008 The FLWOR Foundation.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <sstream>

#include "store/api/item.h"
#include "store/naive/item_vector.h"

namespace zorba { namespace simplestore {

ItemVector::ItemVector(std::vector<store::Item_t>& items)
{
  ulong numItems = items.size();

  theItems.resize(numItems);

  for (ulong i = 0; i < numItems; i++)
    theItems[i].transfer(items[i]);
}

xqpStringStore_t ItemVector::getStringValue() const
{
  std::ostringstream ostr;
  ulong numItems = theItems.size();

  if (numItems > 0)
  {
    ostr << theItems[0]->getStringValue()->c_str();

    for (ulong i = 1; i < numItems; ++i)
    {
      ostr << " " << theItems[i]->getStringValue()->c_str();
    }
  }

  return new xqpStringStore(ostr.str());
}

void ItemVector::getStringValue(xqpStringStore_t& strval) const
{
  strval = new xqpStringStore("");
  getStringValue(strval->str());
}

void ItemVector::getStringValue(std::string& buf) const
{
  ulong numItems = theItems.size();

  if (numItems > 0)
  {
    theItems[0]->getStringValue(buf);

    for (ulong i = 1; i < numItems; i++)
    {
      buf += " ";
      theItems[i]->getStringValue(buf);
    }
  }
}

} // namespace store
} // namespace zorba
<|endoftext|>


<commit_before>#pragma once

// C++ Standard Library
#include <sstream>

// Cereal
#include <cereal/cereal.hpp>
#include <cereal/archives/json.hpp>
#include <cereal/types/polymorphic.hpp>

// MPI
#include <mpi.h>

// Mantella
#include <mantella_bits/optimisationAlgorithm/populationBasedAlgorithm.hpp>
#include <mantella_bits/distanceFunction/euclideanDistance.hpp>

namespace mant {
  template <typename ParameterType, class EuclideanDistance>
  class ParallelAlgorithm : public PopulationBasedAlgorithm<ParameterType, EuclideanDistance> {
    public:
      explicit ParallelAlgorithm(
          const std::shared_ptr<OptimisationProblem<ParameterType>> optimisationProblem,
          const unsigned int& populationSize) noexcept;

      unsigned int getRank() const noexcept;
      unsigned int getNumberOfNodes() const noexcept;

    protected:
      int rank_;
      int numberOfNodes_;

      void optimiseImplementation() noexcept final override;

      virtual void parallelOptimiseImplementation() noexcept = 0;
  };

  template <typename ParameterType, class EuclideanDistance>
  ParallelAlgorithm<ParameterType, EuclideanDistance>::ParallelAlgorithm(
      const std::shared_ptr<OptimisationProblem<ParameterType>> optimisationProblem,
      const unsigned int& populationSize) noexcept
    : PopulationBasedAlgorithm<ParameterType, EuclideanDistance>(optimisationProblem, populationSize) {
    MPI_Comm_rank(MPI_COMM_WORLD, &rank_);
    MPI_Comm_size(MPI_COMM_WORLD, &numberOfNodes_);
  }

  template <typename ParameterType, class EuclideanDistance>
  void ParallelAlgorithm<ParameterType, EuclideanDistance>::optimiseImplementation() noexcept {
    unsigned int serialisedOptimisationProblemSize;
    char* serialisedOptimisationProblemBuffer;

    if (rank_ == 0) {
      std::ostringstream output; {
        cereal::JSONOutputArchive archive(output);
        archive(OptimisationAlgorithm<ParameterType, EuclideanDistance>::optimisationProblem_);
      };

      std::string serialisedOptimisationProblem = output.str();
      serialisedOptimisationProblemSize = serialisedOptimisationProblem.size();
      serialisedOptimisationProblemBuffer = std::strcpy(new char[serialisedOptimisationProblemSize + 1], serialisedOptimisationProblem.c_str());
    }

    MPI_Bcast(&serialisedOptimisationProblemSize, 1, MPI_UNSIGNED, 0, MPI_COMM_WORLD);

    if (rank_ != 0) {
      serialisedOptimisationProblemBuffer = new char[serialisedOptimisationProblemSize + 1];
    }

    MPI_Bcast(serialisedOptimisationProblemBuffer, serialisedOptimisationProblemSize + 1, MPI_CHAR, 0, MPI_COMM_WORLD);

    if (rank_ != 0) {
      std::istringstream input(serialisedOptimisationProblemBuffer); {
        cereal::JSONInputArchive archive(input);
        archive(OptimisationAlgorithm<ParameterType, EuclideanDistance>::optimisationProblem_);
      }
    }

    delete[](serialisedOptimisationProblemBuffer);

    parallelOptimiseImplementation();
  }

  template <typename ParameterType, class EuclideanDistance>
  unsigned int ParallelAlgorithm<ParameterType, EuclideanDistance>::getRank() const noexcept {
    return rank_;
  }

  template <typename ParameterType, class EuclideanDistance>
  unsigned int ParallelAlgorithm<ParameterType, EuclideanDistance>::getNumberOfNodes() const noexcept {
    return numberOfNodes_;
  }
}
<commit_msg>devel: Templated *abstract* parallel algorithm class<commit_after>#pragma once

// C++ Standard Library
#include <sstream>

// Cereal
#include <cereal/cereal.hpp>
#include <cereal/archives/json.hpp>
#include <cereal/types/polymorphic.hpp>

// MPI
#include <mpi.h>

// Mantella
#include <mantella_bits/optimisationAlgorithm/populationBasedAlgorithm.hpp>

namespace mant {
  template <typename ParameterType, class DistanceFunction>
  class ParallelAlgorithm : public PopulationBasedAlgorithm<ParameterType, DistanceFunction> {
    public:
      explicit ParallelAlgorithm(
          const std::shared_ptr<OptimisationProblem<ParameterType>> optimisationProblem,
          const unsigned int& populationSize) noexcept;

      unsigned int getRank() const noexcept;
      unsigned int getNumberOfNodes() const noexcept;

    protected:
      int rank_;
      int numberOfNodes_;

      void optimiseImplementation() noexcept final override;

      virtual void parallelOptimiseImplementation() noexcept = 0;
  };

  template <typename ParameterType, class DistanceFunction>
  ParallelAlgorithm<ParameterType, DistanceFunction>::ParallelAlgorithm(
      const std::shared_ptr<OptimisationProblem<ParameterType>> optimisationProblem,
      const unsigned int& populationSize) noexcept
    : PopulationBasedAlgorithm<ParameterType, DistanceFunction>(optimisationProblem, populationSize) {
    MPI_Comm_rank(MPI_COMM_WORLD, &rank_);
    MPI_Comm_size(MPI_COMM_WORLD, &numberOfNodes_);
  }

  template <typename ParameterType, class DistanceFunction>
  void ParallelAlgorithm<ParameterType, DistanceFunction>::optimiseImplementation() noexcept {
    unsigned int serialisedOptimisationProblemSize;
    char* serialisedOptimisationProblemBuffer;

    if (rank_ == 0) {
      std::ostringstream output; {
        cereal::JSONOutputArchive archive(output);
        archive(OptimisationAlgorithm<ParameterType, DistanceFunction>::optimisationProblem_);
      };

      std::string serialisedOptimisationProblem = output.str();
      serialisedOptimisationProblemSize = serialisedOptimisationProblem.size();
      serialisedOptimisationProblemBuffer = std::strcpy(new char[serialisedOptimisationProblemSize + 1], serialisedOptimisationProblem.c_str());
    }

    MPI_Bcast(&serialisedOptimisationProblemSize, 1, MPI_UNSIGNED, 0, MPI_COMM_WORLD);

    if (rank_ != 0) {
      serialisedOptimisationProblemBuffer = new char[serialisedOptimisationProblemSize + 1];
    }

    MPI_Bcast(serialisedOptimisationProblemBuffer, serialisedOptimisationProblemSize + 1, MPI_CHAR, 0, MPI_COMM_WORLD);

    if (rank_ != 0) {
      std::istringstream input(serialisedOptimisationProblemBuffer); {
        cereal::JSONInputArchive archive(input);
        archive(OptimisationAlgorithm<ParameterType, DistanceFunction>::optimisationProblem_);
      }
    }

    delete[](serialisedOptimisationProblemBuffer);

    parallelOptimiseImplementation();
  }

  template <typename ParameterType, class DistanceFunction>
  unsigned int ParallelAlgorithm<ParameterType, DistanceFunction>::getRank() const noexcept {
    return rank_;
  }

  template <typename ParameterType, class DistanceFunction>
  unsigned int ParallelAlgorithm<ParameterType, DistanceFunction>::getNumberOfNodes() const noexcept {
    return numberOfNodes_;
  }
}
<|endoftext|>


<commit_before>// This file is part of the "x0" project, http://github.com/christianparpart/x0>
//   (c) 2009-2017 Christian Parpart <christian@parpart.family>
//
// Licensed under the MIT License (the "License"); you may not use this
// file except in compliance with the License. You may obtain a copy of
// the License at: http://opensource.org/licenses/MIT

#include <x0d/XzeroEventHandler.h>
#include <x0d/XzeroDaemon.h>
#include <xzero/UnixSignalInfo.h>
#include <xzero/executor/Executor.h>
#include <xzero/logging.h>
#include <signal.h>

namespace x0d {

using namespace xzero;

XzeroEventHandler::XzeroEventHandler(XzeroDaemon* daemon,
                                     xzero::Executor* executor)
    : daemon_(daemon),
      signals_(UnixSignals::create(executor)),
      executor_(executor),
      state_(XzeroState::Inactive) {

  signals_->notify(SIGHUP, std::bind(&XzeroEventHandler::onConfigReload, this, std::placeholders::_1));
  signals_->notify(SIGUSR1, std::bind(&XzeroEventHandler::onCycleLogs, this, std::placeholders::_1));
  signals_->notify(SIGUSR2, std::bind(&XzeroEventHandler::onUpgradeBinary, this, std::placeholders::_1));
  signals_->notify(SIGQUIT, std::bind(&XzeroEventHandler::onGracefulShutdown, this, std::placeholders::_1));
  signals_->notify(SIGTERM, std::bind(&XzeroEventHandler::onQuickShutdown, this, std::placeholders::_1));
  signals_->notify(SIGINT, std::bind(&XzeroEventHandler::onQuickShutdown, this, std::placeholders::_1));
}

XzeroEventHandler::~XzeroEventHandler() {
}

void XzeroEventHandler::onConfigReload(const xzero::UnixSignalInfo& info) {
  logNotice("x0d",
            "Reloading configuration, as requested by pid $0 uid $1.",
            info.pid.getOrElse(-1), info.uid.getOrElse(-1));

  daemon_->reloadConfiguration();

  signals_->notify(SIGHUP, std::bind(&XzeroEventHandler::onConfigReload, this, std::placeholders::_1));
}

void XzeroEventHandler::onCycleLogs(const xzero::UnixSignalInfo& info) {
  logNotice("x0d", "Reload signal received.");

  daemon_->onCycleLogs();

  signals_->notify(SIGUSR1, std::bind(&XzeroEventHandler::onCycleLogs, this, std::placeholders::_1));
}

void XzeroEventHandler::onUpgradeBinary(const UnixSignalInfo& info) {
  logNotice("x0d",
            "Upgrading binary requested by pid $0 uid $1",
            info.pid.getOrElse(-1), info.uid.getOrElse(-1));

  /* TODO [x0d] binary upgrade
   * 1. suspend the world
   * 2. save state into temporary file with an inheriting file descriptor
   * 3. exec into new binary
   * 4. (new process) load state from file descriptor and close fd
   * 5. (new process) resume the world
   */
}

void XzeroEventHandler::onQuickShutdown(const xzero::UnixSignalInfo& info) {
  logNotice("x0d", "Initiating quick shutdown.");
  daemon_->terminate();
}

void XzeroEventHandler::onGracefulShutdown(const xzero::UnixSignalInfo& info) {
  logNotice("x0d", "Initiating graceful shutdown.");

  /* 1. stop all listeners
   * 2. wait until all requests have been handled.
   * 3. orderly shutdown
   */

  daemon_->server()->stop();
}

} // namespace x0d
<commit_msg>[x0d] log message copy'n'paste fix in SIGUSR1 handler<commit_after>// This file is part of the "x0" project, http://github.com/christianparpart/x0>
//   (c) 2009-2017 Christian Parpart <christian@parpart.family>
//
// Licensed under the MIT License (the "License"); you may not use this
// file except in compliance with the License. You may obtain a copy of
// the License at: http://opensource.org/licenses/MIT

#include <x0d/XzeroEventHandler.h>
#include <x0d/XzeroDaemon.h>
#include <xzero/UnixSignalInfo.h>
#include <xzero/executor/Executor.h>
#include <xzero/logging.h>
#include <signal.h>

namespace x0d {

using namespace xzero;

XzeroEventHandler::XzeroEventHandler(XzeroDaemon* daemon,
                                     xzero::Executor* executor)
    : daemon_(daemon),
      signals_(UnixSignals::create(executor)),
      executor_(executor),
      state_(XzeroState::Inactive) {

  signals_->notify(SIGHUP, std::bind(&XzeroEventHandler::onConfigReload, this, std::placeholders::_1));
  signals_->notify(SIGUSR1, std::bind(&XzeroEventHandler::onCycleLogs, this, std::placeholders::_1));
  signals_->notify(SIGUSR2, std::bind(&XzeroEventHandler::onUpgradeBinary, this, std::placeholders::_1));
  signals_->notify(SIGQUIT, std::bind(&XzeroEventHandler::onGracefulShutdown, this, std::placeholders::_1));
  signals_->notify(SIGTERM, std::bind(&XzeroEventHandler::onQuickShutdown, this, std::placeholders::_1));
  signals_->notify(SIGINT, std::bind(&XzeroEventHandler::onQuickShutdown, this, std::placeholders::_1));
}

XzeroEventHandler::~XzeroEventHandler() {
}

void XzeroEventHandler::onConfigReload(const xzero::UnixSignalInfo& info) {
  logNotice("x0d",
            "Reloading configuration, as requested by pid $0 uid $1.",
            info.pid.getOrElse(-1), info.uid.getOrElse(-1));

  daemon_->reloadConfiguration();

  signals_->notify(SIGHUP, std::bind(&XzeroEventHandler::onConfigReload, this, std::placeholders::_1));
}

void XzeroEventHandler::onCycleLogs(const xzero::UnixSignalInfo& info) {
  logNotice("x0d", "Cycling logs, as requested by pid $0 uid $1.",
            info.pid.getOrElse(-1), info.uid.getOrElse(-1));

  daemon_->onCycleLogs();

  signals_->notify(SIGUSR1, std::bind(&XzeroEventHandler::onCycleLogs, this, std::placeholders::_1));
}

void XzeroEventHandler::onUpgradeBinary(const UnixSignalInfo& info) {
  logNotice("x0d",
            "Upgrading binary requested by pid $0 uid $1",
            info.pid.getOrElse(-1), info.uid.getOrElse(-1));

  /* TODO [x0d] binary upgrade
   * 1. suspend the world
   * 2. save state into temporary file with an inheriting file descriptor
   * 3. exec into new binary
   * 4. (new process) load state from file descriptor and close fd
   * 5. (new process) resume the world
   */
}

void XzeroEventHandler::onQuickShutdown(const xzero::UnixSignalInfo& info) {
  logNotice("x0d", "Initiating quick shutdown.");
  daemon_->terminate();
}

void XzeroEventHandler::onGracefulShutdown(const xzero::UnixSignalInfo& info) {
  logNotice("x0d", "Initiating graceful shutdown.");

  /* 1. stop all listeners
   * 2. wait until all requests have been handled.
   * 3. orderly shutdown
   */

  daemon_->server()->stop();
}

} // namespace x0d
<|endoftext|>