remove unused

remove unused

--- inc/BSignals/details/SharedMutex.hpp
+++ inc/BSignals/details/SharedMutex.hpp
@@ -1,815 +0,0 @@
-// Copyright Howard Hinnant 2007-2010. Distributed under the Boost
-// Software License, Version 1.0. (see http://www.boost.org/LICENSE_1_0.txt)
-
-#ifndef SHARED_MUTEX
-#define SHARED_MUTEX
-
-#ifndef _LIBCPP_SHARED_LOCK
-#define _LIBCPP_SHARED_LOCK
-#endif
-
-#include <mutex>
-#include <condition_variable>
-#include <chrono>
-#include <climits>
-#include <system_error>
-
-namespace ting {
-
-class shared_mutex
-{
-    typedef std::mutex              mutex_t;
-    typedef std::condition_variable cond_t;
-    typedef unsigned                count_t;
-
-    mutex_t mut_;
-    cond_t  gate1_;
-    cond_t  gate2_;
-    count_t state_;
-
-    static const count_t write_entered_ = 1U << (sizeof(count_t)*CHAR_BIT - 1);
-    static const count_t n_readers_ = ~write_entered_;
-
-public:
-    shared_mutex();
-    ~shared_mutex();
-
-    shared_mutex(const shared_mutex&) = delete;
-    shared_mutex& operator=(const shared_mutex&) = delete;
-
-// Exclusive ownership
-
-    void lock();
-    bool try_lock();
-    template <class Rep, class Period>
-        bool try_lock_for(const std::chrono::duration<Rep, Period>& rel_time)
-        {
-            return try_lock_until(std::chrono::steady_clock::now() + rel_time);
-        }
-    template <class Clock, class Duration>
-        bool
-        try_lock_until(
-                      const std::chrono::time_point<Clock, Duration>& abs_time);
-    void unlock();
-
-// Shared ownership
-
-    void lock_shared();
-    bool try_lock_shared();
-    template <class Rep, class Period>
-        bool
-        try_lock_shared_for(const std::chrono::duration<Rep, Period>& rel_time)
-        {
-            return try_lock_shared_until(std::chrono::steady_clock::now() +
-                                         rel_time);
-        }
-    template <class Clock, class Duration>
-        bool
-        try_lock_shared_until(
-                      const std::chrono::time_point<Clock, Duration>& abs_time);
-    void unlock_shared();
-};
-
-template <class Clock, class Duration>
-bool
-shared_mutex::try_lock_until(
-                       const std::chrono::time_point<Clock, Duration>& abs_time)
-{
-    std::unique_lock<mutex_t> lk(mut_);
-    if (state_ & write_entered_)
-    {
-        while (true)
-        {
-            std::cv_status status = gate1_.wait_until(lk, abs_time);
-            if ((state_ & write_entered_) == 0)
-                break;
-            if (status == std::cv_status::timeout)
-                return false;
-        }
-    }
-    state_ |= write_entered_;
-    if (state_ & n_readers_)
-    {
-        while (true)
-        {
-            std::cv_status status = gate2_.wait_until(lk, abs_time);
-            if ((state_ & n_readers_) == 0)
-                break;
-            if (status == std::cv_status::timeout)
-            {
-                state_ &= ~write_entered_;
-                return false;
-            }
-        }
-    }
-    return true;
-}
-
-template <class Clock, class Duration>
-bool
-shared_mutex::try_lock_shared_until(
-                       const std::chrono::time_point<Clock, Duration>& abs_time)
-{
-    std::unique_lock<mutex_t> lk(mut_);
-    if ((state_ & write_entered_) || (state_ & n_readers_) == n_readers_)
-    {
-        while (true)
-        {
-            std::cv_status status = gate1_.wait_until(lk, abs_time);
-            if ((state_ & write_entered_) == 0 &&
-                                             (state_ & n_readers_) < n_readers_)
-                break;
-            if (status == std::cv_status::timeout)
-                return false;
-        }
-    }
-    count_t num_readers = (state_ & n_readers_) + 1;
-    state_ &= ~n_readers_;
-    state_ |= num_readers;
-    return true;
-}
-
-class upgrade_mutex
-{
-    typedef std::mutex              mutex_t;
-    typedef std::condition_variable cond_t;
-    typedef unsigned                count_t;
-
-    mutex_t mut_;
-    cond_t  gate1_;
-    cond_t  gate2_;
-    count_t state_;
-
-    static const unsigned write_entered_ = 1U << (sizeof(count_t)*CHAR_BIT - 1);
-    static const unsigned upgradable_entered_ = write_entered_ >> 1;
-    static const unsigned n_readers_ = ~(write_entered_ | upgradable_entered_);
-
-public:
-
-    upgrade_mutex();
-    ~upgrade_mutex();
-
-    upgrade_mutex(const upgrade_mutex&) = delete;
-    upgrade_mutex& operator=(const upgrade_mutex&) = delete;
-
-// Exclusive ownership
-
-    void lock();
-    bool try_lock();
-    template <class Rep, class Period>
-        bool try_lock_for(const std::chrono::duration<Rep, Period>& rel_time)
-        {
-            return try_lock_until(std::chrono::steady_clock::now() + rel_time);
-        }
-    template <class Clock, class Duration>
-        bool
-        try_lock_until(
-                      const std::chrono::time_point<Clock, Duration>& abs_time);
-    void unlock();
-
-// Shared ownership
-
-    void lock_shared();
-    bool try_lock_shared();
-    template <class Rep, class Period>
-        bool
-        try_lock_shared_for(const std::chrono::duration<Rep, Period>& rel_time)
-        {
-            return try_lock_shared_until(std::chrono::steady_clock::now() +
-                                         rel_time);
-        }
-    template <class Clock, class Duration>
-        bool
-        try_lock_shared_until(
-                      const std::chrono::time_point<Clock, Duration>& abs_time);
-    void unlock_shared();
-
-// Upgrade ownership
-
-    void lock_upgrade();
-    bool try_lock_upgrade();
-    template <class Rep, class Period>
-        bool
-        try_lock_upgrade_for(
-                            const std::chrono::duration<Rep, Period>& rel_time)
-        {
-            return try_lock_upgrade_until(std::chrono::steady_clock::now() +
-                                         rel_time);
-        }
-    template <class Clock, class Duration>
-        bool
-        try_lock_upgrade_until(
-                      const std::chrono::time_point<Clock, Duration>& abs_time);
-    void unlock_upgrade();
-
-// Shared <-> Exclusive
-
-    bool try_unlock_shared_and_lock();
-    template <class Rep, class Period>
-        bool
-        try_unlock_shared_and_lock_for(
-                            const std::chrono::duration<Rep, Period>& rel_time)
-        {
-            return try_unlock_shared_and_lock_until(
-                                   std::chrono::steady_clock::now() + rel_time);
-        }
-    template <class Clock, class Duration>
-        bool
-        try_unlock_shared_and_lock_until(
-                      const std::chrono::time_point<Clock, Duration>& abs_time);
-    void unlock_and_lock_shared();
-
-// Shared <-> Upgrade
-
-    bool try_unlock_shared_and_lock_upgrade();
-    template <class Rep, class Period>
-        bool
-        try_unlock_shared_and_lock_upgrade_for(
-                            const std::chrono::duration<Rep, Period>& rel_time)
-        {
-            return try_unlock_shared_and_lock_upgrade_until(
-                                   std::chrono::steady_clock::now() + rel_time);
-        }
-    template <class Clock, class Duration>
-        bool
-        try_unlock_shared_and_lock_upgrade_until(
-                      const std::chrono::time_point<Clock, Duration>& abs_time);
-    void unlock_upgrade_and_lock_shared();
-
-// Upgrade <-> Exclusive
-
-    void unlock_upgrade_and_lock();
-    bool try_unlock_upgrade_and_lock();
-    template <class Rep, class Period>
-        bool
-        try_unlock_upgrade_and_lock_for(
-                            const std::chrono::duration<Rep, Period>& rel_time)
-        {
-            return try_unlock_upgrade_and_lock_until(
-                                   std::chrono::steady_clock::now() + rel_time);
-        }
-    template <class Clock, class Duration>
-        bool
-        try_unlock_upgrade_and_lock_until(
-                      const std::chrono::time_point<Clock, Duration>& abs_time);
-    void unlock_and_lock_upgrade();
-};
-
-template <class Clock, class Duration>
-bool
-upgrade_mutex::try_lock_until(
-                       const std::chrono::time_point<Clock, Duration>& abs_time)
-{
-    std::unique_lock<mutex_t> lk(mut_);
-    if (state_ & (write_entered_ | upgradable_entered_))
-    {
-        while (true)
-        {
-            std::cv_status status = gate1_.wait_until(lk, abs_time);
-            if ((state_ & (write_entered_ | upgradable_entered_)) == 0)
-                break;
-            if (status == std::cv_status::timeout)
-                return false;
-        }
-    }
-    state_ |= write_entered_;
-    if (state_ & n_readers_)
-    {
-        while (true)
-        {
-            std::cv_status status = gate2_.wait_until(lk, abs_time);
-            if ((state_ & n_readers_) == 0)
-                break;
-            if (status == std::cv_status::timeout)
-            {
-                state_ &= ~write_entered_;
-                return false;
-            }
-        }
-    }
-    return true;
-}
-
-template <class Clock, class Duration>
-bool
-upgrade_mutex::try_lock_shared_until(
-                       const std::chrono::time_point<Clock, Duration>& abs_time)
-{
-    std::unique_lock<mutex_t> lk(mut_);
-    if ((state_ & write_entered_) || (state_ & n_readers_) == n_readers_)
-    {
-        while (true)
-        {
-            std::cv_status status = gate1_.wait_until(lk, abs_time);
-            if ((state_ & write_entered_) == 0 &&
-                                             (state_ & n_readers_) < n_readers_)
-                break;
-            if (status == std::cv_status::timeout)
-                return false;
-        }
-    }
-    count_t num_readers = (state_ & n_readers_) + 1;
-    state_ &= ~n_readers_;
-    state_ |= num_readers;
-    return true;
-}
-
-template <class Clock, class Duration>
-bool
-upgrade_mutex::try_lock_upgrade_until(
-                       const std::chrono::time_point<Clock, Duration>& abs_time)
-{
-    std::unique_lock<mutex_t> lk(mut_);
-    if ((state_ & (write_entered_ | upgradable_entered_)) ||
-        (state_ & n_readers_) == n_readers_)
-    {
-        while (true)
-        {
-            std::cv_status status = gate1_.wait_until(lk, abs_time);
-            if ((state_ & (write_entered_ | upgradable_entered_)) == 0 &&
-                                             (state_ & n_readers_) < n_readers_)
-                break;
-            if (status == std::cv_status::timeout)
-                return false;
-        }
-    }
-    count_t num_readers = (state_ & n_readers_) + 1;
-    state_ &= ~n_readers_;
-    state_ |= upgradable_entered_ | num_readers;
-    return true;
-}
-
-template <class Clock, class Duration>
-bool
-upgrade_mutex::try_unlock_shared_and_lock_until(
-                       const std::chrono::time_point<Clock, Duration>& abs_time)
-{
-    std::unique_lock<mutex_t> lk(mut_);
-    if (state_ != 1)
-    {
-        while (true)
-        {
-            std::cv_status status = gate2_.wait_until(lk, abs_time);
-            if (state_ == 1)
-                break;
-            if (status == std::cv_status::timeout)
-                return false;
-        }
-    }
-    state_ = write_entered_;
-    return true;
-}
-
-template <class Clock, class Duration>
-bool
-upgrade_mutex::try_unlock_shared_and_lock_upgrade_until(
-                       const std::chrono::time_point<Clock, Duration>& abs_time)
-{
-    std::unique_lock<mutex_t> lk(mut_);
-    if ((state_ & (write_entered_ | upgradable_entered_)) != 0)
-    {
-        while (true)
-        {
-            std::cv_status status = gate2_.wait_until(lk, abs_time);
-            if ((state_ & (write_entered_ | upgradable_entered_)) == 0)
-                break;
-            if (status == std::cv_status::timeout)
-                return false;
-        }
-    }
-    state_ |= upgradable_entered_;
-    return true;
-}
-
-template <class Clock, class Duration>
-bool
-upgrade_mutex::try_unlock_upgrade_and_lock_until(
-                       const std::chrono::time_point<Clock, Duration>& abs_time)
-{
-    std::unique_lock<mutex_t> lk(mut_);
-    if ((state_ & n_readers_) != 1)
-    {
-        while (true)
-        {
-            std::cv_status status = gate2_.wait_until(lk, abs_time);
-            if ((state_ & n_readers_) == 1)
-                break;
-            if (status == std::cv_status::timeout)
-                return false;
-        }
-    }
-    state_ = write_entered_;
-    return true;
-}
-
-template <class Mutex> class upgrade_lock;
-
-template <class Mutex>
-class shared_lock
-{
-public:
-    typedef Mutex mutex_type;
-
-private:
-    mutex_type* m_;
-    bool owns_;
-
-    struct __nat {int _;};
-
-public:
-    shared_lock()
-        : m_(nullptr), owns_(false) {}
-
-    explicit shared_lock(mutex_type& m)
-        : m_(&m), owns_(true)
-        {m_->lock_shared();}
-
-    shared_lock(mutex_type& m, std::defer_lock_t)
-        : m_(&m), owns_(false) {}
-
-    shared_lock(mutex_type& m, std::try_to_lock_t)
-        : m_(&m), owns_(m.try_lock_shared()) {}
-
-    shared_lock(mutex_type& m, std::adopt_lock_t)
-        : m_(&m), owns_(true) {}
-
-    template <class Clock, class Duration>
-        shared_lock(mutex_type& m,
-                    const std::chrono::time_point<Clock, Duration>& abs_time)
-        : m_(&m), owns_(m.try_lock_shared_until(abs_time)) {}
-    template <class Rep, class Period>
-        shared_lock(mutex_type& m,
-                    const std::chrono::duration<Rep, Period>& rel_time)
-        : m_(&m), owns_(m.try_lock_shared_for(rel_time)) {}
-
-    ~shared_lock()
-    {
-        if (owns_)
-            m_->unlock_shared();
-    }
-
-    shared_lock(shared_lock const&) = delete;
-    shared_lock& operator=(shared_lock const&) = delete;
-
-    shared_lock(shared_lock&& sl)
-        : m_(sl.m_), owns_(sl.owns_)
-        {sl.m_ = nullptr; sl.owns_ = false;}
-
-    shared_lock& operator=(shared_lock&& sl)
-    {
-        if (owns_)
-            m_->unlock_shared();
-        m_ = sl.m_;
-        owns_ = sl.owns_;
-        sl.m_ = nullptr;
-        sl.owns_ = false;
-        return *this;
-    }
-
-    explicit shared_lock(upgrade_lock<mutex_type>&& ul)
-        : m_(ul.mutex()), owns_(ul.owns_lock())
-    {
-        if (owns_)
-            m_->unlock_upgrade_and_lock_shared();
-        ul.release();
-    }
-
-    explicit shared_lock(std::unique_lock<mutex_type>&& ul)
-        : m_(ul.mutex()), owns_(ul.owns_lock())
-    {
-        if (owns_)
-            m_->unlock_and_lock_shared();
-        ul.release();
-    }
-
-    void lock();
-    bool try_lock();
-    template <class Rep, class Period>
-        bool try_lock_for(const std::chrono::duration<Rep, Period>& rel_time)
-        {
-            return try_lock_until(std::chrono::steady_clock::now() + rel_time);
-        }
-    template <class Clock, class Duration>
-        bool
-        try_lock_until(
-                      const std::chrono::time_point<Clock, Duration>& abs_time);
-    void unlock();
-
-    void swap(shared_lock&& u)
-    {
-        std::swap(m_, u.m_);
-        std::swap(owns_, u.owns_);
-    }
-
-    mutex_type* release()
-    {
-        mutex_type* r = m_;
-        m_ = nullptr;
-        owns_ = false;
-        return r;
-    }
-    bool owns_lock() const {return owns_;}
-    operator int __nat::* () const {return owns_ ? &__nat::_ : 0;}
-    mutex_type* mutex() const {return m_;}
-
-};
-
-template <class Mutex>
-void
-shared_lock<Mutex>::lock()
-{
-    if (m_ == nullptr)
-        throw std::system_error(std::error_code(EPERM, std::system_category()),
-                                    "shared_lock::lock: references null mutex");
-    if (owns_)
-        throw std::system_error(std::error_code(EDEADLK, std::system_category()),
-                                           "shared_lock::lock: already locked");
-    m_->lock_shared();
-    owns_ = true;
-}
-
-template <class Mutex>
-bool
-shared_lock<Mutex>::try_lock()
-{
-    if (m_ == nullptr)
-        throw std::system_error(std::error_code(EPERM, std::system_category()),
-                                "shared_lock::try_lock: references null mutex");
-    if (owns_)
-        throw std::system_error(std::error_code(EDEADLK, std::system_category()),
-                                       "shared_lock::try_lock: already locked");
-    owns_ = m_->try_lock_shared();
-    return owns_;
-}
-
-template <class Mutex>
-template <class Clock, class Duration>
-bool
-shared_lock<Mutex>::try_lock_until(
-                       const std::chrono::time_point<Clock, Duration>& abs_time)
-{
-    if (m_ == nullptr)
-        throw std::system_error(std::error_code(EPERM, std::system_category()),
-                          "shared_lock::try_lock_until: references null mutex");
-    if (owns_)
-        throw std::system_error(std::error_code(EDEADLK, std::system_category()),
-                                 "shared_lock::try_lock_until: already locked");
-    owns_ = m_->try_lock_shared_until(abs_time);
-    return owns_;
-}
-
-template <class Mutex>
-void
-shared_lock<Mutex>::unlock()
-{
-    if (!owns_)
-        throw std::system_error(std::error_code(EPERM, std::system_category()),
-                                "shared_lock::unlock: not locked");
-    m_->unlock_shared();
-    owns_ = false;
-}
-
-template <class Mutex>
-inline
-void
-swap(shared_lock<Mutex>&  x, shared_lock<Mutex>&  y)
-{
-    x.swap(y);
-}
-
-template <class Mutex>
-class upgrade_lock
-{
-public:
-    typedef Mutex mutex_type;
-
-private:
-    mutex_type* m_;
-    bool owns_;
-
-    struct __nat {int _;};
-
-public:
-    upgrade_lock()
-        : m_(nullptr), owns_(false) {}
-
-    explicit upgrade_lock(mutex_type& m)
-        : m_(&m), owns_(true)
-        {m_->lock_upgrade();}
-
-    upgrade_lock(mutex_type& m, std::defer_lock_t)
-        : m_(&m), owns_(false) {}
-
-    upgrade_lock(mutex_type& m, std::try_to_lock_t)
-        : m_(&m), owns_(m.try_lock_upgrade()) {}
-
-    upgrade_lock(mutex_type& m, std::adopt_lock_t)
-        : m_(&m), owns_(true) {}
-
-    template <class Clock, class Duration>
-        upgrade_lock(mutex_type& m,
-                    const std::chrono::time_point<Clock, Duration>& abs_time)
-        : m_(&m), owns_(m.try_lock_upgrade_until(abs_time)) {}
-    template <class Rep, class Period>
-        upgrade_lock(mutex_type& m,
-                    const std::chrono::duration<Rep, Period>& rel_time)
-        : m_(&m), owns_(m.try_lock_upgrade_for(rel_time)) {}
-
-    ~upgrade_lock()
-    {
-        if (owns_)
-            m_->unlock_upgrade();
-    }
-
-    upgrade_lock(upgrade_lock const&) = delete;
-    upgrade_lock& operator=(upgrade_lock const&) = delete;
-
-    upgrade_lock(upgrade_lock&& ul)
-        : m_(ul.m_), owns_(ul.owns_)
-        {
-            ul.m_ = nullptr;
-            ul.owns_ = false;
-        }
-
-    upgrade_lock& operator=(upgrade_lock&& ul)
-    {
-        if (owns_)
-            m_->unlock_upgrade();
-        m_ = ul.m_;
-        owns_ = ul.owns_;
-        ul.m_ = nullptr;
-        ul.owns_ = false;
-        return *this;
-    }
-
-    upgrade_lock(shared_lock<mutex_type>&& sl, std::try_to_lock_t)
-        : m_(nullptr), owns_(false)
-    {
-        if (sl.owns_lock())
-        {
-            if (sl.mutex()->try_unlock_shared_and_lock_upgrade())
-            {
-                m_ = sl.release();
-                owns_ = true;
-            }
-        }
-        else
-            m_ = sl.release();
-    }
-
-    template <class Clock, class Duration>
-        upgrade_lock(shared_lock<mutex_type>&& sl,
-                     const std::chrono::time_point<Clock, Duration>& abs_time)
-        : m_(nullptr), owns_(false)
-    {
-        if (sl.owns_lock())
-        {
-            if (sl.mutex()->try_unlock_shared_and_lock_upgrade_until(abs_time))
-            {
-                m_ = sl.release();
-                owns_ = true;
-            }
-        }
-        else
-            m_ = sl.release();
-    }
-
-    template <class Rep, class Period>
-        upgrade_lock(shared_lock<mutex_type>&& sl,
-                     const std::chrono::duration<Rep, Period>& rel_time)
-        : m_(nullptr), owns_(false)
-    {
-        if (sl.owns_lock())
-        {
-            if (sl.mutex()->try_unlock_shared_and_lock_upgrade_for(rel_time))
-            {
-                m_ = sl.release();
-                owns_ = true;
-            }
-        }
-        else
-            m_ = sl.release();
-    }
-
-    explicit upgrade_lock(std::unique_lock<mutex_type>&& ul)
-        : m_(ul.mutex()), owns_(ul.owns_lock())
-    {
-        if (owns_)
-            m_->unlock_and_lock_upgrade();
-        ul.release();
-    }
-
-    void lock();
-    bool try_lock();
-    template <class Rep, class Period>
-        bool try_lock_for(const std::chrono::duration<Rep, Period>& rel_time)
-        {
-            return try_lock_until(std::chrono::steady_clock::now() + rel_time);
-        }
-    template <class Clock, class Duration>
-        bool
-        try_lock_until(
-                      const std::chrono::time_point<Clock, Duration>& abs_time);
-    void unlock();
-
-    void swap(upgrade_lock&& u)
-    {
-        std::swap(m_, u.m_);
-        std::swap(owns_, u.owns_);
-    }
-
-    mutex_type* release()
-    {
-        mutex_type* r = m_;
-        m_ = 0;
-        owns_ = false;
-        return r;
-    }
-
-    bool owns_lock() const {return owns_;}
-    operator int __nat::* () const {return owns_ ? &__nat::_ : 0;}
-    mutex_type* mutex() const {return m_;}
-};
-
-template <class Mutex>
-void
-upgrade_lock<Mutex>::lock()
-{
-    if (m_ == nullptr)
-        throw std::system_error(std::error_code(EPERM, std::system_category()),
-                                   "upgrade_lock::lock: references null mutex");
-    if (owns_)
-        throw std::system_error(std::error_code(EDEADLK, std::system_category()),
-                                          "upgrade_lock::lock: already locked");
-    m_->lock_upgrade();
-    owns_ = true;
-}
-
-template <class Mutex>
-bool
-upgrade_lock<Mutex>::try_lock()
-{
-    if (m_ == nullptr)
-        throw std::system_error(std::error_code(EPERM, std::system_category()),
-                               "upgrade_lock::try_lock: references null mutex");
-    if (owns_)
-        throw std::system_error(std::error_code(EDEADLK, std::system_category()),
-                                      "upgrade_lock::try_lock: already locked");
-    owns_ = m_->try_lock_upgrade();
-    return owns_;
-}
-
-template <class Mutex>
-template <class Clock, class Duration>
-bool
-upgrade_lock<Mutex>::try_lock_until(
-                       const std::chrono::time_point<Clock, Duration>& abs_time)
-{
-    if (m_ == nullptr)
-        throw std::system_error(std::error_code(EPERM, std::system_category()),
-                         "upgrade_lock::try_lock_until: references null mutex");
-    if (owns_)
-        throw std::system_error(std::error_code(EDEADLK, std::system_category()),
-                                "upgrade_lock::try_lock_until: already locked");
-    owns_ = m_->try_lock_upgrade_until(abs_time);
-    return owns_;
-}
-
-template <class Mutex>
-void
-upgrade_lock<Mutex>::unlock()
-{
-    if (!owns_)
-        throw std::system_error(std::error_code(EPERM, std::system_category()),
-                                "upgrade_lock::unlock: not locked");
-    m_->unlock_upgrade();
-    owns_ = false;
-}
-
-template <class Mutex>
-inline
-void
-swap(upgrade_lock<Mutex>&  x, upgrade_lock<Mutex>&  y)
-{
-    x.swap(y);
-}
-
-template <class ToLock, class FromLock>
-class transfer_lock
-{
-    ToLock to_lock_;
-    FromLock& from_lock_;
-
-public:
-    explicit transfer_lock(FromLock& fl)
-        : to_lock_(std::move(fl)),
-          from_lock_(fl) {}
-    ~transfer_lock() {from_lock_ = FromLock(std::move(to_lock_));}
-
-    transfer_lock(const transfer_lock&) = delete;
-    transfer_lock& operator=(const transfer_lock&) = delete;
-};
-
-}  // ting
-
-#endif


Consider also lib64 directories when looking for libvlc

--- src/libvlc.cpp
+++ src/libvlc.cpp
@@ -168,6 +168,7 @@
     paths = QString::fromLatin1(qgetenv("LD_LIBRARY_PATH"))
             .split(QLatin1Char(':'), QString::SkipEmptyParts);
     paths << QLatin1String(PHONON_LIB_INSTALL_DIR) << QLatin1String("/usr/lib") << QLatin1String("/usr/local/lib");
+    paths << QLatin1String("/usr/lib64") << QLatin1String("/usr/local/lib64");

 #if defined(Q_WS_MAC)
     paths


Put the oculus helper class inside the Annwvyn namespace

Signed-off-by: Arthur Brainville (Ybalrid) <9af089ff2f965cf1ff051bcad0648fdc32c01648@ybalrid.info>

--- include/AnnOculusInterfaceHelper.hpp
+++ include/AnnOculusInterfaceHelper.hpp
@@ -1,5 +1,5 @@
 /**
- * \file AnnAnnOculusInterfaceHelper.hpp
+ * \file AnnOculusInterfaceHelper.hpp
  * \brief Simple class for accessing Oculus Rift data
  * \author A. Brainville (Ybalrid)
  */
@@ -14,53 +14,57 @@
 #include <Ogre.h>
 #include <AnnException.hpp>

-///Communicate with the Rift runtime (initialize OVR and get the info)
-class AnnDllExport AnnOculusInterfaceHelper
+namespace Annwvyn
 {
-public:
-	///Construct an AnnOculusInterfaceHelper object. This create an Oculus Session for communication with the Oculus Runtime
-	AnnOculusInterfaceHelper();

-	///Destructor of Oculus Interface
-	~AnnOculusInterfaceHelper();
+	///Communicate with the Rift runtime (initialize OVR and get the info)
+	class AnnDllExport AnnOculusInterfaceHelper
+	{
+	public:
+		///Construct an AnnOculusInterfaceHelper object. This create an Oculus Session for communication with the Oculus Runtime
+		AnnOculusInterfaceHelper();

-	///Return the active HmdDesc object
-	ovrHmdDesc getHmdDesc() const;
+		///Destructor of Oculus Interface
+		~AnnOculusInterfaceHelper();

-	///Return the current oculus session
-	ovrSession getSession() const;
+		///Return the active HmdDesc object
+		ovrHmdDesc getHmdDesc() const;

-	///Return the eye's height of the current user
-	float getUserEyeHeight() const;
+		///Return the current oculus session
+		ovrSession getSession() const;

-	///Recenter the tracking origin
-	void recenterTrackingOrigin() const;
+		///Return the eye's height of the current user
+		float getUserEyeHeight() const;

-	///Set the performance HUD mode
-	void setPerfHudMode(ovrPerfHudMode mode) const;
+		///Recenter the tracking origin
+		void recenterTrackingOrigin() const;

-	///get HMD resolution in the Oculus format
-	ovrSizei getHmdResolution() const;
+		///Set the performance HUD mode
+		void setPerfHudMode(ovrPerfHudMode mode) const;

-	///get HMD Refresh rate. e.g. 90 (or 89.99) for an Oculus Rift CV1
-	float getHmdDisplayRefreshRate() const;
+		///get HMD resolution in the Oculus format
+		ovrSizei getHmdResolution() const;

-	///Set the reference point to be a point on the ground, not the "zero" position of the headset
-	void setTrackingOriginToFloorLevel() const;
+		///get HMD Refresh rate. e.g. 90 (or 89.99) for an Oculus Rift CV1
+		float getHmdDisplayRefreshRate() const;

-private:
-	///Print every known characteristics about the hardware to the log output
-	void logHardwareReport() const;
+		///Set the reference point to be a point on the ground, not the "zero" position of the headset
+		void setTrackingOriginToFloorLevel() const;

-	///Abort, display error, log it and crash the game
-	void abortOnFailure();
+	private:
+		///Print every known characteristics about the hardware to the log output
+		void logHardwareReport() const;

-	///Oculus session for the application
-	ovrSession session;
+		///Abort, display error, log it and crash the game
+		void abortOnFailure();

-	///Description of the HMD
-	ovrHmdDesc hmdDesc;
+		///Oculus session for the application
+		ovrSession session;

-	///Graphics device identifier (internal for the Rift SDK)
-	ovrGraphicsLuid luid;
-};
+		///Description of the HMD
+		ovrHmdDesc hmdDesc;
+
+		///Graphics device identifier (internal for the Rift SDK)
+		ovrGraphicsLuid luid;
+	};
+}


verbose off

verbose off

--- src/linreg.hpp
+++ src/linreg.hpp
@@ -180,7 +180,7 @@
         return std::make_pair(cost, grad);
     };

-    const vector_type theta = num::fmincg(cost_fn, m_theta0, m_max_iter, true);
+    const vector_type theta = num::fmincg(cost_fn, m_theta0, m_max_iter, false);

     return theta;
 }


SkPDF: refactor generate_page_tree

SkPDF: refactor generate_page_tree

function now takes a constant ref, as needed.

re-written to make it easier to think about state.

Change-Id: I5b9935cd88b4f8b1f35d4df622adcfb61655d42b
Reviewed-on: https://skia-review.googlesource.com/c/160383
Reviewed-by: Ben Wagner <53965154ffeecc4a10886eab9259e95965f2979a@google.com>
Commit-Queue: Hal Canary <fd9641b23487c8ee78406c27513624c460600766@google.com>

--- src/pdf/SkPDFDocument.cpp
+++ src/pdf/SkPDFDocument.cpp
@@ -119,9 +119,7 @@
     return SkToS32(offset - fBaseOffset);
 }

-
-// return root node.
-static sk_sp<SkPDFDict> generate_page_tree(std::vector<sk_sp<SkPDFDict>>* pages) {
+static sk_sp<SkPDFDict> generate_page_tree(const std::vector<sk_sp<SkPDFDict>>& pages) {
     // PDF wants a tree describing all the pages in the document.  We arbitrary
     // choose 8 (kNodeSize) as the number of allowed children.  The internal
     // nodes have type "Pages" with an array of children, a parent pointer, and
@@ -129,57 +127,53 @@
     // into the method, have type "Page" and need a parent pointer. This method
     // builds the tree bottom up, skipping internal nodes that would have only
     // one child.
-    static const int kNodeSize = 8;
-
-    // curNodes takes a reference to its items, which it passes to pageTree.
-    size_t totalPageCount = pages->size();
-    std::vector<sk_sp<SkPDFDict>> curNodes;
-    curNodes.swap(*pages);
-
-    // nextRoundNodes passes its references to nodes on to curNodes.
-    int treeCapacity = kNodeSize;
-    do {
-        std::vector<sk_sp<SkPDFDict>> nextRoundNodes;
-        for (size_t i = 0; i < curNodes.size(); ) {
-            if (i > 0 && i + 1 == curNodes.size()) {
-                SkASSERT(curNodes[i]);
-                nextRoundNodes.emplace_back(std::move(curNodes[i]));
-                break;
+    SkASSERT(pages.size() > 0);
+    struct PageTreeNode {
+        sk_sp<SkPDFDict> fNode;
+        int fPageObjectDescendantCount;
+
+        static void Layer(std::vector<PageTreeNode>* vec) {
+            std::vector<PageTreeNode> result;
+            static constexpr size_t kMaxNodeSize = 8;
+            const size_t n = vec->size();
+            SkASSERT(n >= 1);
+            const size_t result_len = (n - 1) / kMaxNodeSize + 1;
+            SkASSERT(result_len >= 1);
+            SkASSERT(n == 1 || result_len < n);
+            result.reserve(result_len);
+            size_t index = 0;
+            for (size_t i = 0; i < result_len; ++i) {
+                if (n != 1 && index + 1 == n) {  // No need to create a new node.
+                    result.push_back(std::move((*vec)[index++]));
+                    continue;
+                }
+                auto next = sk_make_sp<SkPDFDict>("Pages");
+                auto kids_list = sk_make_sp<SkPDFArray>();
+                int descendantCount = 0;
+                for (size_t j = 0; j < kMaxNodeSize && index < n; ++j) {
+                    PageTreeNode& node = (*vec)[index++];
+                    node.fNode->insertObjRef("Parent", next);
+                    kids_list->appendObjRef(std::move(node.fNode));
+                    descendantCount += node.fPageObjectDescendantCount;
+                }
+                next->insertInt("Count", descendantCount);
+                next->insertObject("Kids", std::move(kids_list));
+                result.push_back(PageTreeNode{std::move(next), descendantCount});
             }
-
-            auto newNode = sk_make_sp<SkPDFDict>("Pages");
-            auto kids = sk_make_sp<SkPDFArray>();
-            kids->reserve(kNodeSize);
-
-            int count = 0;
-            for (; i < curNodes.size() && count < kNodeSize; i++, count++) {
-                SkASSERT(curNodes[i]);
-                curNodes[i]->insertObjRef("Parent", newNode);
-                kids->appendObjRef(std::move(curNodes[i]));
-            }
-
-            // treeCapacity is the number of leaf nodes possible for the
-            // current set of subtrees being generated. (i.e. 8, 64, 512, ...).
-            // It is hard to count the number of leaf nodes in the current
-            // subtree. However, by construction, we know that unless it's the
-            // last subtree for the current depth, the leaf count will be
-            // treeCapacity, otherwise it's what ever is left over after
-            // consuming treeCapacity chunks.
-            size_t pageCount = treeCapacity;
-            if (i == curNodes.size()) {
-                pageCount = ((totalPageCount - 1) % treeCapacity) + 1;
-            }
-            newNode->insertInt("Count", SkToInt(pageCount));
-            newNode->insertObject("Kids", std::move(kids));
-            nextRoundNodes.emplace_back(std::move(newNode));
+            *vec = result;
         }
-        SkDEBUGCODE( for (const auto& n : curNodes) { SkASSERT(!n); } );
-
-        curNodes.swap(nextRoundNodes);
-        nextRoundNodes = std::vector<sk_sp<SkPDFDict>>();
-        treeCapacity *= kNodeSize;
-    } while (curNodes.size() > 1);
-    return std::move(curNodes[0]);
+    };
+    std::vector<PageTreeNode> currentLayer;
+    currentLayer.reserve(pages.size());
+    for (const sk_sp<SkPDFDict>& page : pages) {
+        currentLayer.push_back(PageTreeNode{page, 1});
+    }
+    PageTreeNode::Layer(&currentLayer);
+    while (currentLayer.size() > 1) {
+        PageTreeNode::Layer(&currentLayer);
+    }
+    SkASSERT(currentLayer.size() == 1);
+    return std::move(currentLayer[0].fNode);
 }

 template<typename T, typename... Args>
@@ -496,12 +490,9 @@
         docCatalog->insertObject("OutputIntents", make_srgb_output_intents());
     }

-    std::vector<sk_sp<SkPDFDict>> pagesCopy(fPages);
-    SkASSERT(!pagesCopy.empty());
-    sk_sp<SkPDFDict> pageTree = generate_page_tree(&pagesCopy);
+    sk_sp<SkPDFDict> pageTree = generate_page_tree(fPages);
     pageTree->insertObject("Resources", make_top_resource_dict());
     docCatalog->insertObjRef("Pages", std::move(pageTree));
-    SkASSERT(pagesCopy.empty());
     if (fDests->size() > 0) {
         docCatalog->insertObjRef("Dests", std::move(fDests));
     }


corrected default constructor

corrected default constructor

--- include/SAX/filter/TextCoalescer.hpp
+++ include/SAX/filter/TextCoalescer.hpp
@@ -24,7 +24,7 @@
   typedef basic_Attributes<string_type> AttributesT;

   TextCoalescer() :
-    XMLFilterT(0)
+    XMLFilterT()
   {
   } // basic_TextCoalescer


VoxelGrid now knows how to de/serialize

VoxelGrid now knows how to de/serialize

--- include/arc_utilities/voxel_grid.hpp
+++ include/arc_utilities/voxel_grid.hpp
@@ -7,6 +7,8 @@
 #include <algorithm>
 #include <Eigen/Geometry>
 #include <stdexcept>
+#include <arc_utilities/arc_helpers.hpp>
+#include <arc_utilities/eigen_helpers.hpp>

 #ifndef VOXEL_GRID_HPP
 #define VOXEL_GRID_HPP
@@ -220,6 +222,18 @@

         EIGEN_MAKE_ALIGNED_OPERATOR_NEW

+        inline static uint64_t Serialize(const VoxelGrid<T, Allocator>& grid, std::vector<uint8_t>& buffer, const std::function<uint64_t(const T&, std::vector<uint8_t>&)>& value_serializer)
+        {
+            return grid.SerializeSelf(buffer, value_serializer);
+        }
+
+        inline static std::pair<VoxelGrid<T, Allocator>, uint64_t> Deserialize(const std::vector<uint8_t>& buffer, const uint64_t current, const std::function<std::pair<T, uint64_t>(const std::vector<uint8_t>&, const uint64_t)>& value_deserializer)
+        {
+            VoxelGrid<T, Allocator> temp_grid;
+            const uint64_t bytes_read = temp_grid.DeserializeSelf(buffer, current, value_deserializer);
+            return std::make_pair(temp_grid, bytes_read);
+        }
+
         VoxelGrid(const Eigen::Affine3d& origin_transform, const double cell_size, const double x_size, const double y_size, double const z_size, const T& default_value)
         {
             Initialize(origin_transform, cell_size, cell_size, cell_size, x_size, y_size, z_size, default_value, default_value);
@@ -361,6 +375,119 @@
             initialized_ = true;
         }

+        inline uint64_t SerializeSelf(std::vector<uint8_t>& buffer, const std::function<uint64_t(const T&, std::vector<uint8_t>&)>& value_serializer) const
+        {
+            const uint64_t start_buffer_size = buffer.size();
+            // Serialize the initialized
+            arc_helpers::SerializeFixedSizePOD<uint8_t>((uint8_t)initialized_, buffer);
+            // Serialize the transforms
+            EigenHelpers::Serialize<Eigen::Affine3d>(origin_transform_, buffer);
+            EigenHelpers::Serialize<Eigen::Affine3d>(inverse_origin_transform_, buffer);
+            // Serialize the data
+            arc_helpers::SerializeVector<T, Allocator>(data_, buffer, value_serializer);
+            // Serialize the cell sizes
+            arc_helpers::SerializeFixedSizePOD<double>(cell_x_size_, buffer);
+            arc_helpers::SerializeFixedSizePOD<double>(cell_y_size_, buffer);
+            arc_helpers::SerializeFixedSizePOD<double>(cell_z_size_, buffer);
+            arc_helpers::SerializeFixedSizePOD<double>(inv_cell_x_size_, buffer);
+            arc_helpers::SerializeFixedSizePOD<double>(inv_cell_y_size_, buffer);
+            arc_helpers::SerializeFixedSizePOD<double>(inv_cell_z_size_, buffer);
+            // Serialize the grid sizes
+            arc_helpers::SerializeFixedSizePOD<double>(x_size_, buffer);
+            arc_helpers::SerializeFixedSizePOD<double>(y_size_, buffer);
+            arc_helpers::SerializeFixedSizePOD<double>(z_size_, buffer);
+            // Serialize the control/bounds values
+            arc_helpers::SerializeFixedSizePOD<int64_t>(stride1_, buffer);
+            arc_helpers::SerializeFixedSizePOD<int64_t>(stride2_, buffer);
+            arc_helpers::SerializeFixedSizePOD<int64_t>(num_x_cells_, buffer);
+            arc_helpers::SerializeFixedSizePOD<int64_t>(num_y_cells_, buffer);
+            arc_helpers::SerializeFixedSizePOD<int64_t>(num_z_cells_, buffer);
+            // Serialize the default value
+            value_serializer(default_value_, buffer);
+            // Serialize the OOB value
+            value_serializer(oob_value_, buffer);
+            // Figure out how many bytes were written
+            const uint64_t end_buffer_size = buffer.size();
+            const uint64_t bytes_written = end_buffer_size - start_buffer_size;
+            return bytes_written;
+        }
+
+        inline uint64_t DeserializeSelf(const std::vector<uint8_t>& buffer, const uint64_t current, const std::function<std::pair<T, uint64_t>(const std::vector<uint8_t>&, const uint64_t)>& value_deserializer)
+        {
+            uint64_t current_position = current;
+            // Deserialize the initialized
+            const std::pair<uint8_t, uint64_t> initialized_deserialized = arc_helpers::DeserializeFixedSizePOD<uint8_t>(buffer, current_position);
+            initialized_ = (bool)initialized_deserialized.first;
+            current_position += initialized_deserialized.second;
+            // Deserialize the transforms
+            const std::pair<Eigen::Affine3d, uint64_t> origin_transform_deserialized = EigenHelpers::Deserialize<Eigen::Affine3d>(buffer, current_position);
+            origin_transform_ = origin_transform_deserialized.first;
+            current_position += origin_transform_deserialized.second;
+            const std::pair<Eigen::Affine3d, uint64_t> inverse_origin_transform_deserialized = EigenHelpers::Deserialize<Eigen::Affine3d>(buffer, current_position);
+            inverse_origin_transform_ = inverse_origin_transform_deserialized.first;
+            current_position += inverse_origin_transform_deserialized.second;
+            // Deserialize the data
+            const std::pair<std::vector<T, Allocator>, uint64_t> data_deserialized = arc_helpers::DeserializeVector<T, Allocator>(buffer, current_position, value_deserializer);
+            data_ = data_deserialized.first;
+            current_position += data_deserialized.second;
+            // Deserialize the cell sizes
+            const std::pair<double, uint64_t> cell_x_size_deserialized = arc_helpers::DeserializeFixedSizePOD<double>(buffer, current_position);
+            cell_x_size_ = cell_x_size_deserialized.first;
+            current_position += cell_x_size_deserialized.second;
+            const std::pair<double, uint64_t> cell_y_size_deserialized = arc_helpers::DeserializeFixedSizePOD<double>(buffer, current_position);
+            cell_y_size_ = cell_y_size_deserialized.first;
+            current_position += cell_y_size_deserialized.second;
+            const std::pair<double, uint64_t> cell_z_size_deserialized = arc_helpers::DeserializeFixedSizePOD<double>(buffer, current_position);
+            cell_z_size_ = cell_z_size_deserialized.first;
+            current_position += cell_z_size_deserialized.second;
+            const std::pair<double, uint64_t> inv_cell_x_size_deserialized = arc_helpers::DeserializeFixedSizePOD<double>(buffer, current_position);
+            inv_cell_x_size_ = inv_cell_x_size_deserialized.first;
+            current_position += inv_cell_x_size_deserialized.second;
+            const std::pair<double, uint64_t> inv_cell_y_size_deserialized = arc_helpers::DeserializeFixedSizePOD<double>(buffer, current_position);
+            inv_cell_y_size_ = inv_cell_y_size_deserialized.first;
+            current_position += inv_cell_y_size_deserialized.second;
+            const std::pair<double, uint64_t> inv_cell_z_size_deserialized = arc_helpers::DeserializeFixedSizePOD<double>(buffer, current_position);
+            inv_cell_z_size_ = inv_cell_z_size_deserialized.first;
+            current_position += inv_cell_z_size_deserialized.second;
+            // Deserialize the grid sizes
+            const std::pair<double, uint64_t> x_size_deserialized = arc_helpers::DeserializeFixedSizePOD<double>(buffer, current_position);
+            x_size_ = x_size_deserialized.first;
+            current_position += x_size_deserialized.second;
+            const std::pair<double, uint64_t> y_size_deserialized = arc_helpers::DeserializeFixedSizePOD<double>(buffer, current_position);
+            y_size_ = y_size_deserialized.first;
+            current_position += y_size_deserialized.second;
+            const std::pair<double, uint64_t> z_size_deserialized = arc_helpers::DeserializeFixedSizePOD<double>(buffer, current_position);
+            z_size_ = z_size_deserialized.first;
+            current_position += z_size_deserialized.second;
+            // Deserialize the control/bounds values
+            const std::pair<int64_t, uint64_t> stride1_deserialized = arc_helpers::DeserializeFixedSizePOD<int64_t>(buffer, current_position);
+            stride1_ = stride1_deserialized.first;
+            current_position += stride1_deserialized.second;
+            const std::pair<int64_t, uint64_t> stride2_deserialized = arc_helpers::DeserializeFixedSizePOD<int64_t>(buffer, current_position);
+            stride2_ = stride2_deserialized.first;
+            current_position += stride2_deserialized.second;
+            const std::pair<int64_t, uint64_t> num_x_cells_deserialized = arc_helpers::DeserializeFixedSizePOD<int64_t>(buffer, current_position);
+            num_x_cells_ = num_x_cells_deserialized.first;
+            current_position += num_x_cells_deserialized.second;
+            const std::pair<int64_t, uint64_t> num_y_cells_deserialized = arc_helpers::DeserializeFixedSizePOD<int64_t>(buffer, current_position);
+            num_y_cells_ = num_y_cells_deserialized.first;
+            current_position += num_y_cells_deserialized.second;
+            const std::pair<int64_t, uint64_t> num_z_cells_deserialized = arc_helpers::DeserializeFixedSizePOD<int64_t>(buffer, current_position);
+            num_z_cells_ = num_z_cells_deserialized.first;
+            current_position += num_z_cells_deserialized.second;
+            // Deserialize the default value
+            const std::pair<T, uint64_t> default_value_deserialized = value_deserializer(buffer, current_position);
+            default_value_ = default_value_deserialized.first;
+            current_position += default_value_deserialized.second;
+            // Deserialize the OOB value
+            const std::pair<T, uint64_t> oob_value_deserialized = value_deserializer(buffer, current_position);
+            oob_value_ = oob_value_deserialized.first;
+            current_position += oob_value_deserialized.second;
+            // Figure out how many bytes were read
+            const uint64_t bytes_read = current_position - current;
+            return bytes_read;
+        }
+
         inline bool IsInitialized() const
         {
             return initialized_;
@@ -494,7 +621,7 @@
             return SetValue(location, value);
         }

-        inline bool  SetValue(const GRID_INDEX& index, const T& value)
+        inline bool SetValue(const GRID_INDEX& index, const T& value)
         {
             return SetValue(index.x, index.y, index.z, value);
         }
@@ -535,7 +662,7 @@
             return SetValue(location, value);
         }

-        inline bool  SetValue(const GRID_INDEX& index, T&& value)
+        inline bool SetValue(const GRID_INDEX& index, T&& value)
         {
             return SetValue(index.x, index.y, index.z, value);
         }


Fix empty log level parsing

Fix empty log level parsing

--- src/logger.cpp
+++ src/logger.cpp
@@ -617,23 +617,25 @@
 log_level logger::parse_log_level(const std::string& a_level)
     throw(std::runtime_error)
 {
+    if (a_level.empty()) return LEVEL_NONE;
+
     auto s = boost::to_upper_copy(a_level);
-    if (s == "WIRE")    return LEVEL_DEBUG;  // Backward compatibility
+    if (s == "WIRE")     return LEVEL_DEBUG;  // Backward compatibility
     if (s == "NONE" ||
-        s == "FALSE")   return LEVEL_NONE;
-    if (s == "TRACE")   return LEVEL_TRACE;
-    if (s == "TRACE1")  return log_level(LEVEL_TRACE | LEVEL_TRACE1);
-    if (s == "TRACE2")  return log_level(LEVEL_TRACE | LEVEL_TRACE2);
-    if (s == "TRACE3")  return log_level(LEVEL_TRACE | LEVEL_TRACE3);
-    if (s == "TRACE4")  return log_level(LEVEL_TRACE | LEVEL_TRACE4);
-    if (s == "TRACE5")  return log_level(LEVEL_TRACE | LEVEL_TRACE5);
-    if (s == "DEBUG")   return LEVEL_DEBUG;
-    if (s == "INFO")    return LEVEL_INFO;
-    if (s == "NOTICE")  return LEVEL_NOTICE;
-    if (s == "WARNING") return LEVEL_WARNING;
-    if (s == "ERROR")   return LEVEL_ERROR;
-    if (s == "FATAL")   return LEVEL_FATAL;
-    if (s == "ALERT")   return LEVEL_ALERT;
+        s == "FALSE")    return LEVEL_NONE;
+    if (s == "TRACE")    return LEVEL_TRACE;
+    if (s == "TRACE1")   return log_level(LEVEL_TRACE | LEVEL_TRACE1);
+    if (s == "TRACE2")   return log_level(LEVEL_TRACE | LEVEL_TRACE2);
+    if (s == "TRACE3")   return log_level(LEVEL_TRACE | LEVEL_TRACE3);
+    if (s == "TRACE4")   return log_level(LEVEL_TRACE | LEVEL_TRACE4);
+    if (s == "TRACE5")   return log_level(LEVEL_TRACE | LEVEL_TRACE5);
+    if (s == "DEBUG")    return LEVEL_DEBUG;
+    if (s == "INFO")     return LEVEL_INFO;
+    if (s == "NOTICE")   return LEVEL_NOTICE;
+    if (s == "WARNING")  return LEVEL_WARNING;
+    if (s == "ERROR")    return LEVEL_ERROR;
+    if (s == "FATAL")    return LEVEL_FATAL;
+    if (s == "ALERT")    return LEVEL_ALERT;
     try   { auto n = std::stoi(s); return as_log_level(n); }
     catch (...) {}
     throw std::runtime_error("Invalid log level: " + a_level);


fixed wrong function name

fixed wrong function name

--- include/detail/rt/x86/llvm_cpuid.hpp
+++ include/detail/rt/x86/llvm_cpuid.hpp
@@ -27,7 +27,7 @@

       static std::array<std::uint32_t,4> value = {~0u};

-      int cpuid_rvalue = extended_get_cpud(&value[0],in_eax,in_ecx);
+      int cpuid_rvalue = extended_get_cpuid(&value[0],in_eax,in_ecx);

       if(cpuid_rvalue < 1){
         value = {0,0,0,0};


dht fix

dht fix

--- include/libtorrent/kademlia/node.hpp
+++ include/libtorrent/kademlia/node.hpp
@@ -104,6 +104,8 @@
 // in the DHT.
 struct search_torrent_entry
 {
+	search_torrent_entry(): total_tag_points(0), total_name_points(0) {}
+
 	// the tags of the torrent. The key of
 	// this entry is the sha-1 hash of one of
 	// these tags. The counter is the number of


Correct a deficiency in the objdump disassembly output parsing

--- disassembly.hxx
+++ disassembly.hxx
@@ -86,7 +86,20 @@
 	{
 		int i = 0, x;
 		bool ok;
-		QRegExp rx("^\\s*(\\w+):");
+		QRegExp rx("^\\s*(\\w+):"
+		/* Note: a whitespace is expected here, because the objdump disassembly
+		 * normally starts with something like:
+		 * "<Filename>:	file format elf32-littlearm"
+		 * and the file name may contain the complete path to the file.
+		 * Now, on a windows machine, if the file is in a windows drive which is a
+		 * valid hex digit (i.e., in the range 'a' - 'f'), then this line is being
+		 * incorrectly detected as a valid disassembly line (e.g., if the file is in the 'c'
+		 * drive, a disassmbly line is being detected for address 0x0000000c).
+		 * To avoid such incorrect detection of disassembly lines in the objdump
+		 * disassembly output, only accept lines which contain some whitespace after
+		 * the colon character.
+		 */
+		"\\s+");
 		this->memory = memory;
 		if (cs_open(CS_ARCH_ARM, CS_MODE_THUMB, & cs_handle))
 		{


Removing async memcpys improves multi-GPU throughput (???)

--- scanner/util/memory.cpp
+++ scanner/util/memory.cpp
@@ -494,8 +494,11 @@
              dest_device.id != src_device.id));
     CUDA_PROTECT({
       CU_CHECK(cudaSetDevice(src_device.id));
-      CU_CHECK(cudaMemcpy(dest_buffer, src_buffer, size, cudaMemcpyDefault));
-    });
+      //CU_CHECK(cudaMemcpyAsync(dest_buffer, src_buffer, size, cudaMemcpyDefault, 0));
+      CU_CHECK(
+          cudaMemcpy(dest_buffer, src_buffer, size, cudaMemcpyDefault));
+      //CU_CHECK(cudaStreamSynchronize(0));
+      });
   }
 }

@@ -521,7 +524,7 @@
   if (dest_device.type == DeviceType::GPU ||
       src_device.type == DeviceType::GPU) {
 #ifdef HAVE_CUDA
-    thread_local std::vector<cudaStream_t> streams;
+    static thread_local std::vector<cudaStream_t> streams;
     if (streams.size() == 0) {
       streams.resize(NUM_CUDA_STREAMS);
       for (i32 i = 0; i < NUM_CUDA_STREAMS; ++i) {
@@ -540,20 +543,24 @@
     if (dest_allocator->buffers_in_same_block(dest_buffers) &&
         src_allocator->buffers_in_same_block(src_buffers)) {

-      CU_CHECK(cudaMemcpyAsync(dest_buffers[0], src_buffers[0], total_size,
+      CU_CHECK(cudaMemcpy(dest_buffers[0], src_buffers[0], total_size,
+                               cudaMemcpyDefault));
+      /*CU_CHECK(cudaMemcpyAsync(dest_buffers[0], src_buffers[0], total_size,
                                cudaMemcpyDefault, streams[0]));
-      CU_CHECK(cudaStreamSynchronize(streams[0]));
+                               CU_CHECK(cudaStreamSynchronize(streams[0]));*/
     } else {
       i32 n = dest_buffers.size();

       for (i32 i = 0; i < n; ++i) {
-        CU_CHECK(cudaMemcpyAsync(dest_buffers[i], src_buffers[i], sizes[i],
+        CU_CHECK(cudaMemcpy(dest_buffers[i], src_buffers[i], sizes[i],
+                                 cudaMemcpyDefault));
+        /*CU_CHECK(cudaMemcpyAsync(dest_buffers[i], src_buffers[i], sizes[i],
                                  cudaMemcpyDefault,
-                                 streams[i % NUM_CUDA_STREAMS]));
+                                 streams[i % NUM_CUDA_STREAMS]));*/
       }

       for (i32 i = 0; i < std::min(n, NUM_CUDA_STREAMS); ++i) {
-        CU_CHECK(cudaStreamSynchronize(streams[i]));
+        //CU_CHECK(cudaStreamSynchronize(streams[i]));
       }
     }
 #else


Oops.

Oops.

git-svn-id: 28d9401aa571d5108e51b194aae6f24ca5964c06@16028 8cc4aa7f-3514-0410-904f-f2cc9021211c

--- plugins/csparser/csloader.cpp
+++ plugins/csparser/csloader.cpp
@@ -2835,6 +2835,7 @@
 	        AddToRegion (ldr_context, t->QueryObject ());
 	      }
 	    }
+	    break;
 	  }
 	  SyntaxService->ReportError (
 		"crystalspace.maploader.load.plugin", child,


Firmware updater: Disable dictionary flashing menu entry for the time being

--- xs/src/slic3r/GUI/GUI.cpp
+++ xs/src/slic3r/GUI/GUI.cpp
@@ -475,7 +475,8 @@
 	wxWindowID id_base = wxWindow::NewControlId(FirmwareMenuCnt);

 	menu->Append(id_base + FirmwareMenuFlash, _(L("Flash printer firmware")), _(L("Upload a firmware image into a Prusa printer")));
-	menu->Append(id_base + FirmwareMenuDict,  _(L("Flash language file")),    _(L("Upload a language dictionary file into a Prusa printer")));
+	// TODO: for when we're able to flash dictionaries
+	// menu->Append(id_base + FirmwareMenuDict,  _(L("Flash language file")),    _(L("Upload a language dictionary file into a Prusa printer")));

 	menu->Bind(wxEVT_MENU, [id_base](wxEvent &event) {
 		switch (event.GetId() - id_base) {


edit_object_buttons moved to Object/Part Settings

--- xs/src/slic3r/GUI/GUI.cpp
+++ xs/src/slic3r/GUI/GUI.cpp
@@ -1007,6 +1007,8 @@
 	m_optgroups.push_back(optgroup);  // ogObjectSettings

 	auto sizer = new wxBoxSizer(wxVERTICAL);
+	sizer->Add(content_edit_object_buttons(win), 0, wxEXPAND, 0); // *** Edit Object Buttons***
+
 	sizer->Add(optgroup->sizer, 1, wxEXPAND | wxLEFT, 20);

 	auto add_btn = new wxButton(win, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT | wxNO_BORDER);
@@ -1039,9 +1041,6 @@
 			m_objects_ctrl->UnselectAll();
 		g_right_panel->Layout();
 	}));
-
-	// *** Edit Object Buttons***
- 	main_sizer->Add(content_edit_object_buttons(main_page), 0, wxEXPAND, 0);

 	// *** Object/Part Settings ***
 	m_collpane_settings = add_prusa_collapsible_pane(main_page, main_sizer, "Settings:", content_settings);


avoid stdint.h error as best

avoid stdint.h error as best

--- include/vSMC/helper/parallel_tbb.hpp
+++ include/vSMC/helper/parallel_tbb.hpp
@@ -1,8 +1,8 @@
 #ifndef V_SMC_HELPER_PARALLEL_TBB_HPP
 #define V_SMC_HELPER_PARALLEL_TBB_HPP

+#include <vSMC/internal/common.hpp>
 #include <tbb/tbb.h>
-#include <vSMC/internal/common.hpp>

 namespace vSMC {


Add check for overlap count gt. ploidy

Add check for overlap count gt. ploidy

--- combine-msa-vcf/variant_writer.hh
+++ combine-msa-vcf/variant_writer.hh
@@ -23,6 +23,10 @@

 	struct variant_description
 	{
+	protected:
+		struct private_tag {};
+
+	public:
 		// The genotype is stored in a std::vector <bool> here.
 		// A pair of integers could be used instead, though, since
 		// at the moment we only handle unphased VCF files and thus
@@ -36,6 +40,31 @@
 		variant_origin		origin{};
 		bool				is_skipped{};

+	protected:
+		template <typename t_string_1, typename t_string_2>
+		variant_description(
+			std::size_t const position_,
+			t_string_1 &&ref_,
+			t_string_2 &&alt_,
+			std::size_t const ploidy,
+			std::int32_t const overlap_count_,
+			variant_origin const origin_,
+			private_tag const
+		):
+			ref(std::forward <t_string_1>(ref_)),
+			alt(std::forward <t_string_2>(alt_)),
+			genotype(ploidy, false),
+			position(position_),
+			overlap_count(overlap_count_),
+			origin(origin_)
+		{
+			libbio_assert_lte(overlap_count, ploidy);
+			// Assign the GT values.
+			genotype.resize(overlap_count);
+			genotype.resize(ploidy, true);
+		}
+
+	public:
 		variant_description() = default;

 		variant_description(std::size_t const ploidy, std::int32_t const gt_count, variant_origin const origin_):
@@ -57,17 +86,16 @@
 			std::int32_t const overlap_count_,
 			variant_origin const origin_
 		):
-			ref(std::forward <t_string_1>(ref_)),
-			alt(std::forward <t_string_2>(alt_)),
-			genotype(ploidy, false),
-			position(position_),
-			overlap_count(overlap_count_),
-			origin(origin_)
+			variant_description(
+				position_,
+				std::forward <t_string_1>(ref_),
+				std::forward <t_string_2>(alt_),
+				ploidy,
+				(overlap_count_ < 0 ? overlap_count_ : std::min <std::int32_t>(overlap_count_, ploidy)),
+				origin_,
+				private_tag()
+			)
 		{
-			libbio_assert_lte(overlap_count, ploidy);
-			// Assign the GT values.
-			genotype.resize(overlap_count);
-			genotype.resize(ploidy, true);
 		}
 	};


- fixed getting cell id from generator

- fixed getting cell id from generator

git-svn-id: 28d9401aa571d5108e51b194aae6f24ca5964c06@24024 8cc4aa7f-3514-0410-904f-f2cc9021211c

--- plugins/engine/3d/meshgen.cpp
+++ plugins/engine/3d/meshgen.cpp
@@ -515,9 +515,10 @@

 int csMeshGenerator::GetCellId (const csVector2& pos)
 {
+  SetupSampleBox ();
   int cellx = GetCellX (pos.x);
   int cellz = GetCellZ (pos.y);
-  return cellx*cellz;
+  return cellz*cell_dim + cellx;
 }

 size_t csMeshGenerator::CountPositions (int cidx, csMGCell& cell)


support multiple zones correctly

support multiple zones correctly

git-svn-id: c0942edff5350604e2827ab28bdfcfa5200fadee@13461 08b3d480-bf2c-0410-a26f-811ee3361c24

--- plugins/flagStay/flagStay.cpp
+++ plugins/flagStay/flagStay.cpp
@@ -183,19 +183,27 @@
 	if (!flagAbrev)
 		return;

+	std::vector<FlagStayZone*> validZones;
+
 	// check and see if a zone cares about the current flag
 	for ( unsigned int i = 0; i < zoneList.size(); i++ )
 	{
 		if ( zoneList[i].checkFlag(flagAbrev) )
-		{
-			if ( !zoneList[i].pointIn(pos) )	// they have taken the flag out of a zone, pop it.
-			{
-				bz_removePlayerFlag(playerID);
-				if (zoneList[i].message.size())
-					bz_sendTextMessage(BZ_SERVER,playerID,zoneList[i].message.c_str());
-				i = (unsigned int)zoneList.size();	// finish out
-			}
-		}
+			validZones.push_back(&zoneList[i]);
+	}
+
+	bool insideOne = false;
+	for ( unsigned int i = 0; i < validZones.size(); i++ )
+	{
+		if ( validZones[i]->pointIn(pos) )	// they have taken the flag out of a zone, pop it.
+			insideOne = true;
+	}
+
+	if (!insideOne)
+	{
+		bz_removePlayerFlag(playerID);
+		if (zoneList[i].message.size())
+			bz_sendTextMessage(BZ_SERVER,playerID,zoneList[i].message.c_str());
 	}
 }


use the last zone the player was in with the flag for the messages

git-svn-id: c0942edff5350604e2827ab28bdfcfa5200fadee@13463 08b3d480-bf2c-0410-a26f-811ee3361c24

--- plugins/flagStay/flagStay.cpp
+++ plugins/flagStay/flagStay.cpp
@@ -4,6 +4,7 @@
 #include "bzfsAPI.h"
 #include <string>
 #include <vector>
+#include <map>
 #include <math.h>

 BZ_GET_PLUGIN_VERSION
@@ -156,6 +157,8 @@
 	return true;
 }

+std::map<int,int>	playeIDToZoneMap;
+
 void EventHandler::process ( bz_EventData *eventData )
 {
 	float pos[3] = {0};
@@ -177,6 +180,9 @@
 		pos[2] = ((bz_ShotFiredEventData*)eventData)->pos[2];
 		playerID = ((bz_ShotFiredEventData*)eventData)->playerID;
 		break;
+
+	default:
+		return;
 	}

 	const char* flagAbrev = bz_getPlayerFlag(playerID);
@@ -196,13 +202,20 @@
 	for ( unsigned int i = 0; i < validZones.size(); i++ )
 	{
 		if ( validZones[i]->pointIn(pos) )	// they have taken the flag out of a zone, pop it.
+		{
 			insideOne = true;
+			playeIDToZoneMap[playerID] = i;
+		}
 	}

 	if (!insideOne)
 	{
+		int lastZone = -1;
+		if ( playeIDToZoneMap.find(playerID) !=playeIDToZoneMap.end() )
+			lastZone = playeIDToZoneMap[playerID];
+
 		bz_removePlayerFlag(playerID);
-		if (zoneList[i].message.size())
+		if (lastZone != -1 && zoneList[lastZone].message.size())
 			bz_sendTextMessage(BZ_SERVER,playerID,zoneList[i].message.c_str());
 	}
 }


Refactored existing handling of malloc and realloc to add new pages of memory.  Currently, memory pages are fabricated.

--- contracts/eoslib/memory.hpp
+++ contracts/eoslib/memory.hpp
@@ -16,79 +16,73 @@
    *  @{
    */

-   class memory
+   class memory_manager
    {
-      friend void* malloc(uint32_t size);
-      friend void* realloc(void* ptr, uint32_t size);
-      friend void free(void* ptr);
-
+   friend void* malloc(uint32_t size);
+   friend void* realloc(void* ptr, uint32_t size);
+   friend void free(void* ptr);
    public:
-      memory()
-      : _offset(0)
-      {
-         memset(_initial_heap, 0, sizeof(_initial_heap));
+      memory_manager()
+      : _current_heap(0)
+      {
       }

    private:
       void* malloc(uint32_t size)
       {
-         if (_offset + size + SIZE_MARKER > INITIAL_HEAP_SIZE || size == 0)
-            return nullptr;
-
-         buffer_ptr new_buff(&_initial_heap[_offset + SIZE_MARKER], size);
-         _offset += size + SIZE_MARKER;
-         return new_buff.ptr();
-      }
-
-      void* realloc(void* ptr, uint32_t size)
-      {
-         uint32_t orig_ptr_size = 0;
-         const char* const END_OF_BUFFER = _initial_heap + INITIAL_HEAP_SIZE;
-         char* const char_ptr = static_cast<char*>(ptr);
-         if (ptr != nullptr)
-         {
-            buffer_ptr orig_buffer(ptr);
-            if (orig_buffer.size_ptr() >= _initial_heap && ptr < END_OF_BUFFER)
-            {
-               orig_ptr_size = orig_buffer.size();
-               // is the passed in pointer valid
-               char* const orig_buffer_end = orig_buffer.end();
-               if (orig_buffer_end < END_OF_BUFFER)
+         // first pass of loop never has to initialize the slot in _available_heap
+         uint32_t needs_init = 0;
+         char* buffer = nullptr;
+         uint32_t current_heap = _current_heap;
+         for (;current_heap < HEAPS_SIZE; ++current_heap)
+         {
+            memory& current = _available_heaps[current_heap];
+            if(!current.is_init())
+            {
+               char* new_heap = nullptr;
+               if (current_heap == 0)
                {
-                  // is there enough memory to allocate new buffer
-                  if (ptr >= END_OF_BUFFER - size)
-                  {
-                     // not handling in current implementation
-                     return nullptr;
-                  }
-
-                  const int32_t diff = size - orig_ptr_size;
-                  if (diff < 0)
-                  {
-                     memset(orig_buffer_end + diff, 0, -diff);
-                     // if ptr was the last allocated buffer, we can contract
-                     if (orig_buffer_end == &_initial_heap[_offset])
-                     {
-                        _offset += diff;
-                     }
-                     // else current implementation doesn't worry about freeing excess memory
-
-                     return ptr;
-                  }
-                  // if ptr was the last allocated buffer, we can expand
-                  else if (orig_buffer_end == &_initial_heap[_offset])
-                  {
-                     orig_buffer.size(size);
-                     _offset += diff;
-
-                     return ptr;
-                  }
-                  else if (diff == 0)
-                     return ptr;
+                  memset(_initial_heap, 0, sizeof(_initial_heap));
+                  current.init(_initial_heap, INITIAL_HEAP_SIZE);
                }
                else
                {
-                  orig_ptr_size = 0;
+                  // REMOVE logic, just using to test out multiple heap logic till memory can be allocated
+                  char* const new_heap = &_initial_heap[INITIAL_HEAP_SIZE + NEW_HEAP_SIZE * (current_heap - 1)];
+                  _available_heaps[current_heap].init(new_heap, NEW_HEAP_SIZE);
+               }
+            }
+            buffer = current.malloc(size);
+            if (buffer != nullptr)
+               break;
+         }
+
+         // only update the current_heap if memory was allocated
+         if (buffer != nullptr)
+         {
+            _current_heap = current_heap;
+         }
+
+         return buffer;
+      }
+
+      void* realloc(void* ptr, uint32_t size)
+      {
+         char* realloc_ptr = nullptr;
+         uint32_t orig_ptr_size = 0;
+         if (ptr != nullptr)
+         {
+            char* const char_ptr = static_cast<char*>(ptr);
+            for (memory* realloc_heap = _available_heaps; realloc_heap < _available_heaps + HEAPS_SIZE && realloc_heap->is_init(); ++realloc_heap)
+            {
+               if (realloc_heap->is_in_heap(char_ptr))
+               {
+                  realloc_ptr = realloc_heap->realloc_in_place(char_ptr, size, &orig_ptr_size);
+
+                  if (realloc_ptr != nullptr)
+                     return realloc_ptr;
+                  else
+                     break;
                }
             }
          }
@@ -110,56 +104,168 @@
          // currently no-op
       }

-      class buffer_ptr
+      class memory
       {
       public:
-         buffer_ptr(void* ptr)
-         : _ptr(static_cast<char*>(ptr))
-         , _size(*(uint32_t*)(static_cast<char*>(ptr) - SIZE_MARKER))
-         {
-         }
-
-         buffer_ptr(void* ptr, uint32_t buff_size)
-         : _ptr(static_cast<char*>(ptr))
-         {
-            size(buff_size);
-         }
-
-         const void* size_ptr()
-         {
-            return _ptr - SIZE_MARKER;
-         }
-
-         uint32_t size()
-         {
-            return _size;
-         }
-
-         void size(uint32_t val)
-         {
-            *reinterpret_cast<uint32_t*>(_ptr - SIZE_MARKER) = val;
-            _size = val;
-         }
-
-         char* end()
-         {
-            return _ptr + _size;
-         }
-
-         char* ptr()
-         {
-            return _ptr;
-         }
+         memory()
+         : _heap_size(0)
+         , _heap(nullptr)
+         , _offset(0)
+         {
+         }
+
+         void init(char* const mem_heap, uint32_t size)
+         {
+            _heap_size = size;
+            _heap = mem_heap;
+            _offset = 0;
+            memset(_heap, 0, _heap_size);
+         }
+
+         uint32_t is_init() const
+         {
+            return _heap != nullptr;
+         }
+
+         uint32_t is_in_heap(const char* const ptr) const
+         {
+            const char* const END_OF_BUFFER = _heap + _heap_size;
+            const char* const FIRST_PTR_OF_BUFFER = _heap + SIZE_MARKER;
+            return ptr >= FIRST_PTR_OF_BUFFER && ptr < END_OF_BUFFER;
+         }
+
+         uint32_t is_capacity_remaining() const
+         {
+            return _offset + SIZE_MARKER < _heap_size;
+         }
+
+         char* malloc(uint32_t size)
+         {
+            if (_offset + size + SIZE_MARKER > _heap_size || size == 0)
+            {
+               return nullptr;
+            }
+
+            buffer_ptr new_buff(&_heap[_offset + SIZE_MARKER], size);
+            _offset += size + SIZE_MARKER;
+            return new_buff.ptr();
+         }
+
+         char* realloc_in_place(char* const ptr, uint32_t size, uint32_t* orig_ptr_size)
+         {
+            const char* const END_OF_BUFFER = _heap + _heap_size;
+
+            buffer_ptr orig_buffer(ptr);
+            *orig_ptr_size = orig_buffer.size();
+            // is the passed in pointer valid
+            char* const orig_buffer_end = orig_buffer.end();
+            if (orig_buffer_end > END_OF_BUFFER)
+            {
+               *orig_ptr_size = 0;
+               return nullptr;
+            }
+
+            if (ptr > END_OF_BUFFER - size)
+            {
+               // cannot resize in place
+               return nullptr;
+            }
+
+            const int32_t diff = size - *orig_ptr_size;
+            if (diff < 0)
+            {
+               memset(orig_buffer_end + diff, 0, -diff);
+               // if ptr was the last allocated buffer, we can contract
+               if (orig_buffer_end == &_heap[_offset])
+               {
+                  _offset += diff;
+               }
+               // else current implementation doesn't worry about freeing excess memory
+
+               return ptr;
+            }
+            // if ptr was the last allocated buffer, we can expand
+            else if (orig_buffer_end == &_heap[_offset])
+            {
+               orig_buffer.size(size);
+               _offset += diff;
+
+               return ptr;
+            }
+            else if (diff == 0)
+            {
+               return ptr;
+            }
+
+            // could not resize in place
+            return nullptr;
+         }
+
+         void free(char* )
+         {
+            // currently no-op
+         }
+
       private:
-
-         char* const _ptr;
-         uint32_t _size;
+         class buffer_ptr
+         {
+         public:
+            buffer_ptr(void* ptr)
+            : _ptr(static_cast<char*>(ptr))
+            , _size(*(uint32_t*)(static_cast<char*>(ptr) - SIZE_MARKER))
+            {
+            }
+
+            buffer_ptr(void* ptr, uint32_t buff_size)
+            : _ptr(static_cast<char*>(ptr))
+            {
+               size(buff_size);
+            }
+
+            const void* size_ptr()
+            {
+               return _ptr - SIZE_MARKER;
+            }
+
+            uint32_t size()
+            {
+               return _size;
+            }
+
+            void size(uint32_t val)
+            {
+               *reinterpret_cast<uint32_t*>(_ptr - SIZE_MARKER) = val;
+               _size = val;
+            }
+
+            char* end()
+            {
+               return _ptr + _size;
+            }
+
+            char* ptr()
+            {
+               return _ptr;
+            }
+         private:
+
+            char* const _ptr;
+            uint32_t _size;
+         };
+
+         uint32_t _heap_size;
+         char* _heap;
+         uint32_t _offset;
       };

       static const uint32_t SIZE_MARKER = sizeof(uint32_t);
       static const uint32_t INITIAL_HEAP_SIZE = 8192;//32768;
-      char _initial_heap[INITIAL_HEAP_SIZE];
-      uint32_t _offset;
+      static const uint32_t NEW_HEAP_SIZE = 1024; // should be 65536
+      static const uint32_t HEAPS_SIZE = 4; // _initial_heap plus 3 pages (64K each)
+      // should be just INITIAL_HEAP_SIZE, adding extra space for testing multiple buffers
+      char _initial_heap[INITIAL_HEAP_SIZE + NEW_HEAP_SIZE * (HEAPS_SIZE - 1)];
+      memory _available_heaps[HEAPS_SIZE];
+      uint32_t _current_heap;
    } memory_heap;

   /**


(Box::expandBinding) : Refine the input button style.

git-svn-id: 86dbb1b73ea755ce8c9767cb3be66408d68bb34f@1899 d15c3b8f-5b43-0410-be93-4d5a55ce2954

--- css/Box.cpp
+++ css/Box.cpp
@@ -337,7 +337,7 @@
         if (div && text) {
             div.appendChild(text);
             css::CSSStyleDeclaration divStyle = div.getStyle();
-            divStyle.setCssText(u"float: left; border-style: outset; border-width: thin; height: 1.2em");
+            divStyle.setCssText(u"float: left; border-style: outset; border-width: thin; height: 1.2em; padding: 0 0.5em");
             CSSStyleDeclarationImp* imp = dynamic_cast<CSSStyleDeclarationImp*>(divStyle.self());
             if (imp) {
                 imp->specify(style);


normal mode: ~600Hz out

normal mode: ~600Hz out

--- koala_buzzer/sw/Buzzer.hpp
+++ koala_buzzer/sw/Buzzer.hpp
@@ -6,20 +6,21 @@
 {
   Buzzer()
   {
-    // phase correct PWM
-    TCCR0A |= _BV(WGM00);
+    // normal mode
+    TCCR0A |= 0u;
+    // clear on compare
+    TCCR0A |= _BV(COM0B0);
     //TCCR0B |= _BV(WGM02);
-    // 01 PWM
-    TCCR0A |= _BV(COM0B1);
-    // frequency ~1kHz
-    OCR0B = 20;
+    // volume 0-255
+    OCR0B = 100;
     // output mode
     DDRB |= _BV(PB1);
   }

   void on()
   {
-    TCCR0B |= _BV(CS00); // prescaler = 1
+    // ~586 [Hz]
+    TCCR0B |= _BV(CS01); // prescaler = 8
   }

   void off()


More memory leak stuffing in llsechandler_basic

--- indra/newview/llsechandler_basic.cpp
+++ indra/newview/llsechandler_basic.cpp
@@ -207,6 +207,7 @@
 			}
 		}

+		BASIC_CONSTRAINTS_free( bs );
 	}
 	return result;
 }
@@ -268,6 +269,8 @@
 				ASN1_OBJECT_free(usage);
 			}
 		}
+
+		EXTENDED_KEY_USAGE_free( eku );
 	}
 	return result;
 }
@@ -280,6 +283,8 @@
 	if(skeyid)
 	{
 		result = cert_string_from_octet_string(skeyid);
+
+		ASN1_OCTET_STRING_free( skeyid );
 	}
 	return result;
 }
@@ -300,6 +305,9 @@
 		{
 			result[CERT_AUTHORITY_KEY_IDENTIFIER_SERIAL] = cert_string_from_asn1_integer(akeyid->serial);
 		}
+
+
+		AUTHORITY_KEYID_free( akeyid );
 	}

 	// we ignore the issuer name in the authority key identifier, we check the issue name via


trivial whitespace change...

trivial whitespace change...

--- indra/newview/lltoastnotifypanel.cpp
+++ indra/newview/lltoastnotifypanel.cpp
@@ -200,7 +200,7 @@
 			if(h_pad < 2*HPAD)
 			{
 				/*
-				 * Probably it is  a scriptdialog toast
+				 * Probably it is a scriptdialog toast
 				 * for a scriptdialog toast h_pad can be < 2*HPAD if we have a lot of buttons.
 				 * In last case set default h_pad to avoid heaping of buttons
 				 */


Fix ETH transaction details in ETH operations

--- core/src/wallet/ethereum/database/EthereumLikeTransactionDatabaseHelper.cpp
+++ core/src/wallet/ethereum/database/EthereumLikeTransactionDatabaseHelper.cpp
@@ -81,8 +81,8 @@
             tx.gasLimit = BigInt::fromHex(row.get<std::string>(6));
             tx.gasUsed = BigInt::fromHex(row.get<std::string>(7));

-            tx.receiver = row.get<std::string>(8);
-            tx.sender = row.get<std::string>(9);
+            tx.sender = row.get<std::string>(8);
+            tx.receiver = row.get<std::string>(9);

             tx.confirmations = get_number<uint64_t>(row, 10);
             tx.status = get_number<uint64_t>(row, 11);


smp: introduce distributed::local()

smp: introduce distributed::local()

--- core/smp.hh
+++ core/smp.hh
@@ -79,6 +79,9 @@
                 }, std::move(args));
             });
     }
+
+    // Returns reference to the local instance.
+    Service& local();
 };

 template <typename Service>
@@ -131,6 +134,9 @@
     });
 }

+template <typename Service>
+Service& distributed<Service>::local() {
+    return *_instances[engine.cpu_id()];
 }

 #endif /* SMP_HH_ */


Fix build with current kdelibs

Fix build with current kdelibs

svn path=/trunk/kdepim/; revision=133170

--- kpilot/kpilot/logWidget.cc
+++ kpilot/kpilot/logWidget.cc
@@ -192,7 +192,7 @@

 	if ((i >= 0) && (i <= 100))
 	{
-		fProgress->setProgress(i);
+		fProgress->setValue(i);
 	}
 }

@@ -318,6 +318,9 @@
 }

 // $Log$
+// Revision 1.12  2002/01/21 23:58:55  aseigo
+// KProgress updates
+//
 // Revision 1.11  2001/12/31 14:41:06  harald
 // Make it compile
 //


Lower linalg.indexed_generic with libcall to LLVM.

PiperOrigin-RevId: 283328994
Change-Id: Icc5e580fac279f76d55d715d3d4a83d97f481670

--- third_party/mlir/lib/Conversion/LinalgToLLVM/LinalgToLLVM.cpp
+++ third_party/mlir/lib/Conversion/LinalgToLLVM/LinalgToLLVM.cpp
@@ -340,6 +340,28 @@
   }
 };

+template <typename LinalgOp>
+static SmallVector<Type, 4> ExtractOperandTypes(Operation *op) {
+  return SmallVector<Type, 4>{op->getOperandTypes()};
+}
+
+template <>
+SmallVector<Type, 4> ExtractOperandTypes<IndexedGenericOp>(Operation *op) {
+  auto ctx = op->getContext();
+  auto indexedGenericOp = cast<IndexedGenericOp>(op);
+  auto numLoops = indexedGenericOp.getNumLoops();
+
+  SmallVector<Type, 4> result;
+  result.reserve(numLoops + op->getNumOperands());
+  for (unsigned i = 0; i < numLoops; ++i) {
+    result.push_back(IndexType::get(ctx));
+  }
+  for (auto type : op->getOperandTypes()) {
+    result.push_back(type);
+  }
+  return result;
+}
+
 // Get a SymbolRefAttr containing the library function name for the LinalgOp.
 // If the library function does not exist, insert a declaration.
 template <typename LinalgOp>
@@ -359,7 +381,7 @@
     return fnNameAttr;
   }

-  SmallVector<Type, 4> inputTypes(op->getOperandTypes());
+  SmallVector<Type, 4> inputTypes(ExtractOperandTypes<LinalgOp>(op));
   assert(op->getNumResults() == 0 &&
          "Library call for linalg operation can be generated only for ops that "
          "have void return types");
@@ -427,6 +449,40 @@
     rewriter.replaceOpWithNewOp<mlir::CallOp>(op, libraryCallName.getValue(),
                                               ArrayRef<Type>{}, operands);
     return matchSuccess();
+  }
+};
+
+/// Conversion pattern specialization for IndexedGenericOp.
+template <>
+class LinalgOpConversion<IndexedGenericOp>
+    : public OpRewritePattern<IndexedGenericOp> {
+public:
+  using OpRewritePattern<IndexedGenericOp>::OpRewritePattern;
+
+  PatternMatchResult matchAndRewrite(IndexedGenericOp op,
+                                     PatternRewriter &rewriter) const override {
+    auto libraryCallName =
+        getLibraryCallSymbolRef<IndexedGenericOp>(op, rewriter);
+    if (!libraryCallName)
+      return this->matchFailure();
+
+    // TODO(pifon, ntv): Use induction variables values instead of zeros, when
+    // IndexedGenericOp is tiled.
+    auto zero = rewriter.create<mlir::ConstantOp>(
+        op.getLoc(), rewriter.getIntegerAttr(rewriter.getIndexType(), 0));
+    auto indexedGenericOp = cast<IndexedGenericOp>(op);
+    auto numLoops = indexedGenericOp.getNumLoops();
+    SmallVector<Value *, 4> operands;
+    operands.reserve(numLoops + op.getNumOperands());
+    for (unsigned i = 0; i < numLoops; ++i) {
+      operands.push_back(zero);
+    }
+    for (auto operand : op.getOperands()) {
+      operands.push_back(operand);
+    }
+    rewriter.replaceOpWithNewOp<mlir::CallOp>(op, libraryCallName.getValue(),
+                                              ArrayRef<Type>{}, operands);
+    return this->matchSuccess();
   }
 };


Adding exception handling for task errors

--- UWPOpenIGTLink/Content/IGTLinkClient.cxx
+++ UWPOpenIGTLink/Content/IGTLinkClient.cxx
@@ -126,6 +126,16 @@
       create_task([this]()
       {
         DataReceiverPump(m_receiverPumpTokenSource.get_token());
+      }).then([this](task<void> previousTask)
+      {
+        try
+        {
+          previousTask.wait();
+        }
+        catch (const std::exception& e)
+        {
+          OutputDebugStringA((std::string("DataReceiverPump crash: ") + e.what()).c_str());
+        }
       });

       return true;


Instalacion Voip mejorada

Instalacion Voip mejorada

--- project/simulation.cc
+++ project/simulation.cc
@@ -93,13 +93,13 @@

   // Instalacion de aplicacion VoIP
   uint16_t port = 9;
-  PacketSinkHelper sink ("ns3::UdpSocketFactory", Address (InetSocketAddress (Ipv4Address::GetAny (), port)));
-  ApplicationContainer app = sink.Install (p2pNodes.Get (0));
+  PacketSinkHelper sink ("ns3::UdpSocketFactory", Address (InetSocketAddress (p2pInterfaces.GetAddress (0), port))); //sumidero udp en el nodo p2p para todo lo que vaya a su ip y a ese puerto
+  ApplicationContainer sinkapp = sink.Install (p2pNodes.Get (0));

   G711Generator VoIPapp;
-  VoIPapp.SetRemote("ns3::UdpSocketFactory",serverAddress);
+  VoIPapp.SetRemote("ns3::UdpSocketFactory", p2pInterfaces.GetAddress (0), port); //aplicacion Voip que envia a la ip del nodo p2p y por un puerto.
   for(uint32_t i = 0 ; i < nVoip ; i++)
-    nodes.Get(i)->AddApplication(&VoIPapp);
+    VoipNodes.Get(i)->AddApplication(&VoIPapp);

   VoIPapp.Start (Seconds (1.0));
   VoIPapp.Stop (Seconds (10.0));
@@ -108,45 +108,11 @@

-  //*********************************************************************************************************************

-  // Dos dispositivos de red
-  Ptr<PointToPointNetDevice> dispTx = CreateObject<PointToPointNetDevice> ();
-  Ptr<PointToPointNetDevice> dispRx = CreateObject<PointToPointNetDevice> ();
-  // Un canal punto a punto
-  Ptr<PointToPointChannel> canal = CreateObject<PointToPointChannel> ();;
-  // Una aplicación transmisora
-  BitAlternanteTx transmisor(dispRx, Time("10ms"), 2048);
-  // Y una receptora
-  BitAlternanteRx receptor(dispTx);
-
-  // Montamos el escenario:
-  // Añadimos una cola a cada dispositivo
-  dispTx->SetQueue (CreateObject<DropTailQueue> ());
-  dispRx->SetQueue (CreateObject<DropTailQueue> ());
-  // Añadimos cada dispositivo a su nodo
-  nodoTx->AddDevice (dispTx);
-  nodoRx->AddDevice (dispRx);
-  // Añadimos cada aplicación a su nodo
-  nodoTx->AddApplication(&transmisor);
-  nodoRx->AddApplication(&receptor);
-  // Asociamos los dos dispositivos al canal
-  dispTx->Attach (canal);
-  dispRx->Attach (canal);
-
-  // Modificamos los parámetos configurables
-  canal->SetAttribute ("Delay", StringValue ("2ms"));
-  dispTx->SetAttribute ("DataRate", StringValue ("5Mbps"));
-
-  // Activamos el transmisor
-  transmisor.SetStartTime (Seconds (1.0));
-  transmisor.SetStopTime (Seconds (10.0));

   NS_LOG_UNCOND ("Voy a simular");
   Simulator::Run ();
   Simulator::Destroy ();

-  NS_LOG_UNCOND ("Total paquetes: " << transmisor.TotalDatos());
-
   return 0;
 }


type: avoid KeySet cast

type: avoid KeySet cast

--- src/plugins/type/type.cpp
+++ src/plugins/type/type.cpp
@@ -45,6 +45,7 @@
 		setError (key, errorKey);
 		ret = 0;
 	}
+
 	k.release ();
 	return ret;
 }
@@ -82,15 +83,17 @@

 int elektraTypeSet (ckdb::Plugin * handle, ckdb::KeySet * returned, ckdb::Key * parentKey)
 {
-	/* set all keys */
+	int ret = 1;

-	if (!TC::get (handle)->check (reinterpret_cast<kdb::KeySet &> (returned)))
+	kdb::KeySet ks (returned); // reinterpret_cast<kdb::KeySet &> (returned)
+	if (!TC::get (handle)->check (ks))
 	{
 		setError (ksCurrent (returned), parentKey);
-		return -1;
+		ret = -1;
 	}

-	return 1; /* success */
+	ks.release ();
+	return ret;
 }

 ckdb::Plugin * ELEKTRA_PLUGIN_EXPORT (type)


Update API to include baro altitude.

Update API to include baro altitude.

--- src/modules/fw_att_pos_estimator/fw_att_pos_estimator_main.cpp
+++ src/modules/fw_att_pos_estimator/fw_att_pos_estimator_main.cpp
@@ -400,6 +400,7 @@
 	fuseHgtData = false;
 	fuseMagData = false;
 	fuseVtasData = false;
+	statesInitialised = false;

 	/* wakeup source(s) */
 	struct pollfd fds[2];
@@ -577,7 +578,7 @@
 			if (baro_updated) {
 				orb_copy(ORB_ID(sensor_baro), _baro_sub, &_baro);

-				/* XXX leverage baro */
+				baroHgt = _baro.altitude;
 			}

 			bool gps_updated;
@@ -601,6 +602,7 @@
 					if (hrt_elapsed_time(&start_time) > 500000 && !_initialized) {
 						InitialiseFilter();
 						_initialized = true;
+
 						warnx("init done.");
 						continue;
 					}


Fix memory leak.

Fix memory leak.

--- Vendors/lepton/src/ExpressionProgram.cpp
+++ Vendors/lepton/src/ExpressionProgram.cpp
@@ -64,6 +64,8 @@
 ExpressionProgram& ExpressionProgram::operator=(const ExpressionProgram& program) {
     maxArgs = program.maxArgs;
     stackSize = program.stackSize;
+    for(auto& op : operations)
+        delete op;
     operations.resize(program.operations.size());
     for (int i = 0; i < (int) operations.size(); i++)
         operations[i] = program.operations[i]->clone();


- now that I need a local APIC and an I/O APIC, I made a base class   bx_generic_apic_c which both kinds can inherit from.  This makes it   type-safe to have pointers to either kind, and they can share some code   for ID setting and such.  Lots of functions are virtual so that you   get the right function even if called on a generic pointer.  Many methods   of the base class are just bx_panics. - you can read and write lots of the local APIC registers, even the ones   I don't use or know what to do with. - now the BX_CPU_C class has its own INTR line, which it uses to detect   interrupts.  This allows the local APIC to interrupt just one CPU. - apic_index array is now an array of bx_generic_apic_c pointers   (either local apics or I/O apics) - read method that handles wierd byte and word reads - added some real interrupt code (trigger_irq, untrigger_irq, acknowledge_int,   an irr[] register) and it sort of works now.

--- cpu/apic.cc
+++ cpu/apic.cc
@@ -2,121 +2,256 @@
 #include "bochs.h"
 #include <assert.h>

-BX_CPU_C *apic_index[APIC_MAX_ID];
-
-bx_apic_c::bx_apic_c(BX_CPU_C *mycpu)
+bx_generic_apic_c *apic_index[APIC_MAX_ID];
+
+bx_generic_apic_c::bx_generic_apic_c ()
+{
+}
+
+bx_generic_apic_c::~bx_generic_apic_c ()
+{
+}
+
+void bx_generic_apic_c::init ()
 {
   id = APIC_UNKNOWN_ID;
-  cpu = mycpu;
-  // default address for a local APIC, can be moved
-  apic_base_msr = 0xfee00000;
-  err_status = 0;
-}
-
-bx_apic_c::~bx_apic_c(void)
-{
-  // nothing for now
-}
-
-Bit32u bx_apic_c::get_base (void)
-{
-  return apic_base_msr;
-}
-
-void bx_apic_c::set_id (Bit8u newid) {
+}
+
+void bx_generic_apic_c::set_base (Bit32u newbase)
+{
+  bx_printf ("relocate APIC id=%d to %8x\n", id, newbase);
+  base_addr = newbase;
+}
+
+void bx_generic_apic_c::set_id (Bit8u newid) {
   // update apic_index
   if (id != APIC_UNKNOWN_ID) {
     bx_assert (id < APIC_MAX_ID);
-    if (apic_index[id] != cpu)
-      bx_panic ("inconsistent APIC id table");
+    if (apic_index[id] != this)
+      bx_panic ("inconsistent APIC id table\n");
     apic_index[id] = NULL;
   }
   id = newid;
   if (apic_index[id] != NULL)
-    bx_panic ("duplicate APIC id assigned");
-  apic_index[id] = cpu;
+    bx_panic ("duplicate APIC id assigned\n");
+  apic_index[id] = this;
+}
+
+char *
+bx_generic_apic_c::get_name () {
+  bx_panic ("get_name called on bx_generic_apic_c base class");
+}
+
+Boolean
+bx_generic_apic_c::is_selected (Bit32u addr, Bit32u len)
+{
+  if ((addr & ~0xfff) == get_base ()) {
+    if ((addr & 0xf != 0) || (len != 4))
+      bx_printf ("warning: misaligned or wrong-size APIC write\n");
+    return true;
+  }
+  return false;
+}
+
+void
+bx_generic_apic_c::read (Bit32u addr, void *data, unsigned len)
+{
+  if ((addr & ~0xf) != ((addr+len-1) & ~0xf))
+    bx_panic ("APIC read spans 32-bit boundary\n");
+  Bit32u value;
+  read_aligned (addr, &value, 4);
+  if ((addr&3) == 0) {
+    *((Bit32u *)data) = value;
+    return;
+  }
+  // handle partial word read
+  Bit8u bytes[4];
+  bytes[0] = value & 0xff;
+  bytes[1] = (value >> 8) & 0xff;
+  bytes[2] = (value >> 16) & 0xff;
+  bytes[3] = (value >> 24) & 0xff;
+  Bit8u *p1 = bytes+(addr&3);
+  Bit8u *p2 = (Bit8u *)data;
+  for (int i=0; i<len; i++) {
+    bx_printf ("apic: Copying byte %02x\n", (unsigned int) *p1);
+    *p2++ = *p1++;
+  }
+}
+
+void bx_generic_apic_c::read_aligned (Bit32u address, Bit32u *data, unsigned len)
+{
+  bx_panic ("read_aligned not implemented in base class bx_generic_apic_c\n");
+}
+
+void bx_generic_apic_c::write(Bit32u address, Bit32u *value, unsigned len)
+{
+  bx_panic ("write not implemented in base class bx_generic_apic_c\n");
+}
+
+void bx_generic_apic_c::startup_msg (Bit32u vector)
+{
+  bx_panic ("startup message sent to an I/O APIC\n");
+}
+
+void bx_generic_apic_c::trigger_irq (unsigned num, unsigned from)
+{
+  bx_panic ("trigger_irq called on base class\n");
+}
+
+void bx_generic_apic_c::untrigger_irq (unsigned num, unsigned from)
+{
+  bx_panic ("untrigger_irq called on base class");
+}
+
+bx_local_apic_c::bx_local_apic_c(BX_CPU_C *mycpu)
+{
+  cpu = mycpu;
+}
+
+void
+bx_local_apic_c::init ()
+{
+  // default address for a local APIC, can be moved
+  bx_generic_apic_c::init ();
+  base_addr = 0xfee00000;
+  err_status = 0;
+}
+
+BX_CPU_C
+bx_local_apic_c::*get_cpu (Bit8u id)
+{
+  bx_assert (id < APIC_MAX_ID);
+}
+
+bx_local_apic_c::~bx_local_apic_c(void)
+{
+  // nothing for now
+}
+
+void bx_local_apic_c::set_id (Bit8u newid) {
+  bx_generic_apic_c::set_id (newid);
   sprintf (cpu->name, "CPU apicid=%02x", (Bit32u)id);
 }

-void bx_apic_c::set_base (Bit32u newbase)
-{
-  bx_printf ("relocate APIC to %8x\n", newbase);
-  apic_base_msr = newbase;
-}
-
-void bx_apic_c::write_handler (Bit32u addr, Bit32u *data, unsigned len)
+char *
+bx_local_apic_c::get_name()
+{
+  return cpu->name;
+}
+
+void bx_local_apic_c::write (Bit32u addr, Bit32u *data, unsigned len)
 {
   assert (len == 4);
   bx_printf ("write %08x to APIC address %08x\n", *data, addr);
   //assert (!(addr & 0xf));
-  switch (addr & 0xff0) {
-  case 0x20: // local APIC id
-    id = ((*data)>>24) & 0xf;
-    break;
-  case 0x30: // local APIC version
-    bx_printf ("warning: write to read-only APIC register\n");
-    break;
-  case 0x80: // task priority
-  case 0x90: // arbitration priority
-  case 0xa0: // processor priority
-  case 0xb0: // EOI
-  case 0xd0: // logical destination
-  case 0xe0: // destination format
-  case 0xf0: // spurious interrupt vector
-    break;
-  case 0x280: // error status reg
-    // Here's what the IA-devguide-3 says on p.7-45:
-    // The ESR is a read/write register and is reset after being written to by
-    // the processor. A write to the ESR must be done just prior to reading the
-    // ESR to allow the register to be updated.
-    // This doesn't seem clear.  If the write clears the register, then
-    // wouldn't you always read zero?  Otherwise, what does the write do?
-    // In my model, the write will do nothing.
-    break;
-  case 0x300: // interrupt command reg 0-31
-    {
-      icr_low = *data & ~(1<<12);  // force delivery status bit = 0 (idle)
-      // and trigger an interrupt to be sent
-      int dest_shorthand = (icr_low >> 18) & 3;
-      char *dests[4] = {NULL, "self", "all including self", "all except self" };
-      char buf[32];
-      unsigned int target_id = (icr_high >> 24);
-      sprintf (buf, "APIC 0x%02x\n", target_id);
-      bx_printf ("APIC 0x%02x sending interrupt to destination %s",
-	 id,
-	 (dest_shorthand==0) ? buf : dests[dest_shorthand]);
-      bx_printf ("low word of APIC 0x%02x ICR = 0x%04x\n", id, icr_low & 0xffff);
-      int delivery_mode = (icr_low >> 8) & 7;
-      int vector = (icr_low & 0xff);
-      if (delivery_mode == 6 && dest_shorthand == 0) {
-	// tell target to start up
-	if (target_id > APIC_MAX_ID) bx_panic ("target apic id out of range");
-	BX_CPU_C *target = apic_index[target_id];
-	if (target == NULL) bx_panic ("apic target id not found");
-	target->local_apic.startup_msg (vector);
-      } else {
-	  bx_printf ("APIC operation not supported");
+  addr &= 0xff0;
+  switch (addr) {
+    case 0x20: // local APIC id
+      id = ((*data)>>24) & 0xf;
+      break;
+    case 0x80: // task priority
+      tpr = *data & ~0xff;  // low 8 bits reserved.
+      break;
+    case 0xb0: // EOI
+      // not readable
+      bx_printf ("%s: Wrote 0x%04x to EOI\n", cpu->name);
+      break;
+    case 0xd0: // logical destination
+      log_dest = *data;
+      break;
+    case 0xe0: // destination format
+      dest_format = (dest_format & 0x0fffffff) | (*data & 0xf0000000);
+      break;
+    case 0xf0: // spurious interrupt vector
+      spurious_vec = (spurious_vec & 0x0f) | (*data & 0x3f0);
+      break;
+    case 0x280: // error status reg
+      // Here's what the IA-devguide-3 says on p.7-45:
+      // The ESR is a read/write register and is reset after being written to by
+      // the processor. A write to the ESR must be done just prior to reading the
+      // ESR to allow the register to be updated.
+      //
+      // This doesn't seem clear.  If the write clears the register, then
+      // wouldn't you always read zero?  Otherwise, what does the write do?
+      // In my model, the write will do nothing.
+      break;
+    case 0x300: // interrupt command reg 0-31
+      {
+	icr_low = *data & ~(1<<12);  // force delivery status bit = 0 (idle)
+	// and trigger an interrupt to be sent
+	int dest_shorthand = (icr_low >> 18) & 3;
+	char *dests[4] = {NULL, "self", "all including self", "all except self" };
+	char buf[32];
+	unsigned int target_id = (icr_high >> 24);
+	sprintf (buf, "APIC 0x%02x\n", target_id);
+	bx_printf ("APIC 0x%02x sending interrupt to destination %s",
+	   id,
+	   (dest_shorthand==0) ? buf : dests[dest_shorthand]);
+	bx_printf ("low word of APIC 0x%02x ICR = 0x%04x\n", id, icr_low & 0xffff);
+	int delivery_mode = (icr_low >> 8) & 7;
+	int vector = (icr_low & 0xff);
+	if (delivery_mode == 6 && dest_shorthand == 0) {
+	  // tell target to start up
+	  if (target_id > APIC_MAX_ID) bx_panic ("target apic id out of range\n");
+	  bx_generic_apic_c *target = apic_index[target_id];
+	  if (target == NULL) bx_panic ("apic target id not found\n");
+	  target->startup_msg (vector);
+	} else {
+	    bx_printf ("APIC operation not supported\n");
+	}
       }
-    }
-    break;
-  case 0x310: // interrupt command reg 31-63
-    icr_high = *data & 0xff000000;
-    break;
-  case 0x320: // LVT Timer Reg
-  case 0x330: // LVT Thermal Monitor
-  case 0x340: // LVT Performance Counter
-  case 0x350: // LVT LINT0 Reg
-  case 0x360: // LVT Lint1 Reg
-  case 0x370: // LVT Error Reg
-  case 0x380: // initial count for timer
-  case 0x390: // current count for timer
-  case 0x3e0: // timer divide configuration
-  default:
-    bx_printf ("APIC register %08x not implemented\n", addr);
-  }
-}
-
-void bx_apic_c::startup_msg (Bit32u vector)
+      break;
+    case 0x310: // interrupt command reg 31-63
+      icr_high = *data & 0xff000000;
+      break;
+    case 0x320: // LVT Timer Reg
+      lvt_timer = *data;  //?
+      break;
+    case 0x330: // LVT Thermal Monitor
+      lvt_thermal = *data;  //?
+      break;
+    case 0x340: // LVT Performance Counter
+      lvt_perf = *data;  //?
+      break;
+    case 0x350: // LVT LINT0 Reg
+      lvt_lint0 = *data;  //?
+      break;
+    case 0x360: // LVT Lint1 Reg
+      lvt_lint1 = *data;  //?
+      break;
+    case 0x370: // LVT Error Reg
+      lvt_err = *data;  //?
+      break;
+    case 0x380: // initial count for timer
+      timer_initial = *data;
+      break;
+    case 0x3e0: // timer divide configuration
+      timer_divide = *data;
+      break;
+    /* all read-only registers go here */
+    case 0x30: // local APIC version
+    case 0x90: // arbitration priority
+    case 0xa0: // processor priority
+    // ISRs not writable
+    case 0x100: case 0x110: case 0x120: case 0x130:
+    case 0x140: case 0x150: case 0x160: case 0x170:
+    // TMRs not writable
+    case 0x180: case 0x190: case 0x1a0: case 0x1b0:
+    case 0x1c0: case 0x1d0: case 0x1e0: case 0x1f0:
+    // IRRs not writable
+    case 0x200: case 0x210: case 0x220: case 0x230:
+    case 0x240: case 0x250: case 0x260: case 0x270:
+      // current count for timer
+    case 0x390:
+      // all read-only registers should fall into this line
+      bx_printf ("warning: write to read-only APIC register 0x%02x\n", addr);
+      break;
+    default:
+      bx_panic ("APIC register %08x not implemented\n", addr);
+  }
+}
+
+void bx_local_apic_c::startup_msg (Bit32u vector)
 {
   if (cpu->debug_trap & 0x80000000) {
     cpu->debug_trap &= ~0x80000000;
@@ -128,51 +263,119 @@
   }
 }

-void bx_apic_c::read_handler (Bit32u addr, Bit32u *data, unsigned len)
+void bx_local_apic_c::read_aligned (Bit32u addr, Bit32u *data, unsigned len)
 {
   assert (len == 4);
   *data = 0;  // default value for unimplemented registers
   switch (addr & 0xff0) {
   case 0x20: // local APIC id
-    *data = (id) << 24;
+    *data = (id) << 24; break;
+  case 0x30: // local APIC version
+    *data = 0x00170011; break;
+  case 0x80: // task priority
+    *data = tpr; break;
+  case 0x90: // arbitration priority
+    *data = arb_priority; break;
+  case 0xa0: // processor priority
+    *data = proc_priority; break;
+  case 0xb0: // EOI
+    bx_panic ("EOI register not writable\n");
     break;
-  case 0x30: // local APIC version
-    *data = 0x00170011;
-    break;
-  case 0x80: // task priority
-  case 0x90: // arbitration priority
-  case 0xa0: // processor priority
-  case 0xb0: // EOI
   case 0xd0: // logical destination
+    *data = log_dest; break;
   case 0xe0: // destination format
+    *data = dest_format; break;
   case 0xf0: // spurious interrupt vector
+    *data = spurious_vec; break;
+  // ISRs not writable
+  case 0x100: case 0x110: case 0x120: case 0x130:
+  case 0x140: case 0x150: case 0x160: case 0x170:
+  case 0x180: case 0x190: case 0x1a0: case 0x1b0:
+  case 0x1c0: case 0x1d0: case 0x1e0: case 0x1f0:
+  case 0x200: case 0x210: case 0x220: case 0x230:
+  case 0x240: case 0x250: case 0x260: case 0x270:
+    *data = 0;
+    bx_printf ("reading ISR,TMR,IRR not implemented");
     break;
   case 0x280: // error status reg
-    *data = err_status;
-    break;
+    *data = err_status; break;
   case 0x300: // interrupt command reg 0-31
-    *data = icr_low;
-    break;
+    *data = icr_low; break;
   case 0x310: // interrupt command reg 31-63
-    *data = icr_high;
-    break;
+    *data = icr_high; break;
   case 0x320: // LVT Timer Reg
+    *data = lvt_timer; break;
   case 0x330: // LVT Thermal Monitor
+    *data = lvt_thermal; break;
   case 0x340: // LVT Performance Counter
+    *data = lvt_perf; break;
   case 0x350: // LVT LINT0 Reg
+    *data = lvt_lint0; break;
   case 0x360: // LVT Lint1 Reg
+    *data = lvt_lint1; break;
   case 0x370: // LVT Error Reg
+    *data = lvt_err; break;
   case 0x380: // initial count for timer
+    *data = timer_initial; break;
   case 0x390: // current count for timer
+    *data = timer_current; break;
   case 0x3e0: // timer divide configuration
+    *data = timer_divide; break;
   default:
     bx_printf ("APIC register %08x not implemented\n", addr);
   }
   bx_printf ("read from APIC address %08x = %08x\n", addr, *data);
 }

-BX_CPU_C
-bx_apic_c::*get_cpu (Bit8u id)
-{
-  bx_assert (id < APIC_MAX_ID);
-}
+int
+bx_local_apic_c::highest_priority_int (Bit8u *array)
+{
+  for (int i=0; i<BX_LOCAL_APIC_MAX_INTS; i++)
+    if (array[i]) return i;
+  return -1;
+}
+
+void bx_local_apic_c::service_local_apic ()
+{
+  if (cpu->INTR) return;  // INTR already up; do nothing
+  // find first interrupt in irr.
+  int first_int = highest_priority_int (irr);
+  if (first_int < 0) return;   // no interrupts, leave INTR=0
+  // interrupt has appeared in irr.  raise INTR.  When the CPU
+  // acknowledges, we will run highest_priority_int again and
+  // return it.
+  cpu->set_INTR (1);
+}
+
+void bx_local_apic_c::trigger_irq (unsigned vector, unsigned from)
+{
+  bx_printf ("Local apic on %s: trigger interrupt %d\n", cpu->name, vector);
+  irr[vector] = 1;
+  service_local_apic ();
+}
+
+void bx_local_apic_c::untrigger_irq (unsigned vector, unsigned from)
+{
+  bx_printf ("Local apic on %s: untrigger interrupt %d\n", cpu->name, vector);
+  // hardware says "no more".  clear the bit.  If the CPU hasn't yet
+  // acknowledged the interrupt, it will never be serviced.
+  bx_assert (irr[vector] == 1);
+  irr[vector] = 0;
+}
+
+Bit8u
+bx_local_apic_c::acknowledge_int ()
+{
+  // CPU calls this when it is ready to service one interrupt
+  if (!cpu->INTR)
+    bx_panic ("%s acknowledged an interrupt, but INTR=0\n", cpu->name);
+  int vector = highest_priority_int (irr);
+  bx_assert (irr[vector] == 1);
+  // currently isr never gets cleared, so no point
+  //bx_assert (isr[vector] == 0);
+  irr[vector] = 0;
+  isr[vector] = 1;
+  cpu->INTR = 0;
+  service_local_apic ();  // will set INTR again if another is ready
+  return vector;
+}