<commit_before>#include <boost/test/unit_test.hpp>

//#include "clotho/powerset/powerset.hpp"
//
#include "clotho/powerset/block_map.hpp"
#include "clotho/powerset/variable_subset.hpp"

struct test_element {
    double k, v;

    test_element( double _k = 0., double _v = 0.) : k (_k), v(_v) {}
    test_element( const test_element & t ) : k(t.k), v(t.v) {}

    friend bool operator==( const test_element & lhs, const test_element & rhs );
    friend bool operator!=( const test_element & lhs, const test_element & rhs );
};

inline bool operator==( const test_element & lhs, const test_element & rhs ) {
    return ( lhs.k == rhs.k && lhs.v == rhs.v);
}

inline bool operator!=( const test_element & lhs, const test_element & rhs ) {
    return ( lhs.k != rhs.k && lhs.v != rhs.v);
}

namespace clotho {
namespace powersets {

template <>
struct element_key_of< test_element > {
    typedef double key_type;

    inline key_type operator()( const test_element & t ) { return t.k; }
};

template< class Block >
struct block_map< test_element, Block > {
    typedef test_element    element_type;
    typedef Block           size_type;

    static const unsigned int bits_per_block = sizeof(size_type) * 8;

    inline size_type operator()( const element_type & elem ) {
        assert( 0. <= elem.k && elem.k < 1. );

        return elem.k * bits_per_block;
    }
};

}   // namespace powersets
}   // namespace clotho

typedef clotho::powersets::variable_subset< test_element > subset_type;
typedef typename subset_type::powerset_type powerset_type;
typedef powerset_type::block_map_type bmap;

BOOST_AUTO_TEST_SUITE( test_powerset )

BOOST_AUTO_TEST_CASE( create_powerset_append) {

    powerset_type ps;

    typename powerset_type::element_index_type idx = ps.appendElement( test_element( 0., 1.0) );
    BOOST_REQUIRE_MESSAGE( idx == 0, "Unexpected index " << idx << " returned for " << 0 << "(" << 0 << ")" );
    BOOST_REQUIRE_MESSAGE( ps.variable_allocated_size() == bmap::bits_per_block, "Unexpected variable space: " << ps.variable_allocated_size() );
}

BOOST_AUTO_TEST_CASE( create_powerset_add) {

    powerset_type ps;

    typename powerset_type::element_index_type idx = ps.addElement( test_element( 0., 1.0) );
    BOOST_REQUIRE_MESSAGE( idx == 0, "Unexpected index " << idx << " returned for " << 0 << "(" << 0 << ")" );

    BOOST_REQUIRE_MESSAGE( ps.size() == 1, "Unexpected size" );
    BOOST_REQUIRE_MESSAGE( ps.variable_allocated_size() == bmap::bits_per_block, "Unexpected variable space: " << ps.variable_allocated_size() );
}

BOOST_AUTO_TEST_CASE( create_powerset_width ) {
    powerset_type ps;

    BOOST_REQUIRE_MESSAGE( ps.empty(), "Unexpected size" );

    typename powerset_type::element_index_type idx = ps.appendElement( test_element( 0., 1.0) );
    BOOST_REQUIRE_MESSAGE( idx == 0, "Unexpected index " << idx << " returned for " << 0 << "(" << 0 << ")" );

    BOOST_REQUIRE_MESSAGE( ps.variable_allocated_size() == bmap::bits_per_block, "Unexpected variable space: " << ps.variable_allocated_size() );

    for( unsigned int i = 1; i < bmap::bits_per_block; ++i ) {
        double v = (double) i;
        double k = v / (double) bmap::bits_per_block;
        test_element te(k, 1.0);

        typename powerset_type::element_index_type e_idx = ps.findFreeIndex(te);

        BOOST_REQUIRE_MESSAGE( e_idx == i, e_idx << " != " << i );

        typename powerset_type::element_index_type idx = ps.addElement(te);

        BOOST_REQUIRE_MESSAGE( idx == i, "Unexpected index " << idx << " returned for " << i << "(" << k << "; " << e_idx << ")" );
    }

    const unsigned int bpb = bmap::bits_per_block;
    BOOST_REQUIRE_MESSAGE( ps.variable_allocated_size() == bpb, "Unexpected size: " << ps.variable_allocated_size() << "(" << bpb << ")" );
}

BOOST_AUTO_TEST_SUITE_END()
<commit_msg>Additional tests to verify find_or_create, and create_subset. As well as to verify that subset functions also work expectedly<commit_after>#include <boost/test/unit_test.hpp>

//#include "clotho/powerset/powerset.hpp"
//
#include "clotho/powerset/block_map.hpp"
#include "clotho/powerset/variable_subset.hpp"

struct test_element {
    double k, v;

    test_element( double _k = 0., double _v = 0.) : k (_k), v(_v) {}
    test_element( const test_element & t ) : k(t.k), v(t.v) {}

    friend bool operator==( const test_element & lhs, const test_element & rhs );
    friend bool operator!=( const test_element & lhs, const test_element & rhs );
};

inline bool operator==( const test_element & lhs, const test_element & rhs ) {
    return ( lhs.k == rhs.k && lhs.v == rhs.v);
}

inline bool operator!=( const test_element & lhs, const test_element & rhs ) {
    return ( lhs.k != rhs.k && lhs.v != rhs.v);
}

namespace clotho {
namespace powersets {

template <>
struct element_key_of< test_element > {
    typedef double key_type;

    inline key_type operator()( const test_element & t ) { return t.k; }
};

template< class Block >
struct block_map< test_element, Block > {
    typedef test_element    element_type;
    typedef Block           size_type;

    static const unsigned int bits_per_block = sizeof(size_type) * 8;

    inline size_type operator()( const element_type & elem ) {
        assert( 0. <= elem.k && elem.k < 1. );

        return elem.k * bits_per_block;
    }
};

}   // namespace powersets
}   // namespace clotho

typedef clotho::powersets::variable_subset< test_element > subset_type;
typedef typename subset_type::powerset_type powerset_type;
typedef powerset_type::block_map_type bmap;

BOOST_AUTO_TEST_SUITE( test_powerset )

/**
 * Create an empty powerset
 *
 * Manually append element to powerset
 * Verify that new element is assigned to expected index
 *
 * Verify allocated size
 */
BOOST_AUTO_TEST_CASE( create_powerset_append) {
    powerset_type ps;

    typename powerset_type::element_index_type idx = ps.appendElement( test_element( 0., 1.0) );
    BOOST_REQUIRE_MESSAGE( idx == 0, "Unexpected index " << idx << " returned for " << 0 << "(" << 0 << ")" );
    BOOST_REQUIRE_MESSAGE( ps.variable_allocated_size() == bmap::bits_per_block, "Unexpected variable space: " << ps.variable_allocated_size() );
}

/**
 * Create an empty powerset
 *
 * Manually add element to powerset (results in append)
 * Verify that new element is assigned to expected index
 *
 * Verify allocated size
 */
BOOST_AUTO_TEST_CASE( create_powerset_add) {

    powerset_type ps;

    typename powerset_type::element_index_type idx = ps.addElement( test_element( 0., 1.0) );
    BOOST_REQUIRE_MESSAGE( idx == 0, "Unexpected index " << idx << " returned for " << 0 << "(" << 0 << ")" );

    BOOST_REQUIRE_MESSAGE( ps.size() == 1, "Unexpected size" );
    BOOST_REQUIRE_MESSAGE( ps.variable_allocated_size() == bmap::bits_per_block, "Unexpected variable space: " << ps.variable_allocated_size() );
}

/**
 * Create an empty powerset
 *
 * Manually append first element to powerset
 * Verify that new element is assigned to expected index
 *
 * add the remaining elements of a block
 * Verify that each new element is assigned to expected index
 *
 * Verify allocated size
 */
BOOST_AUTO_TEST_CASE( create_powerset_width ) {
    powerset_type ps;

    BOOST_REQUIRE_MESSAGE( ps.empty(), "Unexpected size" );

    typename powerset_type::element_index_type idx = ps.appendElement( test_element( 0., 1.0) );
    BOOST_REQUIRE_MESSAGE( idx == 0, "Unexpected index " << idx << " returned for " << 0 << "(" << 0 << ")" );

    BOOST_REQUIRE_MESSAGE( ps.variable_allocated_size() == bmap::bits_per_block, "Unexpected variable space: " << ps.variable_allocated_size() );

    for( unsigned int i = 1; i < bmap::bits_per_block; ++i ) {
        double v = (double) i;
        double k = v / (double) bmap::bits_per_block;
        test_element te(k, 1.0);

        typename powerset_type::element_index_type e_idx = ps.findFreeIndex(te);

        BOOST_REQUIRE_MESSAGE( e_idx == i, e_idx << " != " << i );

        typename powerset_type::element_index_type idx = ps.addElement(te);

        BOOST_REQUIRE_MESSAGE( idx == i, "Unexpected index " << idx << " returned for " << i << "(" << k << "; " << e_idx << ")" );
    }

    const unsigned int bpb = bmap::bits_per_block;
    BOOST_REQUIRE_MESSAGE( ps.variable_allocated_size() == bpb, "Unexpected size: " << ps.variable_allocated_size() << "(" << bpb << ")" );
}

/**
 * Create an empty powerset
 *
 * find_or_create elements in a round robin order.
 * Verify that each new element is assigned to expected index
 */
BOOST_AUTO_TEST_CASE( create_powerset_find_or_create_unique ) {
    powerset_type ps;

    const unsigned int sub_div = 3;
    const double div_offset = (1.0/ ((double)sub_div*bmap::bits_per_block));

    for( unsigned int i = 0; i < sub_div * bmap::bits_per_block; ++i ) {
        double v = (double) (i % bmap::bits_per_block);

        unsigned int s = (i / bmap::bits_per_block );

        double k = v / (double) bmap::bits_per_block + (double)s*div_offset;
        test_element te(k, 1.0);

        typename powerset_type::element_index_type idx = ps.find_or_create(te);

        BOOST_REQUIRE_MESSAGE( idx == i, "Unexpected index " << idx << " returned for " << i << "(" << k << ")" );
    }

    const unsigned int bpb = sub_div * bmap::bits_per_block;
    BOOST_REQUIRE_MESSAGE( ps.variable_allocated_size() == bpb, "Unexpected size: " << ps.variable_allocated_size() << "(" << bpb << ")" );
}

/**
 * Create an empty powerset
 *
 * find_or_create an element to the powerset (results in create)
 *
 * Verify that it is in expected position
 *
 * find_or_create different element with same key (results in find)
 *
 * Verify that element index returned is same as earlier element.
 */
BOOST_AUTO_TEST_CASE( create_powerset_find_or_create_collision ) {
    powerset_type ps;

    double k = 0.5;
    test_element te(k, 1.0);
    typename powerset_type::element_index_type idx = ps.find_or_create(te);
    BOOST_REQUIRE_MESSAGE( idx == bmap()(te), "Unexpected index " << idx << " returned for " << 0 << "(" << k << ")" );

    test_element te2(k, 2.0);
    typename powerset_type::element_index_type cidx = ps.find_or_create(te2);
    BOOST_REQUIRE_MESSAGE( cidx == idx, "Unexpected index " << idx << " returned for " << cidx << "(" << k << ")" );
}

/**
 * Creates a subset of the powerset
 *
 * Verify that subset was added to family
 *
 * Adds a element
 *
 * Checks that element has been added to the set and subset
 * Checks subset count
 * Verifies expected sizes
 * Verifies expected bit state
 *
 * Removes earlier element
 * Checks subset count
 * Checks element bit state
 */
BOOST_AUTO_TEST_CASE( create_powerset_subset ) {
    powerset_type ps;

    typename powerset_type::subset_ptr c = ps.create_subset();

    BOOST_REQUIRE_MESSAGE( ps.family_size() == 1, "Subset was not added to family");

    double k = 0.5;
    test_element te(k, 1.0);

    c->addElement( te );

    size_t cnt = c->count();
    BOOST_REQUIRE_MESSAGE( cnt == 1, "Element has not been added to the subset: " << cnt << "(1)" );

    const unsigned int bpb = bmap::bits_per_block;
    BOOST_REQUIRE_MESSAGE( ps.variable_allocated_size() == bpb, "Unexpected size: " << ps.variable_allocated_size() << "(" << bpb << ")" );

    typename powerset_type::element_index_type idx = ps.find_or_create(te);
    BOOST_REQUIRE_MESSAGE( idx == bmap()(te), "Unexpected index " << idx << " returned for " << 0 << "(" << k << ")" );

    BOOST_REQUIRE_MESSAGE( c->check_state( idx ), "Unexpected state for element after add" );

    c->removeElement( te );

    cnt = c->count();
    BOOST_REQUIRE_MESSAGE( cnt == 0, "Element has not been removed to the subset: " << cnt << "(0)" );
    BOOST_REQUIRE_MESSAGE( !c->check_state( idx ), "Unexpected state for element after remove" );
}

BOOST_AUTO_TEST_CASE( create_powerset_prunespace ) {
// TODO
}

BOOST_AUTO_TEST_SUITE_END()
<|endoftext|>


<commit_before>//===- llvm/unittest/Support/AllocatorTest.cpp - BumpPtrAllocator tests ---===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "llvm/Support/Allocator.h"
#include "gtest/gtest.h"
#include <cstdlib>

using namespace llvm;

namespace {

TEST(AllocatorTest, Basics) {
  BumpPtrAllocator Alloc;
  int *a = (int*)Alloc.Allocate(sizeof(int), 0);
  int *b = (int*)Alloc.Allocate(sizeof(int) * 10, 0);
  int *c = (int*)Alloc.Allocate(sizeof(int), 0);
  *a = 1;
  b[0] = 2;
  b[9] = 2;
  *c = 3;
  EXPECT_EQ(1, *a);
  EXPECT_EQ(2, b[0]);
  EXPECT_EQ(2, b[9]);
  EXPECT_EQ(3, *c);
  EXPECT_EQ(1U, Alloc.GetNumSlabs());
}

// Allocate enough bytes to create three slabs.
TEST(AllocatorTest, ThreeSlabs) {
  BumpPtrAllocator Alloc(4096, 4096);
  Alloc.Allocate(3000, 0);
  EXPECT_EQ(1U, Alloc.GetNumSlabs());
  Alloc.Allocate(3000, 0);
  EXPECT_EQ(2U, Alloc.GetNumSlabs());
  Alloc.Allocate(3000, 0);
  EXPECT_EQ(3U, Alloc.GetNumSlabs());
}

// Allocate enough bytes to create two slabs, reset the allocator, and do it
// again.
TEST(AllocatorTest, TestReset) {
  BumpPtrAllocator Alloc(4096, 4096);
  Alloc.Allocate(3000, 0);
  EXPECT_EQ(1U, Alloc.GetNumSlabs());
  Alloc.Allocate(3000, 0);
  EXPECT_EQ(2U, Alloc.GetNumSlabs());
  Alloc.Reset();
  EXPECT_EQ(1U, Alloc.GetNumSlabs());
  Alloc.Allocate(3000, 0);
  EXPECT_EQ(1U, Alloc.GetNumSlabs());
  Alloc.Allocate(3000, 0);
  EXPECT_EQ(2U, Alloc.GetNumSlabs());
}

// Test some allocations at varying alignments.
TEST(AllocatorTest, TestAlignment) {
  BumpPtrAllocator Alloc;
  uintptr_t a;
  a = (uintptr_t)Alloc.Allocate(1, 2);
  EXPECT_EQ(0U, a & 1);
  a = (uintptr_t)Alloc.Allocate(1, 4);
  EXPECT_EQ(0U, a & 3);
  a = (uintptr_t)Alloc.Allocate(1, 8);
  EXPECT_EQ(0U, a & 7);
  a = (uintptr_t)Alloc.Allocate(1, 16);
  EXPECT_EQ(0U, a & 15);
  a = (uintptr_t)Alloc.Allocate(1, 32);
  EXPECT_EQ(0U, a & 31);
  a = (uintptr_t)Alloc.Allocate(1, 64);
  EXPECT_EQ(0U, a & 63);
  a = (uintptr_t)Alloc.Allocate(1, 128);
  EXPECT_EQ(0U, a & 127);
}

// Test allocating just over the slab size.  This tests a bug where before the
// allocator incorrectly calculated the buffer end pointer.
TEST(AllocatorTest, TestOverflow) {
  BumpPtrAllocator Alloc(4096, 4096);

  // Fill the slab right up until the end pointer.
  Alloc.Allocate(4096 - sizeof(MemSlab), 0);
  EXPECT_EQ(1U, Alloc.GetNumSlabs());

  // If we don't allocate a new slab, then we will have overflowed.
  Alloc.Allocate(1, 0);
  EXPECT_EQ(2U, Alloc.GetNumSlabs());
}

// Test allocating with a size larger than the initial slab size.
TEST(AllocatorTest, TestSmallSlabSize) {
  BumpPtrAllocator Alloc(128);

  Alloc.Allocate(200, 0);
  EXPECT_EQ(2U, Alloc.GetNumSlabs());
}

// Mock slab allocator that returns slabs aligned on 4096 bytes.  There is no
// easy portable way to do this, so this is kind of a hack.
class MockSlabAllocator : public SlabAllocator {
  MemSlab *LastSlab;

public:
  virtual ~MockSlabAllocator() { }

  virtual MemSlab *Allocate(size_t Size) {
    // Allocate space for the alignment, the slab, and a void* that goes right
    // before the slab.
    size_t Alignment = 4096;
    void *MemBase = malloc(Size + Alignment - 1 + sizeof(void*));

    // Make the slab.
    MemSlab *Slab = (MemSlab*)(((uintptr_t)MemBase+sizeof(void*)+Alignment-1) &
                               ~(uintptr_t)(Alignment - 1));
    Slab->Size = Size;
    Slab->NextPtr = 0;

    // Hold a pointer to the base so we can free the whole malloced block.
    ((void**)Slab)[-1] = MemBase;

    LastSlab = Slab;
    return Slab;
  }

  virtual void Deallocate(MemSlab *Slab) {
    free(((void**)Slab)[-1]);
  }

  MemSlab *GetLastSlab() {
    return LastSlab;
  }
};

// Allocate a large-ish block with a really large alignment so that the
// allocator will think that it has space, but after it does the alignment it
// will not.
TEST(AllocatorTest, TestBigAlignment) {
  MockSlabAllocator SlabAlloc;
  BumpPtrAllocator Alloc(4096, 4096, SlabAlloc);
  uintptr_t Ptr = (uintptr_t)Alloc.Allocate(3000, 2048);
  MemSlab *Slab = SlabAlloc.GetLastSlab();
  EXPECT_LE(Ptr + 3000, ((uintptr_t)Slab) + Slab->Size);
}

}  // anonymous namespace
<commit_msg>[Allocator] Simplify unittests by using the default size parameters in more places.<commit_after>//===- llvm/unittest/Support/AllocatorTest.cpp - BumpPtrAllocator tests ---===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "llvm/Support/Allocator.h"
#include "gtest/gtest.h"
#include <cstdlib>

using namespace llvm;

namespace {

TEST(AllocatorTest, Basics) {
  BumpPtrAllocator Alloc;
  int *a = (int*)Alloc.Allocate(sizeof(int), 0);
  int *b = (int*)Alloc.Allocate(sizeof(int) * 10, 0);
  int *c = (int*)Alloc.Allocate(sizeof(int), 0);
  *a = 1;
  b[0] = 2;
  b[9] = 2;
  *c = 3;
  EXPECT_EQ(1, *a);
  EXPECT_EQ(2, b[0]);
  EXPECT_EQ(2, b[9]);
  EXPECT_EQ(3, *c);
  EXPECT_EQ(1U, Alloc.GetNumSlabs());
}

// Allocate enough bytes to create three slabs.
TEST(AllocatorTest, ThreeSlabs) {
  BumpPtrAllocator Alloc;
  Alloc.Allocate(3000, 0);
  EXPECT_EQ(1U, Alloc.GetNumSlabs());
  Alloc.Allocate(3000, 0);
  EXPECT_EQ(2U, Alloc.GetNumSlabs());
  Alloc.Allocate(3000, 0);
  EXPECT_EQ(3U, Alloc.GetNumSlabs());
}

// Allocate enough bytes to create two slabs, reset the allocator, and do it
// again.
TEST(AllocatorTest, TestReset) {
  BumpPtrAllocator Alloc;
  Alloc.Allocate(3000, 0);
  EXPECT_EQ(1U, Alloc.GetNumSlabs());
  Alloc.Allocate(3000, 0);
  EXPECT_EQ(2U, Alloc.GetNumSlabs());
  Alloc.Reset();
  EXPECT_EQ(1U, Alloc.GetNumSlabs());
  Alloc.Allocate(3000, 0);
  EXPECT_EQ(1U, Alloc.GetNumSlabs());
  Alloc.Allocate(3000, 0);
  EXPECT_EQ(2U, Alloc.GetNumSlabs());
}

// Test some allocations at varying alignments.
TEST(AllocatorTest, TestAlignment) {
  BumpPtrAllocator Alloc;
  uintptr_t a;
  a = (uintptr_t)Alloc.Allocate(1, 2);
  EXPECT_EQ(0U, a & 1);
  a = (uintptr_t)Alloc.Allocate(1, 4);
  EXPECT_EQ(0U, a & 3);
  a = (uintptr_t)Alloc.Allocate(1, 8);
  EXPECT_EQ(0U, a & 7);
  a = (uintptr_t)Alloc.Allocate(1, 16);
  EXPECT_EQ(0U, a & 15);
  a = (uintptr_t)Alloc.Allocate(1, 32);
  EXPECT_EQ(0U, a & 31);
  a = (uintptr_t)Alloc.Allocate(1, 64);
  EXPECT_EQ(0U, a & 63);
  a = (uintptr_t)Alloc.Allocate(1, 128);
  EXPECT_EQ(0U, a & 127);
}

// Test allocating just over the slab size.  This tests a bug where before the
// allocator incorrectly calculated the buffer end pointer.
TEST(AllocatorTest, TestOverflow) {
  BumpPtrAllocator Alloc;

  // Fill the slab right up until the end pointer.
  Alloc.Allocate(4096 - sizeof(MemSlab), 0);
  EXPECT_EQ(1U, Alloc.GetNumSlabs());

  // If we don't allocate a new slab, then we will have overflowed.
  Alloc.Allocate(1, 0);
  EXPECT_EQ(2U, Alloc.GetNumSlabs());
}

// Test allocating with a size larger than the initial slab size.
TEST(AllocatorTest, TestSmallSlabSize) {
  BumpPtrAllocator Alloc;

  Alloc.Allocate(8000, 0);
  EXPECT_EQ(2U, Alloc.GetNumSlabs());
}

// Mock slab allocator that returns slabs aligned on 4096 bytes.  There is no
// easy portable way to do this, so this is kind of a hack.
class MockSlabAllocator : public SlabAllocator {
  MemSlab *LastSlab;

public:
  virtual ~MockSlabAllocator() { }

  virtual MemSlab *Allocate(size_t Size) {
    // Allocate space for the alignment, the slab, and a void* that goes right
    // before the slab.
    size_t Alignment = 4096;
    void *MemBase = malloc(Size + Alignment - 1 + sizeof(void*));

    // Make the slab.
    MemSlab *Slab = (MemSlab*)(((uintptr_t)MemBase+sizeof(void*)+Alignment-1) &
                               ~(uintptr_t)(Alignment - 1));
    Slab->Size = Size;
    Slab->NextPtr = 0;

    // Hold a pointer to the base so we can free the whole malloced block.
    ((void**)Slab)[-1] = MemBase;

    LastSlab = Slab;
    return Slab;
  }

  virtual void Deallocate(MemSlab *Slab) {
    free(((void**)Slab)[-1]);
  }

  MemSlab *GetLastSlab() {
    return LastSlab;
  }
};

// Allocate a large-ish block with a really large alignment so that the
// allocator will think that it has space, but after it does the alignment it
// will not.
TEST(AllocatorTest, TestBigAlignment) {
  MockSlabAllocator SlabAlloc;
  BumpPtrAllocator Alloc(4096, 4096, SlabAlloc);
  uintptr_t Ptr = (uintptr_t)Alloc.Allocate(3000, 2048);
  MemSlab *Slab = SlabAlloc.GetLastSlab();
  EXPECT_LE(Ptr + 3000, ((uintptr_t)Slab) + Slab->Size);
}

}  // anonymous namespace
<|endoftext|>


<commit_before>#include "engine/api/route_parameters.hpp"
#include "engine/engine.hpp"
#include "engine/engine_config.hpp"
#include "engine/status.hpp"

#include "engine/plugins/match.hpp"
#include "engine/plugins/nearest.hpp"
#include "engine/plugins/table.hpp"
#include "engine/plugins/tile.hpp"
#include "engine/plugins/trip.hpp"
#include "engine/plugins/viaroute.hpp"

#include "engine/datafacade/datafacade_base.hpp"
#include "engine/datafacade/internal_datafacade.hpp"
#include "engine/datafacade/shared_datafacade.hpp"

#include "storage/shared_barriers.hpp"
#include "util/simple_logger.hpp"

#include <boost/assert.hpp>
#include <boost/interprocess/sync/named_condition.hpp>
#include <boost/interprocess/sync/scoped_lock.hpp>
#include <boost/interprocess/sync/sharable_lock.hpp>
#include <boost/thread/lock_types.hpp>

#include <algorithm>
#include <fstream>
#include <utility>
#include <vector>

namespace
{
// Abstracted away the query locking into a template function
// Works the same for every plugin.
template <typename ParameterT, typename PluginT, typename ResultT>
osrm::engine::Status
RunQuery(const std::unique_ptr<osrm::storage::SharedBarriers> &lock,
         const std::shared_ptr<osrm::engine::datafacade::BaseDataFacade> &facade,
         const ParameterT &parameters,
         PluginT &plugin,
         ResultT &result)
{
    if (!lock)
    {
        return plugin.HandleRequest(facade, parameters, result);
    }

    BOOST_ASSERT(lock);
    // this locks aquires shared ownership of the query mutex: other requets are allowed
    // to run, but data updates need to wait for all queries to finish until they can aquire an exclusive lock
    boost::interprocess::sharable_lock<boost::interprocess::named_sharable_mutex> query_lock(
        lock->query_mutex);

    auto &shared_facade = static_cast<osrm::engine::datafacade::SharedDataFacade &>(*facade);
    shared_facade.CheckAndReloadFacade();
    // Get a shared data lock so that other threads won't update
    // things while the query is running
    boost::shared_lock<boost::shared_mutex> data_lock{shared_facade.data_mutex};

    osrm::engine::Status status = plugin.HandleRequest(facade, parameters, result);

    return status;
}

} // anon. ns

namespace osrm
{
namespace engine
{

Engine::Engine(const EngineConfig &config)
    : lock(config.use_shared_memory ? std::make_unique<storage::SharedBarriers>()
                                    : std::unique_ptr<storage::SharedBarriers>())
{
    if (config.use_shared_memory)
    {
        query_data_facade = std::make_shared<datafacade::SharedDataFacade>();
    }
    else
    {
        if (!config.storage_config.IsValid())
        {
            throw util::exception("Invalid file paths given!");
        }
        query_data_facade = std::make_shared<datafacade::InternalDataFacade>(config.storage_config);
    }

    // Register plugins
    using namespace plugins;

    route_plugin = std::make_unique<ViaRoutePlugin>(config.max_locations_viaroute);
    table_plugin = std::make_unique<TablePlugin>(config.max_locations_distance_table);
    nearest_plugin = std::make_unique<NearestPlugin>(config.max_results_nearest);
    trip_plugin = std::make_unique<TripPlugin>(config.max_locations_trip);
    match_plugin = std::make_unique<MatchPlugin>(config.max_locations_map_matching);
    tile_plugin = std::make_unique<TilePlugin>();
}

// make sure we deallocate the unique ptr at a position where we know the size of the plugins
Engine::~Engine() = default;
Engine::Engine(Engine &&) noexcept = default;
Engine &Engine::operator=(Engine &&) noexcept = default;

Status Engine::Route(const api::RouteParameters &params, util::json::Object &result) const
{
    return RunQuery(lock, query_data_facade, params, *route_plugin, result);
}

Status Engine::Table(const api::TableParameters &params, util::json::Object &result) const
{
    return RunQuery(lock, query_data_facade, params, *table_plugin, result);
}

Status Engine::Nearest(const api::NearestParameters &params, util::json::Object &result) const
{
    return RunQuery(lock, query_data_facade, params, *nearest_plugin, result);
}

Status Engine::Trip(const api::TripParameters &params, util::json::Object &result) const
{
    return RunQuery(lock, query_data_facade, params, *trip_plugin, result);
}

Status Engine::Match(const api::MatchParameters &params, util::json::Object &result) const
{
    return RunQuery(lock, query_data_facade, params, *match_plugin, result);
}

Status Engine::Tile(const api::TileParameters &params, std::string &result) const
{
    return RunQuery(lock, query_data_facade, params, *tile_plugin, result);
}

} // engine ns
} // osrm ns
<commit_msg>Fixes missing memory include for make_unique; reported in #3018.<commit_after>#include "engine/engine.hpp"
#include "engine/api/route_parameters.hpp"
#include "engine/engine_config.hpp"
#include "engine/status.hpp"

#include "engine/plugins/match.hpp"
#include "engine/plugins/nearest.hpp"
#include "engine/plugins/table.hpp"
#include "engine/plugins/tile.hpp"
#include "engine/plugins/trip.hpp"
#include "engine/plugins/viaroute.hpp"

#include "engine/datafacade/datafacade_base.hpp"
#include "engine/datafacade/internal_datafacade.hpp"
#include "engine/datafacade/shared_datafacade.hpp"

#include "storage/shared_barriers.hpp"
#include "util/simple_logger.hpp"

#include <boost/assert.hpp>
#include <boost/interprocess/sync/named_condition.hpp>
#include <boost/interprocess/sync/scoped_lock.hpp>
#include <boost/interprocess/sync/sharable_lock.hpp>
#include <boost/thread/lock_types.hpp>

#include <algorithm>
#include <fstream>
#include <memory>
#include <utility>
#include <vector>

namespace
{
// Abstracted away the query locking into a template function
// Works the same for every plugin.
template <typename ParameterT, typename PluginT, typename ResultT>
osrm::engine::Status
RunQuery(const std::unique_ptr<osrm::storage::SharedBarriers> &lock,
         const std::shared_ptr<osrm::engine::datafacade::BaseDataFacade> &facade,
         const ParameterT &parameters,
         PluginT &plugin,
         ResultT &result)
{
    if (!lock)
    {
        return plugin.HandleRequest(facade, parameters, result);
    }

    BOOST_ASSERT(lock);
    // this locks aquires shared ownership of the query mutex: other requets are allowed
    // to run, but data updates need to wait for all queries to finish until they can aquire an
    // exclusive lock
    boost::interprocess::sharable_lock<boost::interprocess::named_sharable_mutex> query_lock(
        lock->query_mutex);

    auto &shared_facade = static_cast<osrm::engine::datafacade::SharedDataFacade &>(*facade);
    shared_facade.CheckAndReloadFacade();
    // Get a shared data lock so that other threads won't update
    // things while the query is running
    boost::shared_lock<boost::shared_mutex> data_lock{shared_facade.data_mutex};

    osrm::engine::Status status = plugin.HandleRequest(facade, parameters, result);

    return status;
}

} // anon. ns

namespace osrm
{
namespace engine
{

Engine::Engine(const EngineConfig &config)
    : lock(config.use_shared_memory ? std::make_unique<storage::SharedBarriers>()
                                    : std::unique_ptr<storage::SharedBarriers>())
{
    if (config.use_shared_memory)
    {
        query_data_facade = std::make_shared<datafacade::SharedDataFacade>();
    }
    else
    {
        if (!config.storage_config.IsValid())
        {
            throw util::exception("Invalid file paths given!");
        }
        query_data_facade = std::make_shared<datafacade::InternalDataFacade>(config.storage_config);
    }

    // Register plugins
    using namespace plugins;

    route_plugin = std::make_unique<ViaRoutePlugin>(config.max_locations_viaroute);
    table_plugin = std::make_unique<TablePlugin>(config.max_locations_distance_table);
    nearest_plugin = std::make_unique<NearestPlugin>(config.max_results_nearest);
    trip_plugin = std::make_unique<TripPlugin>(config.max_locations_trip);
    match_plugin = std::make_unique<MatchPlugin>(config.max_locations_map_matching);
    tile_plugin = std::make_unique<TilePlugin>();
}

// make sure we deallocate the unique ptr at a position where we know the size of the plugins
Engine::~Engine() = default;
Engine::Engine(Engine &&) noexcept = default;
Engine &Engine::operator=(Engine &&) noexcept = default;

Status Engine::Route(const api::RouteParameters &params, util::json::Object &result) const
{
    return RunQuery(lock, query_data_facade, params, *route_plugin, result);
}

Status Engine::Table(const api::TableParameters &params, util::json::Object &result) const
{
    return RunQuery(lock, query_data_facade, params, *table_plugin, result);
}

Status Engine::Nearest(const api::NearestParameters &params, util::json::Object &result) const
{
    return RunQuery(lock, query_data_facade, params, *nearest_plugin, result);
}

Status Engine::Trip(const api::TripParameters &params, util::json::Object &result) const
{
    return RunQuery(lock, query_data_facade, params, *trip_plugin, result);
}

Status Engine::Match(const api::MatchParameters &params, util::json::Object &result) const
{
    return RunQuery(lock, query_data_facade, params, *match_plugin, result);
}

Status Engine::Tile(const api::TileParameters &params, std::string &result) const
{
    return RunQuery(lock, query_data_facade, params, *tile_plugin, result);
}

} // engine ns
} // osrm ns
<|endoftext|>


<commit_before>/*
 * Copyright 2019-present Facebook, Inc.
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

#include <thrift/compiler/lib/java/util.h>

#include <cctype>

namespace apache {
namespace thrift {
namespace compiler {
namespace java {

std::string mangle_java_name(const std::string& ref, bool capitalize) {
  std::ostringstream res;
  // When we are capitalizing, initialize upCase to true in order to force first
  // character to upper case
  bool upcase = capitalize;
  // On the other hand, force first character to lowercase, unless both first
  // AND second characters are uppercase (this is so we don't mess up any
  // poorly-named method that might start with acronyms)
  bool acronym = ref.size() > 1 && std::isupper(ref[0]) && std::isupper(ref[1]);
  bool downcase = !capitalize && !acronym;
  for (typename std::string::size_type i = 0; i < ref.size(); ++i) {
    if (ref[i] == '_') {
      upcase = true;
      continue;
    } else {
      char ch = ref[i];
      if (downcase) {
        ch = std::tolower(ch);
      }
      if (upcase) {
        ch = std::toupper(ch);
      }
      res << ch;
      upcase = false;
      downcase = false;
    }
  }
  return res.str();
}

std::string mangle_java_constant_name(const std::string& ref) {
  std::ostringstream res;
  bool lowercase = false;
  for (typename std::string::size_type i = 0; i < ref.size(); ++i) {
    char ch = ref[i];
    if (std::isupper(ch)) {
      if (lowercase) {
        res << '_';
      }
      res << static_cast<char>(std::toupper(ch));
      lowercase = false;
    } else if (std::islower(ch)) {
      res << static_cast<char>(std::toupper(ch));
      lowercase = true;
    } else {
      // Not a letter, just emit it
      res << ch;
    }
  }
  return res.str();
}

std::string quote_java_string(const std::string& unescaped) {
  std::ostringstream quoted;
  quoted << '\"';
  for (std::string::size_type i = 0; i < unescaped.size();) {
    switch (unescaped[i]) {
      case '\\': {
        quoted << unescaped[i];
        ++i;
        assert(i <= unescaped.size());
        if (i == unescaped.size()) {
          throw std::runtime_error(
              "compiler error: leading backslash missing escape sequence: " +
              unescaped);
        }
        if (unescaped[i] == 'x') {
          auto end = unescaped.find_first_not_of("0123456789abcdefABCDEF", ++i);
          if (end == std::string::npos) {
            end = unescaped.size();
          }
          if (end == i) {
            throw std::runtime_error(
                "compiler error: missing hexadecimal character code in escape sequence: " +
                unescaped);
          }
          assert(i < end);
          if (end > i + 2) {
            end = i + 2;
          }
          quoted << 'u';
          for (auto n = 4 - (end - i); n--;) {
            quoted << '0';
          }
          quoted.write(std::next(unescaped.data(), i), end - i);
          i = end;
        } else {
          quoted << unescaped[i++];
        }
        break;
      }
      case '"':
        quoted << '\\' << unescaped[i];
        ++i;
        break;
      default:
        quoted << unescaped[i];
        ++i;
        break;
    }
  }
  quoted << '\"';

  return quoted.str();
}

std::string package_to_path(std::string package) {
  if (boost::algorithm::contains(package, "/")) {
    std::ostringstream err;
    err << "\"" << package << "\" is not a valid Java package name";
    throw std::runtime_error{err.str()};
  }
  boost::algorithm::replace_all(package, ".", "/");
  return package;
}
} // namespace java
} // namespace compiler
} // namespace thrift
} // namespace apache
<commit_msg>thrift: add missing cassert include for assert.<commit_after>/*
 * Copyright 2019-present Facebook, Inc.
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

#include <thrift/compiler/lib/java/util.h>

#include <cassert>
#include <cctype>

namespace apache {
namespace thrift {
namespace compiler {
namespace java {

std::string mangle_java_name(const std::string& ref, bool capitalize) {
  std::ostringstream res;
  // When we are capitalizing, initialize upCase to true in order to force first
  // character to upper case
  bool upcase = capitalize;
  // On the other hand, force first character to lowercase, unless both first
  // AND second characters are uppercase (this is so we don't mess up any
  // poorly-named method that might start with acronyms)
  bool acronym = ref.size() > 1 && std::isupper(ref[0]) && std::isupper(ref[1]);
  bool downcase = !capitalize && !acronym;
  for (typename std::string::size_type i = 0; i < ref.size(); ++i) {
    if (ref[i] == '_') {
      upcase = true;
      continue;
    } else {
      char ch = ref[i];
      if (downcase) {
        ch = std::tolower(ch);
      }
      if (upcase) {
        ch = std::toupper(ch);
      }
      res << ch;
      upcase = false;
      downcase = false;
    }
  }
  return res.str();
}

std::string mangle_java_constant_name(const std::string& ref) {
  std::ostringstream res;
  bool lowercase = false;
  for (typename std::string::size_type i = 0; i < ref.size(); ++i) {
    char ch = ref[i];
    if (std::isupper(ch)) {
      if (lowercase) {
        res << '_';
      }
      res << static_cast<char>(std::toupper(ch));
      lowercase = false;
    } else if (std::islower(ch)) {
      res << static_cast<char>(std::toupper(ch));
      lowercase = true;
    } else {
      // Not a letter, just emit it
      res << ch;
    }
  }
  return res.str();
}

std::string quote_java_string(const std::string& unescaped) {
  std::ostringstream quoted;
  quoted << '\"';
  for (std::string::size_type i = 0; i < unescaped.size();) {
    switch (unescaped[i]) {
      case '\\': {
        quoted << unescaped[i];
        ++i;
        assert(i <= unescaped.size());
        if (i == unescaped.size()) {
          throw std::runtime_error(
              "compiler error: leading backslash missing escape sequence: " +
              unescaped);
        }
        if (unescaped[i] == 'x') {
          auto end = unescaped.find_first_not_of("0123456789abcdefABCDEF", ++i);
          if (end == std::string::npos) {
            end = unescaped.size();
          }
          if (end == i) {
            throw std::runtime_error(
                "compiler error: missing hexadecimal character code in escape sequence: " +
                unescaped);
          }
          assert(i < end);
          if (end > i + 2) {
            end = i + 2;
          }
          quoted << 'u';
          for (auto n = 4 - (end - i); n--;) {
            quoted << '0';
          }
          quoted.write(std::next(unescaped.data(), i), end - i);
          i = end;
        } else {
          quoted << unescaped[i++];
        }
        break;
      }
      case '"':
        quoted << '\\' << unescaped[i];
        ++i;
        break;
      default:
        quoted << unescaped[i];
        ++i;
        break;
    }
  }
  quoted << '\"';

  return quoted.str();
}

std::string package_to_path(std::string package) {
  if (boost::algorithm::contains(package, "/")) {
    std::ostringstream err;
    err << "\"" << package << "\" is not a valid Java package name";
    throw std::runtime_error{err.str()};
  }
  boost::algorithm::replace_all(package, ".", "/");
  return package;
}
} // namespace java
} // namespace compiler
} // namespace thrift
} // namespace apache
<|endoftext|>


<commit_before>#include <mlopen/handle.hpp>
#include <mlopen/errors.hpp>
#if MLOPEN_BACKEND_HIPOC
#include <mlopen/kernel_cache.hpp>
#endif
#include <algorithm>

#ifndef _WIN32
#include <unistd.h>
#endif

#include <chrono>
#include <thread>

namespace mlopen {

hipDevice_t get_device(int id)
{
    hipDevice_t device;
    auto status = hipDeviceGet(&device, id);
    if (status != hipSuccess) MLOPEN_THROW("No device");
    return device;
}

int get_device_id() // Get random device
{
    int device;
    auto status = hipGetDevice(&device);
    if (status != hipSuccess) MLOPEN_THROW("No device");
    return device;
}

void set_device(int id)
{
    auto status = hipSetDevice(id);
    if (status != hipSuccess) MLOPEN_THROW("Error setting device");
}

void set_default_device()
{
    int n;
    auto status = hipGetDeviceCount(&n);
    if (status != hipSuccess) MLOPEN_THROW("Error getting device count");
    // Pick device based on process id
    auto pid = ::getpid();
    assert(pid > 0);
    set_device(pid % n);
}

struct HandleImpl
{
    // typedef MLOPEN_MANAGE_PTR(hipStream_t, hipStreamDestroy) StreamPtr;
    using StreamPtr = std::shared_ptr<typename std::remove_pointer<hipStream_t>::type>;

    HandleImpl()
    {}

    StreamPtr create_stream()
    {
        hipStream_t result;
        auto status = hipStreamCreate(&result);
        if (status != hipSuccess) MLOPEN_THROW_HIP_STATUS(status, "Failed to allocate stream");
        return StreamPtr{result, &hipStreamDestroy};
    }

    static StreamPtr reference_stream(hipStream_t s)
    {
        return StreamPtr{s, null_deleter{}};
    }

    void elapsed_time(hipEvent_t start, hipEvent_t stop)
    {
        hipEventElapsedTime(&this->profiling_result, start, stop);
    }

    std::function<void(hipEvent_t, hipEvent_t)> elapsed_time_handler()
    {
        return std::bind(&HandleImpl::elapsed_time, this, std::placeholders::_1, std::placeholders::_2);
    }

    bool enable_profiling = false;
    std::vector<StreamPtr> streams;
    float profiling_result = 0.0;
#if MLOPEN_BACKEND_HIPOC
    KernelCache cache;
#endif
};

Handle::Handle (int numStreams, mlopenAcceleratorQueue_t *streams)
: impl(new HandleImpl())
{
    std::transform(streams, streams+numStreams, std::back_inserter(this->impl->streams), [](hipStream_t x) {
        return HandleImpl::reference_stream(x);
    });
}

Handle::Handle ()
: impl(new HandleImpl())
{
    set_default_device();
    // this->impl->streams.push_back(impl->create_stream());
    this->impl->streams.push_back(HandleImpl::reference_stream(nullptr));
}

Handle::~Handle() {}

mlopenAcceleratorQueue_t Handle::GetStream() const
{
    return impl->streams.front().get();
}

void Handle::EnableProfiling(bool enable)
{
    this->impl->enable_profiling = enable;
}

float Handle::GetKernelTime() const
{
    return this->impl->profiling_result;
}

ManageDataPtr Handle::Create(int sz)
{
    this->Finish();
    void * result;
    // int tries = 10;
    auto status = hipMalloc(&result, sz);
    if (status != hipSuccess)
    {
        status = hipHostMalloc(&result, sz);
        if (status != hipSuccess) MLOPEN_THROW_HIP_STATUS(status, "Hip error creating buffer " + std::to_string(sz) + ": ");
    }
    return ManageDataPtr{result};
}
ManageDataPtr& Handle::WriteTo(const void* data, ManageDataPtr& ddata, int sz)
{
    this->Finish();
    auto status = hipMemcpy(ddata.get(), data, sz, hipMemcpyHostToDevice);
    if (status != hipSuccess) MLOPEN_THROW_HIP_STATUS(status, "Hip error writing to buffer: ");
    return ddata;
}
void Handle::ReadTo(void* data, const ManageDataPtr& ddata, int sz)
{
    this->Finish();
    auto status = hipMemcpy(data, ddata.get(), sz, hipMemcpyDeviceToHost);
    if (status != hipSuccess) MLOPEN_THROW_HIP_STATUS(status, "Hip error reading from buffer: ");
}

void Handle::Copy(ConstData_t src, Data_t dest, int size)
{
    auto status = hipMemcpy(dest, src, size, hipMemcpyDeviceToDevice);
    if (status != hipSuccess) MLOPEN_THROW_HIP_STATUS(status, "Hip error copying buffer: ");
}

#if MLOPEN_BACKEND_HIPOC
KernelInvoke Handle::GetKernel(
        const std::string& algorithm,
        const std::string& network_config,
        const std::string& program_name,
        const std::string& kernel_name,
        const std::vector<size_t>& vld,
        const std::vector<size_t>& vgd,
        const std::string& params)
{
    auto k = this->impl->cache.GetKernel(*this,
            algorithm,
            network_config,
            program_name,
            kernel_name,
            vld,
            vgd,
            params);
    if (this->impl->enable_profiling) return k.Invoke(this->GetStream(), this->impl->elapsed_time_handler());
    else return k.Invoke(this->GetStream());
}

KernelInvoke Handle::GetKernel(
    const std::string& algorithm,
    const std::string& network_config)
{
    auto k = this->impl->cache.GetKernel(
            algorithm,
            network_config);
    if (this->impl->enable_profiling) return k.Invoke(this->GetStream(), this->impl->elapsed_time_handler());
    else return k.Invoke(this->GetStream());
}

Program Handle::LoadProgram(const std::string &program_name, std::string params, bool is_kernel_str)
{
    return HIPOCProgram{program_name, params, is_kernel_str};
}

void Handle::Finish() const
{
    auto status = hipStreamSynchronize(this->GetStream());
    if (status != hipSuccess) MLOPEN_THROW_HIP_STATUS(status, "Failed hip sychronization");
}
void Handle::Flush() const
{

}

bool Handle::IsProfilingEnabled() const
{
	return this->impl->enable_profiling;
}

void Handle::ResetKernelTime(void)
{
    this->impl->profiling_result = 0.0;
}
void Handle::AccumKernelTime(float x)
{
    this->impl->profiling_result += x;
}

std::size_t Handle::GetLocalMemorySize()
{
    int result;
    auto status = hipDeviceGetAttribute(&result, hipDeviceAttributeMaxSharedMemoryPerBlock, get_device_id());
    if (status != hipSuccess) MLOPEN_THROW_HIP_STATUS(status);

    return result;
}

std::size_t Handle::GetMaxComputeUnits()
{
    int result;
    auto status = hipDeviceGetAttribute(&result, hipDeviceAttributeMultiprocessorCount, get_device_id());
    if (status != hipSuccess) MLOPEN_THROW_HIP_STATUS(status);

    return result;
}

std::string Handle::GetDeviceName()
{
    // TODO
    return "Fiji";
}
#endif
}

<commit_msg>fixed device-name for hip<commit_after>#include <mlopen/handle.hpp>
#include <mlopen/errors.hpp>
#if MLOPEN_BACKEND_HIPOC
#include <mlopen/kernel_cache.hpp>
#endif
#include <algorithm>

#ifndef _WIN32
#include <unistd.h>
#endif

#include <chrono>
#include <thread>

namespace mlopen {

hipDevice_t get_device(int id)
{
    hipDevice_t device;
    auto status = hipDeviceGet(&device, id);
    if (status != hipSuccess) MLOPEN_THROW("No device");
    return device;
}

int get_device_id() // Get random device
{
    int device;
    auto status = hipGetDevice(&device);
    if (status != hipSuccess) MLOPEN_THROW("No device");
    return device;
}

void set_device(int id)
{
    auto status = hipSetDevice(id);
    if (status != hipSuccess) MLOPEN_THROW("Error setting device");
}

void set_default_device()
{
    int n;
    auto status = hipGetDeviceCount(&n);
    if (status != hipSuccess) MLOPEN_THROW("Error getting device count");
    // Pick device based on process id
    auto pid = ::getpid();
    assert(pid > 0);
    set_device(pid % n);
}

struct HandleImpl
{
    // typedef MLOPEN_MANAGE_PTR(hipStream_t, hipStreamDestroy) StreamPtr;
    using StreamPtr = std::shared_ptr<typename std::remove_pointer<hipStream_t>::type>;

    HandleImpl()
    {}

    StreamPtr create_stream()
    {
        hipStream_t result;
        auto status = hipStreamCreate(&result);
        if (status != hipSuccess) MLOPEN_THROW_HIP_STATUS(status, "Failed to allocate stream");
        return StreamPtr{result, &hipStreamDestroy};
    }

    static StreamPtr reference_stream(hipStream_t s)
    {
        return StreamPtr{s, null_deleter{}};
    }

    void elapsed_time(hipEvent_t start, hipEvent_t stop)
    {
        hipEventElapsedTime(&this->profiling_result, start, stop);
    }

    std::function<void(hipEvent_t, hipEvent_t)> elapsed_time_handler()
    {
        return std::bind(&HandleImpl::elapsed_time, this, std::placeholders::_1, std::placeholders::_2);
    }

    bool enable_profiling = false;
    std::vector<StreamPtr> streams;
    float profiling_result = 0.0;
#if MLOPEN_BACKEND_HIPOC
    KernelCache cache;
#endif
};

Handle::Handle (int numStreams, mlopenAcceleratorQueue_t *streams)
: impl(new HandleImpl())
{
    std::transform(streams, streams+numStreams, std::back_inserter(this->impl->streams), [](hipStream_t x) {
        return HandleImpl::reference_stream(x);
    });
}

Handle::Handle ()
: impl(new HandleImpl())
{
    set_default_device();
    // this->impl->streams.push_back(impl->create_stream());
    this->impl->streams.push_back(HandleImpl::reference_stream(nullptr));
}

Handle::~Handle() {}

mlopenAcceleratorQueue_t Handle::GetStream() const
{
    return impl->streams.front().get();
}

void Handle::EnableProfiling(bool enable)
{
    this->impl->enable_profiling = enable;
}

float Handle::GetKernelTime() const
{
    return this->impl->profiling_result;
}

ManageDataPtr Handle::Create(int sz)
{
    this->Finish();
    void * result;
    // int tries = 10;
    auto status = hipMalloc(&result, sz);
    if (status != hipSuccess)
    {
        status = hipHostMalloc(&result, sz);
        if (status != hipSuccess) MLOPEN_THROW_HIP_STATUS(status, "Hip error creating buffer " + std::to_string(sz) + ": ");
    }
    return ManageDataPtr{result};
}
ManageDataPtr& Handle::WriteTo(const void* data, ManageDataPtr& ddata, int sz)
{
    this->Finish();
    auto status = hipMemcpy(ddata.get(), data, sz, hipMemcpyHostToDevice);
    if (status != hipSuccess) MLOPEN_THROW_HIP_STATUS(status, "Hip error writing to buffer: ");
    return ddata;
}
void Handle::ReadTo(void* data, const ManageDataPtr& ddata, int sz)
{
    this->Finish();
    auto status = hipMemcpy(data, ddata.get(), sz, hipMemcpyDeviceToHost);
    if (status != hipSuccess) MLOPEN_THROW_HIP_STATUS(status, "Hip error reading from buffer: ");
}

void Handle::Copy(ConstData_t src, Data_t dest, int size)
{
    auto status = hipMemcpy(dest, src, size, hipMemcpyDeviceToDevice);
    if (status != hipSuccess) MLOPEN_THROW_HIP_STATUS(status, "Hip error copying buffer: ");
}

#if MLOPEN_BACKEND_HIPOC
KernelInvoke Handle::GetKernel(
        const std::string& algorithm,
        const std::string& network_config,
        const std::string& program_name,
        const std::string& kernel_name,
        const std::vector<size_t>& vld,
        const std::vector<size_t>& vgd,
        const std::string& params)
{
    auto k = this->impl->cache.GetKernel(*this,
            algorithm,
            network_config,
            program_name,
            kernel_name,
            vld,
            vgd,
            params);
    if (this->impl->enable_profiling) return k.Invoke(this->GetStream(), this->impl->elapsed_time_handler());
    else return k.Invoke(this->GetStream());
}

KernelInvoke Handle::GetKernel(
    const std::string& algorithm,
    const std::string& network_config)
{
    auto k = this->impl->cache.GetKernel(
            algorithm,
            network_config);
    if (this->impl->enable_profiling) return k.Invoke(this->GetStream(), this->impl->elapsed_time_handler());
    else return k.Invoke(this->GetStream());
}

Program Handle::LoadProgram(const std::string &program_name, std::string params, bool is_kernel_str)
{
    return HIPOCProgram{program_name, params, is_kernel_str};
}

void Handle::Finish() const
{
    auto status = hipStreamSynchronize(this->GetStream());
    if (status != hipSuccess) MLOPEN_THROW_HIP_STATUS(status, "Failed hip sychronization");
}
void Handle::Flush() const
{

}

bool Handle::IsProfilingEnabled() const
{
	return this->impl->enable_profiling;
}

void Handle::ResetKernelTime(void)
{
    this->impl->profiling_result = 0.0;
}
void Handle::AccumKernelTime(float x)
{
    this->impl->profiling_result += x;
}

std::size_t Handle::GetLocalMemorySize()
{
    int result;
    auto status = hipDeviceGetAttribute(&result, hipDeviceAttributeMaxSharedMemoryPerBlock, get_device_id());
    if (status != hipSuccess) MLOPEN_THROW_HIP_STATUS(status);

    return result;
}

std::size_t Handle::GetMaxComputeUnits()
{
    int result;
    auto status = hipDeviceGetAttribute(&result, hipDeviceAttributeMultiprocessorCount, get_device_id());
    if (status != hipSuccess) MLOPEN_THROW_HIP_STATUS(status);

    return result;
}

std::string Handle::GetDeviceName()
{
    hipDeviceProp_t props;
    hipGetDeviceProperties(&props, get_device_id());

	return GetDeviceNameFromMap(props.name);
}
#endif
}

<|endoftext|>


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

#include "loggingLogSvcHandler.h"
#include <loggingLoggingProxy.h>
#include <loggingLogLevelDefinition.h>
#ifdef MAKE_VXWORKS
#include <acsutil.h>
#endif

#include <ace/Log_Record.h>

static char *rcsId="@(#) $Id: loggingLogSvcHandler.cpp,v 1.33 2010/04/30 10:26:48 bjeram Exp $";
static void *use_rcsId = ((void)&use_rcsId,(void *) &rcsId);

namespace Logging {
    // ----------------------------------------------------------
    //helper function used to convert from ACS logging priorities
    //to ACE log priorities
    ACE_Log_Priority
    acs2acePriority(Logging::BaseLog::Priority acsPriority)
    {
	ACE_Log_Priority retVal = LM_SHUTDOWN;

	switch(acsPriority)
	    {
	    case Logging::BaseLog::LM_TRACE:
		retVal = LM_TRACE;
		break;

        case Logging::BaseLog::LM_DELOUSE:
        retVal = (ACE_Log_Priority)010000;
        break;

	    case Logging::BaseLog::LM_DEBUG:
		retVal = LM_DEBUG;
		break;

	    case Logging::BaseLog::LM_INFO:
		retVal = LM_INFO;
		break;

	    case Logging::BaseLog::LM_NOTICE:
		retVal = LM_NOTICE;
		break;

	    case Logging::BaseLog::LM_WARNING:
		retVal = LM_WARNING;
		break;

	    case Logging::BaseLog::LM_ERROR:
		retVal = LM_ERROR;
		break;

	    case Logging::BaseLog::LM_CRITICAL:
		retVal = LM_CRITICAL;
		break;

	    case Logging::BaseLog::LM_ALERT:
		retVal = LM_ALERT;
		break;

	    case Logging::BaseLog::LM_EMERGENCY:
		retVal = LM_EMERGENCY;
		break;

            case Logging::BaseLog::LM_SHUTDOWN:
		retVal = LM_SHUTDOWN;
		break;

	    default:
		//should NEVER be the case but
		//if this does occur we default
		//to a level that will always be
		//logged
		retVal = LM_SHUTDOWN;
	    }

	return retVal;
    }

    // ----------------------------------------------------------
    //helper function used to convert from ACE logging priorities
    //to ACS log priorities
    Logging::BaseLog::Priority
    ace2acsPriority(ACE_Log_Priority acePriority)
    {
	Logging::BaseLog::Priority retVal = Logging::BaseLog::LM_SHUTDOWN;

	switch(acePriority)
	    {
	    case LM_TRACE:
		retVal = Logging::BaseLog::LM_TRACE;
		break;

        case 010000:
        retVal = Logging::BaseLog::LM_DELOUSE;
        break;

	    case LM_DEBUG:
		retVal = Logging::BaseLog::LM_DEBUG;
		break;

	    case LM_INFO:
		retVal = Logging::BaseLog::LM_INFO;
		break;

	    case LM_NOTICE:
		retVal = Logging::BaseLog::LM_NOTICE;
		break;

	    case LM_WARNING:
		retVal = Logging::BaseLog::LM_WARNING;
		break;

	    case LM_ERROR:
		retVal = Logging::BaseLog::LM_ERROR;
		break;

	    case LM_CRITICAL:
		retVal = Logging::BaseLog::LM_CRITICAL;
		break;

	    case LM_ALERT:
		retVal = Logging::BaseLog::LM_ALERT;
		break;

	    case LM_EMERGENCY:
		retVal = Logging::BaseLog::LM_EMERGENCY;
		break;

            case LM_SHUTDOWN:
		retVal = Logging::BaseLog::LM_SHUTDOWN;
		break;

	    default:
		//should NEVER be the case but
		//if this does occur we default
		//to a level that will always be
		//logged
		retVal = Logging::BaseLog::LM_SHUTDOWN;
	    }

	return retVal;
    }
    // ----------------------------------------------------------
    LogSvcHandler::LogSvcHandler(const std::string& soName) :
	sourceObjectName_m(soName)
    {
        setRemoteLevelType(NOT_DEFINED_LOG_LEVEL);
        setLocalLevelType(NOT_DEFINED_LOG_LEVEL);
	char *acsSTDIO = getenv("ACS_LOG_STDOUT");
	int envStdioPriority = -1;
	if (acsSTDIO && *acsSTDIO)
	{
		envStdioPriority = atoi(acsSTDIO);
	}

	char *acsCentralizeLogger = getenv("ACS_LOG_CENTRAL");
	int envCentralizePriority = -1;
	if (acsCentralizeLogger && *acsCentralizeLogger)
	{
		envCentralizePriority = atoi(acsCentralizeLogger);
	}
	setLevels(LM_TRACE, LM_TRACE,DEFAULT_LOG_LEVEL);
	if(envStdioPriority >= 0)
		setLevels((Priority)-1, static_cast<Logging::BaseLog::Priority>(LogLevelDefinition::getACELogPriority(envStdioPriority)), ENV_LOG_LEVEL);

	if(envCentralizePriority >= 0)
		setLevels(static_cast<Logging::BaseLog::Priority>(LogLevelDefinition::getACELogPriority(envCentralizePriority)), (Priority)-1, ENV_LOG_LEVEL);
    }
    // ----------------------------------------------------------
    void
    LogSvcHandler::log(const LogRecord& lr)
    {
	//may need to make some changes to the message if the CORBA
	//logging service is down
	std::string message = lr.message;

	//if it's a trace we set the message to be "".
	if((lr.priority==LM_TRACE) &&
	   (message==FIELD_UNAVAILABLE))
	    {
	    message = "";
	    }

	//add a newline if the logging service is unavailable
	if(LoggingProxy::isInit()==false)
	    {
	    message = message + '\n';
	    }

	LoggingProxy::File(lr.file.c_str());
	LoggingProxy::Line(lr.line);

	//only set the logging flags if the priority is debug or trace
	if((lr.priority==LM_DEBUG)||(lr.priority==LM_TRACE))
	    {
	    LoggingProxy::Flags(LM_SOURCE_INFO | LM_RUNTIME_CONTEXT);
	    }

	//if the field is available
	if(lr.method!=FIELD_UNAVAILABLE)
	    {
	    //set the routine name.
	    LoggingProxy::Routine(lr.method.c_str());
	    }
        else
            {
	    LoggingProxy::Routine("");
            }

 	if(lr.priority == LM_SHUTDOWN)
	   message = " -- ERROR in the priority of this message, please check the source --" + message;
	//set the component/container/etc name
	LoggingProxy::SourceObject(sourceObjectName_m.c_str());

	//figure out the time
	long sec_ =  ACE_static_cast(CORBA::ULongLong, lr.timeStamp) / ACE_static_cast(ACE_UINT32, 10000000u) - ACE_UINT64_LITERAL(0x2D8539C80);
        long usec_ = (lr.timeStamp % 10000000u) / 10;
        ACE_Time_Value time(sec_, usec_);

	//create the ACE log message
	/**
         * @todo Here there was an assignment to
	 * a local variable never used.
	 * Why was that?
         * I have now commented it out
	 * int __ace_error = ACE_Log_Msg::last_error_adapter();
	 */
	ACE_Log_Msg::last_error_adapter();

	ACE_Log_Msg *ace___ = ACE_Log_Msg::instance();

	//create the ACE log record using the message
	ACE_Log_Record log_record_(acs2acePriority(lr.priority), time, 0);
	log_record_.msg_data(message.c_str());

	// set private flags
 	const int prohibitLocal  = getLocalLevel() == LM_SHUTDOWN || lr.priority <  getLocalLevel() ? 1 : 0;
 	const int prohibitRemote = getRemoteLevel() == LM_SHUTDOWN ||lr.priority < getRemoteLevel() ? 2 : 0;
  	LoggingProxy::PrivateFlags(prohibitLocal | prohibitRemote);
  	LoggingProxy::LogLevelLocalType(getLocalLevelType());
  	LoggingProxy::LogLevelRemoteType(getRemoteLevelType());
	ace___->log(log_record_, 0);
    }
    // ----------------------------------------------------------
    std::string
    LogSvcHandler::getName() const
    {
	return std::string("acsLogSvc");
    }
    // ----------------------------------------------------------
    void
	LogSvcHandler::setLevels(Priority remotePriority, Priority localPriority, int type)
	{
	    if(remotePriority >0 && (type == CDB_REFRESH_LOG_LEVEL  || getRemoteLevelType() >= type) ){
		    setRemoteLevelType(type);
		    setRemoteLevel(remotePriority);
	    }
	    if(localPriority > 0 && ( type == CDB_REFRESH_LOG_LEVEL || getLocalLevelType() >= type )){
		    setLocalLevelType(type);
		    setLocalLevel(localPriority);
	    }
	    // set global level (min of both)
	    setLevel(static_cast<Logging::BaseLog::Priority>(getLocalLevel() < getRemoteLevel() ? getLocalLevel() : getRemoteLevel()));
	}
    // ----------------------------------------------------------
    //--The following section exists solely to remain
    //--backwards compatible with the ACS 4.0 and earlier
    //--logging systems. This is provided so that formatted
    //--(i.e., printf, scanf, etc) messages are supported.
    //--At some point in time this should
    //--be removed!
    //-----------------------------------------------------------
    LogSvcHandler::DeprecatedLogInfo
    LogSvcHandler::unformatted2formatted(ACE_Log_Priority messagePriority,
					 const char *fmt,
					 ...)
    {
	//tells the compiler to check the format
	//every time it is called for format string and arguments matching in number
	//DWF-for some reason this does not compile
	//__attribute__ ((format (printf, 2, 3)));

	LogSvcHandler::DeprecatedLogInfo retVal;
	retVal.priority = ace2acsPriority(messagePriority);

	//take the format string along with the parameters
	//and convert them into the formatted string.
	va_list argp;
	va_start(argp, fmt);

	//temporary storage to hold the entire formatted
	//message.
	char tempMessage[MAX_MESSAGE_SIZE];

	vsnprintf(tempMessage, sizeof(tempMessage), fmt, argp);

	va_end(argp);

	//copy the data
	retVal.message = tempMessage;

	return retVal;
    }
};

/*___oOo___*/
<commit_msg>replaced ACE_static_cast with static_cast<> as part of port to ACE+TAOx21<commit_after>/*******************************************************************************
* ALMA - Atacama Large Millimiter Array
* (c) UNSPECIFIED - FILL IN, 2005
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
*
* "@(#) $Id: loggingLogSvcHandler.cpp,v 1.33 2010/04/30 10:26:48 bjeram Exp $"
*
* who       when      what
* --------  --------  ----------------------------------------------
* dfugate  2005-04-04  created
*/

#include "loggingLogSvcHandler.h"
#include <loggingLoggingProxy.h>
#include <loggingLogLevelDefinition.h>
#ifdef MAKE_VXWORKS
#include <acsutil.h>
#endif

#include <ace/Log_Record.h>

static char *rcsId="@(#) $Id: loggingLogSvcHandler.cpp,v 1.33 2010/04/30 10:26:48 bjeram Exp $";
static void *use_rcsId = ((void)&use_rcsId,(void *) &rcsId);

namespace Logging {
    // ----------------------------------------------------------
    //helper function used to convert from ACS logging priorities
    //to ACE log priorities
    ACE_Log_Priority
    acs2acePriority(Logging::BaseLog::Priority acsPriority)
    {
	ACE_Log_Priority retVal = LM_SHUTDOWN;

	switch(acsPriority)
	    {
	    case Logging::BaseLog::LM_TRACE:
		retVal = LM_TRACE;
		break;

        case Logging::BaseLog::LM_DELOUSE:
        retVal = (ACE_Log_Priority)010000;
        break;

	    case Logging::BaseLog::LM_DEBUG:
		retVal = LM_DEBUG;
		break;

	    case Logging::BaseLog::LM_INFO:
		retVal = LM_INFO;
		break;

	    case Logging::BaseLog::LM_NOTICE:
		retVal = LM_NOTICE;
		break;

	    case Logging::BaseLog::LM_WARNING:
		retVal = LM_WARNING;
		break;

	    case Logging::BaseLog::LM_ERROR:
		retVal = LM_ERROR;
		break;

	    case Logging::BaseLog::LM_CRITICAL:
		retVal = LM_CRITICAL;
		break;

	    case Logging::BaseLog::LM_ALERT:
		retVal = LM_ALERT;
		break;

	    case Logging::BaseLog::LM_EMERGENCY:
		retVal = LM_EMERGENCY;
		break;

            case Logging::BaseLog::LM_SHUTDOWN:
		retVal = LM_SHUTDOWN;
		break;

	    default:
		//should NEVER be the case but
		//if this does occur we default
		//to a level that will always be
		//logged
		retVal = LM_SHUTDOWN;
	    }

	return retVal;
    }

    // ----------------------------------------------------------
    //helper function used to convert from ACE logging priorities
    //to ACS log priorities
    Logging::BaseLog::Priority
    ace2acsPriority(ACE_Log_Priority acePriority)
    {
	Logging::BaseLog::Priority retVal = Logging::BaseLog::LM_SHUTDOWN;

	switch(acePriority)
	    {
	    case LM_TRACE:
		retVal = Logging::BaseLog::LM_TRACE;
		break;

        case 010000:
        retVal = Logging::BaseLog::LM_DELOUSE;
        break;

	    case LM_DEBUG:
		retVal = Logging::BaseLog::LM_DEBUG;
		break;

	    case LM_INFO:
		retVal = Logging::BaseLog::LM_INFO;
		break;

	    case LM_NOTICE:
		retVal = Logging::BaseLog::LM_NOTICE;
		break;

	    case LM_WARNING:
		retVal = Logging::BaseLog::LM_WARNING;
		break;

	    case LM_ERROR:
		retVal = Logging::BaseLog::LM_ERROR;
		break;

	    case LM_CRITICAL:
		retVal = Logging::BaseLog::LM_CRITICAL;
		break;

	    case LM_ALERT:
		retVal = Logging::BaseLog::LM_ALERT;
		break;

	    case LM_EMERGENCY:
		retVal = Logging::BaseLog::LM_EMERGENCY;
		break;

            case LM_SHUTDOWN:
		retVal = Logging::BaseLog::LM_SHUTDOWN;
		break;

	    default:
		//should NEVER be the case but
		//if this does occur we default
		//to a level that will always be
		//logged
		retVal = Logging::BaseLog::LM_SHUTDOWN;
	    }

	return retVal;
    }
    // ----------------------------------------------------------
    LogSvcHandler::LogSvcHandler(const std::string& soName) :
	sourceObjectName_m(soName)
    {
        setRemoteLevelType(NOT_DEFINED_LOG_LEVEL);
        setLocalLevelType(NOT_DEFINED_LOG_LEVEL);
	char *acsSTDIO = getenv("ACS_LOG_STDOUT");
	int envStdioPriority = -1;
	if (acsSTDIO && *acsSTDIO)
	{
		envStdioPriority = atoi(acsSTDIO);
	}

	char *acsCentralizeLogger = getenv("ACS_LOG_CENTRAL");
	int envCentralizePriority = -1;
	if (acsCentralizeLogger && *acsCentralizeLogger)
	{
		envCentralizePriority = atoi(acsCentralizeLogger);
	}
	setLevels(LM_TRACE, LM_TRACE,DEFAULT_LOG_LEVEL);
	if(envStdioPriority >= 0)
		setLevels((Priority)-1, static_cast<Logging::BaseLog::Priority>(LogLevelDefinition::getACELogPriority(envStdioPriority)), ENV_LOG_LEVEL);

	if(envCentralizePriority >= 0)
		setLevels(static_cast<Logging::BaseLog::Priority>(LogLevelDefinition::getACELogPriority(envCentralizePriority)), (Priority)-1, ENV_LOG_LEVEL);
    }
    // ----------------------------------------------------------
    void
    LogSvcHandler::log(const LogRecord& lr)
    {
	//may need to make some changes to the message if the CORBA
	//logging service is down
	std::string message = lr.message;

	//if it's a trace we set the message to be "".
	if((lr.priority==LM_TRACE) &&
	   (message==FIELD_UNAVAILABLE))
	    {
	    message = "";
	    }

	//add a newline if the logging service is unavailable
	if(LoggingProxy::isInit()==false)
	    {
	    message = message + '\n';
	    }

	LoggingProxy::File(lr.file.c_str());
	LoggingProxy::Line(lr.line);

	//only set the logging flags if the priority is debug or trace
	if((lr.priority==LM_DEBUG)||(lr.priority==LM_TRACE))
	    {
	    LoggingProxy::Flags(LM_SOURCE_INFO | LM_RUNTIME_CONTEXT);
	    }

	//if the field is available
	if(lr.method!=FIELD_UNAVAILABLE)
	    {
	    //set the routine name.
	    LoggingProxy::Routine(lr.method.c_str());
	    }
        else
            {
	    LoggingProxy::Routine("");
            }

 	if(lr.priority == LM_SHUTDOWN)
	   message = " -- ERROR in the priority of this message, please check the source --" + message;
	//set the component/container/etc name
	LoggingProxy::SourceObject(sourceObjectName_m.c_str());

	//figure out the time
	long sec_ =  static_cast<CORBA::ULongLong>( lr.timeStamp) / static_cast<ACE_UINT32>(10000000u) - ACE_UINT64_LITERAL(0x2D8539C80);
        long usec_ = (lr.timeStamp % 10000000u) / 10;
        ACE_Time_Value time(sec_, usec_);

	//create the ACE log message
	/**
         * @todo Here there was an assignment to
	 * a local variable never used.
	 * Why was that?
         * I have now commented it out
	 * int __ace_error = ACE_Log_Msg::last_error_adapter();
	 */
	ACE_Log_Msg::last_error_adapter();

	ACE_Log_Msg *ace___ = ACE_Log_Msg::instance();

	//create the ACE log record using the message
	ACE_Log_Record log_record_(acs2acePriority(lr.priority), time, 0);
	log_record_.msg_data(message.c_str());

	// set private flags
 	const int prohibitLocal  = getLocalLevel() == LM_SHUTDOWN || lr.priority <  getLocalLevel() ? 1 : 0;
 	const int prohibitRemote = getRemoteLevel() == LM_SHUTDOWN ||lr.priority < getRemoteLevel() ? 2 : 0;
  	LoggingProxy::PrivateFlags(prohibitLocal | prohibitRemote);
  	LoggingProxy::LogLevelLocalType(getLocalLevelType());
  	LoggingProxy::LogLevelRemoteType(getRemoteLevelType());
	ace___->log(log_record_, 0);
    }
    // ----------------------------------------------------------
    std::string
    LogSvcHandler::getName() const
    {
	return std::string("acsLogSvc");
    }
    // ----------------------------------------------------------
    void
	LogSvcHandler::setLevels(Priority remotePriority, Priority localPriority, int type)
	{
	    if(remotePriority >0 && (type == CDB_REFRESH_LOG_LEVEL  || getRemoteLevelType() >= type) ){
		    setRemoteLevelType(type);
		    setRemoteLevel(remotePriority);
	    }
	    if(localPriority > 0 && ( type == CDB_REFRESH_LOG_LEVEL || getLocalLevelType() >= type )){
		    setLocalLevelType(type);
		    setLocalLevel(localPriority);
	    }
	    // set global level (min of both)
	    setLevel(static_cast<Logging::BaseLog::Priority>(getLocalLevel() < getRemoteLevel() ? getLocalLevel() : getRemoteLevel()));
	}
    // ----------------------------------------------------------
    //--The following section exists solely to remain
    //--backwards compatible with the ACS 4.0 and earlier
    //--logging systems. This is provided so that formatted
    //--(i.e., printf, scanf, etc) messages are supported.
    //--At some point in time this should
    //--be removed!
    //-----------------------------------------------------------
    LogSvcHandler::DeprecatedLogInfo
    LogSvcHandler::unformatted2formatted(ACE_Log_Priority messagePriority,
					 const char *fmt,
					 ...)
    {
	//tells the compiler to check the format
	//every time it is called for format string and arguments matching in number
	//DWF-for some reason this does not compile
	//__attribute__ ((format (printf, 2, 3)));

	LogSvcHandler::DeprecatedLogInfo retVal;
	retVal.priority = ace2acsPriority(messagePriority);

	//take the format string along with the parameters
	//and convert them into the formatted string.
	va_list argp;
	va_start(argp, fmt);

	//temporary storage to hold the entire formatted
	//message.
	char tempMessage[MAX_MESSAGE_SIZE];

	vsnprintf(tempMessage, sizeof(tempMessage), fmt, argp);

	va_end(argp);

	//copy the data
	retVal.message = tempMessage;

	return retVal;
    }
};

/*___oOo___*/
<|endoftext|>


<commit_before>/*
 * (C) Copyright 2015 ETH Zurich Systems Group (http://www.systems.ethz.ch/) and others.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * Contributors:
 *     Markus Pilman <mpilman@inf.ethz.ch>
 *     Simon Loesing <sloesing@inf.ethz.ch>
 *     Thomas Etter <etterth@gmail.com>
 *     Kevin Bocksrocker <kevin.bocksrocker@gmail.com>
 *     Lucas Braun <braunl@inf.ethz.ch>
 */
#include <ch_ethz_tell_Schema.h>
#include <tellstore/Record.hpp>
#include <crossbow/enum_underlying.hpp>

#include "helpers.hpp"

jlong Java_ch_ethz_tell_Schema_construct(JNIEnv*, jobject) {
    return reinterpret_cast<long>(new tell::store::Schema());
}

void Java_ch_ethz_tell_Schema_destruct(JNIEnv*, jobject, jlong self) {
    delete reinterpret_cast<tell::store::Schema*>(self);
}

jboolean Java_ch_ethz_tell_Schema_addFieldImpl(JNIEnv* env, jobject, jlong self, jshort type, jstring jname, jboolean notNull) {
    auto s = reinterpret_cast<tell::store::Schema*>(self);
    crossbow::string name = to_string(env, jname);
    uint16_t ftU = type;
    return s->addField(crossbow::from_underlying<tell::store::FieldType>(ftU), name, notNull);
}

jboolean Java_ch_ethz_tell_Schema_allNotNullImpl(JNIEnv*, jobject, jlong self) {
    auto s = reinterpret_cast<tell::store::Schema*>(self);
    return s->allNotNull();
}

namespace {
jintArray toIntArray(JNIEnv* env, const std::vector<tell::store::Field>& fields) {
    auto res = env->NewIntArray(fields.size());
    std::unique_ptr<jint[]> tmp(new jint[fields.size()]);
    for (unsigned i = 0; i < fields.size(); ++i) {
        tmp[i] = crossbow::to_underlying(fields[i].type());
    }
    env->SetIntArrayRegion(res, 0, fields.size(), tmp.get());
    return res;
}

}

jintArray Java_ch_ethz_tell_Schema_fixedSizeFieldsImpl(JNIEnv* env, jobject, jlong self) {
    auto s = reinterpret_cast<tell::store::Schema*>(self);
    return toIntArray(env, s->fixedSizeFields());
}

jintArray Java_ch_ethz_tell_Schema_variableSizedFieldsImpl(JNIEnv* env, jobject, jlong self) {
    auto s = reinterpret_cast<tell::store::Schema*>(self);
    return toIntArray(env, s->varSizeFields());
}

jshort Java_ch_ethz_tell_Schema_idOfImpl (JNIEnv* env, jobject, jlong self, jstring columnName) {
    auto s = reinterpret_cast<tell::store::Schema*>(self);
    return s->idOf(to_string(env, columnName));
}

jshort Java_ch_ethz_tell_Schema_typeOfImpl (JNIEnv* env, jobject, jlong self, jstring columName) {
    auto s = reinterpret_cast<tell::store::Schema*>(self);
    auto field = s->getFieldFromName(to_string(env, columName));
    return static_cast<short>(field.type());
}

jboolean Java_ch_ethz_tell_Schema_nullabiltyOfImpl (JNIEnv* env, jobject, jlong self, jstring columName) {
    auto s = reinterpret_cast<tell::store::Schema*>(self);
    auto field = s->getFieldFromName(to_string(env, columName));
    return field.isNotNull();
}

jobjectArray Java_ch_ethz_tell_Schema_getFieldNamesImpl (JNIEnv* env, jobject, jlong self) {
    std::vector<const char *> resultVec;
    auto s = reinterpret_cast<tell::store::Schema*>(self);
    for (auto &field: s->fixedSizeFields())
        resultVec.emplace_back(field.name().c_str());
    for (auto &field: s->varSizeFields())
        resultVec.emplace_back(field.name().c_str());

    auto cls = env->FindClass("java/lang/String");
    auto init = env->NewStringUTF("");
    auto result = env->NewObjectArray(resultVec.size(), cls, init);
    for (unsigned i = 0; i < resultVec.size(); ++i) {
        env->SetObjectArrayElement(result, static_cast<int>(i), env->NewStringUTF(resultVec[i]));
    }
    return result;
}

<commit_msg>simplified Schema.getFieldNames<commit_after>/*
 * (C) Copyright 2015 ETH Zurich Systems Group (http://www.systems.ethz.ch/) and others.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * Contributors:
 *     Markus Pilman <mpilman@inf.ethz.ch>
 *     Simon Loesing <sloesing@inf.ethz.ch>
 *     Thomas Etter <etterth@gmail.com>
 *     Kevin Bocksrocker <kevin.bocksrocker@gmail.com>
 *     Lucas Braun <braunl@inf.ethz.ch>
 */
#include <ch_ethz_tell_Schema.h>
#include <tellstore/Record.hpp>
#include <crossbow/enum_underlying.hpp>

#include "helpers.hpp"

jlong Java_ch_ethz_tell_Schema_construct(JNIEnv*, jobject) {
    return reinterpret_cast<long>(new tell::store::Schema());
}

void Java_ch_ethz_tell_Schema_destruct(JNIEnv*, jobject, jlong self) {
    delete reinterpret_cast<tell::store::Schema*>(self);
}

jboolean Java_ch_ethz_tell_Schema_addFieldImpl(JNIEnv* env, jobject, jlong self, jshort type, jstring jname, jboolean notNull) {
    auto s = reinterpret_cast<tell::store::Schema*>(self);
    crossbow::string name = to_string(env, jname);
    uint16_t ftU = type;
    return s->addField(crossbow::from_underlying<tell::store::FieldType>(ftU), name, notNull);
}

jboolean Java_ch_ethz_tell_Schema_allNotNullImpl(JNIEnv*, jobject, jlong self) {
    auto s = reinterpret_cast<tell::store::Schema*>(self);
    return s->allNotNull();
}

namespace {
jintArray toIntArray(JNIEnv* env, const std::vector<tell::store::Field>& fields) {
    auto res = env->NewIntArray(fields.size());
    std::unique_ptr<jint[]> tmp(new jint[fields.size()]);
    for (unsigned i = 0; i < fields.size(); ++i) {
        tmp[i] = crossbow::to_underlying(fields[i].type());
    }
    env->SetIntArrayRegion(res, 0, fields.size(), tmp.get());
    return res;
}

}

jintArray Java_ch_ethz_tell_Schema_fixedSizeFieldsImpl(JNIEnv* env, jobject, jlong self) {
    auto s = reinterpret_cast<tell::store::Schema*>(self);
    return toIntArray(env, s->fixedSizeFields());
}

jintArray Java_ch_ethz_tell_Schema_variableSizedFieldsImpl(JNIEnv* env, jobject, jlong self) {
    auto s = reinterpret_cast<tell::store::Schema*>(self);
    return toIntArray(env, s->varSizeFields());
}

jshort Java_ch_ethz_tell_Schema_idOfImpl (JNIEnv* env, jobject, jlong self, jstring columnName) {
    auto s = reinterpret_cast<tell::store::Schema*>(self);
    return s->idOf(to_string(env, columnName));
}

jshort Java_ch_ethz_tell_Schema_typeOfImpl (JNIEnv* env, jobject, jlong self, jstring columName) {
    auto s = reinterpret_cast<tell::store::Schema*>(self);
    auto field = s->getFieldFromName(to_string(env, columName));
    return static_cast<short>(field.type());
}

jboolean Java_ch_ethz_tell_Schema_nullabiltyOfImpl (JNIEnv* env, jobject, jlong self, jstring columName) {
    auto s = reinterpret_cast<tell::store::Schema*>(self);
    auto field = s->getFieldFromName(to_string(env, columName));
    return field.isNotNull();
}

jobjectArray Java_ch_ethz_tell_Schema_getFieldNamesImpl (JNIEnv* env, jobject, jlong self) {
    auto s = reinterpret_cast<tell::store::Schema*>(self);
    auto cls = env->FindClass("java/lang/String");
    auto init = env->NewStringUTF("");
    auto result = env->NewObjectArray(s->fixedSizeFields().size() + s->varSizeFields().size(), cls, init);
    int i = 0;
    for (auto &field: s->fixedSizeFields()) {
        env->SetObjectArrayElement(result, i, env->NewStringUTF(field.name().c_str()));
        ++i;
    }
    for (auto &field: s->varSizeFields()) {
        env->SetObjectArrayElement(result, i, env->NewStringUTF(field.name().c_str()));
        ++i;
    }
    return result;
}

<|endoftext|>


<commit_before>// Licensed GNU LGPL v2.1 or later: http://www.gnu.org/licenses/lgpl.html
#include "birnetdebugtools.hh"
#include "birnetthread.hh"
#include <syslog.h>
#include <errno.h>
#include <stdio.h>
#ifndef _ // FIXME
#define _(x)    (x)
#endif
namespace Birnet {
DebugChannel::DebugChannel()
{}
DebugChannel::~DebugChannel ()
{}
struct DebugChannelFileAsync : public virtual DebugChannel, public virtual Thread {
  FILE                    *fout;
  uint                     skip_count;
  Atomic::RingBuffer<char> aring;
  ~DebugChannelFileAsync()
  {
    if (fout)
      fclose (fout);
  }
  DebugChannelFileAsync (const String &filename) :
    Thread ("DebugChannelFileAsync::logger"),
    fout (NULL), skip_count (0), aring (65536)
  {
    fout = fopen (filename.c_str(), "w");
    if (fout)
      start();
  }
  virtual void
  printf_valist (const char *format,
                 va_list     args)
  {
    const int bsz = 4000;
    char buffer[bsz + 2];
    int l = vsnprintf (buffer, bsz, format, args);
    if (l > 0)
      {
        l = MIN (l, bsz);
        if (buffer[l - 1] != '\n')
          {
            buffer[l++] = '\n';
            buffer[l] = 0;
          }
        if (false) // skip trailing 0 in ring buffer
          buffer[l++] = 0;
        uint n = aring.write (l, buffer, false);
        if (!n)
          Atomic::uint_swap_add (&skip_count, 1);
      }
  }
  virtual void
  run ()
  {
    do
      {
        char buffer[65536];
        uint n;
        do
          {
            n = aring.read (sizeof (buffer), buffer);
            if (n)
              {
                fwrite (buffer, n, 1, fout);
                fflush (fout);
              }
            else
              {
                uint j;
                do
                  j = Atomic::uint_get (&skip_count);
                while (!Atomic::uint_cas (&skip_count, j, 0));
                if (j)
                  fprintf (fout, "...[skipped %u messages]\n", j);
              }
          }
        while (n);
      }
    while (Thread::Self::sleep (15 * 1000));
  }
};
DebugChannel*
DebugChannel::new_from_file_async (const String &filename)
{
  DebugChannelFileAsync *dcfa = new DebugChannelFileAsync (filename);
  return dcfa;
}
} // Birnet
<commit_msg>BIRNET: birnetdebugtools: port debug channel to std::thread<commit_after>// Licensed GNU LGPL v2.1 or later: http://www.gnu.org/licenses/lgpl.html
#include "birnetdebugtools.hh"
#include <syslog.h>
#include <errno.h>
#include <stdio.h>
#ifndef _ // FIXME
#define _(x)    (x)
#endif
namespace Birnet {
DebugChannel::DebugChannel()
{}
DebugChannel::~DebugChannel ()
{}
struct DebugChannelFileAsync : public virtual DebugChannel {
  FILE                  *fout_;
  Rapicorn::Atomic<uint> skip_count_;
  std::thread            thread_;
  Rapicorn::AsyncRingBuffer<char> aring_;
  ~DebugChannelFileAsync()
  {
    if (fout_)
      fclose (fout_);
  }
  DebugChannelFileAsync (const String &filename) :
    fout_ (NULL), skip_count_ (0), aring_ (65536)
  {
    fout_ = fopen (filename.c_str(), "w");
    if (fout_)
      thread_ = std::thread (&DebugChannelFileAsync::run, this);
  }
  virtual void
  printf_valist (const char *format,
                 va_list     args)
  {
    const int bsz = 4000;
    char buffer[bsz + 2];
    int l = vsnprintf (buffer, bsz, format, args);
    if (l > 0)
      {
        l = MIN (l, bsz);
        if (buffer[l - 1] != '\n')
          {
            buffer[l++] = '\n';
            buffer[l] = 0;
          }
        if (false) // skip trailing 0 in ring buffer
          buffer[l++] = 0;
        uint n = aring_.write (l, buffer, false);
        if (!n)
          skip_count_ += 1;
      }
  }
  virtual void
  run ()
  {
    while (1)
      {
        char buffer[65536];
        uint n;
        do
          {
            n = aring_.read (sizeof (buffer), buffer);
            if (n)
              {
                fwrite (buffer, n, 1, fout_);
                fflush (fout_);
              }
            else
              {
                uint j;
                do
                  j = skip_count_;
                while (!skip_count_.cas (j, 0));
                if (j)
                  fprintf (fout_, "...[skipped %u messages]\n", j);
              }
          }
        while (n);
        std::this_thread::sleep_for (std::chrono::milliseconds (15));
      }
  }
};
DebugChannel*
DebugChannel::new_from_file_async (const String &filename)
{
  DebugChannelFileAsync *dcfa = new DebugChannelFileAsync (filename);
  return dcfa;
}
} // Birnet
<|endoftext|>


<commit_before>#include "Tasks.h"
#include <blackbox/BlackBox.h>
#include <blackbox/gfx/utils_imgui.h>
#include <bblib/codecvt.h>

namespace bb {

	void /*Workspaces::*/SwitchToWindow (HWND hwnd_app)
	{
		SwitchToThisWindow(hwnd_app, 1);
// 		HWND hwnd = GetLastActivePopup(GetRootWindow(hwnd_app));
// 		if (have_imp(pSwitchToThisWindow)) {
// 			// this one also restores the window, if it's iconic:
// 			pSwitchToThisWindow(hwnd, 1);
// 		}
// 		else {
// 			SetForegroundWindow(hwnd);
// 			if (IsIconic(hwnd))
// 				send_syscommand(hwnd, SC_RESTORE);
// 		}
	}

	void /*Workspaces::*/WS_BringToFront (HWND hwnd, bool to_current)
	{
		int windesk;

		//CleanTasks();

// 		windesk = vwm_get_desk(hwnd);
// 		if (windesk != currentScreen)
// 		{
// 			if (false == to_current)
// 				switchToDesktop(windesk);
// 			else
// 				setDesktop(hwnd, currentScreen, false);
// 		}
		SwitchToWindow(hwnd);
	}

	bool /*Workspaces::*/FocusTopWindow()
	{
// 		HWND hw = get_top_window(currentScreen);
// 		if (hw) {
// 			SwitchToWindow(hw);
// 			return true;
// 		}
// 		SwitchToBBWnd();
		return false;
	}

	void focus (HWND hwnd)
	{
		if (hwnd)
			//WS_BringToFront(hwnd, 0 != (wParam & BBBTF_CURRENT));
			WS_BringToFront(hwnd, false);
		else
			FocusTopWindow();
	}

	void switchDesk()
	{

	}

	void showInFromTaskBar(HWND hwnd, bool show)
	{
		if (show)
		{
			long style = GetWindowLong(hwnd, GWL_STYLE);
			style &= ~(WS_VISIBLE);    // this works - window become invisible

			style |= WS_EX_TOOLWINDOW;   // flags don't work - windows remains in taskbar
			style &= ~(WS_EX_APPWINDOW);

			ShowWindow(hwnd, SW_HIDE); // hide the window
			SetWindowLong(hwnd, GWL_STYLE, style); // set the style
			ShowWindow(hwnd, SW_SHOW); // show the window for the new style to come into effect
			ShowWindow(hwnd, SW_HIDE); // hide the window so we can't see it
		}
		else
		{
			long style = GetWindowLong(hwnd, GWL_STYLE);
			style &= ~(WS_VISIBLE);    // this works - window become invisible

			style |= WS_EX_TOOLWINDOW;   // flags don't work - windows remains in taskbar
			style &= ~(WS_EX_APPWINDOW);

			ShowWindow(hwnd, SW_HIDE); // hide the window
			SetWindowLong(hwnd, GWL_STYLE, style); // set the style
			ShowWindow(hwnd, SW_SHOW); // show the window for the new style to come into effect
			ShowWindow(hwnd, SW_HIDE); // hide the window so we can't see it
		}
	}

	void TasksWidget::DrawUI ()
	{
		// useless windows
		// Store hwnd == WinStore.Mobile.exe process
		// Get Started hwnd == WhatsNew.Store.exe

			////////////////////////////////////////////////////////////////////////////////////////////////////
			////////////////////////////////////////////////////////////////////////////////////////////////////
			// temporary task list
			Tasks const & tasks = BlackBox::Instance().GetTasks();
			//tasks.m_lock.Lock();
			//if (ImGui::TreeNode("Tasks", "%s", "tasks"))
			{
				std::string name2;
				if (tasks.m_active)
				{
					codecvt_utf16_utf8(tasks.m_active->m_caption, name2); // @TODO: perf!
					ImGui::Button(name2.c_str());
				}
				ImGui::Separator();
				for (Tasks::TaskInfoPtr const & t : tasks.m_tasks)
				{
					std::string name;
					codecvt_utf16_utf8(t->m_caption, name); // @TODO: perf!
					IconId const icoid = t->m_icoSmall;
					ImGui::Icon(icoid, ImColor(255, 255, 255, 255), ImColor(255, 255, 255, 128));
					if (!icoid.IsValid())
					{
						// @TODO: assign color to hwnd?
						ImGui::ColorButton(ImColor(0, 0, 128, 255));
					}
					ImGui::SameLine();

					if (ImGui::Button("i"))
					{
						if (t->m_ignored)
						{
							showInFromTaskBar(t->m_hwnd, true);
							t->m_ignored = false;
						}
						else
						{
							showInFromTaskBar(t->m_hwnd, false);
							t->m_ignored = true;
						}
					}

					ImGui::SameLine();

					if (ImGui::Button(name.c_str()))
					{
						focus(t->m_hwnd);
// 						if (t->m_ignored)
// 						{
// 							showInFromTaskBar(t->m_hwnd, true);
// 							t->m_ignored = false;
// 						}
// 						else
// 						{
// 							showInFromTaskBar(t->m_hwnd, false);
// 							t->m_ignored = true;
// 						}
					}
				}
				//ImGui::TreePop();

				if (ImGui::TreeNode("Ignored", "%s", "ignored"))
				{
					ImGui::TreePop();
				}
			}
			//tasks.m_lock.Unlock();	}
	}

}

<commit_msg>* task widget exclude<commit_after>#include "Tasks.h"
#include <blackbox/BlackBox.h>
#include <blackbox/gfx/utils_imgui.h>
#include <bblib/codecvt.h>

namespace bb {

	void /*Workspaces::*/SwitchToWindow (HWND hwnd_app)
	{
		SwitchToThisWindow(hwnd_app, 1);
// 		HWND hwnd = GetLastActivePopup(GetRootWindow(hwnd_app));
// 		if (have_imp(pSwitchToThisWindow)) {
// 			// this one also restores the window, if it's iconic:
// 			pSwitchToThisWindow(hwnd, 1);
// 		}
// 		else {
// 			SetForegroundWindow(hwnd);
// 			if (IsIconic(hwnd))
// 				send_syscommand(hwnd, SC_RESTORE);
// 		}
	}

	void /*Workspaces::*/WS_BringToFront (HWND hwnd, bool to_current)
	{
		int windesk;

		//CleanTasks();

// 		windesk = vwm_get_desk(hwnd);
// 		if (windesk != currentScreen)
// 		{
// 			if (false == to_current)
// 				switchToDesktop(windesk);
// 			else
// 				setDesktop(hwnd, currentScreen, false);
// 		}
		SwitchToWindow(hwnd);
	}

	bool /*Workspaces::*/FocusTopWindow()
	{
// 		HWND hw = get_top_window(currentScreen);
// 		if (hw) {
// 			SwitchToWindow(hw);
// 			return true;
// 		}
// 		SwitchToBBWnd();
		return false;
	}

	void focus (HWND hwnd)
	{
		if (hwnd)
			//WS_BringToFront(hwnd, 0 != (wParam & BBBTF_CURRENT));
			WS_BringToFront(hwnd, false);
		else
			FocusTopWindow();
	}

	void switchDesk()
	{

	}

	void showInFromTaskBar(HWND hwnd, bool show)
	{
		if (show)
		{
			long style = GetWindowLong(hwnd, GWL_STYLE);
			style &= ~(WS_VISIBLE);    // this works - window become invisible

			style |= WS_EX_TOOLWINDOW;   // flags don't work - windows remains in taskbar
			style &= ~(WS_EX_APPWINDOW);

			ShowWindow(hwnd, SW_HIDE); // hide the window
			SetWindowLong(hwnd, GWL_STYLE, style); // set the style
			ShowWindow(hwnd, SW_SHOW); // show the window for the new style to come into effect
			ShowWindow(hwnd, SW_HIDE); // hide the window so we can't see it
		}
		else
		{
			long style = GetWindowLong(hwnd, GWL_STYLE);
			style &= ~(WS_VISIBLE);    // this works - window become invisible

			style |= WS_EX_TOOLWINDOW;   // flags don't work - windows remains in taskbar
			style &= ~(WS_EX_APPWINDOW);

			ShowWindow(hwnd, SW_HIDE); // hide the window
			SetWindowLong(hwnd, GWL_STYLE, style); // set the style
			ShowWindow(hwnd, SW_SHOW); // show the window for the new style to come into effect
			ShowWindow(hwnd, SW_HIDE); // hide the window so we can't see it
		}
	}

	void TasksWidget::DrawUI ()
	{
		// useless windows
		// Store hwnd == WinStore.Mobile.exe process
		// Get Started hwnd == WhatsNew.Store.exe

			////////////////////////////////////////////////////////////////////////////////////////////////////
			////////////////////////////////////////////////////////////////////////////////////////////////////
			// temporary task list
			Tasks const & tasks = BlackBox::Instance().GetTasks();
			//tasks.m_lock.Lock();
			//if (ImGui::TreeNode("Tasks", "%s", "tasks"))
			{
				std::string name2;
				if (tasks.m_active)
				{
					codecvt_utf16_utf8(tasks.m_active->m_caption, name2); // @TODO: perf!
					ImGui::Button(name2.c_str());
				}
				ImGui::Separator();
				for (Tasks::TaskInfoPtr const & t : tasks.m_tasks)
				{
					if (t->m_exclude)
						continue;

					std::string name;
					codecvt_utf16_utf8(t->m_caption, name); // @TODO: perf!
					IconId const icoid = t->m_icoSmall;
					ImGui::Icon(icoid, ImColor(255, 255, 255, 255), ImColor(255, 255, 255, 128));
					if (!icoid.IsValid())
					{
						// @TODO: assign color to hwnd?
						ImGui::ColorButton(ImColor(0, 0, 128, 255));
					}
					ImGui::SameLine();

					if (ImGui::Button("i"))
					{
						if (t->m_ignored)
						{
							showInFromTaskBar(t->m_hwnd, true);
							t->m_ignored = false;
						}
						else
						{
							showInFromTaskBar(t->m_hwnd, false);
							t->m_ignored = true;
						}
					}

					ImGui::SameLine();

					if (ImGui::Button(name.c_str()))
					{
						focus(t->m_hwnd);
// 						if (t->m_ignored)
// 						{
// 							showInFromTaskBar(t->m_hwnd, true);
// 							t->m_ignored = false;
// 						}
// 						else
// 						{
// 							showInFromTaskBar(t->m_hwnd, false);
// 							t->m_ignored = true;
// 						}
					}
				}
				//ImGui::TreePop();

				if (ImGui::TreeNode("Ignored", "%s", "ignored"))
				{
					ImGui::TreePop();
				}
			}
			//tasks.m_lock.Unlock();	}
	}

}

<|endoftext|>