<commit_before>/*****************************************************************************
 *  Copyright (C) 2008-2011 Massachusetts Institute of Technology            *
 *                                                                           *
 *  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           *
 *                                                                           *
 *  This source code is part of the PetaBricks project:                      *
 *    http://projects.csail.mit.edu/petabricks/                              *
 *                                                                           *
 *****************************************************************************/
#include "workerthread.h"

#include "dynamicscheduler.h"
#include "common/jasm.h"

#include <pthread.h>
#include <signal.h>
#include <unistd.h>

#ifdef HAVE_CONFIG_H
#  include "config.h"
#endif

#ifdef DEBUG
#  define DEBUGONLY(args...) args
#else
#  define DEBUGONLY(args...) (void)0
#endif

//singleton main thread
static petabricks::WorkerThread theMainWorkerThread(petabricks::DynamicScheduler::cpuScheduler());

#ifdef HAVE_THREADLOCAL
//this is the simple/fast version
__thread petabricks::WorkerThread* mySelfPtr = NULL;
petabricks::WorkerThread* petabricks::WorkerThread::self(){
  return mySelfPtr;
}
void setSelf(petabricks::WorkerThread* v){
  mySelfPtr = v;
}
#else
//this is a backwards compatible version for archs that dont support __thread
namespace { //file local
  static pthread_key_t  worker_key;
  static pthread_once_t worker_key_once = PTHREAD_ONCE_INIT;
  static void worker_destroy(int* buf){ delete buf; }
  static void worker_key_alloc(){  pthread_key_create(&worker_key, (void (*)(void*)) worker_destroy); }
  static void worker_alloc(){
    pthread_once(&worker_key_once, worker_key_alloc);
    pthread_setspecific(worker_key, new petabricks::WorkerThread*);
  }
}
petabricks::WorkerThread* petabricks::WorkerThread::self(){
  petabricks::WorkerThread** t = (petabricks::WorkerThread**)pthread_getspecific(worker_key);
  return t!=NULL ? *t : NULL;
}
void setSelf(petabricks::WorkerThread* v){
  petabricks::WorkerThread** t = (petabricks::WorkerThread**)pthread_getspecific(worker_key);
  if(t==NULL){
    worker_alloc();
    t = (petabricks::WorkerThread**)pthread_getspecific(worker_key);
    JASSERT(t!=NULL);
  }
  *t = v;
}
#endif

petabricks::WorkerThread::WorkerThread(DynamicScheduler& ds)
  : _pool(ds.pool())
{
  static jalib::AtomicT lastId = -1;
  _id = (int)jalib::atomicIncrementReturn(&lastId);
  _randomNumState.z = _id * _id * 2;
  _randomNumState.w = _id + 1;
  setSelf(this);
  _pool.insert(this);
#ifdef WORKERTHREAD_ONDECK
  _ondeck = NULL;
#endif
  DEBUGONLY(_isWorking=false);
}
petabricks::WorkerThread::~WorkerThread(){
  _pool.remove(this);
}

int petabricks::WorkerThread::threadRandInt() const {
  _randomNumState.z = 36969 * (_randomNumState.z & 65535) + (_randomNumState.z >> 16);
  _randomNumState.w = 18000 * (_randomNumState.w & 65535) + (_randomNumState.w >> 16);
  int retVal = (_randomNumState.z << 16) + _randomNumState.w;
  if (retVal < 0) {
    retVal = -retVal;
  }
  return retVal;
}

void petabricks::WorkerThread::popAndRunOneTask(int stealLimit)
{
  DynamicTask *task;

  //try from the local deque
  task = popLocal();

  //try stealing a bunch of times
  while(task == NULL && stealLimit-->0){
    WorkerThread* victim = _pool.getRandom(this);
    task = victim->steal();
  }

  //if we got something, run it
  if (task != NULL) {
    DEBUGONLY(_isWorking=true);
    task->runWrapper();
    DEBUGONLY(_isWorking=false);
  } else {
    sched_yield();
  }
}

void petabricks::WorkerThread::mainLoop(){
  for(;;){
    try {
      for(;;) popAndRunOneTask(STEAL_ATTEMPTS_MAINLOOP);
    }catch(DynamicScheduler::AbortException e){}
  }
}

petabricks::WorkerThreadPool::WorkerThreadPool(){
  memset(_pool, 0, sizeof _pool);
}

void petabricks::WorkerThreadPool::insert(WorkerThread* thread){
  int i = _count; // the slot we wish to insert into
  for(;;++i){
    JASSERT(i<MAX_NUM_WORKERS)(i)(MAX_NUM_WORKERS).Text("Too many workers!");
    if(jalib::compareAndSwap<WorkerThread*>(_pool+i, NULL, thread))
      break;
    // the slot wasn't null when we tried to put it in... someone else took our slot
    // try again on the next slot
  }
  //ensure _count>i
  while(! jalib::compareAndSwap(&_count, _count, std::max(_count, i+1)) ) ;
}

void petabricks::WorkerThreadPool::remove(WorkerThread* thread){
  for(int i=0; i<_count; ++i){
    if(_pool[i] == thread)
      _pool[i] = NULL;//dont need a CAS here
  }
  // reduce _count if possible
  for(int t; _pool[t=_count-1] == NULL; ){
    jalib::compareAndSwap(&_count, t+1, t);//tryDecrement
  }
}

petabricks::WorkerThread* petabricks::WorkerThreadPool::getRandom(const WorkerThread* caller){
  WorkerThread* rv;
  do {
    rv=_pool[caller->threadRandInt()%_count];
    if(_count==1)
      return NULL;
    jalib::staticMemFence();//don't optimize _count
  } while(rv==caller || rv == NULL);
  return rv;
}

petabricks::WorkerThread* petabricks::WorkerThreadPool::getFixed(int i/*=0*/){
  WorkerThread* rv;
  do {
    rv=_pool[i++%_count];
  } while(rv == NULL);
  return rv;
}

petabricks::AbortTask::AbortTask(int totalThreads, bool shouldExit) {
  _numLive = totalThreads;
  _numAborting = totalThreads;
  _shutdown = shouldExit;
  _state = S_READY;
}
petabricks::DynamicTaskPtr petabricks::AbortTask::run(){
  DynamicTaskPtr abortTask = this; // ensure this task isn't deleted
  WorkerThread* self = WorkerThread::self();
  JASSERT(self!=NULL);
  WorkerThreadPool& pool = self->pool();
  DynamicTask* t=NULL;

  jalib::atomicDecrement(&_numLive);

  //cancel all our pending tasks
  while((t=self->popLocal())!=NULL){
    t->cancel();
  }

  //until all threads are aborted, steal and cancel tasks
  while(_numLive>0){
    jalib::staticMemFence();
    //make sure there is something to be stolen from us, 5 and 15 are arbitrary
    if(self->workCount()<5)
      for(int i=0; i<15; ++i)
        self->pushLocal(this);
    //pick a victim to steal work from
    WorkerThread* victim = pool.getRandom(self);
    if(victim!=NULL){
      //try to steal all of the victim's work
      for(int c=victim->workCount(); c>0; --c){
        t = victim->steal();
        if(t!=NULL && t!=this) t->cancel();
        else break;
      }
    }
  }

  //drain off all our abort tasks
  while((t=self->popLocal())!=NULL){
    JASSERT(t==this);
  }

  //wait until all threads reach this point
  jalib::atomicDecrement(&_numAborting);
  while(_numAborting>0) {
    jalib::staticMemFence();
    sched_yield();
  }
 //_lock.lock();
 //if(--_numAborting==0)
 //  _lock.broadcast();
 //else
 //  _lock.wait();
 //_lock.unlock();

  //either exit or throw
  if(_shutdown && self!=&theMainWorkerThread){
    //pthread_exit(0);
    throw DynamicScheduler::CleanExitException();
  }else{
    throw DynamicScheduler::AbortException();
  }
}

void petabricks::WorkerThreadPool::debugPrint() const {
  std::cerr << "thread status: " << std::endl;

  for(int i=0; i<_count; ++i){
    const WorkerThread* t = _pool[i];
    if(t == 0){
      std::cerr << "  * empty slot " << std::endl;
    }else{
      std::cerr << "  * thread " << t->id() << " workCount:" << t->workCount();
      DEBUGONLY(std::cerr << " isWorking:" << t->isWorking());
      if(t==WorkerThread::self())
        std::cerr << " (current)";
      std::cerr << std::endl;
    }
  }
}

void petabricks::WorkerThreadPool::debugPrint(jalib::JAssert& o) const {
  if(!o.IsFatal())
    return;
  o.Prefix();
  o << "WorkerThread status:";
  o.EndLine();

  for(int i=0; i<_count; ++i){
    const WorkerThread* t = _pool[i];
    o.Prefix();
    if(t == 0){
      o << "  - empty slot";
    }else{
      o << "  - thread " << t->id() << " workCount:" << t->workCount();
      DEBUGONLY(o << " isWorking:" << t->isWorking());
      if(t==WorkerThread::self())
        o << " (current)";
    }
    o.EndLine();
  }
  o.Prefix();
  o.EndLine();
}

extern "C" int threadstatus() {
  petabricks::WorkerThread::self()->pool().debugPrint();
  return petabricks::DynamicScheduler::cpuScheduler().numThreads();
}

namespace{
  void onJassert(jalib::JAssert& o) {
    petabricks::WorkerThread::self()->pool().debugPrint(o);
  }
}
int _ignored = jalib::JAssert::onBegin(&onJassert);

<commit_msg>check NULL if _pool.getRandom return NULL<commit_after>/*****************************************************************************
 *  Copyright (C) 2008-2011 Massachusetts Institute of Technology            *
 *                                                                           *
 *  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           *
 *                                                                           *
 *  This source code is part of the PetaBricks project:                      *
 *    http://projects.csail.mit.edu/petabricks/                              *
 *                                                                           *
 *****************************************************************************/
#include "workerthread.h"

#include "dynamicscheduler.h"
#include "common/jasm.h"

#include <pthread.h>
#include <signal.h>
#include <unistd.h>

#ifdef HAVE_CONFIG_H
#  include "config.h"
#endif

#ifdef DEBUG
#  define DEBUGONLY(args...) args
#else
#  define DEBUGONLY(args...) (void)0
#endif

//singleton main thread
static petabricks::WorkerThread theMainWorkerThread(petabricks::DynamicScheduler::cpuScheduler());

#ifdef HAVE_THREADLOCAL
//this is the simple/fast version
__thread petabricks::WorkerThread* mySelfPtr = NULL;
petabricks::WorkerThread* petabricks::WorkerThread::self(){
  return mySelfPtr;
}
void setSelf(petabricks::WorkerThread* v){
  mySelfPtr = v;
}
#else
//this is a backwards compatible version for archs that dont support __thread
namespace { //file local
  static pthread_key_t  worker_key;
  static pthread_once_t worker_key_once = PTHREAD_ONCE_INIT;
  static void worker_destroy(int* buf){ delete buf; }
  static void worker_key_alloc(){  pthread_key_create(&worker_key, (void (*)(void*)) worker_destroy); }
  static void worker_alloc(){
    pthread_once(&worker_key_once, worker_key_alloc);
    pthread_setspecific(worker_key, new petabricks::WorkerThread*);
  }
}
petabricks::WorkerThread* petabricks::WorkerThread::self(){
  petabricks::WorkerThread** t = (petabricks::WorkerThread**)pthread_getspecific(worker_key);
  return t!=NULL ? *t : NULL;
}
void setSelf(petabricks::WorkerThread* v){
  petabricks::WorkerThread** t = (petabricks::WorkerThread**)pthread_getspecific(worker_key);
  if(t==NULL){
    worker_alloc();
    t = (petabricks::WorkerThread**)pthread_getspecific(worker_key);
    JASSERT(t!=NULL);
  }
  *t = v;
}
#endif

petabricks::WorkerThread::WorkerThread(DynamicScheduler& ds)
  : _pool(ds.pool())
{
  static jalib::AtomicT lastId = -1;
  _id = (int)jalib::atomicIncrementReturn(&lastId);
  _randomNumState.z = _id * _id * 2;
  _randomNumState.w = _id + 1;
  setSelf(this);
  _pool.insert(this);
#ifdef WORKERTHREAD_ONDECK
  _ondeck = NULL;
#endif
  DEBUGONLY(_isWorking=false);
}
petabricks::WorkerThread::~WorkerThread(){
  _pool.remove(this);
}

int petabricks::WorkerThread::threadRandInt() const {
  _randomNumState.z = 36969 * (_randomNumState.z & 65535) + (_randomNumState.z >> 16);
  _randomNumState.w = 18000 * (_randomNumState.w & 65535) + (_randomNumState.w >> 16);
  int retVal = (_randomNumState.z << 16) + _randomNumState.w;
  if (retVal < 0) {
    retVal = -retVal;
  }
  return retVal;
}

void petabricks::WorkerThread::popAndRunOneTask(int stealLimit)
{
  DynamicTask *task;

  //try from the local deque
  task = popLocal();

  //try stealing a bunch of times
  while(task == NULL && stealLimit-->0){
    WorkerThread* victim = _pool.getRandom(this);
    if(victim !=NULL)
      task = victim->steal();
  }

  //if we got something, run it
  if (task != NULL) {
    DEBUGONLY(_isWorking=true);
    task->runWrapper();
    DEBUGONLY(_isWorking=false);
  } else {
    sched_yield();
  }
}

void petabricks::WorkerThread::mainLoop(){
  for(;;){
    try {
      for(;;) popAndRunOneTask(STEAL_ATTEMPTS_MAINLOOP);
    }catch(DynamicScheduler::AbortException e){}
  }
}

petabricks::WorkerThreadPool::WorkerThreadPool(){
  memset(_pool, 0, sizeof _pool);
}

void petabricks::WorkerThreadPool::insert(WorkerThread* thread){
  int i = _count; // the slot we wish to insert into
  for(;;++i){
    JASSERT(i<MAX_NUM_WORKERS)(i)(MAX_NUM_WORKERS).Text("Too many workers!");
    if(jalib::compareAndSwap<WorkerThread*>(_pool+i, NULL, thread))
      break;
    // the slot wasn't null when we tried to put it in... someone else took our slot
    // try again on the next slot
  }
  //ensure _count>i
  while(! jalib::compareAndSwap(&_count, _count, std::max(_count, i+1)) ) ;
}

void petabricks::WorkerThreadPool::remove(WorkerThread* thread){
  for(int i=0; i<_count; ++i){
    if(_pool[i] == thread)
      _pool[i] = NULL;//dont need a CAS here
  }
  // reduce _count if possible
  for(int t; _pool[t=_count-1] == NULL; ){
    jalib::compareAndSwap(&_count, t+1, t);//tryDecrement
  }
}

petabricks::WorkerThread* petabricks::WorkerThreadPool::getRandom(const WorkerThread* caller){
  WorkerThread* rv;
  do {
    rv=_pool[caller->threadRandInt()%_count];
    if(_count==1)
      return NULL;
    jalib::staticMemFence();//don't optimize _count
  } while(rv==caller || rv == NULL);
  return rv;
}

petabricks::WorkerThread* petabricks::WorkerThreadPool::getFixed(int i/*=0*/){
  WorkerThread* rv;
  do {
    rv=_pool[i++%_count];
  } while(rv == NULL);
  return rv;
}

petabricks::AbortTask::AbortTask(int totalThreads, bool shouldExit) {
  _numLive = totalThreads;
  _numAborting = totalThreads;
  _shutdown = shouldExit;
  _state = S_READY;
}
petabricks::DynamicTaskPtr petabricks::AbortTask::run(){
  DynamicTaskPtr abortTask = this; // ensure this task isn't deleted
  WorkerThread* self = WorkerThread::self();
  JASSERT(self!=NULL);
  WorkerThreadPool& pool = self->pool();
  DynamicTask* t=NULL;

  jalib::atomicDecrement(&_numLive);

  //cancel all our pending tasks
  while((t=self->popLocal())!=NULL){
    t->cancel();
  }

  //until all threads are aborted, steal and cancel tasks
  while(_numLive>0){
    jalib::staticMemFence();
    //make sure there is something to be stolen from us, 5 and 15 are arbitrary
    if(self->workCount()<5)
      for(int i=0; i<15; ++i)
        self->pushLocal(this);
    //pick a victim to steal work from
    WorkerThread* victim = pool.getRandom(self);
    if(victim!=NULL){
      //try to steal all of the victim's work
      for(int c=victim->workCount(); c>0; --c){
        t = victim->steal();
        if(t!=NULL && t!=this) t->cancel();
        else break;
      }
    }
  }

  //drain off all our abort tasks
  while((t=self->popLocal())!=NULL){
    JASSERT(t==this);
  }

  //wait until all threads reach this point
  jalib::atomicDecrement(&_numAborting);
  while(_numAborting>0) {
    jalib::staticMemFence();
    sched_yield();
  }
 //_lock.lock();
 //if(--_numAborting==0)
 //  _lock.broadcast();
 //else
 //  _lock.wait();
 //_lock.unlock();

  //either exit or throw
  if(_shutdown && self!=&theMainWorkerThread){
    //pthread_exit(0);
    throw DynamicScheduler::CleanExitException();
  }else{
    throw DynamicScheduler::AbortException();
  }
}

void petabricks::WorkerThreadPool::debugPrint() const {
  std::cerr << "thread status: " << std::endl;

  for(int i=0; i<_count; ++i){
    const WorkerThread* t = _pool[i];
    if(t == 0){
      std::cerr << "  * empty slot " << std::endl;
    }else{
      std::cerr << "  * thread " << t->id() << " workCount:" << t->workCount();
      DEBUGONLY(std::cerr << " isWorking:" << t->isWorking());
      if(t==WorkerThread::self())
        std::cerr << " (current)";
      std::cerr << std::endl;
    }
  }
}

void petabricks::WorkerThreadPool::debugPrint(jalib::JAssert& o) const {
  if(!o.IsFatal())
    return;
  o.Prefix();
  o << "WorkerThread status:";
  o.EndLine();

  for(int i=0; i<_count; ++i){
    const WorkerThread* t = _pool[i];
    o.Prefix();
    if(t == 0){
      o << "  - empty slot";
    }else{
      o << "  - thread " << t->id() << " workCount:" << t->workCount();
      DEBUGONLY(o << " isWorking:" << t->isWorking());
      if(t==WorkerThread::self())
        o << " (current)";
    }
    o.EndLine();
  }
  o.Prefix();
  o.EndLine();
}

extern "C" int threadstatus() {
  petabricks::WorkerThread::self()->pool().debugPrint();
  return petabricks::DynamicScheduler::cpuScheduler().numThreads();
}

namespace{
  void onJassert(jalib::JAssert& o) {
    petabricks::WorkerThread::self()->pool().debugPrint(o);
  }
}
int _ignored = jalib::JAssert::onBegin(&onJassert);

<|endoftext|>


<commit_before>#include "hornet/vm.hh"

#include "hornet/java.hh"

#include <string>

namespace hornet {

klass::klass(const std::string& name_, loader *loader, std::shared_ptr<constant_pool> const_pool)
    : object(nullptr)
    , name(name_)
    , nr_fields(0)
    , _const_pool(const_pool)
    , _loader(loader)
{
}

klass::~klass()
{
}

void klass::link()
{
    if (!bootstrap_done) {
        return;
    }
    object = gc_new_object(java_lang_Class.get());
    // FIXME: Add a link between this klass structure and java/lang/Class. In
    // GNU Classpath, it's in the vmdata field.
}

void klass::add(std::shared_ptr<klass> iface)
{
    interfaces.push_back(iface);
}

void klass::add(std::shared_ptr<field> field)
{
    if (field->is_static()) {
        auto offset = static_values.size();
        static_values.reserve(offset + 1);
        static_values[offset] = 0;
        field->offset = offset;
    } else {
        auto offset = nr_fields;
        field->offset = offset;
        nr_fields++;
    }
    _fields.push_back(field);
}

void klass::add(std::shared_ptr<method> method)
{
    _methods.push_back(method);
}

std::shared_ptr<klass> klass::load_class(std::string name)
{
    return _loader->load_class(name);
}

std::shared_ptr<field> klass::lookup_field(std::string name, std::string descriptor)
{
    klass* klass = this;
    while (klass) {
        for (auto field : klass->_fields) {
            if (field->matches(name, descriptor))
                return field;
        }
        klass = klass->super;
    }
    return nullptr;
}

std::shared_ptr<method> klass::lookup_method(std::string name, std::string descriptor)
{
    klass* klass = this;
    while (klass) {
        for (auto method : klass->_methods) {
            if (method->matches(name, descriptor))
                return method;
        }
        klass = klass->super;
    }
    return nullptr;
}

std::shared_ptr<klass> klass::resolve_class(uint16_t idx)
{
    auto& klassref = _const_pool->get_class(idx);
    auto& klass_name = _const_pool->get_utf8(klassref.name_index);
    return _loader->load_class(klass_name.bytes);
}

std::shared_ptr<field> klass::resolve_field(uint16_t idx)
{
    auto& fieldref = _const_pool->get_fieldref(idx);
    auto target_klass = resolve_class(fieldref.class_index);
    if (!target_klass) {
        return nullptr;
    }
    auto& field_name_and_type = _const_pool->get_name_and_type(fieldref.name_and_type_index);
    auto& field_name = _const_pool->get_utf8(field_name_and_type.name_index);
    auto& field_type = _const_pool->get_utf8(field_name_and_type.descriptor_index);
    return target_klass->lookup_field(field_name.bytes, field_type.bytes);
}

std::shared_ptr<method> klass::resolve_method(uint16_t idx)
{
    auto& methodref = _const_pool->get_methodref(idx);
    auto target_klass = resolve_class(methodref.class_index);
    if (!target_klass) {
        return nullptr;
    }
    auto& method_name_and_type = _const_pool->get_name_and_type(methodref.name_and_type_index);
    auto& method_name = _const_pool->get_utf8(method_name_and_type.name_index);
    auto& method_type = _const_pool->get_utf8(method_name_and_type.descriptor_index);
    return target_klass->lookup_method(method_name.bytes, method_type.bytes);
}

std::shared_ptr<method> klass::resolve_interface_method(uint16_t idx)
{
    auto& methodref = _const_pool->get_interface_methodref(idx);
    auto target_klass = resolve_class(methodref.class_index);
    if (!target_klass) {
        return nullptr;
    }
    auto& method_name_and_type = _const_pool->get_name_and_type(methodref.name_and_type_index);
    auto& method_name = _const_pool->get_utf8(method_name_and_type.name_index);
    auto& method_type = _const_pool->get_utf8(method_name_and_type.descriptor_index);
    return target_klass->lookup_method(method_name.bytes, method_type.bytes);
}

void klass::init()
{
    switch (state) {
    case klass_state::loaded: {
        state = klass_state::initialized;
        auto clinit = lookup_method("<clinit>", "()V");
        if (clinit) {
            auto thread = hornet::thread::current();
            auto new_frame = thread->make_frame(0);
            hornet::_backend->execute(clinit.get(), *new_frame);
            thread->free_frame(new_frame);
        }
        break;
    }
    case klass_state::initialized:
        break;
    }
}

bool klass::verify()
{
    for (auto method : _methods) {
        if (!verify_method(method))
            return false;
    }
    return true;
}

}
<commit_msg>vm/klass: Initialize super to nullptr<commit_after>#include "hornet/vm.hh"

#include "hornet/java.hh"

#include <string>

namespace hornet {

klass::klass(const std::string& name_, loader *loader, std::shared_ptr<constant_pool> const_pool)
    : object(nullptr)
    , name(name_)
    , super(nullptr)
    , nr_fields(0)
    , _const_pool(const_pool)
    , _loader(loader)
{
}

klass::~klass()
{
}

void klass::link()
{
    if (!bootstrap_done) {
        return;
    }
    object = gc_new_object(java_lang_Class.get());
    // FIXME: Add a link between this klass structure and java/lang/Class. In
    // GNU Classpath, it's in the vmdata field.
}

void klass::add(std::shared_ptr<klass> iface)
{
    interfaces.push_back(iface);
}

void klass::add(std::shared_ptr<field> field)
{
    if (field->is_static()) {
        auto offset = static_values.size();
        static_values.reserve(offset + 1);
        static_values[offset] = 0;
        field->offset = offset;
    } else {
        auto offset = nr_fields;
        field->offset = offset;
        nr_fields++;
    }
    _fields.push_back(field);
}

void klass::add(std::shared_ptr<method> method)
{
    _methods.push_back(method);
}

std::shared_ptr<klass> klass::load_class(std::string name)
{
    return _loader->load_class(name);
}

std::shared_ptr<field> klass::lookup_field(std::string name, std::string descriptor)
{
    klass* klass = this;
    while (klass) {
        for (auto field : klass->_fields) {
            if (field->matches(name, descriptor))
                return field;
        }
        klass = klass->super;
    }
    return nullptr;
}

std::shared_ptr<method> klass::lookup_method(std::string name, std::string descriptor)
{
    klass* klass = this;
    while (klass) {
        for (auto method : klass->_methods) {
            if (method->matches(name, descriptor))
                return method;
        }
        klass = klass->super;
    }
    return nullptr;
}

std::shared_ptr<klass> klass::resolve_class(uint16_t idx)
{
    auto& klassref = _const_pool->get_class(idx);
    auto& klass_name = _const_pool->get_utf8(klassref.name_index);
    return _loader->load_class(klass_name.bytes);
}

std::shared_ptr<field> klass::resolve_field(uint16_t idx)
{
    auto& fieldref = _const_pool->get_fieldref(idx);
    auto target_klass = resolve_class(fieldref.class_index);
    if (!target_klass) {
        return nullptr;
    }
    auto& field_name_and_type = _const_pool->get_name_and_type(fieldref.name_and_type_index);
    auto& field_name = _const_pool->get_utf8(field_name_and_type.name_index);
    auto& field_type = _const_pool->get_utf8(field_name_and_type.descriptor_index);
    return target_klass->lookup_field(field_name.bytes, field_type.bytes);
}

std::shared_ptr<method> klass::resolve_method(uint16_t idx)
{
    auto& methodref = _const_pool->get_methodref(idx);
    auto target_klass = resolve_class(methodref.class_index);
    if (!target_klass) {
        return nullptr;
    }
    auto& method_name_and_type = _const_pool->get_name_and_type(methodref.name_and_type_index);
    auto& method_name = _const_pool->get_utf8(method_name_and_type.name_index);
    auto& method_type = _const_pool->get_utf8(method_name_and_type.descriptor_index);
    return target_klass->lookup_method(method_name.bytes, method_type.bytes);
}

std::shared_ptr<method> klass::resolve_interface_method(uint16_t idx)
{
    auto& methodref = _const_pool->get_interface_methodref(idx);
    auto target_klass = resolve_class(methodref.class_index);
    if (!target_klass) {
        return nullptr;
    }
    auto& method_name_and_type = _const_pool->get_name_and_type(methodref.name_and_type_index);
    auto& method_name = _const_pool->get_utf8(method_name_and_type.name_index);
    auto& method_type = _const_pool->get_utf8(method_name_and_type.descriptor_index);
    return target_klass->lookup_method(method_name.bytes, method_type.bytes);
}

void klass::init()
{
    switch (state) {
    case klass_state::loaded: {
        state = klass_state::initialized;
        auto clinit = lookup_method("<clinit>", "()V");
        if (clinit) {
            auto thread = hornet::thread::current();
            auto new_frame = thread->make_frame(0);
            hornet::_backend->execute(clinit.get(), *new_frame);
            thread->free_frame(new_frame);
        }
        break;
    }
    case klass_state::initialized:
        break;
    }
}

bool klass::verify()
{
    for (auto method : _methods) {
        if (!verify_method(method))
            return false;
    }
    return true;
}

}
<|endoftext|>


<commit_before>#include <QCoreApplication>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    return a.exec();
}
<commit_msg>agregando codigo<commit_after>#include "stdafx.h"
#include "cv.h"
#include "cvaux.h"
#include "highgui.h"
#include <stdio.h>

int main()
{
    char name0[] = "/home/mrc/ProyectosQt/Guda/Ejercicio1/Ejercicio1/img/1.jpg";
    char name1[] = "/home/mrc/ProyectosQt/Guda/Ejercicio1/Ejercicio1/img/resized.jpg";
    char name2[] = "/home/mrc/ProyectosQt/Guda/Ejercicio1/Ejercicio1/img/corte.jpg";";
    float dx = 2;
    float dy = 2;
    int deltax = 50;
    int deltay = 50;
    int i = 0, j = 0, R = 0, G = 0, B = 0;

    CvScalar s;
    CvRect faceCoords;
    IplImage* imagen = NULL;
    IplImage* faceImagen = NULL;
    imagen = cvLoadImage(name0, 1);
    cvNamedWindow("Fuente", 1);
    cvShowImage("Fuente", imagen);
}
<|endoftext|>


<commit_before>## This file is a template.  The comment below is emitted
## into the rendered file; feel free to edit this file.
// WARNING: Generated header. Do not edit!
<%
import re
from collections import defaultdict
from sdbusplus.namedelement import NamedElement
objects = settingsDict.keys()
sdbusplus_includes = []
props = defaultdict(list)
validators = defaultdict(tuple)

def get_setting_sdbusplus_type(setting_intf):
    setting = "sdbusplus::" + setting_intf.replace('.', '::')
    i = setting.rfind('::')
    setting = setting[:i] + '::server::' + setting[i+2:]
    return setting

def get_setting_type(path):
    path = path[1:]
    path = path.replace('/', '::')
    return path
%>\
#pragma once

% for object in objects:
    % for item in settingsDict[object]:
<%
    include = item['Interface']
    include = include.replace('.', '/')
    include = include + "/server.hpp"
    sdbusplus_includes.append(include)
%>\
    % endfor
% endfor
#include <cereal/archives/json.hpp>
#include <cereal/types/vector.hpp>
#include <fstream>
#include <utility>
#include <experimental/filesystem>
#include <regex>
#include <phosphor-logging/elog.hpp>
#include <phosphor-logging/elog-errors.hpp>
#include <phosphor-logging/log.hpp>
#include "config.h"
#include <xyz/openbmc_project/Common/error.hpp>
using namespace phosphor::logging;

% for i in set(sdbusplus_includes):
#include "${i}"
% endfor

namespace phosphor
{
namespace settings
{

namespace fs = std::experimental::filesystem;

namespace persistent
{

// A setting d-bus object /foo/bar/baz is persisted in the filesystem with the
// same path. This eases re-construction of settings objects when we restore
// from the filesystem. This can be a problem though when you have two objects
// such as - /foo/bar and /foo/bar/baz. This is because 'bar' will be treated as
// a file in the first case, and a subdir in the second. To solve this, suffix
// files with a trailing __. The __ is a safe character sequence to use, because
// we won't have d-bus object paths ending with this.
// With this the objects would be persisted as - /foo/bar__ and /foo/bar/baz__.
constexpr auto fileSuffix = "__";

}

% for object in objects:
<%
   ns = object.split('/')
   ns.pop(0)
%>\
% for n in ns:
namespace ${n}
{
% endfor
<%
    interfaces = []
    aliases = []
    for item in settingsDict[object]:
        interfaces.append(item['Interface'])
        for name, meta in item['Properties'].items():
            if 'Validation' in meta:
                dict = meta['Validation']
                if dict['Type'] == "range":
                    validators[name] = (dict['Type'], dict['Validator'], dict['Unit'])
                else:
                    validators[name] = (dict['Type'], dict['Validator'])
%>
% for index, intf in enumerate(interfaces):
using Iface${index} = ${get_setting_sdbusplus_type(intf)};
<% aliases.append("Iface" + str(index)) %>\
% endfor
<%
    parent = "sdbusplus::server::object::object" + "<" + ", ".join(aliases) + ">"
%>\
using Parent = ${parent};

class Impl : public Parent
{
    public:
        Impl(sdbusplus::bus::bus& bus, const char* path):
            Parent(bus, path, true),
            path(path)
        {
        }
        virtual ~Impl() = default;

% for index, item in enumerate(settingsDict[object]):
    % for propName, metaDict in item['Properties'].items():
<% t = NamedElement(name=propName).camelCase %>\
<% fname = "validate" + propName %>\
        decltype(std::declval<Iface${index}>().${t}()) ${t}(decltype(std::declval<Iface${index}>().${t}()) value) override
        {
            auto result = Iface${index}::${t}();
            if (value != result)
            {
            % if propName in validators:
                if (!${fname}(value))
                {
                    namespace error =
                        sdbusplus::xyz::openbmc_project::Common::Error;
                    namespace metadata =
                        phosphor::logging::xyz::openbmc_project::Common;
                    phosphor::logging::report<error::InvalidArgument>(
                        metadata::InvalidArgument::ARGUMENT_NAME("${t}"),
                    % if validators[propName][0] != "regex":
                        metadata::InvalidArgument::ARGUMENT_VALUE(std::to_string(value).c_str()));
                    % else:
                        metadata::InvalidArgument::ARGUMENT_VALUE(value.c_str()));
                    % endif
                    return result;
                }
             % endif
                fs::path p(SETTINGS_PERSIST_PATH);
                p /= path;
                p += persistent::fileSuffix;
                fs::create_directories(p.parent_path());
                std::ofstream os(p.c_str(), std::ios::binary);
                cereal::JSONOutputArchive oarchive(os);
                result = Iface${index}::${t}(value);
                oarchive(*this);
            }
            return result;
        }
        using Iface${index}::${t};

    % endfor
% endfor
    private:
        fs::path path;
% for index, item in enumerate(settingsDict[object]):
  % for propName, metaDict in item['Properties'].items():
<% t = NamedElement(name=propName).camelCase %>\
<% fname = "validate" + propName %>\
    % if propName in validators:

        bool ${fname}(decltype(std::declval<Iface${index}>().${t}()) value)
        {
            bool matched = false;
        % if (validators[propName][0] == 'regex'):
            std::regex regexToCheck("${validators[propName][1]}");
            matched = std::regex_search(value, regexToCheck);
            if (!matched)
            {
                std::string err = "Input parameter for ${propName} is invalid "
                    "Input: " + value + " not in the format of this regex: "
                    "${validators[propName][1]}";
                using namespace phosphor::logging;
                log<level::ERR>(err.c_str());
            }
        % elif (validators[propName][0] == 'range'):
<% lowhigh = re.split('\.\.', validators[propName][1]) %>\
            if ((value <= ${lowhigh[1]}) && (value >= ${lowhigh[0]}))
            {
                matched = true;
            }
            else
            {
                std::string err = "Input parameter for ${propName} is invalid "
                    "Input: " + std::to_string(value) + "in uint: "
                    "${validators[propName][2]} is not in range:${validators[propName][1]}";
                using namespace phosphor::logging;
                log<level::ERR>(err.c_str());
            }
        % else:
            <% assert("Unknown validation type: propName") %>\
        % endif
            return matched;
        }
    % endif
  % endfor
% endfor
};

template<class Archive>
void save(Archive& a,
          const Impl& setting,
          const std::uint32_t version)
{
<%
props = []
for index, item in enumerate(settingsDict[object]):
    intfProps = ["setting." + NamedElement(name=propName).camelCase + "()" for \
                    propName, metaDict in item['Properties'].items()]
    props.extend(intfProps)
props = ', '.join(props)
%>\
    a(${props});
}

template<class Archive>
void load(Archive& a,
          Impl& setting,
          const std::uint32_t version)
{
<% props = [] %>\
% for index, item in enumerate(settingsDict[object]):
  % for  prop, metaDict in item['Properties'].items():
<%
    t = "setting." + NamedElement(name=prop).camelCase + "()"
    props.append(prop)
%>\
    decltype(${t}) ${prop}{};
  % endfor
% endfor
<% props = ', '.join(props) %>
    a(${props});
<% props = [] %>
% for index, item in enumerate(settingsDict[object]):
  % for  prop, metaDict in item['Properties'].items():
<%
    t = "setting." + NamedElement(name=prop).camelCase + "(" + prop + ")"
%>\
    ${t};
  % endfor
% endfor
}

% for n in reversed(ns):
} // namespace ${n}
% endfor

% endfor

/** @class Manager
 *
 *  @brief Compose settings objects and put them on the bus.
 */
class Manager
{
    public:
        Manager() = delete;
        Manager(const Manager&) = delete;
        Manager& operator=(const Manager&) = delete;
        Manager(Manager&&) = delete;
        Manager& operator=(Manager&&) = delete;
        virtual ~Manager() = default;

        /** @brief Constructor to put settings objects on to the bus.
         *  @param[in] bus - Bus to attach to.
         */
        Manager(sdbusplus::bus::bus& bus)
        {
            fs::path path{};
            settings =
                std::make_tuple(
% for index, path in enumerate(objects):
<% type = get_setting_type(path) + "::Impl" %>\
                    std::make_unique<${type}>(
                        bus,
  % if index < len(settingsDict) - 1:
                        "${path}"),
  % else:
                        "${path}"));
  % endif
% endfor

% for index, path in enumerate(objects):
            path = fs::path(SETTINGS_PERSIST_PATH) / "${path}";
            path += persistent::fileSuffix;
            auto initSetting${index} = [&]()
            {
  % for item in settingsDict[path]:
    % for propName, metaDict in item['Properties'].items():
<% p = NamedElement(name=propName).camelCase %>\
<% defaultValue = metaDict['Default'] %>\
% if isinstance(defaultValue, str) and  not \
    defaultValue.startswith('"') and '::' in defaultValue:
<% ns = get_setting_sdbusplus_type(item['Interface'])
i = ns.rfind('::')
defaultValue = "{}::{}".format(ns[:i], defaultValue)
%>\
% endif
                std::get<${index}>(settings)->
                  ${get_setting_sdbusplus_type(item['Interface'])}::${p}(${defaultValue});
  % endfor
% endfor
            };

            try
            {
                if (fs::exists(path))
                {
                    std::ifstream is(path.c_str(), std::ios::in);
                    cereal::JSONInputArchive iarchive(is);
                    iarchive(*std::get<${index}>(settings));
                }
                else
                {
                    initSetting${index}();
                }
            }
            catch (const cereal::Exception& e)
            {
                log<level::ERR>(e.what());
                fs::remove(path);
                initSetting${index}();
            }
            std::get<${index}>(settings)->emit_object_added();

% endfor
        }

    private:
        /* @brief Composition of settings objects. */
        std::tuple<
% for index, path in enumerate(objects):
<% type = get_setting_type(path) + "::Impl" %>\
  % if index < len(settingsDict) - 1:
            std::unique_ptr<${type}>,
  % else:
            std::unique_ptr<${type}>> settings;
  % endif
% endfor
};

} // namespace settings
} // namespace phosphor

// Now register the class version with Cereal
% for object in objects:
<%
   classname = "phosphor::settings"
   ns = object.split('/')
   ns.pop(0)
%>\
% for n in ns:
<%
    classname += "::" + n
%>\
% endfor
CEREAL_CLASS_VERSION(${classname + "::Impl"}, CLASS_VERSION);
% endfor
<commit_msg>mako: Support interfaces without property<commit_after>## This file is a template.  The comment below is emitted
## into the rendered file; feel free to edit this file.
// WARNING: Generated header. Do not edit!
<%
import re
from collections import defaultdict
from sdbusplus.namedelement import NamedElement
objects = settingsDict.keys()
sdbusplus_includes = []
props = defaultdict(list)
validators = defaultdict(tuple)

def get_setting_sdbusplus_type(setting_intf):
    setting = "sdbusplus::" + setting_intf.replace('.', '::')
    i = setting.rfind('::')
    setting = setting[:i] + '::server::' + setting[i+2:]
    return setting

def get_setting_type(path):
    path = path[1:]
    path = path.replace('/', '::')
    return path
%>\
#pragma once

% for object in objects:
    % for item in settingsDict[object]:
<%
    include = item['Interface']
    include = include.replace('.', '/')
    include = include + "/server.hpp"
    sdbusplus_includes.append(include)
%>\
    % endfor
% endfor
#include <cereal/archives/json.hpp>
#include <cereal/types/vector.hpp>
#include <fstream>
#include <utility>
#include <experimental/filesystem>
#include <regex>
#include <phosphor-logging/elog.hpp>
#include <phosphor-logging/elog-errors.hpp>
#include <phosphor-logging/log.hpp>
#include "config.h"
#include <xyz/openbmc_project/Common/error.hpp>
using namespace phosphor::logging;

% for i in set(sdbusplus_includes):
#include "${i}"
% endfor

namespace phosphor
{
namespace settings
{

namespace fs = std::experimental::filesystem;

namespace persistent
{

// A setting d-bus object /foo/bar/baz is persisted in the filesystem with the
// same path. This eases re-construction of settings objects when we restore
// from the filesystem. This can be a problem though when you have two objects
// such as - /foo/bar and /foo/bar/baz. This is because 'bar' will be treated as
// a file in the first case, and a subdir in the second. To solve this, suffix
// files with a trailing __. The __ is a safe character sequence to use, because
// we won't have d-bus object paths ending with this.
// With this the objects would be persisted as - /foo/bar__ and /foo/bar/baz__.
constexpr auto fileSuffix = "__";

}

% for object in objects:
<%
   ns = object.split('/')
   ns.pop(0)
%>\
% for n in ns:
namespace ${n}
{
% endfor
<%
    interfaces = []
    aliases = []
    for item in settingsDict[object]:
        interfaces.append(item['Interface'])
        for name, meta in item['Properties'].items():
            if 'Validation' in meta:
                dict = meta['Validation']
                if dict['Type'] == "range":
                    validators[name] = (dict['Type'], dict['Validator'], dict['Unit'])
                else:
                    validators[name] = (dict['Type'], dict['Validator'])
%>
% for index, intf in enumerate(interfaces):
using Iface${index} = ${get_setting_sdbusplus_type(intf)};
<% aliases.append("Iface" + str(index)) %>\
% endfor
<%
    parent = "sdbusplus::server::object::object" + "<" + ", ".join(aliases) + ">"
%>\
using Parent = ${parent};

class Impl : public Parent
{
    public:
        Impl(sdbusplus::bus::bus& bus, const char* path):
            Parent(bus, path, true),
            path(path)
        {
        }
        virtual ~Impl() = default;

% for index, item in enumerate(settingsDict[object]):
    % for propName, metaDict in item['Properties'].items():
<% t = NamedElement(name=propName).camelCase %>\
<% fname = "validate" + propName %>\
        decltype(std::declval<Iface${index}>().${t}()) ${t}(decltype(std::declval<Iface${index}>().${t}()) value) override
        {
            auto result = Iface${index}::${t}();
            if (value != result)
            {
            % if propName in validators:
                if (!${fname}(value))
                {
                    namespace error =
                        sdbusplus::xyz::openbmc_project::Common::Error;
                    namespace metadata =
                        phosphor::logging::xyz::openbmc_project::Common;
                    phosphor::logging::report<error::InvalidArgument>(
                        metadata::InvalidArgument::ARGUMENT_NAME("${t}"),
                    % if validators[propName][0] != "regex":
                        metadata::InvalidArgument::ARGUMENT_VALUE(std::to_string(value).c_str()));
                    % else:
                        metadata::InvalidArgument::ARGUMENT_VALUE(value.c_str()));
                    % endif
                    return result;
                }
             % endif
                fs::path p(SETTINGS_PERSIST_PATH);
                p /= path;
                p += persistent::fileSuffix;
                fs::create_directories(p.parent_path());
                std::ofstream os(p.c_str(), std::ios::binary);
                cereal::JSONOutputArchive oarchive(os);
                result = Iface${index}::${t}(value);
                oarchive(*this);
            }
            return result;
        }
        using Iface${index}::${t};

    % endfor
% endfor
    private:
        fs::path path;
% for index, item in enumerate(settingsDict[object]):
  % for propName, metaDict in item['Properties'].items():
<% t = NamedElement(name=propName).camelCase %>\
<% fname = "validate" + propName %>\
    % if propName in validators:

        bool ${fname}(decltype(std::declval<Iface${index}>().${t}()) value)
        {
            bool matched = false;
        % if (validators[propName][0] == 'regex'):
            std::regex regexToCheck("${validators[propName][1]}");
            matched = std::regex_search(value, regexToCheck);
            if (!matched)
            {
                std::string err = "Input parameter for ${propName} is invalid "
                    "Input: " + value + " not in the format of this regex: "
                    "${validators[propName][1]}";
                using namespace phosphor::logging;
                log<level::ERR>(err.c_str());
            }
        % elif (validators[propName][0] == 'range'):
<% lowhigh = re.split('\.\.', validators[propName][1]) %>\
            if ((value <= ${lowhigh[1]}) && (value >= ${lowhigh[0]}))
            {
                matched = true;
            }
            else
            {
                std::string err = "Input parameter for ${propName} is invalid "
                    "Input: " + std::to_string(value) + "in uint: "
                    "${validators[propName][2]} is not in range:${validators[propName][1]}";
                using namespace phosphor::logging;
                log<level::ERR>(err.c_str());
            }
        % else:
            <% assert("Unknown validation type: propName") %>\
        % endif
            return matched;
        }
    % endif
  % endfor
% endfor
};

template<class Archive>
void save(Archive& a,
          const Impl& setting,
          const std::uint32_t version)
{
<%
props = []
for index, item in enumerate(settingsDict[object]):
    intfProps = ["setting." + NamedElement(name=propName).camelCase + "()" for \
                    propName, metaDict in item['Properties'].items()]
    props.extend(intfProps)
props = ', '.join(props)
%>\
% if props:
    a(${props});
% endif
}

template<class Archive>
void load(Archive& a,
          Impl& setting,
          const std::uint32_t version)
{
<% props = [] %>\
% for index, item in enumerate(settingsDict[object]):
  % for  prop, metaDict in item['Properties'].items():
<%
    t = "setting." + NamedElement(name=prop).camelCase + "()"
    props.append(prop)
%>\
    decltype(${t}) ${prop}{};
  % endfor
% endfor
<% props = ', '.join(props) %>
% if props:
    a(${props});
% endif

<% props = [] %>
% for index, item in enumerate(settingsDict[object]):
  % for  prop, metaDict in item['Properties'].items():
<%
    t = "setting." + NamedElement(name=prop).camelCase + "(" + prop + ")"
%>\
    ${t};
  % endfor
% endfor
}

% for n in reversed(ns):
} // namespace ${n}
% endfor

% endfor

/** @class Manager
 *
 *  @brief Compose settings objects and put them on the bus.
 */
class Manager
{
    public:
        Manager() = delete;
        Manager(const Manager&) = delete;
        Manager& operator=(const Manager&) = delete;
        Manager(Manager&&) = delete;
        Manager& operator=(Manager&&) = delete;
        virtual ~Manager() = default;

        /** @brief Constructor to put settings objects on to the bus.
         *  @param[in] bus - Bus to attach to.
         */
        Manager(sdbusplus::bus::bus& bus)
        {
            fs::path path{};
            settings =
                std::make_tuple(
% for index, path in enumerate(objects):
<% type = get_setting_type(path) + "::Impl" %>\
                    std::make_unique<${type}>(
                        bus,
  % if index < len(settingsDict) - 1:
                        "${path}"),
  % else:
                        "${path}"));
  % endif
% endfor

% for index, path in enumerate(objects):
            path = fs::path(SETTINGS_PERSIST_PATH) / "${path}";
            path += persistent::fileSuffix;
            auto initSetting${index} = [&]()
            {
  % for item in settingsDict[path]:
    % for propName, metaDict in item['Properties'].items():
<% p = NamedElement(name=propName).camelCase %>\
<% defaultValue = metaDict['Default'] %>\
% if isinstance(defaultValue, str) and  not \
    defaultValue.startswith('"') and '::' in defaultValue:
<% ns = get_setting_sdbusplus_type(item['Interface'])
i = ns.rfind('::')
defaultValue = "{}::{}".format(ns[:i], defaultValue)
%>\
% endif
                std::get<${index}>(settings)->
                  ${get_setting_sdbusplus_type(item['Interface'])}::${p}(${defaultValue});
  % endfor
% endfor
            };

            try
            {
                if (fs::exists(path))
                {
                    std::ifstream is(path.c_str(), std::ios::in);
                    cereal::JSONInputArchive iarchive(is);
                    iarchive(*std::get<${index}>(settings));
                }
                else
                {
                    initSetting${index}();
                }
            }
            catch (const cereal::Exception& e)
            {
                log<level::ERR>(e.what());
                fs::remove(path);
                initSetting${index}();
            }
            std::get<${index}>(settings)->emit_object_added();

% endfor
        }

    private:
        /* @brief Composition of settings objects. */
        std::tuple<
% for index, path in enumerate(objects):
<% type = get_setting_type(path) + "::Impl" %>\
  % if index < len(settingsDict) - 1:
            std::unique_ptr<${type}>,
  % else:
            std::unique_ptr<${type}>> settings;
  % endif
% endfor
};

} // namespace settings
} // namespace phosphor

// Now register the class version with Cereal
% for object in objects:
<%
   classname = "phosphor::settings"
   ns = object.split('/')
   ns.pop(0)
%>\
% for n in ns:
<%
    classname += "::" + n
%>\
% endfor
CEREAL_CLASS_VERSION(${classname + "::Impl"}, CLASS_VERSION);
% endfor
<|endoftext|>


<commit_before>#include "SysConfig.h"
#if(HAS_MPL3115A2)

#include <CI2C.h>
#include "CMPL3115A2.h"
#include "CTimer.h"
#include "NDataManager.h"

namespace
{
    CTimer mpl3115a2_report_timer;
    CTimer mpl3115a2_sample_timer;

    bool initalized = false;
}

CMPL3115A2::CMPL3115A2( CI2C *i2cInterfaceIn )
    : m_mpl( i2cInterfaceIn )
{

}

void CMPL3115A2::Initialize()
{
    Serial.println( "MPL3115A2.Status:INIT;" );

    //init process
    mpl3115a2_sample_timer.Reset();
    mpl3115a2_report_timer.Reset();

    auto ret = m_mpl.Initialize();
    if( ret != mpl3115a2::ERetCode::SUCCESS )
    {
        Serial.println( "MPL3115A2.Status:INIT_FAILED" );
    }

    Serial.println( "MPL3115A2.Status:POST_INIT; ");
}

void CMPL3115A2::InitializeSensor()
{
    //Attempt to init the sensor
    auto ret = m_mpl.Initialize();
    if( ret != mpl3115a2::ERetCode::SUCCESS )
    {
        Serial.println( "MPL3115A2_INIT_STATUS:FAILED;" );
    }
    else
    {
        Serial.println( "MPL3115A2_INIT_STATUS:SUCCESS;" );

        //Set the mode
        m_mpl.SetMode( mpl3115a2::EMode::BAROMETER );

        //Set the over sample rate_div
        m_mpl.SetOversampleRatio( mpl3115a2::EOversampleRatio::ORS_128 );

        //Enable event flags
        m_mpl.EnableEventFlags();

    }
}

void CMPL3115A2::Update( CCommand &commandIn )
{
    //1 Hz
    if( mpl3115a2_sample_timer.HasElapsed( 1000 ) )
    {
        if( !m_mpl.IsInitialized() )
        {
            //Attempt to init every 5 seconds
            if( mpl3115a2_report_timer.HasElapsed( 5000 ) )
            {
                Serial.println( "MPL3115A2.Status:TRYING;" );
                InitializeSensor();
            }
            return;
        }
        else
        {
            Serial.println( "MPL3115A2.Status:RUNNING;" );
            float pressure;
            auto ret = m_mpl.ReadPressure(pressure);

            if( ret != mpl3115a2::ERetCode::SUCCESS )
            {
                Serial.println( "MPL3115A2.Status:FAILED_READ;" );
            }

            Serial.print( "MPL3115A2.Value.Pressure: " );
            Serial.print( pressure );
            Serial.println( ";" );
        }
    }

}

#endif<commit_msg>More expressive error code<commit_after>#include "SysConfig.h"
#if(HAS_MPL3115A2)

#include <CI2C.h>
#include "CMPL3115A2.h"
#include "CTimer.h"
#include "NDataManager.h"

namespace
{
    CTimer mpl3115a2_report_timer;
    CTimer mpl3115a2_sample_timer;

    bool initalized = false;
}

CMPL3115A2::CMPL3115A2( CI2C *i2cInterfaceIn )
    : m_mpl( i2cInterfaceIn )
{

}

void CMPL3115A2::Initialize()
{
    Serial.println( "MPL3115A2.Status:INIT;" );

    //init process
    mpl3115a2_sample_timer.Reset();
    mpl3115a2_report_timer.Reset();

    auto ret = m_mpl.Initialize();
    if( ret != mpl3115a2::ERetCode::SUCCESS )
    {
        Serial.println( "MPL3115A2.Status:INIT_FAILED" );
    }

    Serial.println( "MPL3115A2.Status:POST_INIT; ");
}

void CMPL3115A2::InitializeSensor()
{
    //Attempt to init the sensor
    auto ret = m_mpl.Initialize();
    if( ret != mpl3115a2::ERetCode::SUCCESS )
    {
        Serial.println( "MPL3115A2_INIT_STATUS:FAILED;" );
    }
    else
    {
        Serial.println( "MPL3115A2_INIT_STATUS:SUCCESS;" );

        //Set the mode
        m_mpl.SetMode( mpl3115a2::EMode::BAROMETER );

        //Set the over sample rate_div
        m_mpl.SetOversampleRatio( mpl3115a2::EOversampleRatio::ORS_128 );

        //Enable event flags
        m_mpl.EnableEventFlags();

    }
}

void CMPL3115A2::Update( CCommand &commandIn )
{
    //1 Hz
    if( mpl3115a2_sample_timer.HasElapsed( 1000 ) )
    {
        if( !m_mpl.IsInitialized() )
        {
            //Attempt to init every 5 seconds
            if( mpl3115a2_report_timer.HasElapsed( 5000 ) )
            {
                Serial.println( "MPL3115A2.Status:TRYING;" );
                InitializeSensor();
            }
            return;
        }
        else
        {
            Serial.println( "MPL3115A2.Status:RUNNING;" );
            float pressure;
            auto ret = m_mpl.ReadPressure(pressure);

            if( ret != mpl3115a2::ERetCode::SUCCESS )
            {
                Serial.println( "MPL3115A2.Status:FAILED_READ;" );
                Serial.print( "REASON: ");
                Serial.print( ret );
                Serial.println( ";" );
            }

            Serial.print( "MPL3115A2.Value.Pressure: " );
            Serial.print( pressure );
            Serial.println( ";" );
        }
    }

}

#endif<|endoftext|>


<commit_before>/*
 * Copyright (c) 2004 The Regents of The University of Michigan
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef __IO_DEVICE_HH__
#define __IO_DEVICE_HH__

#include "mem/functional_mem/functional_memory.hh"

class BaseInterface;
class Bus;
class HierParams;
template <class Bus> class DMAInterface;

class PioDevice : public FunctionalMemory
{
  protected:
    BaseInterface *pioInterface;
    Tick pioLatency;

  public:
    PioDevice(const std::string &name);
    virtual ~PioDevice();
};

class DmaDevice : public PioDevice
{
  protected:
    DMAInterface<Bus> *dmaInterface;

  public:
    DmaDevice(const std::string &name);
    virtual ~DmaDevice();
};

#endif // __IO_DEVICE_HH__
<commit_msg>Change Bus template parameter to BusType (to avoid confusion with Bus class). Change Mem template parameter to MemType while we're at it.<commit_after>/*
 * Copyright (c) 2004 The Regents of The University of Michigan
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef __IO_DEVICE_HH__
#define __IO_DEVICE_HH__

#include "mem/functional_mem/functional_memory.hh"

class BaseInterface;
class Bus;
class HierParams;
template <class BusType> class DMAInterface;

class PioDevice : public FunctionalMemory
{
  protected:
    BaseInterface *pioInterface;
    Tick pioLatency;

  public:
    PioDevice(const std::string &name);
    virtual ~PioDevice();
};

class DmaDevice : public PioDevice
{
  protected:
    DMAInterface<Bus> *dmaInterface;

  public:
    DmaDevice(const std::string &name);
    virtual ~DmaDevice();
};

#endif // __IO_DEVICE_HH__
<|endoftext|>


<commit_before>#include "Runtime/World/CAiFuncMap.hpp"

#include "Runtime/CStateManager.hpp"
#include "Runtime/World/CAi.hpp"

namespace urde {
CAiFuncMap::CAiFuncMap() {
  /* Ai States */
  x0_stateFuncs.emplace("Patrol", &CAi::Patrol);
  x0_stateFuncs.emplace("FollowPattern", &CAi::FollowPattern);
  x0_stateFuncs.emplace("Dead", &CAi::Dead);
  x0_stateFuncs.emplace("PathFind", &CAi::PathFind);
  x0_stateFuncs.emplace("Start", &CAi::Start);
  x0_stateFuncs.emplace("SelectTarget", &CAi::SelectTarget);
  x0_stateFuncs.emplace("TargetPatrol", &CAi::TargetPatrol);
  x0_stateFuncs.emplace("TargetPlayer", &CAi::TargetPlayer);
  x0_stateFuncs.emplace("TargetCover", &CAi::TargetCover);
  x0_stateFuncs.emplace("Halt", &CAi::Halt);
  x0_stateFuncs.emplace("Walk", &CAi::Walk);
  x0_stateFuncs.emplace("Run", &CAi::Run);
  x0_stateFuncs.emplace("Generate", &CAi::Generate);
  x0_stateFuncs.emplace("Deactivate", &CAi::Deactivate);
  x0_stateFuncs.emplace("Attack", &CAi::Attack);
  x0_stateFuncs.emplace("LoopedAttack", &CAi::LoopedAttack);
  x0_stateFuncs.emplace("JumpBack", &CAi::JumpBack);
  x0_stateFuncs.emplace("DoubleSnap", &CAi::DoubleSnap);
  x0_stateFuncs.emplace("Shuffle", &CAi::Shuffle);
  x0_stateFuncs.emplace("TurnAround", &CAi::TurnAround);
  x0_stateFuncs.emplace("Skid", &CAi::Skid);
  x0_stateFuncs.emplace("Active", &CAi::Active);
  x0_stateFuncs.emplace("InActive", &CAi::InActive);
  x0_stateFuncs.emplace("CoverAttack", &CAi::CoverAttack);
  x0_stateFuncs.emplace("Crouch", &CAi::Crouch);
  x0_stateFuncs.emplace("FadeIn", &CAi::FadeIn);
  x0_stateFuncs.emplace("FadeOut", &CAi::FadeOut);
  x0_stateFuncs.emplace("GetUp", &CAi::GetUp);
  x0_stateFuncs.emplace("Taunt", &CAi::Taunt);
  x0_stateFuncs.emplace("Suck", &CAi::Suck);
  x0_stateFuncs.emplace("Flee", &CAi::Flee);
  x0_stateFuncs.emplace("Lurk", &CAi::Lurk);
  x0_stateFuncs.emplace("ProjectileAttack", &CAi::ProjectileAttack);
  x0_stateFuncs.emplace("Flinch", &CAi::Flinch);
  x0_stateFuncs.emplace("Hurled", &CAi::Hurled);
  x0_stateFuncs.emplace("TelegraphAttack", &CAi::TelegraphAttack);
  x0_stateFuncs.emplace("Jump", &CAi::Jump);
  x0_stateFuncs.emplace("Explode", &CAi::Explode);
  x0_stateFuncs.emplace("Dodge", &CAi::Dodge);
  x0_stateFuncs.emplace("Retreat", &CAi::Retreat);
  x0_stateFuncs.emplace("Cover", &CAi::Cover);
  x0_stateFuncs.emplace("Approach", &CAi::Approach);
  x0_stateFuncs.emplace("WallHang", &CAi::WallHang);
  x0_stateFuncs.emplace("WallDetach", &CAi::WallDetach);
  x0_stateFuncs.emplace("Enraged", &CAi::Enraged);
  x0_stateFuncs.emplace("SpecialAttack", &CAi::SpecialAttack);
  x0_stateFuncs.emplace("Growth", &CAi::Growth);
  x0_stateFuncs.emplace("Faint", &CAi::Faint);
  x0_stateFuncs.emplace("Land", &CAi::Land);
  x0_stateFuncs.emplace("Bounce", &CAi::Bounce);
  x0_stateFuncs.emplace("PathFindEx", &CAi::PathFindEx);
  x0_stateFuncs.emplace("Dizzy", &CAi::Dizzy);
  x0_stateFuncs.emplace("CallForBackup", &CAi::CallForBackup);
  x0_stateFuncs.emplace("BulbAttack", &CAi::BulbAttack);
  x0_stateFuncs.emplace("PodAttack", &CAi::PodAttack);

  /* Ai Triggers */
  x10_triggerFuncs.emplace("InAttackPosition", &CAi::InAttackPosition);
  x10_triggerFuncs.emplace("Leash", &CAi::Leash);
  x10_triggerFuncs.emplace("OffLine", &CAi::OffLine);
  x10_triggerFuncs.emplace("Attacked", &CAi::Attacked);
  x10_triggerFuncs.emplace("PathShagged", &CAi::PathShagged);
  x10_triggerFuncs.emplace("PathOver", &CAi::PathOver);
  x10_triggerFuncs.emplace("PathFound", &CAi::PathFound);
  x10_triggerFuncs.emplace("TooClose", &CAi::TooClose);
  x10_triggerFuncs.emplace("InRange", &CAi::InRange);
  x10_triggerFuncs.emplace("InMaxRange", &CAi::InMaxRange);
  x10_triggerFuncs.emplace("InDetectionRange", &CAi::InDetectionRange);
  x10_triggerFuncs.emplace("SpotPlayer", &CAi::SpotPlayer);
  x10_triggerFuncs.emplace("PlayerSpot", &CAi::PlayerSpot);
  x10_triggerFuncs.emplace("PatternOver", &CAi::PatternOver);
  x10_triggerFuncs.emplace("PatternShagged", &CAi::PatternShagged);
  x10_triggerFuncs.emplace("HasAttackPattern", &CAi::HasAttackPattern);
  x10_triggerFuncs.emplace("HasPatrolPath", &CAi::HasPatrolPath);
  x10_triggerFuncs.emplace("HasRetreatPattern", &CAi::HasRetreatPattern);
  x10_triggerFuncs.emplace("Delay", &CAi::Delay);
  x10_triggerFuncs.emplace("RandomDelay", &CAi::RandomDelay);
  x10_triggerFuncs.emplace("FixedDelay", &CAi::FixedDelay);
  x10_triggerFuncs.emplace("Default", &CAi::Default);
  x10_triggerFuncs.emplace("AnimOver", &CAi::AnimOver);
  x10_triggerFuncs.emplace("ShouldAttack", &CAi::ShouldAttack);
  x10_triggerFuncs.emplace("ShouldDoubleSnap", &CAi::ShouldDoubleSnap);
  x10_triggerFuncs.emplace("InPosition", &CAi::InPosition);
  x10_triggerFuncs.emplace("ShouldTurn", &CAi::ShouldTurn);
  x10_triggerFuncs.emplace("HitSomething", &CAi::HitSomething);
  x10_triggerFuncs.emplace("ShouldJumpBack", &CAi::ShouldJumpBack);
  x10_triggerFuncs.emplace("Stuck", &CAi::Stuck);
  x10_triggerFuncs.emplace("NoPathNodes", &CAi::NoPathNodes);
  x10_triggerFuncs.emplace("Landed", &CAi::Landed);
  x10_triggerFuncs.emplace("HearShot", &CAi::HearShot);
  x10_triggerFuncs.emplace("HearPlayer", &CAi::HearPlayer);
  x10_triggerFuncs.emplace("CoverCheck", &CAi::CoverCheck);
  x10_triggerFuncs.emplace("CoverFind", &CAi::CoverFind);
  x10_triggerFuncs.emplace("CoverBlown", &CAi::CoverBlown);
  x10_triggerFuncs.emplace("CoverNearlyBlown", &CAi::CoverNearlyBlown);
  x10_triggerFuncs.emplace("CoveringFire", &CAi::CoveringFire);
  x10_triggerFuncs.emplace("GotUp", &CAi::GotUp);
  x10_triggerFuncs.emplace("LineOfSight", &CAi::LineOfSight);
  x10_triggerFuncs.emplace("AggressionCheck", &CAi::AggressionCheck);
  x10_triggerFuncs.emplace("AttackOver", &CAi::AttackOver);
  x10_triggerFuncs.emplace("ShouldTaunt", &CAi::ShouldTaunt);
  x10_triggerFuncs.emplace("Inside", &CAi::Inside);
  x10_triggerFuncs.emplace("ShouldFire", &CAi::ShouldFire);
  x10_triggerFuncs.emplace("ShouldFlinch", &CAi::ShouldFlinch);
  x10_triggerFuncs.emplace("PatrolPathOver", &CAi::PatrolPathOver);
  x10_triggerFuncs.emplace("ShouldDodge", &CAi::ShouldDodge);
  x10_triggerFuncs.emplace("ShouldRetreat", &CAi::ShouldRetreat);
  x10_triggerFuncs.emplace("ShouldCrouch", &CAi::ShouldCrouch);
  x10_triggerFuncs.emplace("ShouldMove", &CAi::ShouldMove);
  x10_triggerFuncs.emplace("ShotAt", &CAi::ShotAt);
  x10_triggerFuncs.emplace("HasTargetingPoint", &CAi::HasTargetingPoint);
  x10_triggerFuncs.emplace("ShouldWallHang", &CAi::ShouldWallHang);
  x10_triggerFuncs.emplace("SetAIStage", &CAi::SetAIStage);
  x10_triggerFuncs.emplace("AIStage", &CAi::AIStage);
  x10_triggerFuncs.emplace("StartAttack", &CAi::StartAttack);
  x10_triggerFuncs.emplace("BreakAttack", &CAi::BreakAttack);
  x10_triggerFuncs.emplace("ShouldStrafe", &CAi::ShouldStrafe);
  x10_triggerFuncs.emplace("ShouldSpecialAttack", &CAi::ShouldSpecialAttack);
  x10_triggerFuncs.emplace("LostInterest", &CAi::LostInterest);
  x10_triggerFuncs.emplace("CodeTrigger", &CAi::CodeTrigger);
  x10_triggerFuncs.emplace("BounceFind", &CAi::BounceFind);
  x10_triggerFuncs.emplace("Random", &CAi::Random);
  x10_triggerFuncs.emplace("FixedRandom", &CAi::FixedRandom);
  x10_triggerFuncs.emplace("IsDizzy", &CAi::IsDizzy);
  x10_triggerFuncs.emplace("ShouldCallForBackup", &CAi::ShouldCallForBackup);

  CAi::CreateFuncLookup(this);
}

CAiStateFunc CAiFuncMap::GetStateFunc(const char* func) const {
  const auto iter = x0_stateFuncs.find(func);

  if (iter == x0_stateFuncs.cend()) {
    return nullptr;
  }

  return iter->second;
}

CAiTriggerFunc CAiFuncMap::GetTriggerFunc(const char* func) const {
  const auto iter = x10_triggerFuncs.find(func);

  if (iter == x10_triggerFuncs.cend()) {
    return nullptr;
  }

  return iter->second;
}
} // namespace urde
<commit_msg>CAiFuncMap: Reserve containers before adding entries<commit_after>#include "Runtime/World/CAiFuncMap.hpp"

#include "Runtime/CStateManager.hpp"
#include "Runtime/World/CAi.hpp"

namespace urde {
CAiFuncMap::CAiFuncMap() {
  /* Ai States */
  x0_stateFuncs.reserve(55);
  x0_stateFuncs.emplace("Patrol", &CAi::Patrol);
  x0_stateFuncs.emplace("FollowPattern", &CAi::FollowPattern);
  x0_stateFuncs.emplace("Dead", &CAi::Dead);
  x0_stateFuncs.emplace("PathFind", &CAi::PathFind);
  x0_stateFuncs.emplace("Start", &CAi::Start);
  x0_stateFuncs.emplace("SelectTarget", &CAi::SelectTarget);
  x0_stateFuncs.emplace("TargetPatrol", &CAi::TargetPatrol);
  x0_stateFuncs.emplace("TargetPlayer", &CAi::TargetPlayer);
  x0_stateFuncs.emplace("TargetCover", &CAi::TargetCover);
  x0_stateFuncs.emplace("Halt", &CAi::Halt);
  x0_stateFuncs.emplace("Walk", &CAi::Walk);
  x0_stateFuncs.emplace("Run", &CAi::Run);
  x0_stateFuncs.emplace("Generate", &CAi::Generate);
  x0_stateFuncs.emplace("Deactivate", &CAi::Deactivate);
  x0_stateFuncs.emplace("Attack", &CAi::Attack);
  x0_stateFuncs.emplace("LoopedAttack", &CAi::LoopedAttack);
  x0_stateFuncs.emplace("JumpBack", &CAi::JumpBack);
  x0_stateFuncs.emplace("DoubleSnap", &CAi::DoubleSnap);
  x0_stateFuncs.emplace("Shuffle", &CAi::Shuffle);
  x0_stateFuncs.emplace("TurnAround", &CAi::TurnAround);
  x0_stateFuncs.emplace("Skid", &CAi::Skid);
  x0_stateFuncs.emplace("Active", &CAi::Active);
  x0_stateFuncs.emplace("InActive", &CAi::InActive);
  x0_stateFuncs.emplace("CoverAttack", &CAi::CoverAttack);
  x0_stateFuncs.emplace("Crouch", &CAi::Crouch);
  x0_stateFuncs.emplace("FadeIn", &CAi::FadeIn);
  x0_stateFuncs.emplace("FadeOut", &CAi::FadeOut);
  x0_stateFuncs.emplace("GetUp", &CAi::GetUp);
  x0_stateFuncs.emplace("Taunt", &CAi::Taunt);
  x0_stateFuncs.emplace("Suck", &CAi::Suck);
  x0_stateFuncs.emplace("Flee", &CAi::Flee);
  x0_stateFuncs.emplace("Lurk", &CAi::Lurk);
  x0_stateFuncs.emplace("ProjectileAttack", &CAi::ProjectileAttack);
  x0_stateFuncs.emplace("Flinch", &CAi::Flinch);
  x0_stateFuncs.emplace("Hurled", &CAi::Hurled);
  x0_stateFuncs.emplace("TelegraphAttack", &CAi::TelegraphAttack);
  x0_stateFuncs.emplace("Jump", &CAi::Jump);
  x0_stateFuncs.emplace("Explode", &CAi::Explode);
  x0_stateFuncs.emplace("Dodge", &CAi::Dodge);
  x0_stateFuncs.emplace("Retreat", &CAi::Retreat);
  x0_stateFuncs.emplace("Cover", &CAi::Cover);
  x0_stateFuncs.emplace("Approach", &CAi::Approach);
  x0_stateFuncs.emplace("WallHang", &CAi::WallHang);
  x0_stateFuncs.emplace("WallDetach", &CAi::WallDetach);
  x0_stateFuncs.emplace("Enraged", &CAi::Enraged);
  x0_stateFuncs.emplace("SpecialAttack", &CAi::SpecialAttack);
  x0_stateFuncs.emplace("Growth", &CAi::Growth);
  x0_stateFuncs.emplace("Faint", &CAi::Faint);
  x0_stateFuncs.emplace("Land", &CAi::Land);
  x0_stateFuncs.emplace("Bounce", &CAi::Bounce);
  x0_stateFuncs.emplace("PathFindEx", &CAi::PathFindEx);
  x0_stateFuncs.emplace("Dizzy", &CAi::Dizzy);
  x0_stateFuncs.emplace("CallForBackup", &CAi::CallForBackup);
  x0_stateFuncs.emplace("BulbAttack", &CAi::BulbAttack);
  x0_stateFuncs.emplace("PodAttack", &CAi::PodAttack);

  /* Ai Triggers */
  x10_triggerFuncs.reserve(68);
  x10_triggerFuncs.emplace("InAttackPosition", &CAi::InAttackPosition);
  x10_triggerFuncs.emplace("Leash", &CAi::Leash);
  x10_triggerFuncs.emplace("OffLine", &CAi::OffLine);
  x10_triggerFuncs.emplace("Attacked", &CAi::Attacked);
  x10_triggerFuncs.emplace("PathShagged", &CAi::PathShagged);
  x10_triggerFuncs.emplace("PathOver", &CAi::PathOver);
  x10_triggerFuncs.emplace("PathFound", &CAi::PathFound);
  x10_triggerFuncs.emplace("TooClose", &CAi::TooClose);
  x10_triggerFuncs.emplace("InRange", &CAi::InRange);
  x10_triggerFuncs.emplace("InMaxRange", &CAi::InMaxRange);
  x10_triggerFuncs.emplace("InDetectionRange", &CAi::InDetectionRange);
  x10_triggerFuncs.emplace("SpotPlayer", &CAi::SpotPlayer);
  x10_triggerFuncs.emplace("PlayerSpot", &CAi::PlayerSpot);
  x10_triggerFuncs.emplace("PatternOver", &CAi::PatternOver);
  x10_triggerFuncs.emplace("PatternShagged", &CAi::PatternShagged);
  x10_triggerFuncs.emplace("HasAttackPattern", &CAi::HasAttackPattern);
  x10_triggerFuncs.emplace("HasPatrolPath", &CAi::HasPatrolPath);
  x10_triggerFuncs.emplace("HasRetreatPattern", &CAi::HasRetreatPattern);
  x10_triggerFuncs.emplace("Delay", &CAi::Delay);
  x10_triggerFuncs.emplace("RandomDelay", &CAi::RandomDelay);
  x10_triggerFuncs.emplace("FixedDelay", &CAi::FixedDelay);
  x10_triggerFuncs.emplace("Default", &CAi::Default);
  x10_triggerFuncs.emplace("AnimOver", &CAi::AnimOver);
  x10_triggerFuncs.emplace("ShouldAttack", &CAi::ShouldAttack);
  x10_triggerFuncs.emplace("ShouldDoubleSnap", &CAi::ShouldDoubleSnap);
  x10_triggerFuncs.emplace("InPosition", &CAi::InPosition);
  x10_triggerFuncs.emplace("ShouldTurn", &CAi::ShouldTurn);
  x10_triggerFuncs.emplace("HitSomething", &CAi::HitSomething);
  x10_triggerFuncs.emplace("ShouldJumpBack", &CAi::ShouldJumpBack);
  x10_triggerFuncs.emplace("Stuck", &CAi::Stuck);
  x10_triggerFuncs.emplace("NoPathNodes", &CAi::NoPathNodes);
  x10_triggerFuncs.emplace("Landed", &CAi::Landed);
  x10_triggerFuncs.emplace("HearShot", &CAi::HearShot);
  x10_triggerFuncs.emplace("HearPlayer", &CAi::HearPlayer);
  x10_triggerFuncs.emplace("CoverCheck", &CAi::CoverCheck);
  x10_triggerFuncs.emplace("CoverFind", &CAi::CoverFind);
  x10_triggerFuncs.emplace("CoverBlown", &CAi::CoverBlown);
  x10_triggerFuncs.emplace("CoverNearlyBlown", &CAi::CoverNearlyBlown);
  x10_triggerFuncs.emplace("CoveringFire", &CAi::CoveringFire);
  x10_triggerFuncs.emplace("GotUp", &CAi::GotUp);
  x10_triggerFuncs.emplace("LineOfSight", &CAi::LineOfSight);
  x10_triggerFuncs.emplace("AggressionCheck", &CAi::AggressionCheck);
  x10_triggerFuncs.emplace("AttackOver", &CAi::AttackOver);
  x10_triggerFuncs.emplace("ShouldTaunt", &CAi::ShouldTaunt);
  x10_triggerFuncs.emplace("Inside", &CAi::Inside);
  x10_triggerFuncs.emplace("ShouldFire", &CAi::ShouldFire);
  x10_triggerFuncs.emplace("ShouldFlinch", &CAi::ShouldFlinch);
  x10_triggerFuncs.emplace("PatrolPathOver", &CAi::PatrolPathOver);
  x10_triggerFuncs.emplace("ShouldDodge", &CAi::ShouldDodge);
  x10_triggerFuncs.emplace("ShouldRetreat", &CAi::ShouldRetreat);
  x10_triggerFuncs.emplace("ShouldCrouch", &CAi::ShouldCrouch);
  x10_triggerFuncs.emplace("ShouldMove", &CAi::ShouldMove);
  x10_triggerFuncs.emplace("ShotAt", &CAi::ShotAt);
  x10_triggerFuncs.emplace("HasTargetingPoint", &CAi::HasTargetingPoint);
  x10_triggerFuncs.emplace("ShouldWallHang", &CAi::ShouldWallHang);
  x10_triggerFuncs.emplace("SetAIStage", &CAi::SetAIStage);
  x10_triggerFuncs.emplace("AIStage", &CAi::AIStage);
  x10_triggerFuncs.emplace("StartAttack", &CAi::StartAttack);
  x10_triggerFuncs.emplace("BreakAttack", &CAi::BreakAttack);
  x10_triggerFuncs.emplace("ShouldStrafe", &CAi::ShouldStrafe);
  x10_triggerFuncs.emplace("ShouldSpecialAttack", &CAi::ShouldSpecialAttack);
  x10_triggerFuncs.emplace("LostInterest", &CAi::LostInterest);
  x10_triggerFuncs.emplace("CodeTrigger", &CAi::CodeTrigger);
  x10_triggerFuncs.emplace("BounceFind", &CAi::BounceFind);
  x10_triggerFuncs.emplace("Random", &CAi::Random);
  x10_triggerFuncs.emplace("FixedRandom", &CAi::FixedRandom);
  x10_triggerFuncs.emplace("IsDizzy", &CAi::IsDizzy);
  x10_triggerFuncs.emplace("ShouldCallForBackup", &CAi::ShouldCallForBackup);

  CAi::CreateFuncLookup(this);
}

CAiStateFunc CAiFuncMap::GetStateFunc(const char* func) const {
  const auto iter = x0_stateFuncs.find(func);

  if (iter == x0_stateFuncs.cend()) {
    return nullptr;
  }

  return iter->second;
}

CAiTriggerFunc CAiFuncMap::GetTriggerFunc(const char* func) const {
  const auto iter = x10_triggerFuncs.find(func);

  if (iter == x10_triggerFuncs.cend()) {
    return nullptr;
  }

  return iter->second;
}
} // namespace urde
<|endoftext|>


<commit_before>/*++

Module Name:

    CommandProcessor.cpp

Abstract:

    Code for running the top-level commands of SNAP

Authors:

    Bill Bolosky, November, 2014

Environment:

User mode service.

Revision History:

    Pulled from the main program and expanded to handle daemon mode

--*/

#include "stdafx.h"
#include "options.h"
#include "FASTA.h"
#include "GenomeIndex.h"
#include "SingleAligner.h"
#include "PairedAligner.h"
#include "exit.h"
#include "SeedSequencer.h"
#include "AlignerOptions.h"
#include "CommandProcessor.h"
#include "Error.h"
#include "Compat.h"

const char *SNAP_VERSION = "1.0dev.103";

static void usage()
{
	WriteErrorMessage(
		"Usage: snap-aligner <command> [<options>]\n"
		"Commands:\n"
		"   index    build a genome index\n"
		"   single   align single-end reads\n"
		"   paired   align paired-end reads\n"
		"   daemon   run in daemon mode--accept commands remotely\n"
		"Type a command without arguments to see its help.\n");
}

void ProcessNonDaemonCommands(int argc, const char **argv) {
	if (strcmp(argv[1], "index") == 0) {
		if (CommandPipe == NULL) {
			GenomeIndex::runIndexer(argc - 2, argv + 2);
		} else {
			//
			// The error cases in index build don't really free memory properly, so we just don't allow it in daemon mode.
			//
			WriteErrorMessage("The index command is not available in daemon mode.  Please run 'snap-aligner index' directly.\n");
		}
	} else if (strcmp(argv[1], "single") == 0 || strcmp(argv[1], "paired") == 0) {
		for (int i = 1; i < argc; /* i is increased below */) {
			unsigned nArgsConsumed;
			if (strcmp(argv[i], "single") == 0) {
				SingleAlignerContext single;
				single.runAlignment(argc - i, argv + i, SNAP_VERSION, &nArgsConsumed);
			} else if (strcmp(argv[i], "paired") == 0) {
				PairedAlignerContext paired;
				paired.runAlignment(argc - i, argv + i, SNAP_VERSION, &nArgsConsumed);
			} else {
				fprintf(stderr, "Invalid command: %s\n\n", argv[i]);
				usage();
				return;
			}
			_ASSERT(nArgsConsumed > 0);
			i += nArgsConsumed;
		}
	} else {
		WriteErrorMessage("Invalid command: %s\n\n", argv[1]);
		usage();
	}
}

static void daemonUsage()
{
	fprintf(stderr, "Usage: snap-aligner daemon [Named pipe name]\n");
	soft_exit_no_print(1);    // Don't use soft_exit, it's confusing people to get an "error" message after the usage
}

void RunDaemonMode(int argc, const char **argv)
{
	if (argc < 2 || argc > 3) {
		daemonUsage();
	}

	printf("SNAP in daemon mode, waiting for commands to execute\n");

	const char *pipeName = argc == 3 ? argv[2] : DEFAULT_NAMED_PIPE_NAME;
	CommandPipe = OpenNamedPipe(pipeName, true);

	if (NULL == CommandPipe) {
		WriteErrorMessage("Unable to open named pipe for command IO.\n");
		soft_exit(1);
	}

	const size_t commandBufferSize = 10000;	// Yes, this is fixed size, no it's not a buffer overflow.  The named pipe reader just quits if it's too long.
	char commandBuffer[commandBufferSize];

	//
	// Format of commands is argc (in ascii) followed by argc arguments, each in one line.
	//
	for (;;) {
		if (!ReadFromNamedPipe(CommandPipe, commandBuffer, commandBufferSize)) {
			CloseNamedPipe(CommandPipe);
			CommandPipe = NULL;
			WriteStatusMessage("Named pipe closed.  Exiting\n");
			soft_exit_no_print(0);
		}

		int argc = atoi(commandBuffer);
		if (0 == argc) {
			WriteErrorMessage("Expected argument count on named pipe, got '%s'; ignoring.\n", commandBuffer);
		} else {
			char **argv = new char*[argc];
			for (int i = 0; i < argc; i++) {
				argv[i] = new char[commandBufferSize];
				if (!ReadFromNamedPipe(CommandPipe, argv[i], commandBufferSize)) {
					CloseNamedPipe(CommandPipe);
					CommandPipe = NULL;
					WriteStatusMessage("Error reading argument #%d from named pipe.\n", i);
					soft_exit(1);
				}
			} // for each arg

			if (argc > 1 && strcmp(argv[1], "exit") == 0) {
				WriteStatusMessage("SNAP server exiting by request\n");
				WriteToNamedPipe(CommandPipe, CommandExecutedString);
				soft_exit_no_print(1);
			}

			printf("Executing command: ");
			for (int i = 1; i < argc; i++) {
				printf("%s ", argv[i]);
			}
			printf("\n");

			ProcessNonDaemonCommands(argc, (const char **) argv);

			printf("\n");

			for (int i = 0; i < argc; i++) {
				delete[] argv[i];
				argv[i] = NULL;
			}
			delete[] argv;
			argv = NULL;
		}
		WriteToNamedPipe(CommandPipe, CommandExecutedString);
	}
}

void ProcessTopLevelCommands(int argc, const char **argv)
{
	fprintf(stderr, "Welcome to SNAP version %s.\n\n", SNAP_VERSION);       // Can't use WriteStatusMessage, because we haven't parsed args yet to determine if -hdp is specified.  Just stick with stderr.

	InitializeSeedSequencers();

	if (argc < 2) {
		usage();
		soft_exit_no_print(1);
	}

	if (strcmp(argv[1], "daemon") == 0) {
		RunDaemonMode(argc, argv);
	} else {
		ProcessNonDaemonCommands(argc, argv);
	}
}

NamedPipe *CommandPipe = NULL;
const char *CommandExecutedString = "***SNAP Command completed execution***";
<commit_msg>1.0dev.104: update version number for release<commit_after>/*++

Module Name:

    CommandProcessor.cpp

Abstract:

    Code for running the top-level commands of SNAP

Authors:

    Bill Bolosky, November, 2014

Environment:

User mode service.

Revision History:

    Pulled from the main program and expanded to handle daemon mode

--*/

#include "stdafx.h"
#include "options.h"
#include "FASTA.h"
#include "GenomeIndex.h"
#include "SingleAligner.h"
#include "PairedAligner.h"
#include "exit.h"
#include "SeedSequencer.h"
#include "AlignerOptions.h"
#include "CommandProcessor.h"
#include "Error.h"
#include "Compat.h"

const char *SNAP_VERSION = "1.0dev.104";

static void usage()
{
	WriteErrorMessage(
		"Usage: snap-aligner <command> [<options>]\n"
		"Commands:\n"
		"   index    build a genome index\n"
		"   single   align single-end reads\n"
		"   paired   align paired-end reads\n"
		"   daemon   run in daemon mode--accept commands remotely\n"
		"Type a command without arguments to see its help.\n");
}

void ProcessNonDaemonCommands(int argc, const char **argv) {
	if (strcmp(argv[1], "index") == 0) {
		if (CommandPipe == NULL) {
			GenomeIndex::runIndexer(argc - 2, argv + 2);
		} else {
			//
			// The error cases in index build don't really free memory properly, so we just don't allow it in daemon mode.
			//
			WriteErrorMessage("The index command is not available in daemon mode.  Please run 'snap-aligner index' directly.\n");
		}
	} else if (strcmp(argv[1], "single") == 0 || strcmp(argv[1], "paired") == 0) {
		for (int i = 1; i < argc; /* i is increased below */) {
			unsigned nArgsConsumed;
			if (strcmp(argv[i], "single") == 0) {
				SingleAlignerContext single;
				single.runAlignment(argc - i, argv + i, SNAP_VERSION, &nArgsConsumed);
			} else if (strcmp(argv[i], "paired") == 0) {
				PairedAlignerContext paired;
				paired.runAlignment(argc - i, argv + i, SNAP_VERSION, &nArgsConsumed);
			} else {
				fprintf(stderr, "Invalid command: %s\n\n", argv[i]);
				usage();
				return;
			}
			_ASSERT(nArgsConsumed > 0);
			i += nArgsConsumed;
		}
	} else {
		WriteErrorMessage("Invalid command: %s\n\n", argv[1]);
		usage();
	}
}

static void daemonUsage()
{
	fprintf(stderr, "Usage: snap-aligner daemon [Named pipe name]\n");
	soft_exit_no_print(1);    // Don't use soft_exit, it's confusing people to get an "error" message after the usage
}

void RunDaemonMode(int argc, const char **argv)
{
	if (argc < 2 || argc > 3) {
		daemonUsage();
	}

	printf("SNAP in daemon mode, waiting for commands to execute\n");

	const char *pipeName = argc == 3 ? argv[2] : DEFAULT_NAMED_PIPE_NAME;
	CommandPipe = OpenNamedPipe(pipeName, true);

	if (NULL == CommandPipe) {
		WriteErrorMessage("Unable to open named pipe for command IO.\n");
		soft_exit(1);
	}

	const size_t commandBufferSize = 10000;	// Yes, this is fixed size, no it's not a buffer overflow.  The named pipe reader just quits if it's too long.
	char commandBuffer[commandBufferSize];

	//
	// Format of commands is argc (in ascii) followed by argc arguments, each in one line.
	//
	for (;;) {
		if (!ReadFromNamedPipe(CommandPipe, commandBuffer, commandBufferSize)) {
			CloseNamedPipe(CommandPipe);
			CommandPipe = NULL;
			WriteStatusMessage("Named pipe closed.  Exiting\n");
			soft_exit_no_print(0);
		}

		int argc = atoi(commandBuffer);
		if (0 == argc) {
			WriteErrorMessage("Expected argument count on named pipe, got '%s'; ignoring.\n", commandBuffer);
		} else {
			char **argv = new char*[argc];
			for (int i = 0; i < argc; i++) {
				argv[i] = new char[commandBufferSize];
				if (!ReadFromNamedPipe(CommandPipe, argv[i], commandBufferSize)) {
					CloseNamedPipe(CommandPipe);
					CommandPipe = NULL;
					WriteStatusMessage("Error reading argument #%d from named pipe.\n", i);
					soft_exit(1);
				}
			} // for each arg

			if (argc > 1 && strcmp(argv[1], "exit") == 0) {
				WriteStatusMessage("SNAP server exiting by request\n");
				WriteToNamedPipe(CommandPipe, CommandExecutedString);
				soft_exit_no_print(1);
			}

			printf("Executing command: ");
			for (int i = 1; i < argc; i++) {
				printf("%s ", argv[i]);
			}
			printf("\n");

			ProcessNonDaemonCommands(argc, (const char **) argv);

			printf("\n");

			for (int i = 0; i < argc; i++) {
				delete[] argv[i];
				argv[i] = NULL;
			}
			delete[] argv;
			argv = NULL;
		}
		WriteToNamedPipe(CommandPipe, CommandExecutedString);
	}
}

void ProcessTopLevelCommands(int argc, const char **argv)
{
	fprintf(stderr, "Welcome to SNAP version %s.\n\n", SNAP_VERSION);       // Can't use WriteStatusMessage, because we haven't parsed args yet to determine if -hdp is specified.  Just stick with stderr.

	InitializeSeedSequencers();

	if (argc < 2) {
		usage();
		soft_exit_no_print(1);
	}

	if (strcmp(argv[1], "daemon") == 0) {
		RunDaemonMode(argc, argv);
	} else {
		ProcessNonDaemonCommands(argc, argv);
	}
}

NamedPipe *CommandPipe = NULL;
const char *CommandExecutedString = "***SNAP Command completed execution***";
<|endoftext|>


<commit_before>// Copyright (c) 2007-2010 Paul Hodge. All rights reserved.

#include "circa.h"

namespace circa {
namespace filter_function {

    void evaluate(EvalContext* cxt, Term* caller)
    {
        Branch& inputs = as_branch(caller->input(0));
        Branch& bools = as_branch(caller->input(1));
        Branch& output = as_branch(caller);

        if (inputs.length() != bools.length()) {
            error_occurred(cxt, caller, "Lists have different lengths");
            return;
        }

        int write = 0;

        for (int i=0; i < inputs.length(); i++) {
            if (bools[i]->asBool()) {
                if (output.length() <= i) {
                    create_value(output, inputs[i]->type);
                }

                assign_value(inputs[i], output[write]);
                write++;
            }
        }

        // Remove extra elements
        for (int i=write; i < output.length(); i++)
            output.set(i, NULL);

        output.removeNulls();
    }

    void setup(Branch& kernel)
    {
        import_function(kernel, evaluate, "filter(List,List) -> List");
    }
}
} // namespace circa
<commit_msg>filter() now uses list-generic functions<commit_after>// Copyright (c) 2007-2010 Paul Hodge. All rights reserved.

#include "circa.h"

namespace circa {
namespace filter_function {

    void evaluate(EvalContext* cxt, Term* caller)
    {
        TaggedValue* inputs = caller->input(0);
        TaggedValue* bools = caller->input(1);
        Branch& output = as_branch(caller);

        int numInputs = inputs->numElements();
        int numBools = bools->numElements();

        if (numInputs != numBools)
            return error_occurred(cxt, caller, "Lists have different lengths");

        int write = 0;

        for (int i=0; i < numInputs; i++) {
            if (as_bool((*bools)[i])) {
                if (output.length() <= i)
                    output.appendNew();

                copy((*inputs)[i], output[write]);
                write++;
            }
        }

        // Remove extra elements
        for (int i=write; i < output.length(); i++)
            output.set(i, NULL);

        output.removeNulls();
    }

    void setup(Branch& kernel)
    {
        import_function(kernel, evaluate, "filter(List,List) -> List");
    }
}
} // namespace circa
<|endoftext|>