<commit_before>#include "chainerx/context.h"

#include <dlfcn.h>

#include <algorithm>
#include <atomic>
#include <cstdlib>
#include <mutex>
#include <string>
#include <utility>
#include <vector>

#include <gsl/gsl>
#include <nonstd/optional.hpp>

#ifdef CHAINERX_ENABLE_CUDA
#include "chainerx/cuda/cuda_backend.h"
#endif  // CHAINERX_ENABLE_CUDA
#include "chainerx/error.h"
#include "chainerx/macro.h"
#include "chainerx/native/native_backend.h"
#include "chainerx/thread_local_state.h"

namespace chainerx {
namespace {

std::atomic<Context*> g_global_default_context{nullptr};

std::string GetChainerxPath() {
    char* chainerx_path = std::getenv("CHAINERX_PATH");
    if (chainerx_path != nullptr) {
        return chainerx_path;
    }

    char* home_path = std::getenv("HOME");
    if (home_path == nullptr) {
        throw ChainerxError{"ChainerX path is not defined. Set either CHAINERX_PATH or HOME."};
    }
    return std::string(home_path) + "/.chainerx";
}

}  // namespace

Context::Context() {
    // Register the default backprop ID
    static constexpr const char* kDefaultBackpropName = "<default>";
    MakeBackpropId(kDefaultBackpropName);
}

Context::~Context() {
    // Need to call dtor of all backends before closing shared objects
    backends_.clear();
    for (void* handle : dlopen_handles_) {
        ::dlclose(handle);
    }
}

native::NativeBackend& Context::GetNativeBackend() {
    Backend& backend = GetBackend(native::NativeBackend::kDefaultName);
    return static_cast<native::NativeBackend&>(backend);  // NOLINT
}

Backend& Context::GetBackend(const std::string& backend_name) {
    {
        std::lock_guard<std::mutex> lock{mutex_};
        auto it = backends_.find(backend_name);
        if (it != backends_.end()) {
            return *it->second;
        }
    }

    // Ctor of each backend may call member functions of Context.
    // Lock is released here to avoid any deadlocks.
    std::unique_ptr<Backend, context_detail::BackendDeleter> backend;
    if (backend_name == native::NativeBackend::kDefaultName) {
        backend = std::unique_ptr<Backend, context_detail::BackendDeleter>{
                new native::NativeBackend{*this}, context_detail::BackendDeleter{[](Backend* ptr) { delete ptr; }}};
#ifdef CHAINERX_ENABLE_CUDA
    } else if (backend_name == cuda::CudaBackend::kDefaultName) {
        backend = std::unique_ptr<Backend, context_detail::BackendDeleter>{
                new cuda::CudaBackend{*this}, context_detail::BackendDeleter{[](Backend* ptr) { delete ptr; }}};
#endif  // CHAINERX_ENABLE_CUDA
    } else {
        // Load .so file
        std::string so_file_path = GetChainerxPath() + "/backends/" + backend_name + ".so";
        void* handle = ::dlopen(so_file_path.c_str(), RTLD_NOW | RTLD_LOCAL);
        if (handle == nullptr) {
            throw BackendError{"Backend not found: '", backend_name, "'"};
        }
        {
            std::lock_guard<std::mutex> lock{mutex_};
            dlopen_handles_.push_back(handle);
        }

        // Create backend
        void* ptr_create_backend = ::dlsym(handle, "CreateBackend");
        void* ptr_destroy_backend = ::dlsym(handle, "DestroyBackend");
        // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
        auto create_backend = reinterpret_cast<Backend* (*)(Context&)>(ptr_create_backend);
        // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
        auto destroy_backend = reinterpret_cast<void (*)(Backend*)>(ptr_destroy_backend);
        if (create_backend == nullptr) {
            throw BackendError{"Invalid backend plugin: CreateBackend is not found in '", so_file_path, "'."};
        }
        if (destroy_backend == nullptr) {
            throw BackendError{"Invalid backend plugin: DestroyBackend is not found in '", so_file_path, "'."};
        }
        backend = std::unique_ptr<Backend, context_detail::BackendDeleter>{create_backend(*this),
                                                                           context_detail::BackendDeleter{destroy_backend}};
    }

    {
        // In a multi-threaded case, backends_[backend_name] may already exist at this point.
        // In that case, the backend created above is thrown away.
        std::lock_guard<std::mutex> lock{mutex_};
        auto pair = backends_.emplace(backend_name, std::move(backend));
        return *pair.first->second;
    }
}

Device& Context::GetDevice(const DeviceId& device_id) {
    Backend& backend = GetBackend(device_id.backend_name());
    return backend.GetDevice(device_id.index());
}

BackpropId Context::MakeBackpropId(std::string backprop_name) {
    // Create new backprop ID
    std::lock_guard<std::mutex> lock{mutex_};
    backprop_set_.emplace_back(next_backprop_ordinal_, std::move(backprop_name));
    return BackpropId{*this, next_backprop_ordinal_++};
}

void Context::ReleaseBackpropId(const BackpropId& backprop_id) {
    CheckValidBackpropId(backprop_id);

    if (backprop_id.ordinal() == 0) {
        throw ChainerxError{"The default backprop ID cannot be released."};
    }

    ReleaseBackpropIdNoExcept(backprop_id);
}

void Context::ReleaseBackpropIdNoExcept(const BackpropId& backprop_id) noexcept {
    std::lock_guard<std::mutex> lock{mutex_};
    BackpropSetItem* item = GetBackpropSetItem(backprop_id.ordinal());
    if (item == nullptr) {
        return;
    }

    // Remove the connection pairs involving the backprop ID
    backprop_connections_.erase(
            std::remove_if(
                    backprop_connections_.begin(),
                    backprop_connections_.end(),
                    [ordinal = backprop_id.ordinal()](const std::pair<BackpropOrdinal, BackpropOrdinal>& pair) {
                        return pair.first == ordinal || pair.second == ordinal;
                    }),
            backprop_connections_.end());

    // Remove the backprop ID.
    backprop_set_.erase(
            std::find_if(backprop_set_.begin(), backprop_set_.end(), [ordinal = backprop_id.ordinal()](const BackpropSetItem& item) {
                return item.ordinal == ordinal;
            }));
}

void Context::CheckValidBackpropId(const BackpropId& backprop_id) const {
    if (&backprop_id.context() != this) {
        throw ChainerxError{"Invalid context in backprop ID: ", backprop_id};
    }

    const BackpropSetItem* item{nullptr};
    {
        std::lock_guard<std::mutex> lock{mutex_};
        item = GetBackpropSetItem(backprop_id.ordinal());
    }
    if (item == nullptr) {
        throw ChainerxError{"Invalid backprop ID, maybe already expired: ", backprop_id};
    }
}

void Context::ConnectBackpropIds(const BackpropId& backprop_id1, const BackpropId& backprop_id2) {
    CHAINERX_ASSERT(&backprop_id1.context() == this);
    CHAINERX_ASSERT(&backprop_id2.context() == this);
    if (backprop_id1 == backprop_id2) {
        // They are identical
        return;
    }

    std::lock_guard<std::mutex> lock{mutex_};

    BackpropSetItem* item1 = GetBackpropSetItem(backprop_id1.ordinal());
    BackpropSetItem* item2 = GetBackpropSetItem(backprop_id2.ordinal());
    if (item1 == nullptr || item2 == nullptr) {
        // At least one cannot be found
        return;
    }

    std::pair<BackpropOrdinal, BackpropOrdinal> pair = std::minmax(backprop_id1.ordinal(), backprop_id2.ordinal());
    if (backprop_connections_.end() != std::find(backprop_connections_.begin(), backprop_connections_.end(), pair)) {
        // Already in connection
        return;
    }

    // Add a new connection
    backprop_connections_.emplace_back(pair);
}

std::string Context::GetBackpropName(const BackpropId& backprop_id) {
    // Note: backprop name cannot be returned by reference, as the reference may be invalidated when a new graph is pushed to the backprop
    // set.
    std::string name{};
    {
        std::lock_guard<std::mutex> lock{mutex_};
        BackpropSetItem* item = GetBackpropSetItem(backprop_id.ordinal());
        if (item == nullptr) {
            throw ChainerxError{"Backprop not found in the context. Ordinal:", backprop_id.ordinal()};
        }
        name = item->name;
    }
    return name;
}

void Context::CheckBackpropAllowed(const BackpropId& backprop_id) {
    nonstd::optional<BackpropOrdinal> prohibiting_ordinal{nonstd::nullopt};
    {
        std::lock_guard<std::mutex> lock{mutex_};
        BackpropSetItem* item = GetBackpropSetItem(backprop_id.ordinal());
        if (item == nullptr) {
            throw ChainerxError{"Backprop ID not found: ", backprop_id};
        }
        prohibiting_ordinal = item->prohibiting_ordinal;
    }
    if (prohibiting_ordinal.has_value()) {
        throw ChainerxError{"Cannot backward for backprop ID '",
                            backprop_id,
                            "' because an connected backprop ID '",
                            BackpropId{*this, *prohibiting_ordinal},
                            "' which has been created earlier, has already been backpropped."};
    }
}

void Context::SetBackpropDone(const BackpropId& backprop_id) {
#if CHAINERX_DEBUG
    {
        std::lock_guard<std::mutex> lock{mutex_};
        BackpropSetItem* item = GetBackpropSetItem(backprop_id.ordinal());
        CHAINERX_ASSERT(item != nullptr);
    }
#endif  // CHAINERX_DEBUG

    std::lock_guard<std::mutex> lock{mutex_};

    // Find connected backprop IDs
    std::vector<BackpropOrdinal> ordinals_to_prohibit;
    for (const std::pair<BackpropOrdinal, BackpropOrdinal>& pair : backprop_connections_) {
        if (pair.first == backprop_id.ordinal()) {
            ordinals_to_prohibit.emplace_back(pair.second);
        }
    }

    // Mark connected backprop IDs as prohibited.
    for (BackpropOrdinal ord : ordinals_to_prohibit) {
        BackpropSetItem* item2 = GetBackpropSetItem(ord);
        if (!item2->prohibiting_ordinal.has_value()) {
            item2->prohibiting_ordinal = backprop_id.ordinal();
        }
    }
}

std::vector<BackpropId> Context::GetInnerBackpropIds(const BackpropId& backprop_id) {
    std::vector<BackpropId> inner_backprop_ids;
    {
        std::lock_guard<std::mutex> lock{mutex_};
        inner_backprop_ids.reserve(backprop_set_.size());
        for (const std::pair<BackpropOrdinal, BackpropOrdinal>& pair : backprop_connections_) {
            if (pair.first == backprop_id.ordinal()) {
                inner_backprop_ids.emplace_back(BackpropId{*this, pair.second});
            }
        }
    }
    return inner_backprop_ids;
}

template <typename ThisPtr, typename ReturnType>
ReturnType Context::GetBackpropSetItemImpl(ThisPtr this_ptr, BackpropOrdinal ordinal) {
    // using reverse iterator because it's more likely to find earlier
    auto it = std::find_if(this_ptr->backprop_set_.rbegin(), this_ptr->backprop_set_.rend(), [ordinal](const BackpropSetItem& item) {
        return item.ordinal == ordinal;
    });
    if (it == this_ptr->backprop_set_.rend()) {
        return nullptr;
    }
    return &*it;
}

Context& GetGlobalDefaultContext() {
    Context* context = g_global_default_context;
    if (context == nullptr) {
        throw ContextError{"Global default context is not set."};
    }
    return *context;
}

void SetGlobalDefaultContext(Context* context) { g_global_default_context = context; }

namespace internal {

Context* GetDefaultContextNoExcept() noexcept { return internal::GetInternalThreadLocalState().default_context; }

}  // namespace internal

Context& GetDefaultContext() {
    Context* default_context = internal::GetInternalThreadLocalState().default_context;
    if (default_context == nullptr) {
        return GetGlobalDefaultContext();
    }
    return *default_context;
}

void SetDefaultContext(Context* context) {
    Context*& default_context = internal::GetInternalThreadLocalState().default_context;
    if (default_context != context) {
        default_context = context;
        SetDefaultDevice(nullptr);
    }
}

}  // namespace chainerx
<commit_msg>Avoid unnecessary temporary<commit_after>#include "chainerx/context.h"

#include <dlfcn.h>

#include <algorithm>
#include <atomic>
#include <cstdlib>
#include <mutex>
#include <string>
#include <utility>
#include <vector>

#include <gsl/gsl>
#include <nonstd/optional.hpp>

#ifdef CHAINERX_ENABLE_CUDA
#include "chainerx/cuda/cuda_backend.h"
#endif  // CHAINERX_ENABLE_CUDA
#include "chainerx/error.h"
#include "chainerx/macro.h"
#include "chainerx/native/native_backend.h"
#include "chainerx/thread_local_state.h"

namespace chainerx {
namespace {

std::atomic<Context*> g_global_default_context{nullptr};

std::string GetChainerxPath() {
    char* chainerx_path = std::getenv("CHAINERX_PATH");
    if (chainerx_path != nullptr) {
        return chainerx_path;
    }

    char* home_path = std::getenv("HOME");
    if (home_path == nullptr) {
        throw ChainerxError{"ChainerX path is not defined. Set either CHAINERX_PATH or HOME."};
    }
    return std::string(home_path) + "/.chainerx";
}

}  // namespace

Context::Context() {
    // Register the default backprop ID
    static constexpr const char* kDefaultBackpropName = "<default>";
    MakeBackpropId(kDefaultBackpropName);
}

Context::~Context() {
    // Need to call dtor of all backends before closing shared objects
    backends_.clear();
    for (void* handle : dlopen_handles_) {
        ::dlclose(handle);
    }
}

native::NativeBackend& Context::GetNativeBackend() {
    Backend& backend = GetBackend(native::NativeBackend::kDefaultName);
    return static_cast<native::NativeBackend&>(backend);  // NOLINT
}

Backend& Context::GetBackend(const std::string& backend_name) {
    {
        std::lock_guard<std::mutex> lock{mutex_};
        auto it = backends_.find(backend_name);
        if (it != backends_.end()) {
            return *it->second;
        }
    }

    // Ctor of each backend may call member functions of Context.
    // Lock is released here to avoid any deadlocks.
    std::unique_ptr<Backend, context_detail::BackendDeleter> backend;
    if (backend_name == native::NativeBackend::kDefaultName) {
        backend = std::unique_ptr<Backend, context_detail::BackendDeleter>{
                new native::NativeBackend{*this}, context_detail::BackendDeleter{[](Backend* ptr) { delete ptr; }}};
#ifdef CHAINERX_ENABLE_CUDA
    } else if (backend_name == cuda::CudaBackend::kDefaultName) {
        backend = std::unique_ptr<Backend, context_detail::BackendDeleter>{
                new cuda::CudaBackend{*this}, context_detail::BackendDeleter{[](Backend* ptr) { delete ptr; }}};
#endif  // CHAINERX_ENABLE_CUDA
    } else {
        // Load .so file
        std::string so_file_path = GetChainerxPath() + "/backends/" + backend_name + ".so";
        void* handle = ::dlopen(so_file_path.c_str(), RTLD_NOW | RTLD_LOCAL);
        if (handle == nullptr) {
            throw BackendError{"Backend not found: '", backend_name, "'"};
        }
        {
            std::lock_guard<std::mutex> lock{mutex_};
            dlopen_handles_.push_back(handle);
        }

        // Create backend
        void* ptr_create_backend = ::dlsym(handle, "CreateBackend");
        void* ptr_destroy_backend = ::dlsym(handle, "DestroyBackend");
        // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
        auto create_backend = reinterpret_cast<Backend* (*)(Context&)>(ptr_create_backend);
        // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
        auto destroy_backend = reinterpret_cast<void (*)(Backend*)>(ptr_destroy_backend);
        if (create_backend == nullptr) {
            throw BackendError{"Invalid backend plugin: CreateBackend is not found in '", so_file_path, "'."};
        }
        if (destroy_backend == nullptr) {
            throw BackendError{"Invalid backend plugin: DestroyBackend is not found in '", so_file_path, "'."};
        }
        backend = std::unique_ptr<Backend, context_detail::BackendDeleter>{create_backend(*this),
                                                                           context_detail::BackendDeleter{destroy_backend}};
    }

    {
        // In a multi-threaded case, backends_[backend_name] may already exist at this point.
        // In that case, the backend created above is thrown away.
        std::lock_guard<std::mutex> lock{mutex_};
        auto pair = backends_.emplace(backend_name, std::move(backend));
        return *pair.first->second;
    }
}

Device& Context::GetDevice(const DeviceId& device_id) {
    Backend& backend = GetBackend(device_id.backend_name());
    return backend.GetDevice(device_id.index());
}

BackpropId Context::MakeBackpropId(std::string backprop_name) {
    // Create new backprop ID
    std::lock_guard<std::mutex> lock{mutex_};
    backprop_set_.emplace_back(next_backprop_ordinal_, std::move(backprop_name));
    return BackpropId{*this, next_backprop_ordinal_++};
}

void Context::ReleaseBackpropId(const BackpropId& backprop_id) {
    CheckValidBackpropId(backprop_id);

    if (backprop_id.ordinal() == 0) {
        throw ChainerxError{"The default backprop ID cannot be released."};
    }

    ReleaseBackpropIdNoExcept(backprop_id);
}

void Context::ReleaseBackpropIdNoExcept(const BackpropId& backprop_id) noexcept {
    std::lock_guard<std::mutex> lock{mutex_};
    BackpropSetItem* item = GetBackpropSetItem(backprop_id.ordinal());
    if (item == nullptr) {
        return;
    }

    // Remove the connection pairs involving the backprop ID
    backprop_connections_.erase(
            std::remove_if(
                    backprop_connections_.begin(),
                    backprop_connections_.end(),
                    [ordinal = backprop_id.ordinal()](const std::pair<BackpropOrdinal, BackpropOrdinal>& pair) {
                        return pair.first == ordinal || pair.second == ordinal;
                    }),
            backprop_connections_.end());

    // Remove the backprop ID.
    backprop_set_.erase(
            std::find_if(backprop_set_.begin(), backprop_set_.end(), [ordinal = backprop_id.ordinal()](const BackpropSetItem& item) {
                return item.ordinal == ordinal;
            }));
}

void Context::CheckValidBackpropId(const BackpropId& backprop_id) const {
    if (&backprop_id.context() != this) {
        throw ChainerxError{"Invalid context in backprop ID: ", backprop_id};
    }

    const BackpropSetItem* item{nullptr};
    {
        std::lock_guard<std::mutex> lock{mutex_};
        item = GetBackpropSetItem(backprop_id.ordinal());
    }
    if (item == nullptr) {
        throw ChainerxError{"Invalid backprop ID, maybe already expired: ", backprop_id};
    }
}

void Context::ConnectBackpropIds(const BackpropId& backprop_id1, const BackpropId& backprop_id2) {
    CHAINERX_ASSERT(&backprop_id1.context() == this);
    CHAINERX_ASSERT(&backprop_id2.context() == this);
    if (backprop_id1 == backprop_id2) {
        // They are identical
        return;
    }

    std::lock_guard<std::mutex> lock{mutex_};

    BackpropSetItem* item1 = GetBackpropSetItem(backprop_id1.ordinal());
    BackpropSetItem* item2 = GetBackpropSetItem(backprop_id2.ordinal());
    if (item1 == nullptr || item2 == nullptr) {
        // At least one cannot be found
        return;
    }

    std::pair<BackpropOrdinal, BackpropOrdinal> pair = std::minmax(backprop_id1.ordinal(), backprop_id2.ordinal());
    if (backprop_connections_.end() != std::find(backprop_connections_.begin(), backprop_connections_.end(), pair)) {
        // Already in connection
        return;
    }

    // Add a new connection
    backprop_connections_.emplace_back(pair);
}

std::string Context::GetBackpropName(const BackpropId& backprop_id) {
    // Note: backprop name cannot be returned by reference, as the reference may be invalidated when a new graph is pushed to the backprop
    // set.
    std::lock_guard<std::mutex> lock{mutex_};
    BackpropSetItem* item = GetBackpropSetItem(backprop_id.ordinal());
    if (item == nullptr) {
        throw ChainerxError{"Backprop not found in the context. Ordinal:", backprop_id.ordinal()};
    }
    return item->name;
}

void Context::CheckBackpropAllowed(const BackpropId& backprop_id) {
    nonstd::optional<BackpropOrdinal> prohibiting_ordinal{nonstd::nullopt};
    {
        std::lock_guard<std::mutex> lock{mutex_};
        BackpropSetItem* item = GetBackpropSetItem(backprop_id.ordinal());
        if (item == nullptr) {
            throw ChainerxError{"Backprop ID not found: ", backprop_id};
        }
        prohibiting_ordinal = item->prohibiting_ordinal;
    }
    if (prohibiting_ordinal.has_value()) {
        throw ChainerxError{"Cannot backward for backprop ID '",
                            backprop_id,
                            "' because an connected backprop ID '",
                            BackpropId{*this, *prohibiting_ordinal},
                            "' which has been created earlier, has already been backpropped."};
    }
}

void Context::SetBackpropDone(const BackpropId& backprop_id) {
#if CHAINERX_DEBUG
    {
        std::lock_guard<std::mutex> lock{mutex_};
        BackpropSetItem* item = GetBackpropSetItem(backprop_id.ordinal());
        CHAINERX_ASSERT(item != nullptr);
    }
#endif  // CHAINERX_DEBUG

    std::lock_guard<std::mutex> lock{mutex_};

    // Find connected backprop IDs
    std::vector<BackpropOrdinal> ordinals_to_prohibit;
    for (const std::pair<BackpropOrdinal, BackpropOrdinal>& pair : backprop_connections_) {
        if (pair.first == backprop_id.ordinal()) {
            ordinals_to_prohibit.emplace_back(pair.second);
        }
    }

    // Mark connected backprop IDs as prohibited.
    for (BackpropOrdinal ord : ordinals_to_prohibit) {
        BackpropSetItem* item2 = GetBackpropSetItem(ord);
        if (!item2->prohibiting_ordinal.has_value()) {
            item2->prohibiting_ordinal = backprop_id.ordinal();
        }
    }
}

std::vector<BackpropId> Context::GetInnerBackpropIds(const BackpropId& backprop_id) {
    std::vector<BackpropId> inner_backprop_ids;
    {
        std::lock_guard<std::mutex> lock{mutex_};
        inner_backprop_ids.reserve(backprop_set_.size());
        for (const std::pair<BackpropOrdinal, BackpropOrdinal>& pair : backprop_connections_) {
            if (pair.first == backprop_id.ordinal()) {
                inner_backprop_ids.emplace_back(BackpropId{*this, pair.second});
            }
        }
    }
    return inner_backprop_ids;
}

template <typename ThisPtr, typename ReturnType>
ReturnType Context::GetBackpropSetItemImpl(ThisPtr this_ptr, BackpropOrdinal ordinal) {
    // using reverse iterator because it's more likely to find earlier
    auto it = std::find_if(this_ptr->backprop_set_.rbegin(), this_ptr->backprop_set_.rend(), [ordinal](const BackpropSetItem& item) {
        return item.ordinal == ordinal;
    });
    if (it == this_ptr->backprop_set_.rend()) {
        return nullptr;
    }
    return &*it;
}

Context& GetGlobalDefaultContext() {
    Context* context = g_global_default_context;
    if (context == nullptr) {
        throw ContextError{"Global default context is not set."};
    }
    return *context;
}

void SetGlobalDefaultContext(Context* context) { g_global_default_context = context; }

namespace internal {

Context* GetDefaultContextNoExcept() noexcept { return internal::GetInternalThreadLocalState().default_context; }

}  // namespace internal

Context& GetDefaultContext() {
    Context* default_context = internal::GetInternalThreadLocalState().default_context;
    if (default_context == nullptr) {
        return GetGlobalDefaultContext();
    }
    return *default_context;
}

void SetDefaultContext(Context* context) {
    Context*& default_context = internal::GetInternalThreadLocalState().default_context;
    if (default_context != context) {
        default_context = context;
        SetDefaultDevice(nullptr);
    }
}

}  // namespace chainerx
<|endoftext|>


<commit_before>#include "itkWin32Header.h"
#include <iostream>
#include <fstream>
#include "itkNumericTraits.h"
#include "itkImage.h"
#include "itkImageFileReader.h"
#include "itkImageFileWriter.h"
#include "itkRescaleIntensityImageFilter.h"
#include "itkExtractImageFilter.h"
#include "itkDifferenceImageFilter.h"

using namespace std;

#define ITK_TEST_DIMENSION_MAX 6

int RegressionTestImage (const char *, const char *, int, bool);

int main(int argc, char **argv)
{
  if(argc < 3)
    {
    cerr << "Usage:" << endl;
    cerr << "testImage, baselineImage1, [baselineImage2, baselineImage3, ...]" << endl;
    cerr << "Note that if you supply more than one baselineImage, this test will pass if any" << endl;
    cerr << "of them match the testImage" << endl;
    return -1;
    }
  int bestBaselineStatus = 2001;
  int bestBaseline = 2;
  try
    {
    if(argc == 3)
      {
      bestBaselineStatus = RegressionTestImage(argv[1], argv[2], 0, false);
      }
    else
      {
      for(int i=2;i<argc;i++)
        {
        const int currentStatus = RegressionTestImage(argv[1], argv[i], 0, false);
        if(currentStatus < bestBaselineStatus)
          {
          bestBaselineStatus = currentStatus;
          bestBaseline = i;
          }
        if(bestBaselineStatus == 0)
          {
          break;
          }
        }
      }
    // generate images of our closest match
    if(bestBaselineStatus == 0)
      {
      RegressionTestImage(argv[1], argv[bestBaseline], 1, false);
      }
    else
      {
      RegressionTestImage(argv[1], argv[bestBaseline], 1, true);
      }

    }
  catch(const itk::ExceptionObject& e)
    {
    std::cerr << "ITK test driver caught an ITK exception:\n";
    std::cerr << e.GetFile() << ":" << e.GetLine() << ":\n"
              << e.GetDescription() << "\n";
    bestBaselineStatus = -1;
    }
  catch(const std::exception& e)
    {
    std::cerr << "ITK test driver caught an exception:\n";
    std::cerr << e.what() << "\n";
    bestBaselineStatus = -1;
    }
  catch(...)
    {
    std::cerr << "ITK test driver caught an unknown exception!!!\n";
    bestBaselineStatus = -1;
    }
  cout << bestBaselineStatus << endl;
  return bestBaselineStatus;
}

// Regression Testing Code
int RegressionTestImage (const char *testImageFilename, const char *baselineImageFilename,
                         int reportErrors, bool differences)
{
  // Use the factory mechanism to read the test and baseline files and convert them to double
  typedef itk::Image<double,ITK_TEST_DIMENSION_MAX> ImageType;
  typedef itk::Image<unsigned char,ITK_TEST_DIMENSION_MAX> OutputType;
  typedef itk::Image<unsigned char,2> DiffOutputType;
  typedef itk::ImageFileReader<ImageType> ReaderType;

  // Read the baseline file
  ReaderType::Pointer baselineReader = ReaderType::New();
    baselineReader->SetFileName(baselineImageFilename);
  try
    {
    baselineReader->UpdateLargestPossibleRegion();
    }
  catch (itk::ExceptionObject& e)
    {
    std::cerr << "Exception detected while reading " << baselineImageFilename << " : "  << e.GetDescription();
    return 1000;
    }

  // Read the file generated by the test
  ReaderType::Pointer testReader = ReaderType::New();
    testReader->SetFileName(testImageFilename);
  try
    {
    testReader->UpdateLargestPossibleRegion();
    }
  catch (itk::ExceptionObject& e)
    {
    std::cerr << "Exception detected while reading " << testImageFilename << " : "  << e.GetDescription() << std::endl;
    return 1000;
    }

  // The sizes of the baseline and test image must match
  ImageType::SizeType baselineSize;
    baselineSize = baselineReader->GetOutput()->GetLargestPossibleRegion().GetSize();
  ImageType::SizeType testSize;
    testSize = testReader->GetOutput()->GetLargestPossibleRegion().GetSize();

  if (baselineSize != testSize)
    {
    std::cerr << "The size of the Baseline image and Test image do not match!" << std::endl;
    std::cerr << "Baseline image: " << baselineImageFilename
              << " has size " << baselineSize << std::endl;
    std::cerr << "Test image:     " << testImageFilename
              << " has size " << testSize << std::endl;
    return 1;
    }

  // Now compare the two images
  typedef itk::DifferenceImageFilter<ImageType,ImageType> DiffType;
  DiffType::Pointer diff = DiffType::New();
    diff->SetValidInput(baselineReader->GetOutput());
    diff->SetTestInput(testReader->GetOutput());
    diff->SetDifferenceThreshold(2.0);
    diff->UpdateLargestPossibleRegion();

  double status = diff->GetTotalDifference();

  if (reportErrors)
    {
    typedef itk::RescaleIntensityImageFilter<ImageType,OutputType> RescaleType;
    typedef itk::ExtractImageFilter<OutputType,DiffOutputType> ExtractType;
    typedef itk::ImageFileWriter<DiffOutputType> WriterType;
    typedef itk::ImageRegion<ITK_TEST_DIMENSION_MAX> RegionType;
    OutputType::IndexType index; index.Fill(0);
    OutputType::SizeType size; size.Fill(0);

    RescaleType::Pointer rescale = RescaleType::New();
      rescale->SetOutputMinimum(itk::NumericTraits<unsigned char>::NonpositiveMin());
      rescale->SetOutputMaximum(itk::NumericTraits<unsigned char>::max());
      rescale->SetInput(diff->GetOutput());
      rescale->UpdateLargestPossibleRegion();

    RegionType region;
    region.SetIndex(index);

    size = rescale->GetOutput()->GetLargestPossibleRegion().GetSize();
    for (unsigned int i = 2; i < ITK_TEST_DIMENSION_MAX; i++)
      {
      size[i] = 0;
      }
    region.SetSize(size);

    ExtractType::Pointer extract = ExtractType::New();
      extract->SetInput(rescale->GetOutput());
      extract->SetExtractionRegion(region);

    WriterType::Pointer writer = WriterType::New();
      writer->SetInput(extract->GetOutput());
    if(differences)
      {
      // if there are discrepencies, create an diff image
      std::cout << "<DartMeasurement name=\"ImageError\" type=\"numeric/double\">";
      std::cout << status;
      std::cout <<  "</DartMeasurement>" << std::endl;

      ::itk::OStringStream diffName;
        diffName << testImageFilename << ".diff.png";
      try
        {
        rescale->SetInput(diff->GetOutput());
        rescale->Update();
        }
      catch (...)
        {
        std::cerr << "Error during rescale of " << diffName.str() << std::endl;
        }
      writer->SetFileName(diffName.str().c_str());
      try
        {
        writer->Update();
        }
      catch (...)
        {
        std::cerr << "Error during write of " << diffName.str() << std::endl;
        }

      std::cout << "<DartMeasurementFile name=\"DifferenceImage\" type=\"image/png\">";
      std::cout << diffName.str();
      std::cout << "</DartMeasurementFile>" << std::endl;
      }
    ::itk::OStringStream baseName;
    baseName << testImageFilename << ".base.png";
    try
      {
      rescale->SetInput(baselineReader->GetOutput());
      rescale->Update();
      }
    catch (...)
      {
      std::cerr << "Error during rescale of " << baseName.str() << std::endl;
      }
    try
      {
      writer->SetFileName(baseName.str().c_str());
      writer->Update();
      }
    catch (...)
      {
      std::cerr << "Error during write of " << baseName.str() << std::endl;
      }

    std::cout << "<DartMeasurementFile name=\"BaselineImage\" type=\"image/png\">";
    std::cout << baseName.str();
    std::cout << "</DartMeasurementFile>" << std::endl;

    ::itk::OStringStream testName;
    testName << testImageFilename << ".test.png";
    try
      {
      rescale->SetInput(testReader->GetOutput());
      rescale->Update();
      }
    catch (...)
      {
      std::cerr << "Error during rescale of " << testName.str()
                << std::endl;
      }
    try
      {
      writer->SetFileName(testName.str().c_str());
      writer->Update();
      }
    catch (...)
      {
      std::cerr << "Error during write of " << testName.str() << std::endl;
      }

    std::cout << "<DartMeasurementFile name=\"TestImage\" type=\"image/png\">";
    std::cout << testName.str();
    std::cout << "</DartMeasurementFile>" << std::endl;

    }
  return (status != 0) ? 1 : 0;
}
<commit_msg>STYLE: minor style<commit_after>/*=========================================================================

  Program:   Insight Segmentation & Registration Toolkit
  Module:    ImageCompare.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) Insight Software Consortium. All rights reserved.
  See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/
#include "itkNumericTraits.h"
#include "itkImage.h"
#include "itkImageFileReader.h"
#include "itkImageFileWriter.h"
#include "itkRescaleIntensityImageFilter.h"
#include "itkExtractImageFilter.h"
#include "itkDifferenceImageFilter.h"

#include <iostream>
#include <fstream>

#define ITK_TEST_DIMENSION_MAX 6

int RegressionTestImage (const char *, const char *, int, bool);

int main(int argc, char **argv)
{
  if(argc < 3)
    {
    std::cerr << "Usage:" << std::endl;
    std::cerr << "testImage, baselineImage1, [baselineImage2, baselineImage3, ...]" << std::endl;
    std::cerr << "Note that if you supply more than one baselineImage, this test will pass if any" << std::endl;
    std::cerr << "of them match the testImage" << std::endl;
    return -1;
    }
  int bestBaselineStatus = 2001;
  int bestBaseline = 2;
  try
    {
    if(argc == 3)
      {
      bestBaselineStatus = RegressionTestImage(argv[1], argv[2], 0, false);
      }
    else
      {
      for(int i=2;i<argc;i++)
        {
        const int currentStatus = RegressionTestImage(argv[1], argv[i], 0, false);
        if(currentStatus < bestBaselineStatus)
          {
          bestBaselineStatus = currentStatus;
          bestBaseline = i;
          }
        if(bestBaselineStatus == 0)
          {
          break;
          }
        }
      }
    // generate images of our closest match
    if(bestBaselineStatus == 0)
      {
      RegressionTestImage(argv[1], argv[bestBaseline], 1, false);
      }
    else
      {
      RegressionTestImage(argv[1], argv[bestBaseline], 1, true);
      }

    }
  catch(const itk::ExceptionObject& e)
    {
    std::cerr << "ITK test driver caught an ITK exception:\n";
    std::cerr << e.GetFile() << ":" << e.GetLine() << ":\n"
              << e.GetDescription() << "\n";
    bestBaselineStatus = -1;
    }
  catch(const std::exception& e)
    {
    std::cerr << "ITK test driver caught an exception:\n";
    std::cerr << e.what() << "\n";
    bestBaselineStatus = -1;
    }
  catch(...)
    {
    std::cerr << "ITK test driver caught an unknown exception!!!\n";
    bestBaselineStatus = -1;
    }
  std::cout << bestBaselineStatus << std::endl;
  return bestBaselineStatus;
}

// Regression Testing Code
int RegressionTestImage (const char *testImageFilename, const char *baselineImageFilename,
                         int reportErrors, bool differences)
{
  // Use the factory mechanism to read the test and baseline files and convert them to double
  typedef itk::Image<double,ITK_TEST_DIMENSION_MAX> ImageType;
  typedef itk::Image<unsigned char,ITK_TEST_DIMENSION_MAX> OutputType;
  typedef itk::Image<unsigned char,2> DiffOutputType;
  typedef itk::ImageFileReader<ImageType> ReaderType;

  // Read the baseline file
  ReaderType::Pointer baselineReader = ReaderType::New();
    baselineReader->SetFileName(baselineImageFilename);
  try
    {
    baselineReader->UpdateLargestPossibleRegion();
    }
  catch (itk::ExceptionObject& e)
    {
    std::cerr << "Exception detected while reading " << baselineImageFilename << " : "  << e.GetDescription();
    return 1000;
    }

  // Read the file generated by the test
  ReaderType::Pointer testReader = ReaderType::New();
    testReader->SetFileName(testImageFilename);
  try
    {
    testReader->UpdateLargestPossibleRegion();
    }
  catch (itk::ExceptionObject& e)
    {
    std::cerr << "Exception detected while reading " << testImageFilename << " : "  << e.GetDescription() << std::endl;
    return 1000;
    }

  // The sizes of the baseline and test image must match
  ImageType::SizeType baselineSize;
    baselineSize = baselineReader->GetOutput()->GetLargestPossibleRegion().GetSize();
  ImageType::SizeType testSize;
    testSize = testReader->GetOutput()->GetLargestPossibleRegion().GetSize();

  if (baselineSize != testSize)
    {
    std::cerr << "The size of the Baseline image and Test image do not match!" << std::endl;
    std::cerr << "Baseline image: " << baselineImageFilename
              << " has size " << baselineSize << std::endl;
    std::cerr << "Test image:     " << testImageFilename
              << " has size " << testSize << std::endl;
    return 1;
    }

  // Now compare the two images
  typedef itk::DifferenceImageFilter<ImageType,ImageType> DiffType;
  DiffType::Pointer diff = DiffType::New();
    diff->SetValidInput(baselineReader->GetOutput());
    diff->SetTestInput(testReader->GetOutput());
    diff->SetDifferenceThreshold(2.0);
    diff->UpdateLargestPossibleRegion();

  double status = diff->GetTotalDifference();

  if (reportErrors)
    {
    typedef itk::RescaleIntensityImageFilter<ImageType,OutputType> RescaleType;
    typedef itk::ExtractImageFilter<OutputType,DiffOutputType> ExtractType;
    typedef itk::ImageFileWriter<DiffOutputType> WriterType;
    typedef itk::ImageRegion<ITK_TEST_DIMENSION_MAX> RegionType;
    OutputType::IndexType index; index.Fill(0);
    OutputType::SizeType size; size.Fill(0);

    RescaleType::Pointer rescale = RescaleType::New();
      rescale->SetOutputMinimum(itk::NumericTraits<unsigned char>::NonpositiveMin());
      rescale->SetOutputMaximum(itk::NumericTraits<unsigned char>::max());
      rescale->SetInput(diff->GetOutput());
      rescale->UpdateLargestPossibleRegion();

    RegionType region;
    region.SetIndex(index);

    size = rescale->GetOutput()->GetLargestPossibleRegion().GetSize();
    for (unsigned int i = 2; i < ITK_TEST_DIMENSION_MAX; i++)
      {
      size[i] = 0;
      }
    region.SetSize(size);

    ExtractType::Pointer extract = ExtractType::New();
      extract->SetInput(rescale->GetOutput());
      extract->SetExtractionRegion(region);

    WriterType::Pointer writer = WriterType::New();
      writer->SetInput(extract->GetOutput());
    if(differences)
      {
      // if there are discrepencies, create an diff image
      std::cout << "<DartMeasurement name=\"ImageError\" type=\"numeric/double\">";
      std::cout << status;
      std::cout <<  "</DartMeasurement>" << std::endl;

      ::itk::OStringStream diffName;
        diffName << testImageFilename << ".diff.png";
      try
        {
        rescale->SetInput(diff->GetOutput());
        rescale->Update();
        }
      catch (...)
        {
        std::cerr << "Error during rescale of " << diffName.str() << std::endl;
        }
      writer->SetFileName(diffName.str().c_str());
      try
        {
        writer->Update();
        }
      catch (...)
        {
        std::cerr << "Error during write of " << diffName.str() << std::endl;
        }

      std::cout << "<DartMeasurementFile name=\"DifferenceImage\" type=\"image/png\">";
      std::cout << diffName.str();
      std::cout << "</DartMeasurementFile>" << std::endl;
      }
    ::itk::OStringStream baseName;
    baseName << testImageFilename << ".base.png";
    try
      {
      rescale->SetInput(baselineReader->GetOutput());
      rescale->Update();
      }
    catch (...)
      {
      std::cerr << "Error during rescale of " << baseName.str() << std::endl;
      }
    try
      {
      writer->SetFileName(baseName.str().c_str());
      writer->Update();
      }
    catch (...)
      {
      std::cerr << "Error during write of " << baseName.str() << std::endl;
      }

    std::cout << "<DartMeasurementFile name=\"BaselineImage\" type=\"image/png\">";
    std::cout << baseName.str();
    std::cout << "</DartMeasurementFile>" << std::endl;

    ::itk::OStringStream testName;
    testName << testImageFilename << ".test.png";
    try
      {
      rescale->SetInput(testReader->GetOutput());
      rescale->Update();
      }
    catch (...)
      {
      std::cerr << "Error during rescale of " << testName.str()
                << std::endl;
      }
    try
      {
      writer->SetFileName(testName.str().c_str());
      writer->Update();
      }
    catch (...)
      {
      std::cerr << "Error during write of " << testName.str() << std::endl;
      }

    std::cout << "<DartMeasurementFile name=\"TestImage\" type=\"image/png\">";
    std::cout << testName.str();
    std::cout << "</DartMeasurementFile>" << std::endl;

    }
  return (status != 0) ? 1 : 0;
}
<|endoftext|>


<commit_before>#include "Thread.hpp"

namespace Util
{
    namespace Thread
    {
        uintmax_t GetCurrentThreadId()
        {
#ifdef _WIN64
            /*
            mov         rax,qword ptr gs:[30h]
            mov         eax,dword ptr [rax+48h]
            */
            return Pointer(__readgsqword(0x30))(0x48).Read<uint64_t>();
#else
            /*
            mov         eax,dword ptr fs:[18h]
            mov         eax,dword ptr [eax+24h]
            */
            return Pointer(__readgsdword(0x18))(0x24).Read<uint32_t>();
#endif
        }

        Pointer GetThreadLocalStorage(size_t Index)
        {
#ifdef _WIN64
            return Pointer(__readgsdword(0x1480 + Index * 8));
#else
            return Pointer(__readgsdword(0x18))(0xE10).Read<uintptr_t>();
#endif
        }
    }
}<commit_msg>Fixed segment reads to use proper segments<commit_after>#include "Thread.hpp"

namespace Util
{
    namespace Thread
    {
        uintmax_t GetCurrentThreadId()
        {
#ifdef _WIN64
            /*
            mov         rax,qword ptr gs:[30h]
            mov         eax,dword ptr [rax+48h]
            */
            return Pointer(__readgsqword(0x30))(0x48).Read<uint64_t>();
#else
            /*
            mov         eax,dword ptr fs:[18h]
            mov         eax,dword ptr [eax+24h]
            */
            return Pointer(__readfsdword(0x18))(0x24).Read<uint32_t>();
#endif
        }

        Pointer GetThreadLocalStorage(size_t Index)
        {
#ifdef _WIN64
            return Pointer(__readgsdword(0x1480 + Index * 8));
#else
            return Pointer(__readfsdword(0x18))(0xE10).Read<uintptr_t>();
#endif
        }
    }
}<|endoftext|>


<commit_before>/*
This file is part of Bohrium and copyright (c) 2012 the Bohrium
team <http://www.bh107.org>.

Bohrium is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation, either version 3
of the License, or (at your option) any later version.

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

You should have received a copy of the
GNU Lesser General Public License along with Bohrium.

If not, see <http://www.gnu.org/licenses/>.
*/
#include <bh.h>
#include <iostream>
#include <fstream>
#include <boost/foreach.hpp>
#include <vector>
#include <map>
#include <stdexcept>

using namespace std;
using namespace boost;

void fuser(bh_ir &bhir)
{
    if(bhir.kernel_list.size() != 0)
    {
        throw logic_error("The kernel_list is not empty!");
    }
    //map from an instruction in the kernel_list to an index into the
    //original instruction list
    map<pair<int,int>,int> index_map;

    vector<bh_instruction>::iterator it = bhir.instr_list.begin();
    int instr_count=0;
    while(it != bhir.instr_list.end())
    {
        const unsigned int ksize = bhir.kernel_list.size();

        //Start new kernel
        bh_ir_kernel kernel;
        kernel.add_instr(*it);

        //Add the instruction to the map
        index_map.insert(pair<pair<int,int>,int>(pair<int,int>(ksize, 0), instr_count++));

        //Add fusible instructions to the kernel
        int i=1;
        for(it=it+1; it != bhir.instr_list.end(); ++it, ++i)
        {
            if(kernel.fusible(*it))
            {
                kernel.add_instr(*it);
                index_map.insert(pair<pair<int,int>,int>(pair<int,int>(ksize, i), instr_count++));
            }
            else
                break;
        }
        bhir.kernel_list.push_back(kernel);
    }
//    bhir.pprint_kernels();

    if(not bhir.check_kernel_cycles(index_map))
        throw logic_error("Cyclic dependencies between the kernels in the BhIR!");
}

<commit_msg>fuse topological now calls check_kernel_cycles() when NDEBUG isn't defined<commit_after>/*
This file is part of Bohrium and copyright (c) 2012 the Bohrium
team <http://www.bh107.org>.

Bohrium is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation, either version 3
of the License, or (at your option) any later version.

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

You should have received a copy of the
GNU Lesser General Public License along with Bohrium.

If not, see <http://www.gnu.org/licenses/>.
*/
#include <bh.h>
#include <iostream>
#include <fstream>
#include <boost/foreach.hpp>
#include <vector>
#include <map>
#include <stdexcept>

using namespace std;
using namespace boost;

void fuser(bh_ir &bhir)
{
    if(bhir.kernel_list.size() != 0)
    {
        throw logic_error("The kernel_list is not empty!");
    }
    //map from an instruction in the kernel_list to an index into the
    //original instruction list
    map<pair<int,int>,int> index_map;

    vector<bh_instruction>::iterator it = bhir.instr_list.begin();
    int instr_count=0;
    while(it != bhir.instr_list.end())
    {
        const unsigned int ksize = bhir.kernel_list.size();

        //Start new kernel
        bh_ir_kernel kernel;
        kernel.add_instr(*it);

        //Add the instruction to the map
        index_map.insert(pair<pair<int,int>,int>(pair<int,int>(ksize, 0), instr_count++));

        //Add fusible instructions to the kernel
        int i=1;
        for(it=it+1; it != bhir.instr_list.end(); ++it, ++i)
        {
            if(kernel.fusible(*it))
            {
                kernel.add_instr(*it);
                index_map.insert(pair<pair<int,int>,int>(pair<int,int>(ksize, i), instr_count++));
            }
            else
                break;
        }
        bhir.kernel_list.push_back(kernel);
    }

#ifndef NDEBUG
    if(not bhir.check_kernel_cycles(index_map))
        throw logic_error("Cyclic dependencies between the kernels in the BhIR!");
#endif
}

<|endoftext|>


<commit_before>//
//  Sprite.cpp
//  SpaceStationKeeper
//
//  Created by Sean Dawson on 24/05/2014.
//
//

#include "Sprite.h"
#include "GameObject.h"
#include "SimpleMesh.h"
#include "ComponentDrivenApp.h"
#include "Material.h"

// Constructors/Destructors
Sprite::Sprite() : GameComponent() {}

Sprite::Sprite(TextureDefRef texture, int spriteFrame) : GameComponent() {
  this->_spriteTexture = texture;
  this->_spriteFrame = spriteFrame;
}

Sprite::~Sprite() { releaseCache(); }

// Getters/Setters

TextureDefRef Sprite::getSpriteTexture() { return _spriteTexture; }

int Sprite::getSpriteFrame() { return _spriteFrame; }

void Sprite::setSpriteTexture(TextureDefRef texture) {
  releaseCache();
  _spriteTexture = texture;
  refresh();
}

void Sprite::setSpriteFrame(int frame) {
  _spriteFrame = frame;
  refresh();
}

// Methods
void Sprite::setup() {
  _assetLoader = ComponentDrivenApp::Instance()->getAssetLoader();

  if (_spriteTexture != nullptr) {
    if (_spriteFrame < 0 || _spriteFrame >= _spriteTexture->getFrameCount()) {
      cout << "Warning: Frame '" << _spriteFrame
           << "' is out of range for texture '" << _spriteTexture->getAssetRef()
           << "'. Setting to 0." << endl;
      _spriteFrame = 0;
    }

    Rectf dims = Rectf(0, 0, _spriteTexture->getFrameWidth(),
                       _spriteTexture->getFrameHeight());
    Rectf uvCoords = _spriteTexture->getFrameUvCoords(_spriteFrame);

    RenderInfoRef renderer = this->gameObject->renderer;
    renderer->mesh = SimpleMesh::generateQuad(dims, uvCoords);

    MaterialRef mat = getOrCreateCacheEntry();
    // cout << "Sprite using tex: " << mat->texture << endl;

    renderer->material = mat;

    if (renderer->getIsBatched()) {
      renderer->invalidateBatch();
      // cout << "Invalidate batch because sprite regenerated." << endl;
    }
  }
}

void Sprite::refresh() { setup(); }

// Private Methods

MaterialRef Sprite::getOrCreateCacheEntry() {
  MaterialRef mat;
  if (_materialCache.count(_spriteTexture) == 0) {
    mat = make_shared<Material>();
    mat->texture = _spriteTexture;
    mat->shader = _assetLoader->loadAsset<ShaderDef>(SpriteShader);
    _materialCache[_spriteTexture] =
        SpriteCacheEntryPtr(new SpriteCacheEntry(mat));
  } else {
    mat = _materialCache[_spriteTexture]->material;
  }
  return mat;
}

void Sprite::releaseCache() {
  if (_spriteTexture != nullptr && _materialCache.count(_spriteTexture) > 0) {
    int useCount = --_materialCache[_spriteTexture]->useCount;
    if (useCount == 0) {
      _materialCache.erase(_spriteTexture);
    }
  }
}

// Static Fields

map<TextureDefRef, SpriteCacheEntryPtr> Sprite::_materialCache;<commit_msg>The sprite mesh is now only regenerated if the setSpriteTexture() or setSpriteFrame() has actually changed a value.<commit_after>//
//  Sprite.cpp
//  SpaceStationKeeper
//
//  Created by Sean Dawson on 24/05/2014.
//
//

#include "Sprite.h"
#include "GameObject.h"
#include "SimpleMesh.h"
#include "ComponentDrivenApp.h"
#include "Material.h"

// Constructors/Destructors
Sprite::Sprite() : GameComponent() {}

Sprite::Sprite(TextureDefRef texture, int spriteFrame) : GameComponent() {
  this->_spriteTexture = texture;
  this->_spriteFrame = spriteFrame;
}

Sprite::~Sprite() { releaseCache(); }

// Getters/Setters

TextureDefRef Sprite::getSpriteTexture() { return _spriteTexture; }

int Sprite::getSpriteFrame() { return _spriteFrame; }

void Sprite::setSpriteTexture(TextureDefRef texture) {
  if (_spriteTexture != texture) {
    releaseCache();
    _spriteTexture = texture;
    refresh();
  }
}

void Sprite::setSpriteFrame(int frame) {
  if (_spriteFrame != frame) {
    _spriteFrame = frame;
    refresh();
  }
}

// Methods
void Sprite::setup() {
  _assetLoader = ComponentDrivenApp::Instance()->getAssetLoader();
  RenderInfoRef renderer = this->gameObject->renderer;

  if (_spriteTexture == nullptr) {
    renderer->mesh = nullptr;
    renderer->material = nullptr;
  } else {
    if (_spriteFrame < 0 || _spriteFrame >= _spriteTexture->getFrameCount()) {
      cout << "Warning: Frame '" << _spriteFrame
           << "' is out of range for texture '" << _spriteTexture->getAssetRef()
           << "'. Setting to 0." << endl;
      _spriteFrame = 0;
    }

    Rectf dims = Rectf(0, 0, _spriteTexture->getFrameWidth(),
                       _spriteTexture->getFrameHeight());
    Rectf uvCoords = _spriteTexture->getFrameUvCoords(_spriteFrame);

    renderer->mesh = SimpleMesh::generateQuad(dims, uvCoords);

    MaterialRef mat = getOrCreateCacheEntry();
    // cout << "Sprite using tex: " << mat->texture << endl;

    renderer->material = mat;

    if (renderer->getIsBatched()) {
      renderer->invalidateBatch();
      // cout << "Invalidate batch because sprite regenerated." << endl;
    }
  }
}

void Sprite::refresh() { setup(); }

// Private Methods

MaterialRef Sprite::getOrCreateCacheEntry() {
  MaterialRef mat;
  if (_materialCache.count(_spriteTexture) == 0) {
    mat = make_shared<Material>();
    mat->texture = _spriteTexture;
    mat->shader = _assetLoader->loadAsset<ShaderDef>(SpriteShader);
    _materialCache[_spriteTexture] =
        SpriteCacheEntryPtr(new SpriteCacheEntry(mat));
  } else {
    mat = _materialCache[_spriteTexture]->material;
  }
  return mat;
}

void Sprite::releaseCache() {
  if (_spriteTexture != nullptr && _materialCache.count(_spriteTexture) > 0) {
    int useCount = --_materialCache[_spriteTexture]->useCount;
    if (useCount == 0) {
      _materialCache.erase(_spriteTexture);
    }
  }
}

// Static Fields

map<TextureDefRef, SpriteCacheEntryPtr> Sprite::_materialCache;<|endoftext|>


<commit_before>#include <pthread.h>
#include <string.h>
#include <string>
#include <stdint.h>
#include <unistd.h>
#include <re.h>
#include <vector>

#include "sipua.hpp"
#include "stack.hpp"

struct tmr base_timer;

static int count = 0;
static std::vector<SIPUE*> ues;

static void cleanup()
{

    for (SIPUE* a : ues)
    {
        delete a;
    }

    close_sip_stacks(false);
}

static void timer_fn(void* arg)
{
//    printf("Called on timer!\n");
    count++;
    if (count < 10000)
    {
        tmr_start(&base_timer, 10, timer_fn, NULL);
        SIPUE* a = new SIPUE("sip:127.0.0.1",
                             "sip:1234@127.0.0.1",
                             "1234@127.0.0.1",
                             "secret");
        a->register_ue();
        ues.push_back(a);
    }
    else
    {
        cleanup();
    }
}

int main(int argc, char *argv[])
{
    int err; /* errno return values */

    /* initialize libre state */
    err = libre_init();
    fd_setsize(50000);
    if (err) {
        re_fprintf(stderr, "re init failed: %s\n", strerror(err));
    }

    re_init_timer_heap();

    tmr_init(&base_timer);
    tmr_start(&base_timer, 0, timer_fn, NULL);

    create_sip_stacks(20);
    re_main(NULL);
    printf("End of loop\n");

    free_sip_stacks();
    libre_close();

    /* check for memory leaks */
    //tmr_debug();
    mem_debug();

    return 0;
}
<commit_msg>Fine-tune the repeated timer<commit_after>#include <pthread.h>
#include <string.h>
#include <string>
#include <stdint.h>
#include <unistd.h>
#include <re.h>
#include <vector>

#include "sipua.hpp"
#include "stack.hpp"

struct tmr base_timer;

static int count = 0;
static uint64_t start_time = 0;
static uint64_t tick = 0;
static std::vector<SIPUE*> ues;

static void cleanup()
{

    for (SIPUE* a : ues)
    {
        delete a;
    }

    close_sip_stacks(false);
}

static void timer_fn(void* arg)
{
//    printf("Called on timer!\n");
    uint64_t next_tick = start_time + (10*tick);
    int diff = next_tick - tmr_jiffies();
    if (diff > 0)
    {
        tmr_start(&base_timer, diff, timer_fn, NULL);
        return;
    }

    count++;
    if (count < 10000)
    {
        tick++;
        int ms_to_sleep = diff + 10;
        if (ms_to_sleep > 0)
            ms_to_sleep = 0;
        tmr_start(&base_timer, ms_to_sleep, timer_fn, NULL);
        SIPUE* a = new SIPUE("sip:127.0.0.1",
                             "sip:1234@127.0.0.1",
                             "1234@127.0.0.1",
                             "secret");
        a->register_ue();
        ues.push_back(a);
    }
    else
    {
        cleanup();
    }
}

int main(int argc, char *argv[])
{
    int err; /* errno return values */

    /* initialize libre state */
    err = libre_init();
    fd_setsize(50000);
    if (err) {
        re_fprintf(stderr, "re init failed: %s\n", strerror(err));
    }

    re_init_timer_heap();

    tmr_init(&base_timer);
    tmr_start(&base_timer, 0, timer_fn, NULL);

    create_sip_stacks(20);
    start_time = tmr_jiffies();
    re_main(NULL);
    printf("End of loop\n");

    free_sip_stacks();
    libre_close();

    /* check for memory leaks */
    //tmr_debug();
    mem_debug();

    return 0;
}
<|endoftext|>


<commit_before>// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2014 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "pow.h"

#include "chain.h"
#include "chainparams.h"
#include "primitives/block.h"
#include "uint256.h"
#include "util.h"

unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHeader *pblock)
{
    // Standard retargeting for the first blocks
    if (pindexLast->nHeight+1 < 100) // Briliantcoin: block < 36000
    {
        //int64_t nParamsTargetTimespan = Params().TargetTimespan();
		//int64_t nParamsInterval = Params().Interval();
		return GetNextWorkRequiredn(pindexLast, pblock);
    }
    else{
	if (pindexLast->nHeight+1 < 120000) // Briliantcoin: block < 1200000
    { //New non Standard retargeting eXs
        //int64_t nParamsTargetTimespan = Params().TargetTimespans();
		//int64_t nParamsInterval = Params().Intervals();
		return GetNextWorkRequireds(pindexLast, pblock);
    }
    else
    { //New non Standard retargeting eX
		//int64_t nParamsTargetTimespan = Params().TargetTimespanx();
		//int64_t nParamsInterval = Params().Intervalx();
		return GetNextWorkRequiredx(pindexLast, pblock);
    }
	}

}

unsigned int GetNextWorkRequiredn(const CBlockIndex* pindexLast, const CBlockHeader *pblock)
{
    unsigned int nProofOfWorkLimit = Params().ProofOfWorkLimit().GetCompact();

    // Genesis block
    if (pindexLast == NULL)
        return nProofOfWorkLimit;

	// Only change once per interval
    if ((pindexLast->nHeight+1) % Params().Interval() != 0)
    {
        if (Params().AllowMinDifficultyBlocks())
        {
            // Special difficulty rule for testnet:
            // If the new block's timestamp is more than 2* 10 minutes
            // then allow mining of a min-difficulty block.
            if (pblock->GetBlockTime() > pindexLast->GetBlockTime() + Params().TargetSpacing()*2)
                return nProofOfWorkLimit;
            else
            {
                // Return the last non-special-min-difficulty-rules-block
                const CBlockIndex* pindex = pindexLast;
                while (pindex->pprev && pindex->nHeight % Params().Interval() != 0 && pindex->nBits == nProofOfWorkLimit)
                    pindex = pindex->pprev;
                return pindex->nBits;
            }
        }
        return pindexLast->nBits;
    }

    // Briliantcoin: This fixes an issue where a 51% attack can change difficulty at will.
    // Go back the full period unless it's the first retarget after genesis. Code courtesy of Art Forz
    int blockstogoback = Params().Interval()-1;
    if ((pindexLast->nHeight+1) != Params().Interval())
        blockstogoback = Params().Interval();

    // Go back by what we want to be 14 days worth of blocks
    const CBlockIndex* pindexFirst = pindexLast;
    for (int i = 0; pindexFirst && i < blockstogoback; i++)
        pindexFirst = pindexFirst->pprev;
    assert(pindexFirst);

    // Limit adjustment step
    int64_t nActualTimespan = pindexLast->GetBlockTime() - pindexFirst->GetBlockTime();
    LogPrintf("  nActualTimespan = %d  before bounds\n", nActualTimespan);
    if (nActualTimespan < Params().TargetTimespan()/4)
        nActualTimespan = Params().TargetTimespan()/4;
    if (nActualTimespan > Params().TargetTimespan()*4)
        nActualTimespan = Params().TargetTimespan()*4;

    // Retarget
    uint256 bnNew;
    uint256 bnOld;
    bnNew.SetCompact(pindexLast->nBits);
    bnOld = bnNew;
    // Briliantcoin: intermediate uint256 can overflow by 1 bit
    bool fShift = bnNew.bits() > 235;
    if (fShift)
        bnNew >>= 1;
    bnNew *= nActualTimespan;
    bnNew /= Params().TargetTimespan();
    if (fShift)
        bnNew <<= 1;

    if (bnNew > Params().ProofOfWorkLimit())
        bnNew = Params().ProofOfWorkLimit();

    /// debug print
    LogPrintf("GetNextWorkRequired RETARGET\n");
    LogPrintf("Params().TargetTimespan() = %d    nActualTimespan = %d\n", Params().TargetTimespan(), nActualTimespan);
    LogPrintf("Before: %08x  %s\n", pindexLast->nBits, bnOld.ToString());
    LogPrintf("After:  %08x  %s\n", bnNew.GetCompact(), bnNew.ToString());

    return bnNew.GetCompact();
}

unsigned int GetNextWorkRequiredx(const CBlockIndex* pindexLast, const CBlockHeader *pblock)
{
    unsigned int nProofOfWorkLimit = Params().ProofOfWorkLimit().GetCompact();

    // Genesis block
    if (pindexLast == NULL)
        return nProofOfWorkLimit;

	// Only change once per interval
    if ((pindexLast->nHeight+1) % Params().Intervalx() != 0)
    {
        if (Params().AllowMinDifficultyBlocks())
        {
            // Special difficulty rule for testnet:
            // If the new block's timestamp is more than 2* 10 minutes
            // then allow mining of a min-difficulty block.
            if (pblock->GetBlockTime() > pindexLast->GetBlockTime() + Params().TargetSpacing()*2)
                return nProofOfWorkLimit;
            else
            {
                // Return the last non-special-min-difficulty-rules-block
                const CBlockIndex* pindex = pindexLast;
                while (pindex->pprev && pindex->nHeight % Params().Intervalx() != 0 && pindex->nBits == nProofOfWorkLimit)
                    pindex = pindex->pprev;
                return pindex->nBits;
            }
        }
        return pindexLast->nBits;
    }

    // Briliantcoin: This fixes an issue where a 51% attack can change difficulty at will.
    // Go back the full period unless it's the first retarget after genesis. Code courtesy of Art Forz
    int blockstogoback = Params().Intervalx()-1;
    if ((pindexLast->nHeight+1) != Params().Intervalx())
        blockstogoback = Params().Intervalx();

    // Go back by what we want to be 14 days worth of blocks
    const CBlockIndex* pindexFirst = pindexLast;
    for (int i = 0; pindexFirst && i < blockstogoback; i++)
        pindexFirst = pindexFirst->pprev;
    assert(pindexFirst);

    // Limit adjustment step
    int64_t nActualTimespan = pindexLast->GetBlockTime() - pindexFirst->GetBlockTime();
    LogPrintf("  nActualTimespan = %d  before bounds\n", nActualTimespan);
    if (nActualTimespan < Params().TargetTimespanx()/4)
        nActualTimespan = Params().TargetTimespanx()/4;
    if (nActualTimespan > Params().TargetTimespanx()*4)
        nActualTimespan = Params().TargetTimespanx()*4;

    // Retarget
    uint256 bnNew;
    uint256 bnOld;
    bnNew.SetCompact(pindexLast->nBits);
    bnOld = bnNew;
    // Briliantcoin: intermediate uint256 can overflow by 1 bit
    bool fShift = bnNew.bits() > 235;
    if (fShift)
        bnNew >>= 1;
    bnNew *= nActualTimespan;
    bnNew /= Params().TargetTimespanx();
    if (fShift)
        bnNew <<= 1;

    if (bnNew > Params().ProofOfWorkLimit())
        bnNew = Params().ProofOfWorkLimit();

    /// debug print
    LogPrintf("GetNextWorkRequired eX RETARGET\n");
    LogPrintf("Params().TargetTimespanx() = %d    nActualTimespan = %d\n", Params().TargetTimespanx(), nActualTimespan);
    LogPrintf("Before: %08x  %s\n", pindexLast->nBits, bnOld.ToString());
    LogPrintf("After:  %08x  %s\n", bnNew.GetCompact(), bnNew.ToString());

    return bnNew.GetCompact();
}

unsigned int GetNextWorkRequireds(const CBlockIndex* pindexLast, const CBlockHeader *pblock)
{
    unsigned int nProofOfWorkLimit = Params().ProofOfWorkLimit().GetCompact();

    // Genesis block
    if (pindexLast == NULL)
        return nProofOfWorkLimit;

	// Only change once per interval
    if ((pindexLast->nHeight+1) % Params().Intervals() != 0)
    {
        if (Params().AllowMinDifficultyBlocks())
        {
            // Special difficulty rule for testnet:
            // If the new block's timestamp is more than 2* 10 minutes
            // then allow mining of a min-difficulty block.
            if (pblock->GetBlockTime() > pindexLast->GetBlockTime() + Params().TargetSpacing()*2)
                return nProofOfWorkLimit;
            else
            {
                // Return the last non-special-min-difficulty-rules-block
                const CBlockIndex* pindex = pindexLast;
                while (pindex->pprev && pindex->nHeight % Params().Intervals() != 0 && pindex->nBits == nProofOfWorkLimit)
                    pindex = pindex->pprev;
                return pindex->nBits;
            }
        }
        return pindexLast->nBits;
    }

    // Briliantcoin: This fixes an issue where a 51% attack can change difficulty at will.
    // Go back the full period unless it's the first retarget after genesis. Code courtesy of Art Forz
    int blockstogoback = Params().Intervals()-1;
    if ((pindexLast->nHeight+1) != Params().Intervals())
        blockstogoback = Params().Intervals();

    // Go back by what we want to be 14 days worth of blocks
    const CBlockIndex* pindexFirst = pindexLast;
    for (int i = 0; pindexFirst && i < blockstogoback; i++)
        pindexFirst = pindexFirst->pprev;
    assert(pindexFirst);

    // Limit adjustment step
    int64_t nActualTimespan = pindexLast->GetBlockTime() - pindexFirst->GetBlockTime();
    LogPrintf("  nActualTimespan = %d  before bounds\n", nActualTimespan);
    if (nActualTimespan < Params().TargetTimespans()/4)
        nActualTimespan = Params().TargetTimespans()/4;
    if (nActualTimespan > Params().TargetTimespans()*4)
        nActualTimespan = Params().TargetTimespans()*4;

    // Retarget
    uint256 bnNew;
    uint256 bnOld;
    bnNew.SetCompact(pindexLast->nBits);
    bnOld = bnNew;
    // Briliantcoin: intermediate uint256 can overflow by 1 bit
    bool fShift = bnNew.bits() > 235;
    if (fShift)
        bnNew >>= 1;
    bnNew *= nActualTimespan;
    bnNew /= Params().TargetTimespans();
    if (fShift)
        bnNew <<= 1;

    if (bnNew > Params().ProofOfWorkLimit())
        bnNew = Params().ProofOfWorkLimit();

    /// debug print
    LogPrintf("GetNextWorkRequired eXs RETARGET\n");
    LogPrintf("Params().TargetTimespans() = %d    nActualTimespan = %d\n", Params().TargetTimespans(), nActualTimespan);
    LogPrintf("Before: %08x  %s\n", pindexLast->nBits, bnOld.ToString());
    LogPrintf("After:  %08x  %s\n", bnNew.GetCompact(), bnNew.ToString());

    return bnNew.GetCompact();
}

bool CheckProofOfWork(uint256 hash, unsigned int nBits)
{
    bool fNegative;
    bool fOverflow;
    uint256 bnTarget;

    if (Params().SkipProofOfWorkCheck())
       return true;

    bnTarget.SetCompact(nBits, &fNegative, &fOverflow);

    // Check range
    if (fNegative || bnTarget == 0 || fOverflow || bnTarget > Params().ProofOfWorkLimit())
        return error("CheckProofOfWork() : nBits below minimum work");

    // Check proof of work matches claimed amount
    if (hash > bnTarget)
        return error("CheckProofOfWork() : hash doesn't match nBits");

    return true;
}

uint256 GetBlockProof(const CBlockIndex& block)
{
    uint256 bnTarget;
    bool fNegative;
    bool fOverflow;
    bnTarget.SetCompact(block.nBits, &fNegative, &fOverflow);
    if (fNegative || fOverflow || bnTarget == 0)
        return 0;
    // We need to compute 2**256 / (bnTarget+1), but we can't represent 2**256
    // as it's too large for a uint256. However, as 2**256 is at least as large
    // as bnTarget+1, it is equal to ((2**256 - bnTarget - 1) / (bnTarget+1)) + 1,
    // or ~bnTarget / (nTarget+1) + 1.
    return (~bnTarget / (bnTarget + 1)) + 1;
}
<commit_msg>22092017<commit_after>// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2014 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "pow.h"

#include "chain.h"
#include "chainparams.h"
#include "primitives/block.h"
#include "uint256.h"
#include "util.h"

unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHeader *pblock)
{
    // Standard retargeting for the first blocks
    if (pindexLast->nHeight+1 < 100) // Briliantcoin: block < 36000
    {
        //int64_t nParamsTargetTimespan = Params().TargetTimespan();
		//int64_t nParamsInterval = Params().Interval();
		return GetNextWorkRequiredn(pindexLast, pblock);
    }
    else{
	if (pindexLast->nHeight+1 < 120000) // Briliantcoin: block < 1200000
    { //New non Standard retargeting eX
		//int64_t nParamsTargetTimespan = Params().TargetTimespanx();
		//int64_t nParamsInterval = Params().Intervalx();
		return GetNextWorkRequiredx(pindexLast, pblock);
    }
    else
    { //New non Standard retargeting eXs
        //int64_t nParamsTargetTimespan = Params().TargetTimespans();
		//int64_t nParamsInterval = Params().Intervals();
		return GetNextWorkRequireds(pindexLast, pblock);
    }
	}

}

unsigned int GetNextWorkRequiredn(const CBlockIndex* pindexLast, const CBlockHeader *pblock)
{
    unsigned int nProofOfWorkLimit = Params().ProofOfWorkLimit().GetCompact();

    // Genesis block
    if (pindexLast == NULL)
        return nProofOfWorkLimit;

	// Only change once per interval
    if ((pindexLast->nHeight+1) % Params().Interval() != 0)
    {
        if (Params().AllowMinDifficultyBlocks())
        {
            // Special difficulty rule for testnet:
            // If the new block's timestamp is more than 2* 10 minutes
            // then allow mining of a min-difficulty block.
            if (pblock->GetBlockTime() > pindexLast->GetBlockTime() + Params().TargetSpacing()*2)
                return nProofOfWorkLimit;
            else
            {
                // Return the last non-special-min-difficulty-rules-block
                const CBlockIndex* pindex = pindexLast;
                while (pindex->pprev && pindex->nHeight % Params().Interval() != 0 && pindex->nBits == nProofOfWorkLimit)
                    pindex = pindex->pprev;
                return pindex->nBits;
            }
        }
        return pindexLast->nBits;
    }

    // Briliantcoin: This fixes an issue where a 51% attack can change difficulty at will.
    // Go back the full period unless it's the first retarget after genesis. Code courtesy of Art Forz
    int blockstogoback = Params().Interval()-1;
    if ((pindexLast->nHeight+1) != Params().Interval())
        blockstogoback = Params().Interval();

    // Go back by what we want to be 14 days worth of blocks
    const CBlockIndex* pindexFirst = pindexLast;
    for (int i = 0; pindexFirst && i < blockstogoback; i++)
        pindexFirst = pindexFirst->pprev;
    assert(pindexFirst);

    // Limit adjustment step
    int64_t nActualTimespan = pindexLast->GetBlockTime() - pindexFirst->GetBlockTime();
    LogPrintf("  nActualTimespan = %d  before bounds\n", nActualTimespan);
    if (nActualTimespan < Params().TargetTimespan()/4)
        nActualTimespan = Params().TargetTimespan()/4;
    if (nActualTimespan > Params().TargetTimespan()*4)
        nActualTimespan = Params().TargetTimespan()*4;

    // Retarget
    uint256 bnNew;
    uint256 bnOld;
    bnNew.SetCompact(pindexLast->nBits);
    bnOld = bnNew;
    // Briliantcoin: intermediate uint256 can overflow by 1 bit
    bool fShift = bnNew.bits() > 235;
    if (fShift)
        bnNew >>= 1;
    bnNew *= nActualTimespan;
    bnNew /= Params().TargetTimespan();
    if (fShift)
        bnNew <<= 1;

    if (bnNew > Params().ProofOfWorkLimit())
        bnNew = Params().ProofOfWorkLimit();

    /// debug print
    LogPrintf("GetNextWorkRequired RETARGET\n");
    LogPrintf("Params().TargetTimespan() = %d    nActualTimespan = %d\n", Params().TargetTimespan(), nActualTimespan);
    LogPrintf("Before: %08x  %s\n", pindexLast->nBits, bnOld.ToString());
    LogPrintf("After:  %08x  %s\n", bnNew.GetCompact(), bnNew.ToString());

    return bnNew.GetCompact();
}

unsigned int GetNextWorkRequiredx(const CBlockIndex* pindexLast, const CBlockHeader *pblock)
{
    unsigned int nProofOfWorkLimit = Params().ProofOfWorkLimit().GetCompact();

    // Genesis block
    if (pindexLast == NULL)
        return nProofOfWorkLimit;

	// Only change once per interval
    if ((pindexLast->nHeight+1) % Params().Intervalx() != 0)
    {
        if (Params().AllowMinDifficultyBlocks())
        {
            // Special difficulty rule for testnet:
            // If the new block's timestamp is more than 2* 10 minutes
            // then allow mining of a min-difficulty block.
            if (pblock->GetBlockTime() > pindexLast->GetBlockTime() + Params().TargetSpacing()*2)
                return nProofOfWorkLimit;
            else
            {
                // Return the last non-special-min-difficulty-rules-block
                const CBlockIndex* pindex = pindexLast;
                while (pindex->pprev && pindex->nHeight % Params().Intervalx() != 0 && pindex->nBits == nProofOfWorkLimit)
                    pindex = pindex->pprev;
                return pindex->nBits;
            }
        }
        return pindexLast->nBits;
    }

    // Briliantcoin: This fixes an issue where a 51% attack can change difficulty at will.
    // Go back the full period unless it's the first retarget after genesis. Code courtesy of Art Forz
    int blockstogoback = Params().Intervalx()-1;
    if ((pindexLast->nHeight+1) != Params().Intervalx())
        blockstogoback = Params().Intervalx();

    // Go back by what we want to be 14 days worth of blocks
    const CBlockIndex* pindexFirst = pindexLast;
    for (int i = 0; pindexFirst && i < blockstogoback; i++)
        pindexFirst = pindexFirst->pprev;
    assert(pindexFirst);

    // Limit adjustment step
    int64_t nActualTimespan = pindexLast->GetBlockTime() - pindexFirst->GetBlockTime();
    LogPrintf("  nActualTimespan = %d  before bounds\n", nActualTimespan);
    if (nActualTimespan < Params().TargetTimespanx()/4)
        nActualTimespan = Params().TargetTimespanx()/4;
    if (nActualTimespan > Params().TargetTimespanx()*4)
        nActualTimespan = Params().TargetTimespanx()*4;

    // Retarget
    uint256 bnNew;
    uint256 bnOld;
    bnNew.SetCompact(pindexLast->nBits);
    bnOld = bnNew;
    // Briliantcoin: intermediate uint256 can overflow by 1 bit
    bool fShift = bnNew.bits() > 235;
    if (fShift)
        bnNew >>= 1;
    bnNew *= nActualTimespan;
    bnNew /= Params().TargetTimespanx();
    if (fShift)
        bnNew <<= 1;

    if (bnNew > Params().ProofOfWorkLimit())
        bnNew = Params().ProofOfWorkLimit();

    /// debug print
    LogPrintf("GetNextWorkRequired eX RETARGET\n");
    LogPrintf("Params().TargetTimespanx() = %d    nActualTimespan = %d\n", Params().TargetTimespanx(), nActualTimespan);
    LogPrintf("Before: %08x  %s\n", pindexLast->nBits, bnOld.ToString());
    LogPrintf("After:  %08x  %s\n", bnNew.GetCompact(), bnNew.ToString());

    return bnNew.GetCompact();
}

unsigned int GetNextWorkRequireds(const CBlockIndex* pindexLast, const CBlockHeader *pblock)
{
    unsigned int nProofOfWorkLimit = Params().ProofOfWorkLimit().GetCompact();

    // Genesis block
    if (pindexLast == NULL)
        return nProofOfWorkLimit;

	// Only change once per interval
    if ((pindexLast->nHeight+1) % Params().Intervals() != 0)
    {
        if (Params().AllowMinDifficultyBlocks())
        {
            // Special difficulty rule for testnet:
            // If the new block's timestamp is more than 2* 10 minutes
            // then allow mining of a min-difficulty block.
            if (pblock->GetBlockTime() > pindexLast->GetBlockTime() + Params().TargetSpacing()*2)
                return nProofOfWorkLimit;
            else
            {
                // Return the last non-special-min-difficulty-rules-block
                const CBlockIndex* pindex = pindexLast;
                while (pindex->pprev && pindex->nHeight % Params().Intervals() != 0 && pindex->nBits == nProofOfWorkLimit)
                    pindex = pindex->pprev;
                return pindex->nBits;
            }
        }
        return pindexLast->nBits;
    }

    // Briliantcoin: This fixes an issue where a 51% attack can change difficulty at will.
    // Go back the full period unless it's the first retarget after genesis. Code courtesy of Art Forz
    int blockstogoback = Params().Intervals()-1;
    if ((pindexLast->nHeight+1) != Params().Intervals())
        blockstogoback = Params().Intervals();

    // Go back by what we want to be 14 days worth of blocks
    const CBlockIndex* pindexFirst = pindexLast;
    for (int i = 0; pindexFirst && i < blockstogoback; i++)
        pindexFirst = pindexFirst->pprev;
    assert(pindexFirst);

    // Limit adjustment step
    int64_t nActualTimespan = pindexLast->GetBlockTime() - pindexFirst->GetBlockTime();
    LogPrintf("  nActualTimespan = %d  before bounds\n", nActualTimespan);
    if (nActualTimespan < Params().TargetTimespans()/4)
        nActualTimespan = Params().TargetTimespans()/4;
    if (nActualTimespan > Params().TargetTimespans()*4)
        nActualTimespan = Params().TargetTimespans()*4;

    // Retarget
    uint256 bnNew;
    uint256 bnOld;
    bnNew.SetCompact(pindexLast->nBits);
    bnOld = bnNew;
    // Briliantcoin: intermediate uint256 can overflow by 1 bit
    bool fShift = bnNew.bits() > 235;
    if (fShift)
        bnNew >>= 1;
    bnNew *= nActualTimespan;
    bnNew /= Params().TargetTimespans();
    if (fShift)
        bnNew <<= 1;

    if (bnNew > Params().ProofOfWorkLimit())
        bnNew = Params().ProofOfWorkLimit();

    /// debug print
    LogPrintf("GetNextWorkRequired eXs RETARGET\n");
    LogPrintf("Params().TargetTimespans() = %d    nActualTimespan = %d\n", Params().TargetTimespans(), nActualTimespan);
    LogPrintf("Before: %08x  %s\n", pindexLast->nBits, bnOld.ToString());
    LogPrintf("After:  %08x  %s\n", bnNew.GetCompact(), bnNew.ToString());

    return bnNew.GetCompact();
}

bool CheckProofOfWork(uint256 hash, unsigned int nBits)
{
    bool fNegative;
    bool fOverflow;
    uint256 bnTarget;

    if (Params().SkipProofOfWorkCheck())
       return true;

    bnTarget.SetCompact(nBits, &fNegative, &fOverflow);

    // Check range
    if (fNegative || bnTarget == 0 || fOverflow || bnTarget > Params().ProofOfWorkLimit())
        return error("CheckProofOfWork() : nBits below minimum work");

    // Check proof of work matches claimed amount
    if (hash > bnTarget)
        return error("CheckProofOfWork() : hash doesn't match nBits");

    return true;
}

uint256 GetBlockProof(const CBlockIndex& block)
{
    uint256 bnTarget;
    bool fNegative;
    bool fOverflow;
    bnTarget.SetCompact(block.nBits, &fNegative, &fOverflow);
    if (fNegative || fOverflow || bnTarget == 0)
        return 0;
    // We need to compute 2**256 / (bnTarget+1), but we can't represent 2**256
    // as it's too large for a uint256. However, as 2**256 is at least as large
    // as bnTarget+1, it is equal to ((2**256 - bnTarget - 1) / (bnTarget+1)) + 1,
    // or ~bnTarget / (nTarget+1) + 1.
    return (~bnTarget / (bnTarget + 1)) + 1;
}
<|endoftext|>


<commit_before>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/test/test_timeouts.h"

#include "base/command_line.h"
#include "base/logging.h"
#include "base/string_number_conversions.h"
#include "chrome/test/test_switches.h"

namespace {

void InitializeTimeout(const char* switch_name, int* value) {
  DCHECK(value);
  if (CommandLine::ForCurrentProcess()->HasSwitch(switch_name)) {
    std::string string_value(
        CommandLine::ForCurrentProcess()->GetSwitchValueASCII(switch_name));
    int timeout;
    base::StringToInt(string_value, &timeout);
    *value = std::max(*value, timeout);
  }
}

}  // namespace

// static
bool TestTimeouts::initialized_ = false;

// The timeout values should increase in the order they appear in this block.
// static
int TestTimeouts::action_timeout_ms_ = 2000;
int TestTimeouts::action_max_timeout_ms_ = 15000;
int TestTimeouts::medium_test_timeout_ms_ = 60 * 1000;
int TestTimeouts::large_test_timeout_ms_ = 10 * 60 * 1000;

// static
int TestTimeouts::sleep_timeout_ms_ = 2000;

// static
int TestTimeouts::command_execution_timeout_ms_ = 25000;

// static
int TestTimeouts::wait_for_terminate_timeout_ms_ = 15000;

// static
void TestTimeouts::Initialize() {
  if (initialized_) {
    NOTREACHED();
    return;
  }
  initialized_ = true;

  InitializeTimeout(switches::kUiTestActionTimeout, &action_timeout_ms_);
  InitializeTimeout(switches::kUiTestActionMaxTimeout,
                    &action_max_timeout_ms_);
  InitializeTimeout(switches::kMediumTestTimeout, &medium_test_timeout_ms_);
  InitializeTimeout(switches::kUiTestTimeout, &large_test_timeout_ms_);

  // The timeout values should be increasing in the right order.
  CHECK(action_timeout_ms_ <= action_max_timeout_ms_);
  CHECK(action_max_timeout_ms_ <= medium_test_timeout_ms_);
  CHECK(medium_test_timeout_ms_ <= large_test_timeout_ms_);

  InitializeTimeout(switches::kUiTestSleepTimeout, &sleep_timeout_ms_);
  InitializeTimeout(switches::kUiTestCommandExecutionTimeout,
                    &command_execution_timeout_ms_);
  InitializeTimeout(switches::kUiTestTerminateTimeout,
                    &wait_for_terminate_timeout_ms_);
}
<commit_msg>Revert 59421 - GTTF: Increase the timeout for medium tests to one minute.<commit_after>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/test/test_timeouts.h"

#include "base/command_line.h"
#include "base/logging.h"
#include "base/string_number_conversions.h"
#include "chrome/test/test_switches.h"

namespace {

void InitializeTimeout(const char* switch_name, int* value) {
  DCHECK(value);
  if (CommandLine::ForCurrentProcess()->HasSwitch(switch_name)) {
    std::string string_value(
        CommandLine::ForCurrentProcess()->GetSwitchValueASCII(switch_name));
    int timeout;
    base::StringToInt(string_value, &timeout);
    *value = std::max(*value, timeout);
  }
}

}  // namespace

// static
bool TestTimeouts::initialized_ = false;

// The timeout values should increase in the order they appear in this block.
// static
int TestTimeouts::action_timeout_ms_ = 2000;
int TestTimeouts::action_max_timeout_ms_ = 15000;
int TestTimeouts::medium_test_timeout_ms_ = 30 * 1000;
int TestTimeouts::large_test_timeout_ms_ = 10 * 60 * 1000;

// static
int TestTimeouts::sleep_timeout_ms_ = 2000;

// static
int TestTimeouts::command_execution_timeout_ms_ = 25000;

// static
int TestTimeouts::wait_for_terminate_timeout_ms_ = 15000;

// static
void TestTimeouts::Initialize() {
  if (initialized_) {
    NOTREACHED();
    return;
  }
  initialized_ = true;

  InitializeTimeout(switches::kUiTestActionTimeout, &action_timeout_ms_);
  InitializeTimeout(switches::kUiTestActionMaxTimeout,
                    &action_max_timeout_ms_);
  InitializeTimeout(switches::kMediumTestTimeout, &medium_test_timeout_ms_);
  InitializeTimeout(switches::kUiTestTimeout, &large_test_timeout_ms_);

  // The timeout values should be increasing in the right order.
  CHECK(action_timeout_ms_ <= action_max_timeout_ms_);
  CHECK(action_max_timeout_ms_ <= medium_test_timeout_ms_);
  CHECK(medium_test_timeout_ms_ <= large_test_timeout_ms_);

  InitializeTimeout(switches::kUiTestSleepTimeout, &sleep_timeout_ms_);
  InitializeTimeout(switches::kUiTestCommandExecutionTimeout,
                    &command_execution_timeout_ms_);
  InitializeTimeout(switches::kUiTestTerminateTimeout,
                    &wait_for_terminate_timeout_ms_);
}
<|endoftext|>


<commit_before>#ifdef _WIN32
#define _CRT_SECURE_NO_WARNINGS
#endif

#include "support.h"

#include <cstdlib>
#include <fstream>
#include <iso646.h>
#include <iterator>
#include <sstream>

#ifdef _WIN32
#include <io.h>
#define access _access
#define R_OK 04
#define PATHSEP ';'
#else
#include <unistd.h>
#define PATHSEP ':'
#endif

#include "bytecode.h"

namespace {

std::vector<std::string> split(const std::string &s, char d)
{
    std::vector<std::string> r;
    std::string::size_type i = 0;
    auto start = i;
    while (i < s.length()) {
        if (s.at(i) == d) {
            r.push_back(s.substr(start, i-start));
            start = i + 1;
        }
        i++;
    }
    if (i > start) {
        r.push_back(s.substr(start, i-start));
    }
    return r;
}

} // namespace

PathSupport::PathSupport(const std::string &source_path)
  : paths()
{
    if (not source_path.empty()) {
        paths.push_back(source_path);
    }
    paths.push_back("./");
    const char *neonpath = std::getenv("NEONPATH");
    if (neonpath != NULL) {
        std::vector<std::string> p = split(neonpath, PATHSEP);
        std::copy(p.begin(), p.end(), std::back_inserter(paths));
    }
    std::ifstream inf(".neonpath");
    if (inf.good()) {
        std::string s;
        while (std::getline(inf, s)) {
            paths.push_back(s);
        }
    }
}

std::pair<std::string, std::string> PathSupport::findModule(const std::string &name)
{
    std::string module_name = name;
    std::vector<std::string> use_paths = paths;
    std::string::size_type slash = name.find_last_of("/\\");
    if (slash != std::string::npos) {
        use_paths.clear();
        use_paths.push_back(name.substr(0, slash+1));
        module_name = name.substr(slash+1);
    }
    const std::string source_name = module_name + ".neon";
    const std::string object_name = module_name + ".neonx";
    std::pair<std::string, std::string> r;
    for (auto p: use_paths) {
        if (access((p + source_name).c_str(), R_OK) == 0) {
            r.first = p + source_name;
        }
        if (access((p + object_name).c_str(), R_OK) == 0) {
            r.second = p + object_name;
        }
        if (r.first.empty() && r.second.empty()) {
            if (access((p + module_name + "/" + source_name).c_str(), R_OK) == 0) {
                r.first = p + module_name + "/" + source_name;
            }
            if (access((p + module_name + "/" + object_name).c_str(), R_OK) == 0) {
                r.second = p + module_name + "/" + object_name;
            }
        }
        if (not r.first.empty() || not r.second.empty()) {
            break;
        }
    }
    return r;
}
<commit_msg>Remove unused include<commit_after>#ifdef _WIN32
#define _CRT_SECURE_NO_WARNINGS
#endif

#include "support.h"

#include <cstdlib>
#include <fstream>
#include <iso646.h>
#include <iterator>
#include <sstream>

#ifdef _WIN32
#include <io.h>
#define access _access
#define R_OK 04
#define PATHSEP ';'
#else
#include <unistd.h>
#define PATHSEP ':'
#endif

namespace {

std::vector<std::string> split(const std::string &s, char d)
{
    std::vector<std::string> r;
    std::string::size_type i = 0;
    auto start = i;
    while (i < s.length()) {
        if (s.at(i) == d) {
            r.push_back(s.substr(start, i-start));
            start = i + 1;
        }
        i++;
    }
    if (i > start) {
        r.push_back(s.substr(start, i-start));
    }
    return r;
}

} // namespace

PathSupport::PathSupport(const std::string &source_path)
  : paths()
{
    if (not source_path.empty()) {
        paths.push_back(source_path);
    }
    paths.push_back("./");
    const char *neonpath = std::getenv("NEONPATH");
    if (neonpath != NULL) {
        std::vector<std::string> p = split(neonpath, PATHSEP);
        std::copy(p.begin(), p.end(), std::back_inserter(paths));
    }
    std::ifstream inf(".neonpath");
    if (inf.good()) {
        std::string s;
        while (std::getline(inf, s)) {
            paths.push_back(s);
        }
    }
}

std::pair<std::string, std::string> PathSupport::findModule(const std::string &name)
{
    std::string module_name = name;
    std::vector<std::string> use_paths = paths;
    std::string::size_type slash = name.find_last_of("/\\");
    if (slash != std::string::npos) {
        use_paths.clear();
        use_paths.push_back(name.substr(0, slash+1));
        module_name = name.substr(slash+1);
    }
    const std::string source_name = module_name + ".neon";
    const std::string object_name = module_name + ".neonx";
    std::pair<std::string, std::string> r;
    for (auto p: use_paths) {
        if (access((p + source_name).c_str(), R_OK) == 0) {
            r.first = p + source_name;
        }
        if (access((p + object_name).c_str(), R_OK) == 0) {
            r.second = p + object_name;
        }
        if (r.first.empty() && r.second.empty()) {
            if (access((p + module_name + "/" + source_name).c_str(), R_OK) == 0) {
                r.first = p + module_name + "/" + source_name;
            }
            if (access((p + module_name + "/" + object_name).c_str(), R_OK) == 0) {
                r.second = p + module_name + "/" + object_name;
            }
        }
        if (not r.first.empty() || not r.second.empty()) {
            break;
        }
    }
    return r;
}
<|endoftext|>