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

#include "etl/array_count.h"
#include "etl/armv7m/mpu.h"
#include "etl/armv7m/types.h"

#include "common/message.h"
#include "common/descriptor.h"

#include "k/address_range.h"
#include "k/context_layout.h"
#include "k/object_table.h"
#include "k/registers.h"
#include "k/reply_sender.h"
#include "k/scheduler.h"
#include "k/unprivileged.h"

using etl::armv7m::Word;

namespace k {

/*******************************************************************************
 * Context-specific stuff
 */

Context::Context()
  : _stack{nullptr},
    _keys{},
    _ctx_item{this},
    _sender_item{this},
    _priority{0},
    _state{State::stopped},
    _saved_brand{0} {}

void Context::nullify_exchanged_keys(unsigned preserved) {
  // Had to do this somewhere, this is as good a place as any.
  // (The fields in question are private, so this can't be at top level.)
  // (Putting it in the ctor hits the ill-defined non-trivial ctor rules.)
  static_assert(K_CONTEXT_SAVE_OFFSET == __builtin_offsetof(Context, _save),
                "K_CONTEXT_SAVE_OFFSET is wrong");

  // Right, actual implementation now:
  for (unsigned i = preserved; i < config::n_message_keys; ++i) {
    _keys[i] = Key::null();
  }
}

Descriptor Context::get_descriptor() const {
  return _save.sys.m.d0;
}

Keys & Context::get_message_keys() {
  return *reinterpret_cast<Keys *>(_keys);
}

void Context::do_syscall() {
  switch (get_descriptor().get_sysnum()) {
    case 0:  // IPC
      do_ipc();
      break;

    case 1:  // Copy Key
      do_copy_key();
      break;

    default:
      do_bad_sys();
      break;
  }
}

void Context::do_ipc() {
  auto d = get_descriptor();

  // Perform first phase of IPC.
  if (d.get_send_enabled()) {
    key(d.get_target()).deliver_from(this);
  } else if (d.get_receive_enabled()) {
    key(d.get_source()).get()->deliver_to(this);
  } else {
    // Simply return with registers unchanged.
    // (Weirdo.)
  }

  do_deferred_switch();
}

void Context::do_copy_key() {
  auto d = get_descriptor();
  key(d.get_target()) = key(d.get_source());
}

void Context::do_bad_sys() {
  put_message(0, Message::failure(Exception::bad_syscall));
}

void Context::complete_receive(BlockingSender * sender) {
  sender->on_blocked_delivery_accepted(_save.sys.m,
                                       _save.sys.b,
                                       get_message_keys());
}

void Context::complete_receive(Exception e, uint32_t param) {
  _save.sys.m = Message::failure(e, param);
  _save.sys.b = 0;
  nullify_exchanged_keys();
}

void Context::block_in_receive(List<Context> & list) {
  // TODO should we decide to permit non-blocking recieves... here's the spot.
  _ctx_item.unlink();
  list.insert(&_ctx_item);
  _state = State::receiving;

  pend_switch();
}

void Context::complete_blocked_receive(Brand brand, Sender * sender) {
  runnable.insert(&_ctx_item);
  _state = State::runnable;

  sender->on_delivery_accepted(_save.sys.m, get_message_keys());
  _save.sys.b = brand;

  pend_switch();
}

void Context::complete_blocked_receive(Exception e, uint32_t param) {
  runnable.insert(&_ctx_item);
  _state = State::runnable;

  complete_receive(e, param);

  pend_switch();
}

void Context::put_message(Brand brand, Message const & m) {
  _save.sys.m = m.sanitized();
  _save.sys.b = brand;
}

void Context::apply_to_mpu() {
  using etl::armv7m::mpu;

  for (unsigned i = 0; i < config::n_task_regions; ++i) {
    mpu.write_rnr(i);
    auto object = _memory_regions[i].get();
    if (object->is_address_range()) {
      auto range = static_cast<AddressRange *>(object);
      auto region = range->get_region_for_brand(_memory_regions[i].get_brand());
      mpu.write_rbar(region.rbar);
      mpu.write_rasr(region.rasr);
    } else {
      mpu.write_rasr(0);
      mpu.write_rbar(0);
    }
  }
}

void Context::make_runnable() {
  switch (_state) {
    case State::sending:
      on_blocked_delivery_failed(Exception::would_block);
      break;

    case State::receiving:
      complete_blocked_receive(Exception::would_block);
      break;

    case State::stopped:
      runnable.insert(&_ctx_item);
      _state = State::runnable;
      break;

    case State::runnable:
      break;
  }
}

/*******************************************************************************
 * Implementation of Sender and BlockingSender
 */

Priority Context::get_priority() const {
  return _priority;
}

void Context::on_delivery_accepted(Message & m, Keys & k) {
  auto d = get_descriptor();

  m = _save.sys.m.sanitized();

  k.keys[0] = d.is_call() ? make_reply_key() : Key::null();
  for (unsigned ki = 1; ki < config::n_message_keys; ++ki) {
    k.keys[ki] = key(ki);
  }

  if (d.get_receive_enabled()) {
    auto & source = d.is_call() ? k.keys[0]
                                : key(d.get_source());
    source.get()->deliver_to(this);
  }
}

void Context::on_delivery_failed(Exception e, uint32_t param) {
  // Deliver the exception.
  _save.sys.m = Message::failure(e, param);
  _save.sys.b = 0;
  // Avoid looking like we delivered any pre-existing keys.
  nullify_exchanged_keys();
}

void Context::block_in_send(Brand brand, List<BlockingSender> & list) {
  ETL_ASSERT(this == current);

  if (get_descriptor().get_block()) {
    _saved_brand = brand;
    list.insert(&_sender_item);
    _ctx_item.unlink();
    _state = State::sending;

    pend_switch();
  } else {
    // Unprivileged code is unwilling to block for delivery.
    on_delivery_failed(Exception::would_block);
  }
}

void Context::on_blocked_delivery_accepted(Message & m, Brand & b, Keys & k) {
  runnable.insert(&_ctx_item);
  _state = State::runnable;

  b = _saved_brand;
  on_delivery_accepted(m, k);
  pend_switch();
}

void Context::on_blocked_delivery_failed(Exception e, uint32_t param) {
  runnable.insert(&_ctx_item);
  _state = State::runnable;

  on_delivery_failed(e, param);
  pend_switch();
}

Key Context::make_reply_key() const {
  auto maybe_key = object_table[_reply_gate_index].ptr->make_key(0);
  if (maybe_key) return maybe_key.ref();
  return Key::null();
}

/*******************************************************************************
 * Implementation of Context protocol.
 */

using IpcImpl = void (Context::*)(Brand, Message const &, Keys &);

void Context::deliver_from(Brand brand, Sender * sender) {
  Message m;
  Keys k;
  sender->on_delivery_accepted(m, k);

  static constexpr IpcImpl dispatch[] {
    &Context::do_read_register,
    &Context::do_write_register,
    &Context::do_read_key,
    &Context::do_write_key,
    &Context::do_read_region,
    &Context::do_write_region,
    &Context::do_make_runnable,
    &Context::do_read_priority,
    &Context::do_write_priority,
  };
  if (m.d0.get_selector() < etl::array_count(dispatch)) {
    auto fn = dispatch[m.d0.get_selector()];
    (this->*fn)(brand, m, k);
  } else {
    do_badop(m, k);
  }
}

void Context::do_read_register(Brand,
                               Message const & arg,
                               Keys & k) {
  ReplySender reply_sender;
  switch (arg.d1) {
    case 13:
      reply_sender.set_message({
          Descriptor::zero(),
          reinterpret_cast<Word>(_stack),
          });
      break;

#define GP_EF(n) \
    case n: { \
      apply_to_mpu(); \
      auto r = uload(&_stack->r ## n); \
      current->apply_to_mpu(); \
      if (r) { \
        reply_sender.set_message({ \
            Descriptor::zero(), \
            r.ref(), \
          }); \
      } else { \
        reply_sender.set_message(Message::failure(Exception::fault)); \
      } \
      break; \
    }
    GP_EF(0);
    GP_EF(1);
    GP_EF(2);
    GP_EF(3);
    GP_EF(12);
    GP_EF(14);
    GP_EF(15);
#undef GP_EF

    case 16: {
      apply_to_mpu();
      auto r = uload(&_stack->psr);
      current->apply_to_mpu();
      if (r) {
        reply_sender.set_message({
            Descriptor::zero(),
            r.ref(),
          });
      } else {
        reply_sender.set_message(Message::failure(Exception::fault));
      }
      break;
    }

    case 4:
    case 5:
    case 6:
    case 7:
    case 8:
    case 9:
    case 10:
    case 11:
      reply_sender.set_message({Descriptor::zero(), _save.raw[arg.d1 - 4]});
      break;

    default:
      reply_sender.set_message(Message::failure(Exception::index_out_of_range));
      break;
  }

  k.keys[0].deliver_from(&reply_sender);
}

void Context::do_write_register(Brand,
                                Message const & arg,
                                Keys & k) {
  auto r = arg.d1;
  auto v = arg.d2;

  ReplySender reply_sender;

  switch (r) {
    case 13:
      _stack = reinterpret_cast<decltype(_stack)>(v);
      break;

#define GP_EF(n) \
    case n: { \
      if (!ustore(&_stack->r ## n, v)) { \
        reply_sender.set_message(Message::failure(Exception::fault)); \
      } \
      break; \
    }
    GP_EF(0);
    GP_EF(1);
    GP_EF(2);
    GP_EF(3);
    GP_EF(12);
    GP_EF(14);
    GP_EF(15);
#undef GP

    case 16: {
      if (!ustore(&_stack->psr, v)) {
        reply_sender.set_message(Message::failure(Exception::fault));
      }
      break;
    }

    case 4:
    case 5:
    case 6:
    case 7:
    case 8:
    case 9:
    case 10:
    case 11:
      _save.raw[r - 4] = v;
      break;

    default:
      reply_sender.set_message(Message::failure(Exception::index_out_of_range));
      break;
  }

  k.keys[0].deliver_from(&reply_sender);
}

void Context::do_read_key(Brand,
                          Message const & arg,
                          Keys & k) {
  auto r = arg.d1;

  ReplySender reply_sender;
  if (r >= config::n_task_keys) {
    reply_sender.set_message(Message::failure(Exception::index_out_of_range));
  } else {
    reply_sender.set_key(1, key(r));
  }
  k.keys[0].deliver_from(&reply_sender);
}

void Context::do_write_key(Brand,
                           Message const & arg,
                           Keys & k) {
  auto r = arg.d1;

  auto & reply = k.keys[0];
  auto & new_key = k.keys[1];

  ReplySender reply_sender;
  if (r >= config::n_task_keys) {
    reply_sender.set_message(Message::failure(Exception::index_out_of_range));
  } else {
    key(r) = new_key;
  }
  reply.deliver_from(&reply_sender);
}

void Context::do_read_region(Brand,
                             Message const & arg,
                             Keys & k) {
  auto n = arg.d1;

  ReplySender reply_sender;
  if (n < config::n_task_regions) {
    reply_sender.set_key(1, _memory_regions[n]);
  } else {
    reply_sender.set_message(Message::failure(Exception::index_out_of_range));
  }
  k.keys[0].deliver_from(&reply_sender);
}

void Context::do_write_region(Brand,
                              Message const & arg,
                              Keys & k) {
  auto n = arg.d1;
  auto & reply = k.keys[0];
  auto & object_key = k.keys[1];

  ReplySender reply_sender;

  if (n < config::n_task_regions) {
    _memory_regions[n] = object_key;
  } else {
    reply_sender.set_message(Message::failure(Exception::index_out_of_range));
  }

  if (current == this) apply_to_mpu();

  reply.deliver_from(&reply_sender);
}

void Context::do_make_runnable(Brand, Message const & arg, Keys & k) {
  make_runnable();
  pend_switch();

  ReplySender reply_sender;
  k.keys[0].deliver_from(&reply_sender);
}

void Context::do_read_priority(Brand, Message const & arg, Keys & k) {
  ReplySender reply_sender;
  reply_sender.set_message({Descriptor::zero(), _priority});
  k.keys[0].deliver_from(&reply_sender);
}

void Context::do_write_priority(Brand, Message const & arg, Keys & k) {
  auto priority = arg.d1;

  ReplySender reply_sender;

  if (priority < config::n_priorities) {
    _priority = priority;

    if (_ctx_item.is_linked()) _ctx_item.reinsert();
    if (_sender_item.is_linked()) _sender_item.reinsert();
  } else {
    reply_sender.set_message(Message::failure(Exception::index_out_of_range));
  }

  k.keys[0].deliver_from(&reply_sender);
}

}  // namespace k
<commit_msg>k/context: encourage tail calls.<commit_after>#include "k/context.h"

#include "etl/array_count.h"
#include "etl/armv7m/mpu.h"
#include "etl/armv7m/types.h"

#include "common/message.h"
#include "common/descriptor.h"

#include "k/address_range.h"
#include "k/context_layout.h"
#include "k/object_table.h"
#include "k/registers.h"
#include "k/reply_sender.h"
#include "k/scheduler.h"
#include "k/unprivileged.h"

using etl::armv7m::Word;

namespace k {

/*******************************************************************************
 * Context-specific stuff
 */

Context::Context()
  : _stack{nullptr},
    _keys{},
    _ctx_item{this},
    _sender_item{this},
    _priority{0},
    _state{State::stopped},
    _saved_brand{0} {}

void Context::nullify_exchanged_keys(unsigned preserved) {
  // Had to do this somewhere, this is as good a place as any.
  // (The fields in question are private, so this can't be at top level.)
  // (Putting it in the ctor hits the ill-defined non-trivial ctor rules.)
  static_assert(K_CONTEXT_SAVE_OFFSET == __builtin_offsetof(Context, _save),
                "K_CONTEXT_SAVE_OFFSET is wrong");

  // Right, actual implementation now:
  for (unsigned i = preserved; i < config::n_message_keys; ++i) {
    _keys[i] = Key::null();
  }
}

Descriptor Context::get_descriptor() const {
  return _save.sys.m.d0;
}

Keys & Context::get_message_keys() {
  return *reinterpret_cast<Keys *>(_keys);
}

void Context::do_syscall() {
  switch (get_descriptor().get_sysnum()) {
    case 0:  // IPC
      do_ipc();
      break;

    case 1:  // Copy Key
      do_copy_key();
      break;

    default:
      do_bad_sys();
      break;
  }
}

void Context::do_ipc() {
  auto d = get_descriptor();

  // Perform first phase of IPC.
  if (d.get_send_enabled()) {
    key(d.get_target()).deliver_from(this);
  } else if (d.get_receive_enabled()) {
    key(d.get_source()).get()->deliver_to(this);
  } else {
    // Simply return with registers unchanged.
    // (Weirdo.)
  }

  do_deferred_switch();
}

void Context::do_copy_key() {
  auto d = get_descriptor();
  key(d.get_target()) = key(d.get_source());
}

void Context::do_bad_sys() {
  put_message(0, Message::failure(Exception::bad_syscall));
}

void Context::complete_receive(BlockingSender * sender) {
  sender->on_blocked_delivery_accepted(_save.sys.m,
                                       _save.sys.b,
                                       get_message_keys());
}

void Context::complete_receive(Exception e, uint32_t param) {
  _save.sys.m = Message::failure(e, param);
  _save.sys.b = 0;
  nullify_exchanged_keys();
}

void Context::block_in_receive(List<Context> & list) {
  // TODO should we decide to permit non-blocking recieves... here's the spot.
  _ctx_item.unlink();
  list.insert(&_ctx_item);
  _state = State::receiving;

  pend_switch();
}

void Context::complete_blocked_receive(Brand brand, Sender * sender) {
  runnable.insert(&_ctx_item);
  _state = State::runnable;
  _save.sys.b = brand;

  pend_switch();

  sender->on_delivery_accepted(_save.sys.m, get_message_keys());
}

void Context::complete_blocked_receive(Exception e, uint32_t param) {
  runnable.insert(&_ctx_item);
  _state = State::runnable;

  pend_switch();

  complete_receive(e, param);
}

void Context::put_message(Brand brand, Message const & m) {
  _save.sys.m = m.sanitized();
  _save.sys.b = brand;
}

void Context::apply_to_mpu() {
  using etl::armv7m::mpu;

  for (unsigned i = 0; i < config::n_task_regions; ++i) {
    mpu.write_rnr(i);
    auto object = _memory_regions[i].get();
    if (object->is_address_range()) {
      auto range = static_cast<AddressRange *>(object);
      auto region = range->get_region_for_brand(_memory_regions[i].get_brand());
      mpu.write_rbar(region.rbar);
      mpu.write_rasr(region.rasr);
    } else {
      mpu.write_rasr(0);
      mpu.write_rbar(0);
    }
  }
}

void Context::make_runnable() {
  switch (_state) {
    case State::sending:
      on_blocked_delivery_failed(Exception::would_block);
      break;

    case State::receiving:
      complete_blocked_receive(Exception::would_block);
      break;

    case State::stopped:
      runnable.insert(&_ctx_item);
      _state = State::runnable;
      break;

    case State::runnable:
      break;
  }
}

/*******************************************************************************
 * Implementation of Sender and BlockingSender
 */

Priority Context::get_priority() const {
  return _priority;
}

void Context::on_delivery_accepted(Message & m, Keys & k) {
  auto d = get_descriptor();

  m = _save.sys.m.sanitized();

  k.keys[0] = d.is_call() ? make_reply_key() : Key::null();
  for (unsigned ki = 1; ki < config::n_message_keys; ++ki) {
    k.keys[ki] = key(ki);
  }

  if (d.get_receive_enabled()) {
    auto & source = d.is_call() ? k.keys[0]
                                : key(d.get_source());
    source.get()->deliver_to(this);
  }
}

void Context::on_delivery_failed(Exception e, uint32_t param) {
  // Deliver the exception.
  _save.sys.m = Message::failure(e, param);
  _save.sys.b = 0;
  // Avoid looking like we delivered any pre-existing keys.
  nullify_exchanged_keys();
}

void Context::block_in_send(Brand brand, List<BlockingSender> & list) {
  ETL_ASSERT(this == current);

  if (get_descriptor().get_block()) {
    _saved_brand = brand;
    list.insert(&_sender_item);
    _ctx_item.unlink();
    _state = State::sending;

    pend_switch();
  } else {
    // Unprivileged code is unwilling to block for delivery.
    on_delivery_failed(Exception::would_block);
  }
}

void Context::on_blocked_delivery_accepted(Message & m, Brand & b, Keys & k) {
  runnable.insert(&_ctx_item);
  _state = State::runnable;

  b = _saved_brand;
  pend_switch();
  on_delivery_accepted(m, k);
}

void Context::on_blocked_delivery_failed(Exception e, uint32_t param) {
  runnable.insert(&_ctx_item);
  _state = State::runnable;
  pend_switch();

  on_delivery_failed(e, param);
}

Key Context::make_reply_key() const {
  auto maybe_key = object_table[_reply_gate_index].ptr->make_key(0);
  if (maybe_key) return maybe_key.ref();
  return Key::null();
}

/*******************************************************************************
 * Implementation of Context protocol.
 */

using IpcImpl = void (Context::*)(Brand, Message const &, Keys &);

void Context::deliver_from(Brand brand, Sender * sender) {
  Message m;
  Keys k;
  sender->on_delivery_accepted(m, k);

  static constexpr IpcImpl dispatch[] {
    &Context::do_read_register,
    &Context::do_write_register,
    &Context::do_read_key,
    &Context::do_write_key,
    &Context::do_read_region,
    &Context::do_write_region,
    &Context::do_make_runnable,
    &Context::do_read_priority,
    &Context::do_write_priority,
  };
  if (m.d0.get_selector() < etl::array_count(dispatch)) {
    auto fn = dispatch[m.d0.get_selector()];
    (this->*fn)(brand, m, k);
  } else {
    do_badop(m, k);
  }
}

void Context::do_read_register(Brand,
                               Message const & arg,
                               Keys & k) {
  ReplySender reply_sender;
  switch (arg.d1) {
    case 13:
      reply_sender.set_message({
          Descriptor::zero(),
          reinterpret_cast<Word>(_stack),
          });
      break;

#define GP_EF(n) \
    case n: { \
      apply_to_mpu(); \
      auto r = uload(&_stack->r ## n); \
      current->apply_to_mpu(); \
      if (r) { \
        reply_sender.set_message({ \
            Descriptor::zero(), \
            r.ref(), \
          }); \
      } else { \
        reply_sender.set_message(Message::failure(Exception::fault)); \
      } \
      break; \
    }
    GP_EF(0);
    GP_EF(1);
    GP_EF(2);
    GP_EF(3);
    GP_EF(12);
    GP_EF(14);
    GP_EF(15);
#undef GP_EF

    case 16: {
      apply_to_mpu();
      auto r = uload(&_stack->psr);
      current->apply_to_mpu();
      if (r) {
        reply_sender.set_message({
            Descriptor::zero(),
            r.ref(),
          });
      } else {
        reply_sender.set_message(Message::failure(Exception::fault));
      }
      break;
    }

    case 4:
    case 5:
    case 6:
    case 7:
    case 8:
    case 9:
    case 10:
    case 11:
      reply_sender.set_message({Descriptor::zero(), _save.raw[arg.d1 - 4]});
      break;

    default:
      reply_sender.set_message(Message::failure(Exception::index_out_of_range));
      break;
  }

  k.keys[0].deliver_from(&reply_sender);
}

void Context::do_write_register(Brand,
                                Message const & arg,
                                Keys & k) {
  auto r = arg.d1;
  auto v = arg.d2;

  ReplySender reply_sender;

  switch (r) {
    case 13:
      _stack = reinterpret_cast<decltype(_stack)>(v);
      break;

#define GP_EF(n) \
    case n: { \
      if (!ustore(&_stack->r ## n, v)) { \
        reply_sender.set_message(Message::failure(Exception::fault)); \
      } \
      break; \
    }
    GP_EF(0);
    GP_EF(1);
    GP_EF(2);
    GP_EF(3);
    GP_EF(12);
    GP_EF(14);
    GP_EF(15);
#undef GP

    case 16: {
      if (!ustore(&_stack->psr, v)) {
        reply_sender.set_message(Message::failure(Exception::fault));
      }
      break;
    }

    case 4:
    case 5:
    case 6:
    case 7:
    case 8:
    case 9:
    case 10:
    case 11:
      _save.raw[r - 4] = v;
      break;

    default:
      reply_sender.set_message(Message::failure(Exception::index_out_of_range));
      break;
  }

  k.keys[0].deliver_from(&reply_sender);
}

void Context::do_read_key(Brand,
                          Message const & arg,
                          Keys & k) {
  auto r = arg.d1;

  ReplySender reply_sender;
  if (r >= config::n_task_keys) {
    reply_sender.set_message(Message::failure(Exception::index_out_of_range));
  } else {
    reply_sender.set_key(1, key(r));
  }
  k.keys[0].deliver_from(&reply_sender);
}

void Context::do_write_key(Brand,
                           Message const & arg,
                           Keys & k) {
  auto r = arg.d1;

  auto & reply = k.keys[0];
  auto & new_key = k.keys[1];

  ReplySender reply_sender;
  if (r >= config::n_task_keys) {
    reply_sender.set_message(Message::failure(Exception::index_out_of_range));
  } else {
    key(r) = new_key;
  }
  reply.deliver_from(&reply_sender);
}

void Context::do_read_region(Brand,
                             Message const & arg,
                             Keys & k) {
  auto n = arg.d1;

  ReplySender reply_sender;
  if (n < config::n_task_regions) {
    reply_sender.set_key(1, _memory_regions[n]);
  } else {
    reply_sender.set_message(Message::failure(Exception::index_out_of_range));
  }
  k.keys[0].deliver_from(&reply_sender);
}

void Context::do_write_region(Brand,
                              Message const & arg,
                              Keys & k) {
  auto n = arg.d1;
  auto & reply = k.keys[0];
  auto & object_key = k.keys[1];

  ReplySender reply_sender;

  if (n < config::n_task_regions) {
    _memory_regions[n] = object_key;
  } else {
    reply_sender.set_message(Message::failure(Exception::index_out_of_range));
  }

  if (current == this) apply_to_mpu();

  reply.deliver_from(&reply_sender);
}

void Context::do_make_runnable(Brand, Message const & arg, Keys & k) {
  make_runnable();
  pend_switch();

  ReplySender reply_sender;
  k.keys[0].deliver_from(&reply_sender);
}

void Context::do_read_priority(Brand, Message const & arg, Keys & k) {
  ReplySender reply_sender;
  reply_sender.set_message({Descriptor::zero(), _priority});
  k.keys[0].deliver_from(&reply_sender);
}

void Context::do_write_priority(Brand, Message const & arg, Keys & k) {
  auto priority = arg.d1;

  ReplySender reply_sender;

  if (priority < config::n_priorities) {
    _priority = priority;

    if (_ctx_item.is_linked()) _ctx_item.reinsert();
    if (_sender_item.is_linked()) _sender_item.reinsert();
  } else {
    reply_sender.set_message(Message::failure(Exception::index_out_of_range));
  }

  k.keys[0].deliver_from(&reply_sender);
}

}  // namespace k
<|endoftext|>


<commit_before>// Copyright (c) 2012 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include <string>

#include "version.h"

// Name of client reported in the 'version' message. Report the same name
// for both bitcoind and bitcoin-qt, to make it harder for attackers to
// target servers or GUI users specifically.
const std::string CLIENT_NAME("Britcoin");

// Client version number
#define CLIENT_VERSION_SUFFIX   ""

// The following part of the code determines the CLIENT_BUILD variable.
// Several mechanisms are used for this:
// * first, if HAVE_BUILD_INFO is defined, include build.h, a file that is
//   generated by the build environment, possibly containing the output
//   of git-describe in a macro called BUILD_DESC
// * secondly, if this is an exported version of the code, GIT_ARCHIVE will
//   be defined (automatically using the export-subst git attribute), and
//   GIT_COMMIT will contain the commit id.
// * then, three options exist for determining CLIENT_BUILD:
//   * if BUILD_DESC is defined, use that literally (output of git-describe)
//   * if not, but GIT_COMMIT is defined, use v[maj].[min].[rev].[build]-g[commit]
//   * otherwise, use v[maj].[min].[rev].[build]-unk
// finally CLIENT_VERSION_SUFFIX is added

// First, include build.h if requested
#ifdef HAVE_BUILD_INFO
#    include "build.h"
#endif

// git will put "#define GIT_ARCHIVE 1" on the next line inside archives.
#define GIT_ARCHIVE 1
#ifdef GIT_ARCHIVE
#    define GIT_COMMIT_ID ": Experimental"
//#    define GIT_COMMIT_DATE "$Format:%cD"
#endif

#define BUILD_DESC_FROM_COMMIT(maj,min,rev,build,commit) \
    "v" DO_STRINGIZE(maj) "." DO_STRINGIZE(min) "." DO_STRINGIZE(rev) "." DO_STRINGIZE(build) "" commit

#define BUILD_DESC_FROM_UNKNOWN(maj,min,rev,build) \
    "v" DO_STRINGIZE(maj) "." DO_STRINGIZE(min) "." DO_STRINGIZE(rev) "." DO_STRINGIZE(build) ""

#ifndef BUILD_DESC
#    ifdef GIT_COMMIT_ID
#        define BUILD_DESC BUILD_DESC_FROM_COMMIT(CLIENT_VERSION_MAJOR, CLIENT_VERSION_MINOR, CLIENT_VERSION_REVISION, CLIENT_VERSION_BUILD, GIT_COMMIT_ID)
#    else
#        define BUILD_DESC BUILD_DESC_FROM_UNKNOWN(CLIENT_VERSION_MAJOR, CLIENT_VERSION_MINOR, CLIENT_VERSION_REVISION, CLIENT_VERSION_BUILD)
#    endif
#endif

#ifndef BUILD_DATE
#    ifdef GIT_COMMIT_DATE
#        define BUILD_DATE GIT_COMMIT_DATE
#    else
#        define BUILD_DATE __DATE__ ", " __TIME__
#    endif
#endif

const std::string CLIENT_BUILD(BUILD_DESC CLIENT_VERSION_SUFFIX);
const std::string CLIENT_DATE(BUILD_DATE);
<commit_msg>Changed version name<commit_after>// Copyright (c) 2012 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include <string>

#include "version.h"

// Name of client reported in the 'version' message. Report the same name
// for both bitcoind and bitcoin-qt, to make it harder for attackers to
// target servers or GUI users specifically.
const std::string CLIENT_NAME("BritCoin");

// Client version number
#define CLIENT_VERSION_SUFFIX   ""

// The following part of the code determines the CLIENT_BUILD variable.
// Several mechanisms are used for this:
// * first, if HAVE_BUILD_INFO is defined, include build.h, a file that is
//   generated by the build environment, possibly containing the output
//   of git-describe in a macro called BUILD_DESC
// * secondly, if this is an exported version of the code, GIT_ARCHIVE will
//   be defined (automatically using the export-subst git attribute), and
//   GIT_COMMIT will contain the commit id.
// * then, three options exist for determining CLIENT_BUILD:
//   * if BUILD_DESC is defined, use that literally (output of git-describe)
//   * if not, but GIT_COMMIT is defined, use v[maj].[min].[rev].[build]-g[commit]
//   * otherwise, use v[maj].[min].[rev].[build]-unk
// finally CLIENT_VERSION_SUFFIX is added

// First, include build.h if requested
#ifdef HAVE_BUILD_INFO
#    include "build.h"
#endif

// git will put "#define GIT_ARCHIVE 1" on the next line inside archives.
#define GIT_ARCHIVE 1
#ifdef GIT_ARCHIVE
#    define GIT_COMMIT_ID ": Hope"
//#    define GIT_COMMIT_DATE "$Format:%cD"
#endif

#define BUILD_DESC_FROM_COMMIT(maj,min,rev,build,commit) \
    "v" DO_STRINGIZE(maj) "." DO_STRINGIZE(min) "." DO_STRINGIZE(rev) "." DO_STRINGIZE(build) "" commit

#define BUILD_DESC_FROM_UNKNOWN(maj,min,rev,build) \
    "v" DO_STRINGIZE(maj) "." DO_STRINGIZE(min) "." DO_STRINGIZE(rev) "." DO_STRINGIZE(build) ""

#ifndef BUILD_DESC
#    ifdef GIT_COMMIT_ID
#        define BUILD_DESC BUILD_DESC_FROM_COMMIT(CLIENT_VERSION_MAJOR, CLIENT_VERSION_MINOR, CLIENT_VERSION_REVISION, CLIENT_VERSION_BUILD, GIT_COMMIT_ID)
#    else
#        define BUILD_DESC BUILD_DESC_FROM_UNKNOWN(CLIENT_VERSION_MAJOR, CLIENT_VERSION_MINOR, CLIENT_VERSION_REVISION, CLIENT_VERSION_BUILD)
#    endif
#endif

#ifndef BUILD_DATE
#    ifdef GIT_COMMIT_DATE
#        define BUILD_DATE GIT_COMMIT_DATE
#    else
#        define BUILD_DATE __DATE__ ", " __TIME__
#    endif
#endif

const std::string CLIENT_BUILD(BUILD_DESC CLIENT_VERSION_SUFFIX);
const std::string CLIENT_DATE(BUILD_DATE);
<|endoftext|>


<commit_before>// Copyright (c) 2013-2014 The curecoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include <string>

#include "version.h"

// Name of client reported in the 'version' message. Report the same name
// for both curecoind and curecoin-qt, to make it harder for attackers to
// target servers or GUI users specifically.
const std::string CLIENT_NAME("Curecoin");

// Client version number
#define CLIENT_VERSION_SUFFIX   "-CURE"

// The following part of the code determines the CLIENT_BUILD variable.
// Several mechanisms are used for this:
// * first, if HAVE_BUILD_INFO is defined, include build.h, a file that is
//   generated by the build environment, possibly containing the output
//   of git-describe in a macro called BUILD_DESC
// * secondly, if this is an exported version of the code, GIT_ARCHIVE will
//   be defined (automatically using the export-subst git attribute), and
//   GIT_COMMIT will contain the commit id.
// * then, three options exist for determining CLIENT_BUILD:
//   * if BUILD_DESC is defined, use that literally (output of git-describe)
//   * if not, but GIT_COMMIT is defined, use v[maj].[min].[rev].[build]-g[commit]
//   * otherwise, use v[maj].[min].[rev].[build]-unk
// finally CLIENT_VERSION_SUFFIX is added

// First, include build.h if requested
#ifdef HAVE_BUILD_INFO
#    include "build.h"
#endif

// git will put "#define GIT_ARCHIVE 1" on the next line inside archives.
#define GIT_ARCHIVE 1
#ifdef GIT_ARCHIVE
#    define GIT_COMMIT_ID "7b123c3"
#    define GIT_COMMIT_DATE "$Format:%cD"
#endif

#define BUILD_DESC_FROM_COMMIT(maj,min,rev,build,commit) \
    "v" DO_STRINGIZE(maj) "." DO_STRINGIZE(min) "." DO_STRINGIZE(rev) "." DO_STRINGIZE(build)

#define BUILD_DESC_FROM_UNKNOWN(maj,min,rev,build) \
    "v" DO_STRINGIZE(maj) "." DO_STRINGIZE(min) "." DO_STRINGIZE(rev) "." DO_STRINGIZE(build) "-unk"

#ifndef BUILD_DESC
#    ifdef GIT_COMMIT_ID
#        define BUILD_DESC BUILD_DESC_FROM_COMMIT(DISPLAY_VERSION_MAJOR, DISPLAY_VERSION_MINOR, DISPLAY_VERSION_REVISION, DISPLAY_VERSION_BUILD, GIT_COMMIT_ID)
#    else
#        define BUILD_DESC BUILD_DESC_FROM_UNKNOWN(DISPLAY_VERSION_MAJOR, DISPLAY_VERSION_MINOR, DISPLAY_VERSION_REVISION, DISPLAY_VERSION_BUILD)
#    endif
#endif

#ifndef BUILD_DATE
#    ifdef GIT_COMMIT_DATE
#        define BUILD_DATE "July 4, 2013"
#    else
#        define BUILD_DATE __DATE__ ", " __TIME__
#    endif
#endif

const std::string CLIENT_BUILD(BUILD_DESC CLIENT_VERSION_SUFFIX);
const std::string CLIENT_DATE(BUILD_DATE);
<commit_msg>Update version.cpp<commit_after>// Copyright (c) 2013-2020 The Curecoin Developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include <string>

#include "version.h"

// Name of client reported in the 'version' message. Report the same name
// for both curecoind and curecoin-qt, to make it harder for attackers to
// target servers or GUI users specifically.
const std::string CLIENT_NAME("Curecoin");

// Client version number
#define CLIENT_VERSION_SUFFIX   "-CURE"

// The following part of the code determines the CLIENT_BUILD variable.
// Several mechanisms are used for this:
// * first, if HAVE_BUILD_INFO is defined, include build.h, a file that is
//   generated by the build environment, possibly containing the output
//   of git-describe in a macro called BUILD_DESC
// * secondly, if this is an exported version of the code, GIT_ARCHIVE will
//   be defined (automatically using the export-subst git attribute), and
//   GIT_COMMIT will contain the commit id.
// * then, three options exist for determining CLIENT_BUILD:
//   * if BUILD_DESC is defined, use that literally (output of git-describe)
//   * if not, but GIT_COMMIT is defined, use v[maj].[min].[rev].[build]-g[commit]
//   * otherwise, use v[maj].[min].[rev].[build]-unk
// finally CLIENT_VERSION_SUFFIX is added

// First, include build.h if requested
#ifdef HAVE_BUILD_INFO
#    include "build.h"
#endif

// git will put "#define GIT_ARCHIVE 1" on the next line inside archives.
#define GIT_ARCHIVE 1
#ifdef GIT_ARCHIVE
#    define GIT_COMMIT_ID "7b123c3"
#    define GIT_COMMIT_DATE "$Format:%cD"
#endif

#define BUILD_DESC_FROM_COMMIT(maj,min,rev,build,commit) \
    "v" DO_STRINGIZE(maj) "." DO_STRINGIZE(min) "." DO_STRINGIZE(rev) "." DO_STRINGIZE(build)

#define BUILD_DESC_FROM_UNKNOWN(maj,min,rev,build) \
    "v" DO_STRINGIZE(maj) "." DO_STRINGIZE(min) "." DO_STRINGIZE(rev) "." DO_STRINGIZE(build) "-unk"

#ifndef BUILD_DESC
#    ifdef GIT_COMMIT_ID
#        define BUILD_DESC BUILD_DESC_FROM_COMMIT(DISPLAY_VERSION_MAJOR, DISPLAY_VERSION_MINOR, DISPLAY_VERSION_REVISION, DISPLAY_VERSION_BUILD, GIT_COMMIT_ID)
#    else
#        define BUILD_DESC BUILD_DESC_FROM_UNKNOWN(DISPLAY_VERSION_MAJOR, DISPLAY_VERSION_MINOR, DISPLAY_VERSION_REVISION, DISPLAY_VERSION_BUILD)
#    endif
#endif

#ifndef BUILD_DATE
#    ifdef GIT_COMMIT_DATE
#        define BUILD_DATE "July 4, 2013"
#    else
#        define BUILD_DATE __DATE__ ", " __TIME__
#    endif
#endif

const std::string CLIENT_BUILD(BUILD_DESC CLIENT_VERSION_SUFFIX);
const std::string CLIENT_DATE(BUILD_DATE);
<|endoftext|>


<commit_before><commit_msg>coverity#707973 Uninitialized scalar field<commit_after><|endoftext|>


<commit_before>#include <oalplus/al.hpp>
#include <oalplus/all.hpp>
#include <oalplus/alut.hpp>
#include <chrono>
#include <thread>
#include <iostream>

#include <boost/multi_index_container.hpp>
#include <boost/multi_index/hashed_index.hpp>
#include <boost/multi_index/mem_fun.hpp>
class Sound
{
    public:
        Sound():
            Sound{oalplus::ALUtilityToolkit(false).CreateBufferHelloWorld()}
        {
        }

        Sound(const std::string& filename):
            Sound{oalplus::ALUtilityToolkit(false).CreateBufferFromFile(filename)}
        {
        }

        Sound(const oalplus::Buffer& buf):
            m_source{oalplus::ObjectDesc("Source")}
        {
            m_source.Buffer(buf);
            m_source.Looping(true);
            m_source.ReferenceDistance(15);
        }

        auto& source()
        {
            return m_source;
        }

        const auto& source() const
        {
            return m_source;
        }

        void setEnabled(bool)
        {

        }

        const std::string& name() const
        {
            return m_name;
        }

        void setName(const std::string &name)
        {
            m_name = name;
        }

    private:
        std::string m_name;
        oalplus::Source m_source;
};

namespace bmi = boost::multi_index;
using SoundMap = bmi::multi_index_container<
    Sound,
    bmi::indexed_by<
        bmi::hashed_unique<
            bmi::const_mem_fun<
                Sound,
                const std::string&,
                &Sound::name
            >
        >
    >
>;
class Scene
{
    public:
        Scene()
        {
            // create a listener and set its position, velocity and orientation
            m_listener.Position(0.0f, 0.0f, 0.0f);
            m_listener.Velocity(0.0f, 0.0f, 0.0f);
            m_listener.Orientation(0.0f, 0.0f,-1.0f, 0.0f, 1.0f, 0.0f);

            m_sounds.insert(Sound());
        }

        void start()
        {
            for(auto& cst_sound : m_sounds)
            {
                auto& sound = const_cast<Sound&>(cst_sound);
                auto& source = sound.source();
                // let the source play the sound
                source.Play();
                /*

                // the path of the source
                oalplus::CubicBezierLoop<oalplus::Vec3f, double> path(
                {
                                oalplus::Vec3f( 0.0f, 0.0f, -9.0f),
                                oalplus::Vec3f( 9.0f, 2.0f, -8.0f),
                                oalplus::Vec3f( 4.0f,-3.0f, 9.0f),
                                oalplus::Vec3f(-3.0f, 4.0f, 9.0f),
                                oalplus::Vec3f(-9.0f,-1.0f, -7.0f)
                            });
                //

                // play the sound for a while
                typedef std::chrono::system_clock clock;
                typedef std::chrono::time_point<clock> time_point;
                time_point start = clock::now();
                while(true)
                {
                    double t = double((clock::now() - start).count())*
                            double(clock::period::num)/
                            double(clock::period::den);
                    if(t > 10.0) break;
                    source.Position(path.Position(t/5.0));
                    m_listener.Position(m_listener.Position() - oalplus::Vec3f{0.2, 0, 0});
                    // wait for a while
                    std::chrono::milliseconds duration(10);
                    std::this_thread::sleep_for(duration);
                }
                */
                while(true)
                    std::this_thread::sleep_for(std::chrono::seconds(10));
            }
        }

        oalplus::Listener& listener()
        { return m_listener; }

        SoundMap& sounds()
        { return m_sounds; }

    private:
        oalplus::Listener m_listener;
        SoundMap m_sounds;
};

#include <Network/Device.h>
#include <Network/Protocol.h>
#include <Network/Node.h>

template<typename Get, typename Set>
struct Parameter
{
        Get get;
        Set set;
};

template<typename Get, typename Set>
auto make_parameter(Get&& get, Set&& set)
{
    return Parameter<Get, Set>{std::move(get), std::move(set)};
}

template<typename Parameter_t> // a function that returns a Vec3f& to modify.
void add_position(std::shared_ptr<OSSIA::Node> node, Parameter_t&& param)
{
    auto addr = node->createAddress(OSSIA::Value::Type::TUPLE); // [ x y z ]
    auto x_node = *node->emplace(node->children().cend(), "x");
    auto x_addr = x_node->createAddress(OSSIA::Value::Type::FLOAT);
    auto y_node = *node->emplace(node->children().cend(), "y");
    auto y_addr = y_node->createAddress(OSSIA::Value::Type::FLOAT);
    auto z_node = *node->emplace(node->children().cend(), "z");
    auto z_addr = z_node->createAddress(OSSIA::Value::Type::FLOAT);

    addr->setValueCallback([=] (const OSSIA::Value* val) {
        auto tpl = dynamic_cast<const OSSIA::Tuple*>(val);
        if(tpl->value.size() != 3)
            return;

        auto x = dynamic_cast<const OSSIA::Float*>(tpl->value[0]);
        auto y = dynamic_cast<const OSSIA::Float*>(tpl->value[1]);
        auto z = dynamic_cast<const OSSIA::Float*>(tpl->value[2]);
        if(!x || !y || !z)
            return;

        param.set(oalplus::Vec3f{x->value, y->value, z->value});
    });

    auto modify_i = [=] (int i) {
        return [=] (const OSSIA::Value* val) {
            std::cerr << "Got a message!" << std::endl;
            auto float_val = dynamic_cast<const OSSIA::Float*>(val);
            if(!float_val)
                return;

            auto elt = param.get();
            elt[i] = float_val->value;
            param.set(elt);
        };
    };

    x_addr->setValueCallback(modify_i(0));
    y_addr->setValueCallback(modify_i(1));
    z_addr->setValueCallback(modify_i(2));
}

template<typename VecFun> // a function that takes a Vec6f& to modify.
void add_orientation(std::shared_ptr<OSSIA::Node> node, VecFun&& vecfun)
{
    auto addr = node->createAddress(OSSIA::Value::Type::TUPLE); // [ at_x at_y at_z up_x at_y at_z ]
    auto at_node = *node->emplace(node->children().cend(), "at");
    add_position(at_node, [&] () { return vecfun(); } );
    auto up_node = *node->emplace(node->children().cend(), "up");
}

int main(int argc, char** argv)
{
    oalplus::Device device;
    oalplus::ContextMadeCurrent context(
                device,
                oalplus::ContextAttribs().Add(oalplus::ContextAttrib::MonoSources, 1).Get());

    Scene s;

    OSSIA::Local localDeviceParameters{};
    auto local = OSSIA::Device::create(localDeviceParameters, "3DAudioScene");

    auto dev = OSSIA::Device::create(OSSIA::OSC{"127.0.0.1", 9997, 9996}, "MinuitDevice");
    {
        // Listener : position, orientation, volume ?

        // Sources : position, orientation, volume, enabled, sound file ?

        //// Global settings ////
        auto settings_node = *dev->emplace(dev->children().cend(), "settings");
        auto vol_node = *settings_node->emplace(settings_node->children().cend(), "volume");
        auto files_node = *settings_node->emplace(settings_node->children().cend(), "files");

        auto vol_addr = vol_node->createAddress(OSSIA::Value::Type::FLOAT);
        auto files_addr = files_node->createAddress(OSSIA::Value::Type::TUPLE);

        vol_addr->setValueCallback([] (const OSSIA::Value* val) { });
        files_addr->setValueCallback([] (const OSSIA::Value* val) { });

        // updating local tree value
        //OSSIA::Bool b(true);
        //localTestAddress->sendValue(&b);

        //// Listener settings ////
        auto listener_node = *dev->emplace(dev->children().cend(), "listener");

        auto listener_pos_node = *listener_node->emplace(listener_node->children().cend(), "pos");

        add_position(listener_pos_node,
                     make_parameter(
                         [&] () { return s.listener().Position(); },
                         [&] (const auto& elt) { s.listener().Position(elt); }
                     ));

        auto listener_orient_node = *listener_node->emplace(listener_node->children().cend(), "orient");

        //auto addr = listener_orient_node->createAddress(OSSIA::Value::Type::TUPLE); // [ at_x at_y at_z up_x at_y at_z ]
        auto listener_orient_at_node = *listener_orient_node->emplace(listener_orient_node->children().cend(), "at");
        add_position(listener_orient_at_node,
                     make_parameter(
                         [&] () { return s.listener().OrientationAt(); },
                         [&] (const auto& elt) { s.listener().Orientation(elt, s.listener().OrientationUp()); }
                     ));
        auto listener_orient_up_node = *listener_orient_node->emplace(listener_orient_node->children().cend(), "up");
        add_position(listener_orient_up_node,
                     make_parameter(
                         [&] () { return s.listener().OrientationUp(); },
                         [&] (const auto& elt) { s.listener().Orientation(s.listener().OrientationAt(), elt); }
                     ));

    }
    s.start();

    //
    return 0;
}

<commit_msg>all the relevant addresses should be here<commit_after>#include <oalplus/al.hpp>
#include <oalplus/all.hpp>
#include <oalplus/alut.hpp>
#include <chrono>
#include <thread>
#include <iostream>

#include <boost/range/algorithm/find_if.hpp>
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/hashed_index.hpp>
#include <boost/multi_index/mem_fun.hpp>
class Sound
{
    public:
        Sound(const std::string& name):
            Sound{name, oalplus::ALUtilityToolkit(false).CreateBufferHelloWorld()}
        {
        }

        Sound(const std::string& name, const std::string& filename):
            Sound{name, oalplus::ALUtilityToolkit(false).CreateBufferFromFile(filename)}
        {
        }

        Sound(const std::string& name, const oalplus::Buffer& buf):
            m_name{name},
            m_source{oalplus::ObjectDesc(std::string(name))}
        {
            m_source.Buffer(buf);
            m_source.Looping(true);
            m_source.ReferenceDistance(15);
        }

        auto& source()
        {
            return m_source;
        }

        const auto& source() const
        {
            return m_source;
        }

        void setEnabled(bool b)
        {
            m_source.Gain(b ? m_gain : 0.);
        }

        const std::string& name() const
        {
            return m_name;
        }

        void setName(const std::string &name)
        {
            m_name = name;
        }

        void load(const std::string& file)
        {
            m_source.Buffer(oalplus::ALUtilityToolkit(false).CreateBufferFromFile(file));
        }

    private:
        std::string m_name;
        oalplus::Source m_source;
        double m_gain{1.};
};

namespace bmi = boost::multi_index;
using SoundMap = bmi::multi_index_container<
Sound,
bmi::indexed_by<
bmi::hashed_unique<
bmi::const_mem_fun<
Sound,
const std::string&,
&Sound::name
>
>
>
>;
class Scene
{
    public:
        Scene()
        {
            // create a listener and set its position, velocity and orientation
            m_listener.Position(0.0f, 0.0f, 0.0f);
            m_listener.Velocity(0.0f, 0.0f, 0.0f);
            m_listener.Orientation(0.0f, 0.0f,-1.0f, 0.0f, 1.0f, 0.0f);

            m_sounds.insert(Sound("ASound"));
        }

        void start()
        {
            for(auto& cst_sound : m_sounds)
            {
                const_cast<Sound&>(cst_sound).source().Play();

                /*

                // the path of the source
                oalplus::CubicBezierLoop<oalplus::Vec3f, double> path(
                {
                                oalplus::Vec3f( 0.0f, 0.0f, -9.0f),
                                oalplus::Vec3f( 9.0f, 2.0f, -8.0f),
                                oalplus::Vec3f( 4.0f,-3.0f, 9.0f),
                                oalplus::Vec3f(-3.0f, 4.0f, 9.0f),
                                oalplus::Vec3f(-9.0f,-1.0f, -7.0f)
                            });
                //

                // play the sound for a while
                typedef std::chrono::system_clock clock;
                typedef std::chrono::time_point<clock> time_point;
                time_point start = clock::now();
                while(true)
                {
                    double t = double((clock::now() - start).count())*
                            double(clock::period::num)/
                            double(clock::period::den);
                    if(t > 10.0) break;
                    source.Position(path.Position(t/5.0));
                    m_listener.Position(m_listener.Position() - oalplus::Vec3f{0.2, 0, 0});
                    // wait for a while
                    std::chrono::milliseconds duration(10);
                    std::this_thread::sleep_for(duration);
                }
                */
                while(true)
                    std::this_thread::sleep_for(std::chrono::seconds(10));
            }
        }

        oalplus::Listener& listener()
        { return m_listener; }

        SoundMap& sounds()
        { return m_sounds; }

    private:
        oalplus::Listener m_listener;
        SoundMap m_sounds;
};

#include <Network/Device.h>
#include <Network/Protocol.h>
#include <Network/Node.h>

template<typename Get, typename Set>
struct Parameter
{
        Get get;
        Set set;
};

template<typename Get, typename Set>
auto make_parameter(Get&& get, Set&& set)
{
    return Parameter<Get, Set>{std::move(get), std::move(set)};
}

template<typename Fun>
auto add_child(std::shared_ptr<OSSIA::Node>& node,
               const std::string& name,
               OSSIA::Value::Type type,
               Fun&& callback)
{
    auto new_node = *node->emplace(node->children().cend(), name);
    new_node->createAddress(type)->setValueCallback(callback);

    return new_node;
}

template<typename Parameter_t> // a function that returns a Vec3f& to modify.
void add_position(std::shared_ptr<OSSIA::Node> node, Parameter_t&& param)
{
    static auto modify_i = [=] (int i) {
        return [=] (const OSSIA::Value* val) {
            auto float_val = dynamic_cast<const OSSIA::Float*>(val);
            if(!float_val)
                return;

            auto elt = param.get();
            elt[i] = float_val->value;
            param.set(elt);
        };
    };

    auto addr = node->createAddress(OSSIA::Value::Type::TUPLE); // [ x y z ]

    addr->setValueCallback([=] (const OSSIA::Value* val) {
        auto tpl = dynamic_cast<const OSSIA::Tuple*>(val);
        if(tpl->value.size() != 3)
            return;

        auto x = dynamic_cast<const OSSIA::Float*>(tpl->value[0]);
        auto y = dynamic_cast<const OSSIA::Float*>(tpl->value[1]);
        auto z = dynamic_cast<const OSSIA::Float*>(tpl->value[2]);
        if(!x || !y || !z)
            return;

        param.set(oalplus::Vec3f{x->value, y->value, z->value});
    });

    add_child(node, "x", OSSIA::Value::Type::FLOAT, modify_i(0));
    add_child(node, "y", OSSIA::Value::Type::FLOAT, modify_i(1));
    add_child(node, "z", OSSIA::Value::Type::FLOAT, modify_i(2));
}

int main(int argc, char** argv)
{
    oalplus::Device device;
    oalplus::ContextMadeCurrent context(
                device,
                oalplus::ContextAttribs().Add(oalplus::ContextAttrib::MonoSources, 1).Get());

    Scene s;

    OSSIA::Local localDeviceParameters{};
    auto local = OSSIA::Device::create(localDeviceParameters, "3DAudioScene");

    auto dev = OSSIA::Device::create(OSSIA::OSC{"127.0.0.1", 9997, 9996}, "MinuitDevice");
    {
        // Listener : position, orientation, volume ?

        // Sources : position, orientation, volume, enabled, sound file ?

        //// Global settings ////
        {
            auto settings_node = *dev->emplace(dev->children().cend(), "settings");
            auto vol_node = *settings_node->emplace(settings_node->children().cend(), "volume");
            auto files_node = *settings_node->emplace(settings_node->children().cend(), "files");

            auto vol_addr = vol_node->createAddress(OSSIA::Value::Type::FLOAT);
            auto files_addr = files_node->createAddress(OSSIA::Value::Type::TUPLE);

            vol_addr->setValueCallback([] (const OSSIA::Value* val) { });
            files_addr->setValueCallback([] (const OSSIA::Value* val) { });
        }
        //// Listener settings ////
        {
            auto listener_node = *dev->emplace(dev->children().cend(), "listener");

            auto listener_pos_node = *listener_node->emplace(listener_node->children().cend(), "pos");

            add_position(listener_pos_node,
                         make_parameter(
                             [&] () { return s.listener().Position(); },
            [&] (const auto& elt) { s.listener().Position(elt); }
            ));

            auto listener_orient_node = *listener_node->emplace(listener_node->children().cend(), "orientation");
            auto listener_orient_addr = listener_orient_node->createAddress(OSSIA::Value::Type::TUPLE); // [ at_x at_y at_z up_x at_y at_z ]
            listener_orient_addr->setValueCallback([&] (const OSSIA::Value* val) {
                auto tpl = dynamic_cast<const OSSIA::Tuple*>(val);
                if(tpl->value.size() != 6)
                    return;

                auto at_x = dynamic_cast<const OSSIA::Float*>(tpl->value[0]);
                auto at_y = dynamic_cast<const OSSIA::Float*>(tpl->value[1]);
                auto at_z = dynamic_cast<const OSSIA::Float*>(tpl->value[2]);
                auto up_x = dynamic_cast<const OSSIA::Float*>(tpl->value[3]);
                auto up_y = dynamic_cast<const OSSIA::Float*>(tpl->value[4]);
                auto up_z = dynamic_cast<const OSSIA::Float*>(tpl->value[5]);
                if(!at_x || !at_y || !at_z || !up_x || !up_y || !up_z)
                    return;

                s.listener().Orientation(at_x->value, at_y->value, at_z->value, up_x->value, up_y->value, up_z->value);
            });

            auto listener_orient_at_node = *listener_orient_node->emplace(listener_orient_node->children().cend(), "at");
            add_position(listener_orient_at_node,
                         make_parameter(
                             [&] () { return s.listener().OrientationAt(); },
            [&] (const auto& elt) { s.listener().Orientation(elt, s.listener().OrientationUp()); }
            ));
            auto listener_orient_up_node = *listener_orient_node->emplace(listener_orient_node->children().cend(), "up");
            add_position(listener_orient_up_node,
                         make_parameter(
                             [&] () { return s.listener().OrientationUp(); },
            [&] (const auto& elt) { s.listener().Orientation(s.listener().OrientationAt(), elt); }
            ));

        }

        //// Sources settings ////
        {
            auto sources_node = *dev->emplace(dev->children().cend(), "sources");
            auto sources_list_node = *sources_node->emplace(sources_node->children().cend(), "sources");

            add_child(sources_node, "add", OSSIA::Value::Type::STRING,
                      [&] (const OSSIA::Value* val) {
                auto str_val = dynamic_cast<const OSSIA::String*>(val);
                if(!str_val)
                    return;

                // Create the sound
                s.sounds().insert(Sound{str_val->value});
                auto& sound = const_cast<Sound&>(*s.sounds().get<0>().find(str_val->value));

                // Create the callbacks and OSC device commands
                auto src_node = *sources_list_node->emplace(sources_list_node->children().cend(), str_val->value);

                // Position
                auto src_pos_node = *src_node->emplace(src_node->children().cend(), "pos");
                add_position(src_pos_node,
                             make_parameter(
                                 [&] () { return sound.source().Position(); },
                [&] (const auto& elt) { sound.source().Position(elt); }
                ));

                // Enablement
                add_child(src_node, "enabled", OSSIA::Value::Type::BOOL,
                          [&] (const OSSIA::Value* val) {
                    auto enablement_val = dynamic_cast<const OSSIA::Bool*>(val);
                    if(!enablement_val)
                        return;
                    sound.setEnabled(enablement_val->value);
                });

                // Audio file
                add_child(src_node, "file", OSSIA::Value::Type::STRING,
                          [&] (const OSSIA::Value* val) {
                    auto filename_val = dynamic_cast<const OSSIA::String*>(val);
                    if(!filename_val)
                        return;
                    sound.load(filename_val->value);
                });
            });

            add_child(sources_node, "remove", OSSIA::Value::Type::STRING, [&] (const OSSIA::Value* val) {
                auto str_val = dynamic_cast<const OSSIA::String*>(val);
                if(!str_val)
                    return;

                // Remove from the sounds
                s.sounds().erase(str_val->value);

                // Remove from the OSC device
                auto& children = sources_node->children();
                auto it = boost::range::find_if(children,
                                                [&] (auto&& elt) { return elt->getName() == str_val->value; });
                if(it != children.end())
                    children.erase(it);
            });
        }

    }
    s.start();

    return 0;
}
<|endoftext|>


<commit_before>// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s

// PR8839
extern "C" char memmove();

int main() {
  // CHECK: call signext i8 @memmove()
  return memmove();
}
<commit_msg>Permit ABIs where the caller extends the result (test change).<commit_after>// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s

// PR8839
extern "C" char memmove();

int main() {
  // CHECK: call {{signext i8|i8}} @memmove()
  return memmove();
}
<|endoftext|>


<commit_before>/* Copyright (c) 2015 Convey Computer Corporation
 *
 * This file is part of the OpenHT toolset located at:
 *
 * https://github.com/TonyBrewer/OpenHT
 *
 * Use and distribution licensed under the BSD 3-clause license.
 * See the LICENSE file for the complete license text.
 */

#include "HtSageUtils.h"
#include "IsolateModules.h"

extern bool debugHooks;
std::set<std::string> LockFunctionsInUse;

inline std::string Capitalize(std::string str) {
    std::string cap = str;
    if (str.size()) {
        cap[0] = toupper(cap[0]);
    }
    return cap;
}

// Copied these from CnyHt code
inline std::string Upper(std::string str) {
    std::string upper = str;
    for (size_t i = 0; i < upper.size(); i += 1)
        upper[i] = toupper(upper[i]);
    return upper;
}

// Insert preprocessing macros to remove original function declarations
// and wrap each function so it can be isolated from the others by enabling
// the specific function macro.
//
// This is a simple-minded way to do this.   Ideally, we'll eventually break
// each module out into it's own file.

class IsolateModules : public AstSimpleProcessing {

public:

    virtual void visit (SgNode* astNode) {

        SgFunctionDeclaration *fdecl = isSgFunctionDeclaration(astNode);

        if (fdecl) {
            fdeclList.push_back(fdecl);
        }

        SgFunctionDefinition *fdef = isSgFunctionDefinition(astNode);
        if (fdef) {
            fdefList.push_back(fdef);
        }
    }

    void process() {
        int i;

        for (i = 0; i < fdefList.size(); i++) {
            SgFunctionDefinition* fndef = fdefList.at(i);

            if (fndef == NULL) {
                return;
            }

            std::string functionName =
                fndef->get_declaration()->get_name().getString();

            SgFunctionDeclaration *f = fndef->get_declaration();

            if (!debugHooks) {
                SgNode *body = fndef->get_body();

                // Move any preprocessing info before the function to a new
                // null statement preceding the function.
                AttachedPreprocessingInfoType save_buf;
                SageInterface::cutPreprocessingInfo(f,
                                                    PreprocessingInfo::before,
                                                    save_buf) ;
                if (save_buf.size()) {
                    SgVariableDeclaration *dummy =
                        SageBuilder::buildVariableDeclaration(
                            "___htc_dummy_decl_for_preproc_info",
                            SageBuilder::buildIntType(), 0, f->get_scope());
                    SageInterface::setExtern(dummy);

                    SageInterface::insertStatementBefore(f, dummy);
                    SageInterface::pastePreprocessingInfo(
                        dummy,
                        PreprocessingInfo::before,
                        save_buf);
                }

                SageInterface::addTextForUnparser(
                    f,
                    "\n#if 0",
                    AstUnparseAttribute::e_before);

                std::string CapFnName = Capitalize(functionName);
                std::string before_body = "\n#endif\n";
                std::string macro_name = "HTC_KEEP_MODULE_" + Upper(functionName);
                before_body +=
                    "#ifdef " +
                    macro_name +
                    "\n";
                before_body += "#include \"Ht.h\"\n";
                before_body += "#include \"Pers" +
                    CapFnName +
                    ".h\"\n";
                before_body += "#ifndef __htc_GW_write_addr\n";
                before_body += "#define __htc_GW_write_addr(v,a) v.write_addr(a)\n";
                before_body += "#endif\n";
                before_body += "void CPers" +
                    CapFnName +
                    "::Pers" +
                    CapFnName +
                    "()\n";
                SageInterface::addTextForUnparser(body, before_body,
                                                  AstUnparseAttribute::e_before);
                std::string after_body =
                    "\n#endif /* " +
                    macro_name +
                    " */\n";
                SageInterface::addTextForUnparser(body, after_body,
                                                  AstUnparseAttribute::e_after);

                // Write the _src.cpp file
                generate_src_cpp_file(fndef, CapFnName, macro_name);
            }
        }
        for (i = 0; i < fdeclList.size(); i++) {

            SgFunctionDeclaration *fdecl = fdeclList.at(i);

            if (!debugHooks &&
                fdecl &&
                fdecl->get_definingDeclaration() != fdecl) {

                // Move any preprocessing info before the function to a new
                // null statement preceding the function.
                AttachedPreprocessingInfoType save_buf;
                SageInterface::cutPreprocessingInfo(fdecl,
                                                    PreprocessingInfo::before,
                                                    save_buf) ;
                if (save_buf.size()) {
                    SgVariableDeclaration *dummy2 =
                        SageBuilder::buildVariableDeclaration(
                            "___htc_dummy_decl2_for_preproc_info",
                            SageBuilder::buildIntType(),
                            0,
                            fdecl->get_scope());
                    SageInterface::setExtern(dummy2);

                    SageInterface::insertStatementBefore(fdecl, dummy2);
                    SageInterface::pastePreprocessingInfo(
                        dummy2,
                        PreprocessingInfo::before,
                        save_buf);

                }

                SageInterface::addTextForUnparser(fdecl, "\n/* ",
                                                  AstUnparseAttribute::e_before);
                SageInterface::addTextForUnparser(fdecl, " */",
                                                  AstUnparseAttribute::e_after);
                // comment out function prototypes
                //            fdecl->setCompilerGenerated();
                //            fdecl->unsetOutputInCodeGeneration();
            }
        }

    }

    void generate_lock_src_cpp_files(std::string &path_name) {

        // Generate Pers_*_src.cpp file for Lock functions
        std::set<std::string>::iterator it;

        for (it = LockFunctionsInUse.begin(); it != LockFunctionsInUse.end(); it++) {
            std::string module_name = *it;
            std::string macro_name = "HTC_KEEP_MODULE_" + Upper(module_name);
            std::string cpp_name = path_name + "Pers" +
                Capitalize(module_name) + "_src.cpp";
            std::fstream fs;

            fs.open(cpp_name.c_str(), std::fstream::out | std::fstream::trunc);

            fs << "#define " << macro_name << std::endl;
            fs << "#include \"rose_lock.c\"" << std::endl;

            fs.close();
        }

        LockFunctionsInUse.clear();

    }

    void generate_src_cpp_file(SgFunctionDefinition *fndef,
                               std::string &module_name,
                               std::string &macro_name) {

        std::pair<bool, std::string> fret = HtSageUtils::getFileName(fndef);
        std::string src_name = fret.second;
        std::string base_name = StringUtility::stripPathFromFileName(src_name);
        std::string path_name = StringUtility::getPathFromFileName(src_name) + "/";
        std::string cpp_name= path_name + "Pers" + module_name + "_src.cpp";
        std::fstream fs;

        fs.open(cpp_name.c_str(), std::fstream::out | std::fstream::trunc);

        fs << "#define " << macro_name << std::endl;
        fs << "#define CNY_HTC_COPROC" << std::endl;
        fs << "#include \"rose_" << base_name << "\"" << std::endl;

        fs.close();

        generate_lock_src_cpp_files(path_name);

    }

private:
    std::vector<SgFunctionDeclaration *> fdeclList;
    std::vector<SgFunctionDefinition *> fdefList;
};

void IsolateModulesToFiles(SgProject *project) {
    IsolateModules im;
    im.traverseInputFiles(project, preorder, STRICT_INPUT_FILE_TRAVERSAL);
    im.process();
}
<commit_msg>Add missing define<commit_after>/* Copyright (c) 2015 Convey Computer Corporation
 *
 * This file is part of the OpenHT toolset located at:
 *
 * https://github.com/TonyBrewer/OpenHT
 *
 * Use and distribution licensed under the BSD 3-clause license.
 * See the LICENSE file for the complete license text.
 */

#include "HtSageUtils.h"
#include "IsolateModules.h"

extern bool debugHooks;
std::set<std::string> LockFunctionsInUse;

inline std::string Capitalize(std::string str) {
    std::string cap = str;
    if (str.size()) {
        cap[0] = toupper(cap[0]);
    }
    return cap;
}

// Copied these from CnyHt code
inline std::string Upper(std::string str) {
    std::string upper = str;
    for (size_t i = 0; i < upper.size(); i += 1)
        upper[i] = toupper(upper[i]);
    return upper;
}

// Insert preprocessing macros to remove original function declarations
// and wrap each function so it can be isolated from the others by enabling
// the specific function macro.
//
// This is a simple-minded way to do this.   Ideally, we'll eventually break
// each module out into it's own file.

class IsolateModules : public AstSimpleProcessing {

public:

    virtual void visit (SgNode* astNode) {

        SgFunctionDeclaration *fdecl = isSgFunctionDeclaration(astNode);

        if (fdecl) {
            fdeclList.push_back(fdecl);
        }

        SgFunctionDefinition *fdef = isSgFunctionDefinition(astNode);
        if (fdef) {
            fdefList.push_back(fdef);
        }
    }

    void process() {
        int i;

        for (i = 0; i < fdefList.size(); i++) {
            SgFunctionDefinition* fndef = fdefList.at(i);

            if (fndef == NULL) {
                return;
            }

            std::string functionName =
                fndef->get_declaration()->get_name().getString();

            SgFunctionDeclaration *f = fndef->get_declaration();

            if (!debugHooks) {
                SgNode *body = fndef->get_body();

                // Move any preprocessing info before the function to a new
                // null statement preceding the function.
                AttachedPreprocessingInfoType save_buf;
                SageInterface::cutPreprocessingInfo(f,
                                                    PreprocessingInfo::before,
                                                    save_buf) ;
                if (save_buf.size()) {
                    SgVariableDeclaration *dummy =
                        SageBuilder::buildVariableDeclaration(
                            "___htc_dummy_decl_for_preproc_info",
                            SageBuilder::buildIntType(), 0, f->get_scope());
                    SageInterface::setExtern(dummy);

                    SageInterface::insertStatementBefore(f, dummy);
                    SageInterface::pastePreprocessingInfo(
                        dummy,
                        PreprocessingInfo::before,
                        save_buf);
                }

                SageInterface::addTextForUnparser(
                    f,
                    "\n#if 0",
                    AstUnparseAttribute::e_before);

                std::string CapFnName = Capitalize(functionName);
                std::string before_body = "\n#endif\n";
                std::string macro_name = "HTC_KEEP_MODULE_" + Upper(functionName);
                before_body +=
                    "#ifdef " +
                    macro_name +
                    "\n";
                before_body += "#include \"Ht.h\"\n";
                before_body += "#include \"Pers" +
                    CapFnName +
                    ".h\"\n";
                before_body += "#ifndef __htc_GW_write_addr\n";
                before_body += "#define __htc_GW_write_addr(v,a) v.write_addr(a)\n";
                before_body += "#endif\n";
                before_body += "#ifndef __htc_GW_write_addr2\n";
                before_body += "#define __htc_GW_write_addr2(v,a,b) v.write_addr(a,b)\n";
                before_body += "#endif\n";
                before_body += "void CPers" +
                    CapFnName +
                    "::Pers" +
                    CapFnName +
                    "()\n";
                SageInterface::addTextForUnparser(body, before_body,
                                                  AstUnparseAttribute::e_before);
                std::string after_body =
                    "\n#endif /* " +
                    macro_name +
                    " */\n";
                SageInterface::addTextForUnparser(body, after_body,
                                                  AstUnparseAttribute::e_after);

                // Write the _src.cpp file
                generate_src_cpp_file(fndef, CapFnName, macro_name);
            }
        }
        for (i = 0; i < fdeclList.size(); i++) {

            SgFunctionDeclaration *fdecl = fdeclList.at(i);

            if (!debugHooks &&
                fdecl &&
                fdecl->get_definingDeclaration() != fdecl) {

                // Move any preprocessing info before the function to a new
                // null statement preceding the function.
                AttachedPreprocessingInfoType save_buf;
                SageInterface::cutPreprocessingInfo(fdecl,
                                                    PreprocessingInfo::before,
                                                    save_buf) ;
                if (save_buf.size()) {
                    SgVariableDeclaration *dummy2 =
                        SageBuilder::buildVariableDeclaration(
                            "___htc_dummy_decl2_for_preproc_info",
                            SageBuilder::buildIntType(),
                            0,
                            fdecl->get_scope());
                    SageInterface::setExtern(dummy2);

                    SageInterface::insertStatementBefore(fdecl, dummy2);
                    SageInterface::pastePreprocessingInfo(
                        dummy2,
                        PreprocessingInfo::before,
                        save_buf);

                }

                SageInterface::addTextForUnparser(fdecl, "\n/* ",
                                                  AstUnparseAttribute::e_before);
                SageInterface::addTextForUnparser(fdecl, " */",
                                                  AstUnparseAttribute::e_after);
                // comment out function prototypes
                //            fdecl->setCompilerGenerated();
                //            fdecl->unsetOutputInCodeGeneration();
            }
        }

    }

    void generate_lock_src_cpp_files(std::string &path_name) {

        // Generate Pers_*_src.cpp file for Lock functions
        std::set<std::string>::iterator it;

        for (it = LockFunctionsInUse.begin(); it != LockFunctionsInUse.end(); it++) {
            std::string module_name = *it;
            std::string macro_name = "HTC_KEEP_MODULE_" + Upper(module_name);
            std::string cpp_name = path_name + "Pers" +
                Capitalize(module_name) + "_src.cpp";
            std::fstream fs;

            fs.open(cpp_name.c_str(), std::fstream::out | std::fstream::trunc);

            fs << "#define " << macro_name << std::endl;
            fs << "#include \"rose_lock.c\"" << std::endl;

            fs.close();
        }

        LockFunctionsInUse.clear();

    }

    void generate_src_cpp_file(SgFunctionDefinition *fndef,
                               std::string &module_name,
                               std::string &macro_name) {

        std::pair<bool, std::string> fret = HtSageUtils::getFileName(fndef);
        std::string src_name = fret.second;
        std::string base_name = StringUtility::stripPathFromFileName(src_name);
        std::string path_name = StringUtility::getPathFromFileName(src_name) + "/";
        std::string cpp_name= path_name + "Pers" + module_name + "_src.cpp";
        std::fstream fs;

        fs.open(cpp_name.c_str(), std::fstream::out | std::fstream::trunc);

        fs << "#define " << macro_name << std::endl;
        fs << "#define CNY_HTC_COPROC" << std::endl;
        fs << "#include \"rose_" << base_name << "\"" << std::endl;

        fs.close();

        generate_lock_src_cpp_files(path_name);

    }

private:
    std::vector<SgFunctionDeclaration *> fdeclList;
    std::vector<SgFunctionDefinition *> fdefList;
};

void IsolateModulesToFiles(SgProject *project) {
    IsolateModules im;
    im.traverseInputFiles(project, preorder, STRICT_INPUT_FILE_TRAVERSAL);
    im.process();
}
<|endoftext|>


<commit_before>/*******************************
Copyright (c) 2016-2017 Grégoire Angerand

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
**********************************/

#include <yave/device/Device.h>
#include <yave/commands/CmdBuffer.h>

namespace yave {

static void check_features(const vk::PhysicalDeviceFeatures& features, const vk::PhysicalDeviceFeatures& required) {
	auto feats = reinterpret_cast<const vk::Bool32*>(&features);
	auto req = reinterpret_cast<const vk::Bool32*>(&required);
	for(usize i = 0; i != sizeof(features) / sizeof(vk::Bool32); ++i) {
		if(req[i] && !feats[i]) {
			fatal("Required Vulkan feature not supported");
		}
	}
}

static core::Vector<QueueFamily> compute_queue_families(vk::PhysicalDevice physical) {
	core::Vector<QueueFamily> queue_families;

	auto families = physical.getQueueFamilyProperties();
	for(u32 i = 0; i != families.size(); i++) {
		queue_families << QueueFamily(i, families[i]);
	}
	return queue_families;
}

static vk::Device create_device(
		vk::PhysicalDevice physical,
		const core::Vector<QueueFamily>& queue_families,
		const core::Vector<const char*>& extentions,
		const DebugParams& debug) {

	auto queue_create_infos = core::vector_with_capacity<vk::DeviceQueueCreateInfo>(queue_families.size());

	float priorities = 1.0f;
	std::transform(queue_families.begin(), queue_families.end(), std::back_inserter(queue_create_infos), [&](const auto& q) {
		return vk::DeviceQueueCreateInfo()
				.setQueueFamilyIndex(q.index())
				.setPQueuePriorities(&priorities)
				.setQueueCount(q.count())
			;
		});

	auto required = vk::PhysicalDeviceFeatures();
	required.multiDrawIndirect = true;
	required.drawIndirectFirstInstance = true;
	required.fullDrawIndexUint32 = true;
	required.textureCompressionBC  = true;

	if(debug.is_debug_callback_enabled()) {
		required.robustBufferAccess = true;
	}

	check_features(physical.getFeatures(), required);

	return physical.createDevice(vk::DeviceCreateInfo()
			.setEnabledExtensionCount(u32(extentions.size()))
			.setPpEnabledExtensionNames(extentions.begin())
			.setEnabledLayerCount(u32(debug.device_layers().size()))
			.setPpEnabledLayerNames(debug.device_layers().begin())
			.setQueueCreateInfoCount(queue_create_infos.size())
			.setPQueueCreateInfos(queue_create_infos.begin())
			.setPEnabledFeatures(&required)
		);
}

Device::Device(Instance& instance) :
		_instance(instance),
		_physical(instance),
		_queue_families(compute_queue_families(_physical.vk_physical_device())),
		_device(create_device(_physical.vk_physical_device(), _queue_families, {VK_KHR_SWAPCHAIN_EXTENSION_NAME}, _instance.debug_params())),
		_sampler(this),
		_disposable_cmd_pool(this),
		_secondary_cmd_pool(this),
		_primary_cmd_pool(this),
		_descriptor_layout_pool(new DescriptorSetLayoutPool(this)) {

	for(const auto& family : _queue_families) {
		auto q = family.fetch_queues(this);
		_queues.push_back(q.begin(), q.end());
	}
}

Device::~Device() {
	for(auto q : _queues) {
		q.waitIdle();
	}

	if(_disposable_cmd_pool.active_buffers()) {
		fatal("Buffer still active.");
	}

	_sampler = Sampler();

	// we need to destroy the pools before the device
	_secondary_cmd_pool = CmdBufferPool<CmdBufferUsage::Secondary>();
	_disposable_cmd_pool = CmdBufferPool<CmdBufferUsage::Disposable>();
	_primary_cmd_pool = CmdBufferPool<CmdBufferUsage::Normal>();

	delete _descriptor_layout_pool;

	_device.destroy();
}

const PhysicalDevice& Device::physical_device() const {
	return _physical;
}

const Instance &Device::instance() const {
	return _instance;
}

vk::Device Device::vk_device() const {
	return _device;
}

vk::Queue Device::vk_queue(vk::QueueFlags) const {
#warning change Device::vk_queue
	return _queues.first();
}

vk::Sampler Device::vk_sampler() const {
	return _sampler.vk_sampler();
}

const QueueFamily& Device::queue_family(vk::QueueFlags flags) const {
	for(const auto& q : _queue_families) {
		if((q.flags() & flags) == flags) {
			return q;
		}
	}
	return fatal("Unable to find queue.");
}

}
<commit_msg>fixed warning.<commit_after>/*******************************
Copyright (c) 2016-2017 Grégoire Angerand

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
**********************************/

#include <yave/device/Device.h>
#include <yave/commands/CmdBuffer.h>

namespace yave {

static void check_features(const vk::PhysicalDeviceFeatures& features, const vk::PhysicalDeviceFeatures& required) {
	auto feats = reinterpret_cast<const vk::Bool32*>(&features);
	auto req = reinterpret_cast<const vk::Bool32*>(&required);
	for(usize i = 0; i != sizeof(features) / sizeof(vk::Bool32); ++i) {
		if(req[i] && !feats[i]) {
			fatal("Required Vulkan feature not supported");
		}
	}
}

static core::Vector<QueueFamily> compute_queue_families(vk::PhysicalDevice physical) {
	core::Vector<QueueFamily> queue_families;

	auto families = physical.getQueueFamilyProperties();
	for(u32 i = 0; i != families.size(); i++) {
		queue_families << QueueFamily(i, families[i]);
	}
	return queue_families;
}

static vk::Device create_device(
		vk::PhysicalDevice physical,
		const core::Vector<QueueFamily>& queue_families,
		const core::Vector<const char*>& extentions,
		const DebugParams& debug) {

	auto queue_create_infos = core::vector_with_capacity<vk::DeviceQueueCreateInfo>(queue_families.size());

	float priorities = 1.0f;
	std::transform(queue_families.begin(), queue_families.end(), std::back_inserter(queue_create_infos), [&](const auto& q) {
		return vk::DeviceQueueCreateInfo()
				.setQueueFamilyIndex(q.index())
				.setPQueuePriorities(&priorities)
				.setQueueCount(q.count())
			;
		});

	auto required = vk::PhysicalDeviceFeatures();
	required.multiDrawIndirect = true;
	required.drawIndirectFirstInstance = true;
	required.fullDrawIndexUint32 = true;
	required.textureCompressionBC  = true;

	if(debug.is_debug_callback_enabled()) {
		required.robustBufferAccess = true;
	}

	check_features(physical.getFeatures(), required);

	return physical.createDevice(vk::DeviceCreateInfo()
			.setEnabledExtensionCount(u32(extentions.size()))
			.setPpEnabledExtensionNames(extentions.begin())
			.setEnabledLayerCount(u32(debug.device_layers().size()))
			.setPpEnabledLayerNames(debug.device_layers().begin())
			.setQueueCreateInfoCount(queue_create_infos.size())
			.setPQueueCreateInfos(queue_create_infos.begin())
			.setPEnabledFeatures(&required)
		);
}

Device::Device(Instance& instance) :
		_instance(instance),
		_physical(instance),
		_queue_families(compute_queue_families(_physical.vk_physical_device())),
		_device(create_device(_physical.vk_physical_device(), _queue_families, {VK_KHR_SWAPCHAIN_EXTENSION_NAME}, _instance.debug_params())),
		_sampler(this),
		_secondary_cmd_pool(this),
		_disposable_cmd_pool(this),
		_primary_cmd_pool(this),
		_descriptor_layout_pool(new DescriptorSetLayoutPool(this)) {

	for(const auto& family : _queue_families) {
		auto q = family.fetch_queues(this);
		_queues.push_back(q.begin(), q.end());
	}
}

Device::~Device() {
	for(auto q : _queues) {
		q.waitIdle();
	}

	if(_disposable_cmd_pool.active_buffers()) {
		fatal("Buffer still active.");
	}

	_sampler = Sampler();

	// we need to destroy the pools before the device
	_secondary_cmd_pool = CmdBufferPool<CmdBufferUsage::Secondary>();
	_disposable_cmd_pool = CmdBufferPool<CmdBufferUsage::Disposable>();
	_primary_cmd_pool = CmdBufferPool<CmdBufferUsage::Normal>();

	delete _descriptor_layout_pool;

	_device.destroy();
}

const PhysicalDevice& Device::physical_device() const {
	return _physical;
}

const Instance &Device::instance() const {
	return _instance;
}

vk::Device Device::vk_device() const {
	return _device;
}

vk::Queue Device::vk_queue(vk::QueueFlags) const {
#warning change Device::vk_queue
	return _queues.first();
}

vk::Sampler Device::vk_sampler() const {
	return _sampler.vk_sampler();
}

const QueueFamily& Device::queue_family(vk::QueueFlags flags) const {
	for(const auto& q : _queue_families) {
		if((q.flags() & flags) == flags) {
			return q;
		}
	}
	return fatal("Unable to find queue.");
}

}
<|endoftext|>


<commit_before>#include <omp.h>
#include <stdio.h>
#include <opencv2/opencv.hpp>
#include <fstream>
#include <iostream>
#include <armadillo>
#include <iomanip>
#include <vector>

using namespace std;
using namespace arma;

#include "grass-def.hpp"
#include "grass-impl.hpp"

//Home
//const std::string path = "/media/johanna/HD1T/codes/datasets_codes/KTH/";

//WANDA
const std::string path = "/home/johanna/codes/codes-git/study-paper/trunk/features/";

const std::string peopleList = "people_list.txt";
const std::string  actionNames = "actionNames.txt";

///kth
// int ori_col = 160;
// int ori_row = 120;

int
main(int argc, char** argv)
{

  //    if(argc < 3 )
  //   {
  //     cout << "usage: " << argv[0] << " scale_factor " << " shift_factor " << endl;
  //     return -1;
  //   }
  //
  //
  //   int scale_factor = atoi( argv[1] );
  //   int shift = atoi( argv[2] );

  vec vec_shift;
  vec_shift << -25 << -20 << -15 << -10 << -5 << 5 << 10 << 15 << 20 << 25 << endr;
  int scale_factor =1;

  int total_scenes = 1; //Try only with scenario 1
  int segment_length = 20;
  //int p   = 12; //To obtain the optimise sub-space of order p
  int dim = 14;

  //for (int i=0; i< vec_shift.n_elem; ++i)
  for (int p=1; p<= dim; ++p)
  {

    //int shift = vec_shift(i);
    int shift = 0;
    cout << "Gp for p= " << p << endl;

    field<string> all_people;
    all_people.load(peopleList);

    grass_points get_gp(path, actionNames, scale_factor, shift, total_scenes, segment_length, p);
    //get_gp.calculate( all_people, dim );
    get_gp.calculate_onepervideo( all_people, dim );
  }

  return 0;

}
<commit_msg>Get all Grassmann points for all shifts and p<commit_after>#include <omp.h>
#include <stdio.h>
#include <opencv2/opencv.hpp>
#include <fstream>
#include <iostream>
#include <armadillo>
#include <iomanip>
#include <vector>

using namespace std;
using namespace arma;

#include "grass-def.hpp"
#include "grass-impl.hpp"

//Home
//const std::string path = "/media/johanna/HD1T/codes/datasets_codes/KTH/";

//WANDA
const std::string path = "/home/johanna/codes/codes-git/study-paper/trunk/features/";

const std::string peopleList = "people_list.txt";
const std::string  actionNames = "actionNames.txt";

///kth
// int ori_col = 160;
// int ori_row = 120;

int
main(int argc, char** argv)
{

  //    if(argc < 3 )
  //   {
  //     cout << "usage: " << argv[0] << " scale_factor " << " shift_factor " << endl;
  //     return -1;
  //   }
  //
  //
  //   int scale_factor = atoi( argv[1] );
  //   int shift = atoi( argv[2] );

  vec vec_shift;
  vec_shift << -25 << -20 << -15 << -10 << -5 << 5 << 10 << 15 << 20 << 25 << endr;
  int scale_factor =1;

  int total_scenes = 1; //Try only with scenario 1
  int segment_length = 20;
  //int p   = 12; //To obtain the optimise sub-space of order p
  int dim = 14;

  for (int i=0; i< vec_shift.n_elem; ++i)
  {
    for (int p=1; p<= dim; ++p)
    {

      int shift = vec_shift(i);
      cout << "Gp for shift " << shift << " &  p= " << p << endl;

      field<string> all_people;
      all_people.load(peopleList);

      grass_points get_gp(path, actionNames, scale_factor, shift, total_scenes, segment_length, p);
      //get_gp.calculate( all_people, dim );
      get_gp.calculate_onepervideo( all_people, dim );
    }
  }

  return 0;

}
<|endoftext|>