<commit_before>#ifndef SET_ATOM_POSITIONS_H
#define SET_ATOM_POSITIONS_H

#include <stdexcept>
#include <vector>
#include <pybind11/pybind11.h>

#include "Unit_cell/unit_cell.hpp"

namespace sirius {
void set_atom_positions(Unit_cell& unit_cell, pybind11::buffer positions)
{
    using namespace pybind11;

    buffer_info info = positions.request();
    int npositions = info.shape[0];
    if (info.ndim != 2) {
        throw std::runtime_error("set_atom_positions: wrong dimension (expected 2d array)");
    }
    if (info.shape[1] != 3) {
        throw std::runtime_error("set_atom_positions: wrong shape");
    }
    if (npositions != unit_cell.num_atoms()) {
        throw std::runtime_error("number of positions != number of atoms");
    }
    if (info.format != format_descriptor<double>::format())
        throw std::runtime_error("Incompatible format: expected a double array!");

    const double* ptr = static_cast<double*>(info.ptr);
    int s0 = info.strides[0] / sizeof(double);
    int s1 = info.strides[1] / sizeof(double);
    for (int ia = 0; ia < npositions; ++ia) {
        auto& atom = unit_cell.atom(ia);
        double x = *(ptr + s0*ia + s1*0);
        double y = *(ptr + s0*ia + s1*1);
        double z = *(ptr + s0*ia + s1*2);
        atom.set_position({x, y, z});
    }
}

void set_lattice_vectors(Unit_cell& unit_cell,
                         pybind11::buffer l1buf,
                         pybind11::buffer l2buf,
                         pybind11::buffer l3buf)
{
    using namespace pybind11;
    auto to_vector = [](pybind11::buffer in)
                       {
                           buffer_info info = in.request();
                           int npositions = info.shape[0];
                           // checks
                           if (info.ndim != 1) {
                               throw std::runtime_error("Error: set_lattice_vectors expected a vector");
                           }
                           if (info.shape[0] != 3) {
                               throw std::runtime_error("Error: set_lattice_vector ");
                           }
                           if (info.format != format_descriptor<double>::format())
                               throw std::runtime_error("Error: set_lattice_vector: expected type float64");

                           double* ptr = static_cast<double*>(info.ptr);
                           int stride = info.strides[0] / sizeof(double);
                           return vector3d<double>({ptr[0], ptr[stride], ptr[2*stride]});
                       };

    auto l1 = to_vector(l1buf);
    auto l2 = to_vector(l2buf);
    auto l3 = to_vector(l3buf);

    unit_cell.set_lattice_vectors(l1, l2, l3);
}

}  // sirius

#endif /* SET_ATOM_POSITIONS_H */
<commit_msg>pybind11: remove unused variable<commit_after>#ifndef SET_ATOM_POSITIONS_H
#define SET_ATOM_POSITIONS_H

#include <stdexcept>
#include <vector>
#include <pybind11/pybind11.h>

#include "Unit_cell/unit_cell.hpp"

namespace sirius {
void set_atom_positions(Unit_cell& unit_cell, pybind11::buffer positions)
{
    using namespace pybind11;

    buffer_info info = positions.request();
    int npositions = info.shape[0];
    if (info.ndim != 2) {
        throw std::runtime_error("set_atom_positions: wrong dimension (expected 2d array)");
    }
    if (info.shape[1] != 3) {
        throw std::runtime_error("set_atom_positions: wrong shape");
    }
    if (npositions != unit_cell.num_atoms()) {
        throw std::runtime_error("number of positions != number of atoms");
    }
    if (info.format != format_descriptor<double>::format())
        throw std::runtime_error("Incompatible format: expected a double array!");

    const double* ptr = static_cast<double*>(info.ptr);
    int s0 = info.strides[0] / sizeof(double);
    int s1 = info.strides[1] / sizeof(double);
    for (int ia = 0; ia < npositions; ++ia) {
        auto& atom = unit_cell.atom(ia);
        double x = *(ptr + s0*ia + s1*0);
        double y = *(ptr + s0*ia + s1*1);
        double z = *(ptr + s0*ia + s1*2);
        atom.set_position({x, y, z});
    }
}

void set_lattice_vectors(Unit_cell& unit_cell,
                         pybind11::buffer l1buf,
                         pybind11::buffer l2buf,
                         pybind11::buffer l3buf)
{
    using namespace pybind11;
    auto to_vector = [](pybind11::buffer in)
                       {
                           buffer_info info = in.request();
                           // checks
                           if (info.ndim != 1) {
                               throw std::runtime_error("Error: set_lattice_vectors expected a vector");
                           }
                           if (info.shape[0] != 3) {
                               throw std::runtime_error("Error: set_lattice_vector ");
                           }
                           if (info.format != format_descriptor<double>::format())
                               throw std::runtime_error("Error: set_lattice_vector: expected type float64");

                           double* ptr = static_cast<double*>(info.ptr);
                           int stride = info.strides[0] / sizeof(double);
                           return vector3d<double>({ptr[0], ptr[stride], ptr[2*stride]});
                       };

    auto l1 = to_vector(l1buf);
    auto l2 = to_vector(l2buf);
    auto l3 = to_vector(l3buf);

    unit_cell.set_lattice_vectors(l1, l2, l3);
}

}  // sirius

#endif /* SET_ATOM_POSITIONS_H */
<|endoftext|>


<commit_before>#include "webcam.hpp"
#include <chrono>

using namespace cv;
using namespace std;

Mat ellipticKernel(int width, int height = -1) {
 if (height==-1) {
  return getStructuringElement(MORPH_ELLIPSE,Size(width,width), Point(width/2, width/2));
 } else {
  return getStructuringElement(MORPH_ELLIPSE,Size(width,height), Point(width/2, height/2));
 }
}

unsigned long long getMilliseconds() {
 return chrono::system_clock::now().time_since_epoch()/chrono::milliseconds(1);
}

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

/*****
 begin camera setup
*****/

 CvCapture* capture = 0;
 int width, height;

 capture = cvCaptureFromCAM(0);

 if (!capture) {
  printf("No camera detected!");
  return -1;
 }

 ifstream config_file (".config");

 if (config_file.is_open()) {
// does not support corrupted .config

  string line;
  getline(config_file, line);
  istringstream(line)>>width;
  getline(config_file, line);
  istringstream(line)>>height;
  cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH, width);
  cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT, height);

  config_file.close();

 } else {

  initResolutions();

  for (int i=36; i<150; i++) {
   cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH, resolutions[i].width);
   cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT, resolutions[i].height);
  }

  width = cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH);
  height = cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT);

  ofstream config_file_out(".config");
  config_file_out << width;
  config_file_out << "\n";
  config_file_out << height;
  config_file_out << "\n";
  config_file_out.close();
 }

 for (int i = 0; i < 30; i++) {
  // capture some frames so exposure correction takes place
  cvQueryFrame(capture);
 }

/*****
 end camera setup
*****/

/*****
 filter setup
*****/

 Mat acbg(256, 256, CV_8UC3, 0);
// accumulated background
 Mat acbg_m(256, 256, CV_8UC1, 0);
// accumulated background mask

 Mat acfg(256, 256, CV_8UC3, 0);
// accumulated foreground
 Mat acfg_t(256, 256, CV_8UC3, 0);
// accumulated foreground threshold

/*****
 end filter setup
*****/

/*****
 misc
*****/

 unsigned long long times[100];
 for (int i=0; i<100; i++)
  times[i] = 0;

 int tracker1, tracker2, tracker3;
 namedWindow("s",1);
 createTrackbar("1","s",&tracker1,100);
 createTrackbar("2","s",&tracker2,100);
 createTrackbar("3","s",&tracker3,100);

 unsigned long long timenow = getMilliseconds();

 bool keep_going = true;

 CascadeClassifier mouth_cascade;
 mouth_cascade.load("Mouth.xml");

/*****
 begin filter loop
*****/

 while (keep_going) {

  Mat image(cvQueryFrame(capture));
//  imshow("webcam", image);
// at some point preprocess by rotating according to OVR roll
// right now really annoying because of state variables

  Mat gray, img_256, gray_256;
  resize(image, img_256, Size(256, 256));
  cvtColor(image, gray, CV_RGB2GRAY);
  cvtColor(img_256, gray_256, CV_RGB2GRAY);

// this mask gets anything kind of dark (DK2) and dilates
// should work *great*
  Mat gr_m;
// gray mask
  equalizeHist(gray_256, gr_m);
  threshold(gr_m, gr_m, 100, 1, THRESH_BINARY_INV);
  dilate(gr_m, gr_m, ellipticKernel(43));
// verify size of ellipticKernel!
  gr_m = 1 - gr_m;
// change code later so we don't have to do this

  imshow("gray mask", gray_256.mul(gr_m));

 bitwise_or(acbg_m, gr_m, acbg_m);

  imshow("accumulated bg mask", gray_256.mul(acbg_m));

/*
// this mask watches for flow against accumulated bg
 Mat fl_m;
// flow mask
 absdiff(img_256, acbg, fl_m);
// add some morphological operator? but acbg_m!
 threshold(fl_m, fl_m, 80, 1, THRESH_BINARY);
// 80, THRESH_BINARY probably needs tweaking!
// add some other morphological operators? but what about
// acbg_m?

  imshow("flow mask", gray_256.mul(fl_m));

 Mat bg_m;
 bitwise_and(acbg_m, fl_m, bg_m);
 bitwise_or(gr_m, bg_m, bg_m);
// maybe do some morphological operations on bg_m?
// previously combined bg_m with its opening

  imshow("bg mask", gray_256.mul(bg_m));
/*
 // do some stuff with foreground and so on here

 Mat haar_m;
// bitwise_and(1 - bg_m, fg_m, haar_m);
 haar_m = 1 - bg_m;

// run haar classifier
 int scale = width/300;
 if (scale < 1)
  scale = 1;
// can't use 256x256 since haar isn't stretch invariant

 Mat thingy;
 resize(gray, thingy, Size(width/scale, height/scale));
 equalizeHist(thingy, thingy);
///////////////////
// need to change this after foreground stuff gets written

 vector<Rect> mouth_rects;
 resize(haar_m, haar_m, Size(width/scale, height/scale));

 bitwise_and(haar_m, thingy, thingy);
/////////////////

 mouth_cascade.detectMultiScale(thingy, mouth_rects, 1.1, 0, CV_HAAR_SCALE_IMAGE);
 Mat rect_image(height, width, CV_8UC1, Scalar(0));

 for (size_t i=0; i<mouth_rects.size(); i++) {
  Rect scaled(mouth_rects[i].x*scale, mouth_rects[i].y*scale, mouth_rects[i].width*scale,mouth_rects[i].height*scale);
  Mat new_rect(height, width, CV_8UC1, Scalar(0));
  rectangle(new_rect, scaled, Scalar(1), CV_FILLED);
  rect_image += new_rect;
 }

 double min_val, max_val;
 minMaxLoc(rect_image, &min_val, &max_val);

// or maybe equalize? this whole thing needs to be rewritten
// with the new fg and temporal coherence ideas

 Mat rect_thresh;
 threshold(rect_image, rect_thresh, max_val*0.9, 1, THRESH_BINARY);
 imshow("mouth", rect_thresh.mul(gray));

/*
  Moments m = moments(rect_thresh, 1);
  circle(image, Point(m.m10/m.m00,m.m01/m.m00),20,Scalar(128),30);
  imshow("centroid", image);
*/

  keep_going = (waitKey(1)<0);

 }

 cvReleaseCapture(&capture);

 return 0;
}

<commit_msg>hacking<commit_after>#include "webcam.hpp"
#include <chrono>

using namespace cv;
using namespace std;

Mat ellipticKernel(int width, int height = -1) {
 if (height==-1) {
  return getStructuringElement(MORPH_ELLIPSE,Size(width,width), Point(width/2, width/2));
 } else {
  return getStructuringElement(MORPH_ELLIPSE,Size(width,height), Point(width/2, height/2));
 }
}

unsigned long long getMilliseconds() {
 return chrono::system_clock::now().time_since_epoch()/chrono::milliseconds(1);
}

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

/*****
 begin camera setup
*****/

 CvCapture* capture = 0;
 int width, height;

 capture = cvCaptureFromCAM(0);

 if (!capture) {
  printf("No camera detected!");
  return -1;
 }

 ifstream config_file (".config");

 if (config_file.is_open()) {
// does not support corrupted .config

  string line;
  getline(config_file, line);
  istringstream(line)>>width;
  getline(config_file, line);
  istringstream(line)>>height;
  cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH, width);
  cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT, height);

  config_file.close();

 } else {

  initResolutions();

  for (int i=36; i<150; i++) {
   cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH, resolutions[i].width);
   cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT, resolutions[i].height);
  }

  width = cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH);
  height = cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT);

  ofstream config_file_out(".config");
  config_file_out << width;
  config_file_out << "\n";
  config_file_out << height;
  config_file_out << "\n";
  config_file_out.close();
 }

 for (int i = 0; i < 30; i++) {
  // capture some frames so exposure correction takes place
  cvQueryFrame(capture);
 }

/*****
 end camera setup
*****/

/*****
 filter setup
*****/

 Mat acbg(256, 256, CV_8UC3, 0);
// accumulated background
 Mat acbg_m(256, 256, CV_8UC1, 0);
// accumulated background mask

 Mat acfg(256, 256, CV_8UC3, 0);
// accumulated foreground
 Mat acfg_t(256, 256, CV_8UC3, 0);
// accumulated foreground threshold

/*****
 end filter setup
*****/

/*****
 misc
*****/

 unsigned long long times[100];
 for (int i=0; i<100; i++)
  times[i] = 0;

 int tracker1, tracker2, tracker3;
 namedWindow("s",1);
 createTrackbar("1","s",&tracker1,100);
 createTrackbar("2","s",&tracker2,100);
 createTrackbar("3","s",&tracker3,100);

 unsigned long long timenow = getMilliseconds();

 bool keep_going = true;

 CascadeClassifier mouth_cascade;
 mouth_cascade.load("Mouth.xml");

/*****
 begin filter loop
*****/

 while (keep_going) {

  Mat image(cvQueryFrame(capture));
//  imshow("webcam", image);
// at some point preprocess by rotating according to OVR roll
// right now really annoying because of state variables

  Mat gray, img_256, gray_256;
  resize(image, img_256, Size(256, 256));
  cvtColor(image, gray, CV_RGB2GRAY);
  cvtColor(img_256, gray_256, CV_RGB2GRAY);

/*
// this mask gets anything kind of dark (DK2) and dilates
// should work *great*
  Mat gr_m;
// gray mask
  equalizeHist(gray_256, gr_m);
  threshold(gr_m, gr_m, 100, 1, THRESH_BINARY_INV);
  dilate(gr_m, gr_m, ellipticKernel(43));
// verify size of ellipticKernel!
  gr_m = 1 - gr_m;
// change code later so we don't have to do this

  imshow("gray mask", gray_256.mul(gr_m));

 bitwise_or(acbg_m, gr_m, acbg_m);

  imshow("accumulated bg mask", gray_256.mul(acbg_m));

/*
// this mask watches for flow against accumulated bg
 Mat fl_m;
// flow mask
 absdiff(img_256, acbg, fl_m);
// add some morphological operator? but acbg_m!
 threshold(fl_m, fl_m, 80, 1, THRESH_BINARY);
// 80, THRESH_BINARY probably needs tweaking!
// add some other morphological operators? but what about
// acbg_m?

  imshow("flow mask", gray_256.mul(fl_m));

 Mat bg_m;
 bitwise_and(acbg_m, fl_m, bg_m);
 bitwise_or(gr_m, bg_m, bg_m);
// maybe do some morphological operations on bg_m?
// previously combined bg_m with its opening

  imshow("bg mask", gray_256.mul(bg_m));
/*
 // do some stuff with foreground and so on here

 Mat haar_m;
// bitwise_and(1 - bg_m, fg_m, haar_m);
 haar_m = 1 - bg_m;

// run haar classifier
 int scale = width/300;
 if (scale < 1)
  scale = 1;
// can't use 256x256 since haar isn't stretch invariant

 Mat thingy;
 resize(gray, thingy, Size(width/scale, height/scale));
 equalizeHist(thingy, thingy);
///////////////////
// need to change this after foreground stuff gets written

 vector<Rect> mouth_rects;
 resize(haar_m, haar_m, Size(width/scale, height/scale));

 bitwise_and(haar_m, thingy, thingy);
/////////////////

 mouth_cascade.detectMultiScale(thingy, mouth_rects, 1.1, 0, CV_HAAR_SCALE_IMAGE);
 Mat rect_image(height, width, CV_8UC1, Scalar(0));

 for (size_t i=0; i<mouth_rects.size(); i++) {
  Rect scaled(mouth_rects[i].x*scale, mouth_rects[i].y*scale, mouth_rects[i].width*scale,mouth_rects[i].height*scale);
  Mat new_rect(height, width, CV_8UC1, Scalar(0));
  rectangle(new_rect, scaled, Scalar(1), CV_FILLED);
  rect_image += new_rect;
 }

 double min_val, max_val;
 minMaxLoc(rect_image, &min_val, &max_val);

// or maybe equalize? this whole thing needs to be rewritten
// with the new fg and temporal coherence ideas

 Mat rect_thresh;
 threshold(rect_image, rect_thresh, max_val*0.9, 1, THRESH_BINARY);
 imshow("mouth", rect_thresh.mul(gray));

/*
  Moments m = moments(rect_thresh, 1);
  circle(image, Point(m.m10/m.m00,m.m01/m.m00),20,Scalar(128),30);
  imshow("centroid", image);
*/

  keep_going = (waitKey(1)<0);

 }

 cvReleaseCapture(&capture);

 return 0;
}

<|endoftext|>


<commit_before>#include "internal/thread.h"
#include <cassert>
#include <chrono>
#include <iostream>
#include "engine.h"
#include "exception.h"
#include "fmt/format.h"
#include "internal/routine.h"
#include "logger.h"
#include "logger.h"
#include "semaphore.h"

namespace boson {
namespace internal {

// class engine_proxy;

engine_proxy::engine_proxy(engine& parent_engine) : engine_(&parent_engine) {
}

engine_proxy::~engine_proxy() {
}

void engine_proxy::notify_end() {
  engine_->push_command(current_thread_id_,
                        std::make_unique<engine::command>(
                            current_thread_id_, engine::command_type::notify_end_of_thread,
                            engine::command_data{nullptr}));
}

routine_id engine_proxy::get_new_routine_id() {
  return engine_->current_routine_id_++;
}

void engine_proxy::notify_idle(size_t nb_suspended_routines) {
  engine_->push_command(
      current_thread_id_,
      std::make_unique<engine::command>(current_thread_id_, engine::command_type::notify_idle,
                                        engine::command_data{nb_suspended_routines}));
}

void engine_proxy::start_routine(std::unique_ptr<routine> new_routine) {
  start_routine(engine_->max_nb_cores(), std::move(new_routine));
}

void engine_proxy::start_routine(thread_id target_thread, std::unique_ptr<routine> new_routine) {
  engine_->push_command(current_thread_id_, std::make_unique<engine::command>(
                                                target_thread, engine::command_type::add_routine,
                                                engine::command_new_routine_data{
                                                    target_thread, std::move(new_routine)}));
}

void engine_proxy::set_id() {
  current_thread_id_ = engine_->register_thread_id();
}

void thread::handle_engine_event() {
  thread_command* received_command = nullptr;
  while ((received_command = static_cast<thread_command*>(engine_queue_.pop(id())))) {
    static int sub = 0;
    // nb_pending_commands_.fetch_sub(1,std::memory_order_release);
    nb_pending_commands_.fetch_sub(1);
    switch (received_command->type) {
      case thread_command_type::add_routine:
        scheduled_routines_.emplace_back(
            received_command->data.template get<routine_ptr_t>().release());
        break;
      case thread_command_type::schedule_waiting_routine: {
        auto& t = received_command->data.template get<std::tuple<int, int, routine_ptr_t>>();
        int rid = std::get<0>(t);
        int status = std::get<1>(t);
        routine* current_routine = std::get<2>(t).release();
        assert(current_routine->status() == routine_status::wait_sema_wait);
        current_routine->expected_event_happened();
        --suspended_routines_;
        scheduled_routines_.emplace_back(current_routine);
      } break;
      case thread_command_type::finish:
        status_ = thread_status::finishing;
        break;
    }
    delete received_command;
  }
}

void thread::unregister_all_events() {
  loop_.unregister(engine_event_id_);
  loop_.unregister(self_event_id_);
}

thread::thread(engine& parent_engine)
    : engine_proxy_(parent_engine),
      loop_(*this),
      engine_queue_{static_cast<int>(parent_engine.max_nb_cores() + 1)} {
  engine_event_id_ = loop_.register_event(&engine_event_id_);
  self_event_id_ = loop_.register_event(&self_event_id_);
  engine_proxy_.set_id();  // Tells the engine which thread id we got
}

void thread::event(int event_id, void* data) {
  if (event_id == engine_event_id_) {
    handle_engine_event();
  } else if (event_id == self_event_id_) {
    // execute_scheduled_routines();
  }
}

void thread::read(int fd, void* data) {
  routine* target_routine = static_cast<routine*>(data);
  target_routine->expected_event_happened();
  --suspended_routines_;
  scheduled_routines_.emplace_back(target_routine);
}

void thread::write(int fd, void* data) {
  routine* target_routine = static_cast<routine*>(data);
  target_routine->expected_event_happened();
  --suspended_routines_;
  scheduled_routines_.emplace_back(target_routine);
}

// called by engine
void thread::push_command(thread_id from, std::unique_ptr<thread_command> command) {
  nb_pending_commands_.fetch_add(1);
  engine_queue_.push(from, command.release());
  loop_.send_event(engine_event_id_);
};

// called by engine
// void thread::execute_commands() {
//}

namespace {
inline void clear_previous_io_event(routine& routine, event_loop& loop) {
  if (routine.previous_status_is_io_block()) {
    routine_io_event& target_event = routine.waiting_data().get<routine_io_event>();
    if (0 <= target_event.event_id)
      loop.unregister(target_event.event_id);
  }
}
}

bool thread::execute_scheduled_routines() {
  decltype(scheduled_routines_) next_scheduled_routines;
  std::list<std::tuple<size_t, routine_ptr_t>> new_timed_routines_;
  while (!scheduled_routines_.empty()) {
    // For now; we schedule them in order
    auto& routine = scheduled_routines_.front();
    running_routine_ = routine.get();
    routine->resume(this);
    switch (routine->status()) {
      case routine_status::is_new: {
        // Not supposed to happen
        assert(false);
      } break;
      case routine_status::running: {
        // Not supposed to happen
        assert(false);
      } break;
      case routine_status::yielding: {
        // If not finished, then we reschedule it
        clear_previous_io_event(*routine, loop_);
        next_scheduled_routines.emplace_back(routine.release());
      } break;
      case routine_status::wait_timer: {
        clear_previous_io_event(*routine, loop_);
        auto target_data = routine->waiting_data().raw<routine_time_point>();
        timed_routines_[target_data].emplace_back(routine.release());
      } break;
      case routine_status::wait_sys_read: {
        routine_io_event& target_event = routine->waiting_data().get<routine_io_event>();
        ++suspended_routines_;
        if (!target_event.is_same_as_previous_event) {
          clear_previous_io_event(*routine, loop_);
          target_event.event_id = loop_.register_read(target_event.fd, routine.release());
        } else {
          routine.release();
        }
      } break;
      case routine_status::wait_sys_write: {
        routine_io_event& target_event = routine->waiting_data().get<routine_io_event>();
        ++suspended_routines_;
        if (!target_event.is_same_as_previous_event) {
          clear_previous_io_event(*routine, loop_);
          target_event.event_id = loop_.register_write(target_event.fd, routine.release());
        }
        else {
          routine.release();
        }
      } break;
      case routine_status::wait_sema_wait: {
        //clear_previous_io_event(*routine, loop_);
        // Routine missed the lock, lets take care it
        // debug::log("Routine {}:{}:{} is pushed", id(), routine->id(),
        // static_cast<int>(routine->status()));
        semaphore* missed_semaphore = static_cast<semaphore*>(routine->context_.data);
        missed_semaphore->get_queue(this)->push(id(), routine.release());
        // int result =
        // missed_semaphore->counter_.fetch_add(1, std::memory_order::memory_order_release);
        int result = missed_semaphore->counter_.fetch_add(1);
        // if (0 < missed_semaphore->counter_)
        // missed_semaphore->pop_a_waiter(this);
        ++suspended_routines_;
      } break;
      case routine_status::finished: {
        //clear_previous_io_event(*routine, loop_);
        // Should have been made by the routine by closing the FD
      } break;
    };

    // if (routine.get()) {
    // debug::log("Routine {}:{}:{} will be deleted.", id(), routine->id(),
    // static_cast<int>(routine->status()));
    //}
    scheduled_routines_.pop_front();
  }

  // Yielded routines are immediately scheduled
  scheduled_routines_ = std::move(next_scheduled_routines);

  // Timed routines are added in the timer list
  // This is made in two step to limit the syscall to get the current date

  // If finished and no more routines, exit
  size_t nb_pending_commands = nb_pending_commands_;
  bool no_more_routines =
      scheduled_routines_.empty() && timed_routines_.empty() && 0 == suspended_routines_;
  if (no_more_routines) {
    if (thread_status::finishing == status_) {
      unregister_all_events();
      status_ = thread_status::finished;
      return false;
    } else if (0 == nb_pending_commands) {
      engine_proxy_.notify_idle(0);
      return false;
    }
  } else {
    if (scheduled_routines_.empty()) {
      if (0 == nb_pending_commands) {
        engine_proxy_.notify_idle(timed_routines_.size() + suspended_routines_);
        return false;
      } else {
        static int fail = 0;
        // debug::log("Fail send {}", nb_pending_commands_.load());
        loop_.send_event(engine_event_id_);
        return true;
      }
    } else {
      // If some routines already are scheduled, then throw an event to force a loop execution
      //loop_.send_event(self_event_id_);
      debug::log("Has {} scheduled", scheduled_routines_.size());
      return true;
    }
  }
  return false;
}

void thread::loop() {
  using namespace std::chrono;
  current_thread() = this;

  // Check if we should have a time out
  int timeout_ms = -1;
  while (status_ != thread_status::finished) {
    auto first_timed_routines = begin(timed_routines_);
    if (0 != timeout_ms) {
      if (!timed_routines_.empty()) {
        // Compute next timeout
        timeout_ms =
            duration_cast<milliseconds>(first_timed_routines->first - high_resolution_clock::now())
                .count();
      }
    }
    auto return_code = loop_.loop(1, timeout_ms);
    switch (return_code) {
      case loop_end_reason::max_iter_reached:
        break;
      case loop_end_reason::timed_out:
        // Schedule routines that timed out
        for (auto& timed_routine : first_timed_routines->second) {
          timed_routine->expected_event_happened();
          scheduled_routines_.emplace_back(timed_routine.release());
        }
        timed_routines_.erase(first_timed_routines);
        break;
      case loop_end_reason::error_occured:
      default:
        throw exception("Boson unknown error");
        return;
    }
    // debug::log("Thread {} has {} scheduled routines.", id(), scheduled_routines_.size());
    timeout_ms = execute_scheduled_routines() ? 0 : -1;
  }

  engine_proxy_.notify_end();
  // Should not be useful, but a lil discipline does not hurt
  // current_thread = nullptr;
}

thread*& current_thread() {
  thread_local thread* cur_thread = nullptr;
  return cur_thread;
}

}  // namespace internal
}  // namespace boson
<commit_msg>Bugfix<commit_after>#include "internal/thread.h"
#include <cassert>
#include <chrono>
#include <iostream>
#include "engine.h"
#include "exception.h"
#include "fmt/format.h"
#include "internal/routine.h"
#include "logger.h"
#include "logger.h"
#include "semaphore.h"

namespace boson {
namespace internal {

// class engine_proxy;

engine_proxy::engine_proxy(engine& parent_engine) : engine_(&parent_engine) {
}

engine_proxy::~engine_proxy() {
}

void engine_proxy::notify_end() {
  engine_->push_command(current_thread_id_,
                        std::make_unique<engine::command>(
                            current_thread_id_, engine::command_type::notify_end_of_thread,
                            engine::command_data{nullptr}));
}

routine_id engine_proxy::get_new_routine_id() {
  return engine_->current_routine_id_++;
}

void engine_proxy::notify_idle(size_t nb_suspended_routines) {
  engine_->push_command(
      current_thread_id_,
      std::make_unique<engine::command>(current_thread_id_, engine::command_type::notify_idle,
                                        engine::command_data{nb_suspended_routines}));
}

void engine_proxy::start_routine(std::unique_ptr<routine> new_routine) {
  start_routine(engine_->max_nb_cores(), std::move(new_routine));
}

void engine_proxy::start_routine(thread_id target_thread, std::unique_ptr<routine> new_routine) {
  engine_->push_command(current_thread_id_, std::make_unique<engine::command>(
                                                target_thread, engine::command_type::add_routine,
                                                engine::command_new_routine_data{
                                                    target_thread, std::move(new_routine)}));
}

void engine_proxy::set_id() {
  current_thread_id_ = engine_->register_thread_id();
}

void thread::handle_engine_event() {
  thread_command* received_command = nullptr;
  while ((received_command = static_cast<thread_command*>(engine_queue_.pop(id())))) {
    static int sub = 0;
    // nb_pending_commands_.fetch_sub(1,std::memory_order_release);
    nb_pending_commands_.fetch_sub(1);
    switch (received_command->type) {
      case thread_command_type::add_routine:
        scheduled_routines_.emplace_back(
            received_command->data.template get<routine_ptr_t>().release());
        break;
      case thread_command_type::schedule_waiting_routine: {
        auto& t = received_command->data.template get<std::tuple<int, int, routine_ptr_t>>();
        int rid = std::get<0>(t);
        int status = std::get<1>(t);
        routine* current_routine = std::get<2>(t).release();
        assert(current_routine->status() == routine_status::wait_sema_wait);
        current_routine->expected_event_happened();
        --suspended_routines_;
        scheduled_routines_.emplace_back(current_routine);
      } break;
      case thread_command_type::finish:
        status_ = thread_status::finishing;
        break;
    }
    delete received_command;
  }
}

void thread::unregister_all_events() {
  loop_.unregister(engine_event_id_);
  loop_.unregister(self_event_id_);
}

thread::thread(engine& parent_engine)
    : engine_proxy_(parent_engine),
      loop_(*this),
      engine_queue_{static_cast<int>(parent_engine.max_nb_cores() + 1)} {
  engine_event_id_ = loop_.register_event(&engine_event_id_);
  self_event_id_ = loop_.register_event(&self_event_id_);
  engine_proxy_.set_id();  // Tells the engine which thread id we got
}

void thread::event(int event_id, void* data) {
  if (event_id == engine_event_id_) {
    handle_engine_event();
  } else if (event_id == self_event_id_) {
    // execute_scheduled_routines();
  }
}

void thread::read(int fd, void* data) {
  routine* target_routine = static_cast<routine*>(data);
  target_routine->expected_event_happened();
  --suspended_routines_;
  scheduled_routines_.emplace_back(target_routine);
}

void thread::write(int fd, void* data) {
  routine* target_routine = static_cast<routine*>(data);
  target_routine->expected_event_happened();
  --suspended_routines_;
  scheduled_routines_.emplace_back(target_routine);
}

// called by engine
void thread::push_command(thread_id from, std::unique_ptr<thread_command> command) {
  nb_pending_commands_.fetch_add(1);
  engine_queue_.push(from, command.release());
  loop_.send_event(engine_event_id_);
};

// called by engine
// void thread::execute_commands() {
//}

namespace {
inline void clear_previous_io_event(routine& routine, event_loop& loop) {
  if (routine.previous_status_is_io_block()) {
    routine_io_event& target_event = routine.waiting_data().get<routine_io_event>();
    if (0 <= target_event.event_id)
      loop.unregister(target_event.event_id);
  }
}
}

bool thread::execute_scheduled_routines() {
  decltype(scheduled_routines_) next_scheduled_routines;
  std::list<std::tuple<size_t, routine_ptr_t>> new_timed_routines_;
  while (!scheduled_routines_.empty()) {
    // For now; we schedule them in order
    auto& routine = scheduled_routines_.front();
    running_routine_ = routine.get();
    routine->resume(this);
    switch (routine->status()) {
      case routine_status::is_new: {
        // Not supposed to happen
        assert(false);
      } break;
      case routine_status::running: {
        // Not supposed to happen
        assert(false);
      } break;
      case routine_status::yielding: {
        // If not finished, then we reschedule it
        clear_previous_io_event(*routine, loop_);
        next_scheduled_routines.emplace_back(routine.release());
      } break;
      case routine_status::wait_timer: {
        clear_previous_io_event(*routine, loop_);
        auto target_data = routine->waiting_data().raw<routine_time_point>();
        timed_routines_[target_data].emplace_back(routine.release());
      } break;
      case routine_status::wait_sys_read: {
        routine_io_event& target_event = routine->waiting_data().get<routine_io_event>();
        ++suspended_routines_;
        if (!target_event.is_same_as_previous_event) {
          clear_previous_io_event(*routine, loop_);
          target_event.event_id = loop_.register_read(target_event.fd, routine.release());
        } else {
          routine.release();
        }
      } break;
      case routine_status::wait_sys_write: {
        routine_io_event& target_event = routine->waiting_data().get<routine_io_event>();
        ++suspended_routines_;
        if (!target_event.is_same_as_previous_event) {
          clear_previous_io_event(*routine, loop_);
          target_event.event_id = loop_.register_write(target_event.fd, routine.release());
        }
        else {
          routine.release();
        }
      } break;
      case routine_status::wait_sema_wait: {
        //clear_previous_io_event(*routine, loop_);
        // Routine missed the lock, lets take care it
        // debug::log("Routine {}:{}:{} is pushed", id(), routine->id(),
        // static_cast<int>(routine->status()));
        semaphore* missed_semaphore = static_cast<semaphore*>(routine->context_.data);
        missed_semaphore->get_queue(this)->push(id(), routine.release());
        // int result =
        // missed_semaphore->counter_.fetch_add(1, std::memory_order::memory_order_release);
        int result = missed_semaphore->counter_.fetch_add(1);
        if (0 <= result) {
          missed_semaphore->pop_a_waiter(this);
        }
        // if (0 < missed_semaphore->counter_)
        ++suspended_routines_;
      } break;
      case routine_status::finished: {
        //clear_previous_io_event(*routine, loop_);
        // Should have been made by the routine by closing the FD
      } break;
    };

    // if (routine.get()) {
    // debug::log("Routine {}:{}:{} will be deleted.", id(), routine->id(),
    // static_cast<int>(routine->status()));
    //}
    scheduled_routines_.pop_front();
  }

  // Yielded routines are immediately scheduled
  scheduled_routines_ = std::move(next_scheduled_routines);

  // Timed routines are added in the timer list
  // This is made in two step to limit the syscall to get the current date

  // If finished and no more routines, exit
  size_t nb_pending_commands = nb_pending_commands_;
  bool no_more_routines =
      scheduled_routines_.empty() && timed_routines_.empty() && 0 == suspended_routines_;
  if (no_more_routines) {
    if (thread_status::finishing == status_) {
      unregister_all_events();
      status_ = thread_status::finished;
      return false;
    } else if (0 == nb_pending_commands) {
      engine_proxy_.notify_idle(0);
      return false;
    }
  } else {
    if (scheduled_routines_.empty()) {
      if (0 == nb_pending_commands) {
        engine_proxy_.notify_idle(timed_routines_.size() + suspended_routines_);
        return false;
      } else {
        static int fail = 0;
        // debug::log("Fail send {}", nb_pending_commands_.load());
        loop_.send_event(engine_event_id_);
        return true;
      }
    } else {
      // If some routines already are scheduled, then throw an event to force a loop execution
      //loop_.send_event(self_event_id_);
      debug::log("Has {} scheduled", scheduled_routines_.size());
      return true;
    }
  }
  return false;
}

void thread::loop() {
  using namespace std::chrono;
  current_thread() = this;

  // Check if we should have a time out
  int timeout_ms = -1;
  while (status_ != thread_status::finished) {
    auto first_timed_routines = begin(timed_routines_);
    if (0 != timeout_ms) {
      if (!timed_routines_.empty()) {
        // Compute next timeout
        timeout_ms =
            duration_cast<milliseconds>(first_timed_routines->first - high_resolution_clock::now())
                .count();
      }
    }
    auto return_code = loop_.loop(1, timeout_ms);
    switch (return_code) {
      case loop_end_reason::max_iter_reached:
        break;
      case loop_end_reason::timed_out:
        // Schedule routines that timed out
        for (auto& timed_routine : first_timed_routines->second) {
          timed_routine->expected_event_happened();
          scheduled_routines_.emplace_back(timed_routine.release());
        }
        timed_routines_.erase(first_timed_routines);
        break;
      case loop_end_reason::error_occured:
      default:
        throw exception("Boson unknown error");
        return;
    }
    // debug::log("Thread {} has {} scheduled routines.", id(), scheduled_routines_.size());
    timeout_ms = execute_scheduled_routines() ? 0 : -1;
  }

  engine_proxy_.notify_end();
  // Should not be useful, but a lil discipline does not hurt
  // current_thread = nullptr;
}

thread*& current_thread() {
  thread_local thread* cur_thread = nullptr;
  return cur_thread;
}

}  // namespace internal
}  // namespace boson
<|endoftext|>


<commit_before>#include "Iop_Modload.h"
#include "IopBios.h"
#include "../Log.h"

using namespace Iop;

#define LOG_NAME		("iop_modload")

CModload::CModload(CIopBios& bios, uint8* ram)
: m_bios(bios)
, m_ram(ram)
{

}

CModload::~CModload()
{

}

std::string CModload::GetId() const
{
	return "modload";
}

std::string CModload::GetFunctionName(unsigned int functionId) const
{
	return "unknown";
}

void CModload::Invoke(CMIPS& context, unsigned int functionId)
{
	switch(functionId)
	{
	case 7:
		context.m_State.nGPR[CMIPS::V0].nD0 = static_cast<int32>(LoadStartModule(
			reinterpret_cast<const char*>(&m_ram[context.m_State.nGPR[CMIPS::A0].nV0]),
			context.m_State.nGPR[CMIPS::A1].nV0,
			reinterpret_cast<const char*>(&m_ram[context.m_State.nGPR[CMIPS::A2].nV0]),
			reinterpret_cast<uint32*>(&m_ram[context.m_State.nGPR[CMIPS::A3].nV0])
			));
		break;
	default:
		CLog::GetInstance().Print(LOG_NAME, "(%0.8X): Unknown function (%d) called.\r\n",
			context.m_State.nPC, functionId);
		break;
	}
}

uint32 CModload::LoadStartModule(const char* path, uint32 argsLength, const char* args, uint32* result)
{
	try
	{
		m_bios.LoadAndStartModule(path, args, argsLength);
	}
	catch(const std::exception& except)
	{
		CLog::GetInstance().Print(LOG_NAME, "Error occured while trying to load module '%s' : %s\r\n",
			path, except.what());
	}
	return 0;
}
<commit_msg>Added function names for some of modload's functions.<commit_after>#include "Iop_Modload.h"
#include "IopBios.h"
#include "../Log.h"

using namespace Iop;

#define LOG_NAME		("iop_modload")

CModload::CModload(CIopBios& bios, uint8* ram)
: m_bios(bios)
, m_ram(ram)
{

}

CModload::~CModload()
{

}

std::string CModload::GetId() const
{
	return "modload";
}

std::string CModload::GetFunctionName(unsigned int functionId) const
{
	switch(functionId)
	{
	case 7:
		return "LoadStartModule";
		break;
	case 8:
		return "StartModule";
		break;
	case 10:
		return "LoadModuleBuffer";
		break;
	case 16:
		return "GetModuleIdList";
		break;
	case 17:
		return "ReferModuleStatus";
		break;
	default:
		return "unknown";
		break;
	}
}

void CModload::Invoke(CMIPS& context, unsigned int functionId)
{
	switch(functionId)
	{
	case 7:
		context.m_State.nGPR[CMIPS::V0].nD0 = static_cast<int32>(LoadStartModule(
			reinterpret_cast<const char*>(&m_ram[context.m_State.nGPR[CMIPS::A0].nV0]),
			context.m_State.nGPR[CMIPS::A1].nV0,
			reinterpret_cast<const char*>(&m_ram[context.m_State.nGPR[CMIPS::A2].nV0]),
			reinterpret_cast<uint32*>(&m_ram[context.m_State.nGPR[CMIPS::A3].nV0])
			));
		break;
	default:
		CLog::GetInstance().Print(LOG_NAME, "(%0.8X): Unknown function (%d) called.\r\n",
			context.m_State.nPC, functionId);
		break;
	}
}

uint32 CModload::LoadStartModule(const char* path, uint32 argsLength, const char* args, uint32* result)
{
	try
	{
		m_bios.LoadAndStartModule(path, args, argsLength);
	}
	catch(const std::exception& except)
	{
		CLog::GetInstance().Print(LOG_NAME, "Error occured while trying to load module '%s' : %s\r\n",
			path, except.what());
	}
	return 0;
}
<|endoftext|>


<commit_before>
<commit_msg>ready to drive?<commit_after>#include "Timer.h"
#include "Navio/PWM.h"
#include "Navio/RCInput.h"
#include "Navio/RGBled.h"
#include "Navio/Util.h"
#include <algorithm>
#include <limits.h>
#include <stdlib.h>
#include <time.h>

static const int inpThrottle = 0,  minThrottle = 1120,  maxThrottle = 1880;
static const int inpRoll     = 1,  rightRoll   = 1110,  leftRoll    = 1890;
static const int inpPitch    = 2,  upPitch     = 1110,  downPitch   = 1890;
static const int inpYaw      = 3,  rightYaw    = 1110,  leftYaw     = 1890;

static const int inpCenter  = 1500;
static const int inpCenterR = 5;

static const int outTiltCamera = 0;
static const int outLeftMotor  = 1;
static const int outRightMotor = 2;
static const int outPanCamera  = 3;

static const float outMin     = 1.;
static const float outNeutral = 1.5;
static const float outMax     = 2.;

static const int refreshRate = 30;

static void InitPWMChannel(PWM& pwm, int ch) {
    pwm.init(ch);
    pwm.enable(ch);
    pwm.set_period(ch, 50);
}

int main(int /*argc*/, char** /*argv*/) {
    if (! check_apm()) {
        system("sudo modprobe bcm2835-v4l2");

        PWM pwm;
        RCInput rc;
        Timer timer;

        InitPWMChannel(pwm, outLeftMotor);
        InitPWMChannel(pwm, outRightMotor);
        rc.init();

        timer.Start();
        for (;;) {

            int steer = rc.read(inpRoll);
            float rightSteerScale = std::min(std::max(-1., 2. * (steer - rightRoll) / (inpCenter - inpCenterR - rightRoll) - 1.), 1.);
            float leftSteerScale  = std::min(std::max(-1., 2. * (steer - leftRoll)  / (inpCenter + inpCenterR - leftRoll ) - 1.), 1.);
            float throttleScale = float(rc.read(inpThrottle) - minThrottle) / (maxThrottle - minThrottle);

            pwm.set_duty_cycle(outLeftMotor,   leftSteerScale * throttleScale * (outMax - outNeutral) + outNeutral);
            pwm.set_duty_cycle(outRightMotor, rightSteerScale * throttleScale * (outMax - outNeutral) + outNeutral);

            struct timespec sleep = {0, 1000 * timer.NextSleep(refreshRate, INT_MAX)};
            if (sleep.tv_nsec > 0) {
                nanosleep(&sleep, NULL);
            }
        }
    }
    return 0;
}
<|endoftext|>


<commit_before>// Copyright 2010-2012 RethinkDB, all rights reserved.
#ifndef ERRORS_HPP_
#define ERRORS_HPP_

#include <errno.h>
#include <stdlib.h>

#ifndef DISABLE_BREAKPOINTS
#ifdef __linux__
#if defined __i386 || defined __x86_64
#define BREAKPOINT __asm__ volatile ("int3")
#else   /* not x86/amd64 */
#define BREAKPOINT raise(SIGTRAP)
#endif  /* x86/amd64 */
#endif /* __linux__ */

#ifdef __MACH__
#define BREAKPOINT raise(SIGTRAP)
#endif
#else /* Breakpoints Disabled */
#define BREAKPOINT
#endif /* DISABLE_BREAKPOINTS */

#define CT_ASSERT(e) {enum { compile_time_assert_error = 1/(!!(e)) };}

#ifndef NDEBUG
#define DEBUG_ONLY(...) __VA_ARGS__
#define DEBUG_ONLY_CODE(expr) do { expr; } while (0)
#else
#define DEBUG_ONLY(...)
#define DEBUG_ONLY_CODE(expr) ((void)(0))
#endif

/* This macro needs to exist because gcc and icc disagree on how to number the
 * attributes to methods. ICC does different number for methods and functions
 * and it's too unwieldy to make programs use these macros so we're just going
 * to disable them in icc.
 * With this macro attribute number starts at 1. If it is a nonstatic method
 * then "1" refers to the class pointer ("this").
 * */
#ifdef __ICC
#define NON_NULL_ATTR(arg)
#else
#define NON_NULL_ATTR(arg) __attribute__((nonnull(arg)))
#endif

#define NORETURN __attribute__((noreturn))

/* Error handling
 *
 * There are several ways to report errors in RethinkDB:
 *  fail_due_to_user_error(msg, ...)    fail and report line number/stack trace. Should only be used when the user
 *                                      is at fault (e.g. provided wrong database file name) and it is reasonable to
 *                                      fail instead of handling the problem more gracefully.
 *
 *  The following macros are used only for the cases of programmer error checking. For the time being they are also used
 *  for system error checking (especially the *_err variants).
 *
 *  crash(msg, ...)                 always fails and reports line number and such. Never returns.
 *  crash_or_trap(msg, ...)         same as above, but traps into debugger if it is present instead of terminating.
 *                                  That means that it possibly can return, and one can continue stepping through the code in the debugger.
 *                                  All off the rassert/guarantee functions use crash_or_trap.
 *  rassert(cond)                   makes sure cond is true and is a no-op in release mode
 *  rassert(cond, msg, ...)         ditto, with additional message and possibly some arguments used for formatting
 *  rassert_err(cond)               same as rassert(cond), but also print errno error description
 *  rassert_err(cond, msg, ...)     same as rassert(cond, msg, ...), but also print errno error description
 *  guarantee(cond)                 same as rassert(cond), but the check is still done in release mode. Do not use for expensive checks!
 *  guarantee(cond, msg, ...)       same as rassert(cond, msg, ...), but the check is still done in release mode. Do not use for expensive checks!
 *  guarantee_err(cond)             same as guarantee(cond), but also print errno error description
 *  guarantee_err(cond, msg, ...)   same as guarantee(cond, msg, ...), but also print errno error description
 *  guarantee_xerr(cond, err, msg, ...) same as guarantee_err(cond, msg, ...), but also allows to specify errno as err argument
 *                                  (useful for async io functions, which return negated errno)
 *
 * The names rassert* are used instead of assert* because /usr/include/assert.h undefines assert macro and redefines it with its own version
 * every single time it gets included.
 */

#ifndef NDEBUG
#define DEBUG_VAR
#else
#define DEBUG_VAR __attribute__((unused))
#endif

#define UNUSED __attribute__((unused))
#define MUST_USE __attribute__((warn_unused_result))

#define fail_due_to_user_error(msg, ...) do {  \
        report_user_error(msg, ##__VA_ARGS__); \
        BREAKPOINT;                            \
        exit(EXIT_FAILURE);                    \
    } while (0)

#define crash(msg, ...) do {                                        \
        report_fatal_error(__FILE__, __LINE__, msg, ##__VA_ARGS__); \
        BREAKPOINT; /* this used to be abort(), but it didn't cause VALGRIND to print a backtrace */ \
        abort();                                                    \
    } while (0)

#define nice_crash(...) do {          \
        fprintf(stderr, __VA_ARGS__); \
        exit(EXIT_FAILURE);           \
    } while (0)

#define crash_or_trap(msg, ...) do {                                \
        report_fatal_error(__FILE__, __LINE__, msg, ##__VA_ARGS__); \
        BREAKPOINT;                                                 \
    } while (0)

void report_fatal_error(const char*, int, const char*, ...) __attribute__((format (printf, 3, 4)));
void report_user_error(const char*, ...) __attribute__((format (printf, 1, 2)));

#define stringify(x) #x

#define format_assert_message(assert_type, cond) assert_type " failed: [" stringify(cond) "] "
#define guarantee(cond, msg...) do {    \
        if (!(cond)) {                  \
            crash_or_trap(format_assert_message("Guarantee", cond) msg); \
        }                               \
    } while (0)

#define nice_guarantee(cond, msg, ...) do { \
        if (!(cond)) {                      \
            nice_crash(msg, ##__VA_ARGS__); \
        }                                   \
    } while (0)

#define guarantee_xerr(cond, err, msg, args...) do {                            \
        if (!(cond)) {                                                          \
            if (err == 0) {                                                     \
                crash_or_trap(format_assert_message("Guarantee", cond) msg, ##args); \
            } else {                                                            \
                crash_or_trap(format_assert_message("Guarantee", cond) " (errno %d - %s) " msg, err, strerror(err), ##args);  \
            }                                                                   \
        }                                                                       \
    } while (0)
#define guarantee_err(cond, msg, args...) guarantee_xerr(cond, errno, msg, ##args)

#define unreachable(msg, ...) crash("Unreachable code: " msg, ##__VA_ARGS__)    // can't use crash_or_trap since code needs to depend on its noreturn property
#define not_implemented(msg, ...) crash_or_trap("Not implemented: " msg, ##__VA_ARGS__)

#ifdef NDEBUG
#define rassert(cond, msg...) ((void)(0))
#define rassert_err(cond, msg...) ((void)(0))
#else
#define rassert(cond, msg...) do {                                        \
        if (!(cond)) {                                                    \
            crash_or_trap(format_assert_message("Assertion", cond) msg);  \
        }                                                                 \
    } while (0)
#define rassert_err(cond, msg, args...) do {                                \
        if (!(cond)) {                                                      \
            if (errno == 0) {                                               \
                crash_or_trap(format_assert_message("Assert", cond) msg);   \
            } else {                                                        \
                crash_or_trap(format_assert_message("Assert", cond) " (errno %d - %s) " msg, errno, strerror(errno), ##args);  \
            }                                                               \
        }                                                                   \
    } while (0)
#endif

void install_generic_crash_handler();

// If you include errors.hpp before including a Boost library, then Boost assertion
// failures will be forwarded to the RethinkDB error mechanism.
#define BOOST_ENABLE_ASSERT_HANDLER
namespace boost {
void assertion_failed(char const * expr, char const * function, char const * file, long line);  // NOLINT(runtime/int)
}

void mcheck_init(void);
void mcheck_all(void);

// put this in a private: section.
#define DISABLE_COPYING(T)                      \
    T(const T&);                                \
    void operator=(const T&)

/* Put these after functions to indicate what they throw. In release mode, they
turn into noops so that the compiler doesn't have to generate exception-checking
code everywhere. If you need to add an exception specification for compatibility
with e.g. a virtual method, don't use these, or your code won't compile in
release mode. */
#ifdef NDEBUG
#define THROWS_NOTHING
#define THROWS_ONLY(...)
#else
#define THROWS_NOTHING throw ()
#define THROWS_ONLY(...) throw (__VA_ARGS__)
#endif

#endif /* ERRORS_HPP_ */
<commit_msg>Added signal.h to errors.hpp.<commit_after>// Copyright 2010-2012 RethinkDB, all rights reserved.
#ifndef ERRORS_HPP_
#define ERRORS_HPP_

#include <errno.h>
#include <signal.h>
#include <stdlib.h>

#ifndef DISABLE_BREAKPOINTS
#ifdef __linux__
#if defined __i386 || defined __x86_64
#define BREAKPOINT __asm__ volatile ("int3")
#else   /* not x86/amd64 */
#define BREAKPOINT raise(SIGTRAP)
#endif  /* x86/amd64 */
#endif /* __linux__ */

#ifdef __MACH__
#define BREAKPOINT raise(SIGTRAP)
#endif
#else /* Breakpoints Disabled */
#define BREAKPOINT
#endif /* DISABLE_BREAKPOINTS */

#define CT_ASSERT(e) {enum { compile_time_assert_error = 1/(!!(e)) };}

#ifndef NDEBUG
#define DEBUG_ONLY(...) __VA_ARGS__
#define DEBUG_ONLY_CODE(expr) do { expr; } while (0)
#else
#define DEBUG_ONLY(...)
#define DEBUG_ONLY_CODE(expr) ((void)(0))
#endif

/* This macro needs to exist because gcc and icc disagree on how to number the
 * attributes to methods. ICC does different number for methods and functions
 * and it's too unwieldy to make programs use these macros so we're just going
 * to disable them in icc.
 * With this macro attribute number starts at 1. If it is a nonstatic method
 * then "1" refers to the class pointer ("this").
 * */
#ifdef __ICC
#define NON_NULL_ATTR(arg)
#else
#define NON_NULL_ATTR(arg) __attribute__((nonnull(arg)))
#endif

#define NORETURN __attribute__((noreturn))

/* Error handling
 *
 * There are several ways to report errors in RethinkDB:
 *  fail_due_to_user_error(msg, ...)    fail and report line number/stack trace. Should only be used when the user
 *                                      is at fault (e.g. provided wrong database file name) and it is reasonable to
 *                                      fail instead of handling the problem more gracefully.
 *
 *  The following macros are used only for the cases of programmer error checking. For the time being they are also used
 *  for system error checking (especially the *_err variants).
 *
 *  crash(msg, ...)                 always fails and reports line number and such. Never returns.
 *  crash_or_trap(msg, ...)         same as above, but traps into debugger if it is present instead of terminating.
 *                                  That means that it possibly can return, and one can continue stepping through the code in the debugger.
 *                                  All off the rassert/guarantee functions use crash_or_trap.
 *  rassert(cond)                   makes sure cond is true and is a no-op in release mode
 *  rassert(cond, msg, ...)         ditto, with additional message and possibly some arguments used for formatting
 *  rassert_err(cond)               same as rassert(cond), but also print errno error description
 *  rassert_err(cond, msg, ...)     same as rassert(cond, msg, ...), but also print errno error description
 *  guarantee(cond)                 same as rassert(cond), but the check is still done in release mode. Do not use for expensive checks!
 *  guarantee(cond, msg, ...)       same as rassert(cond, msg, ...), but the check is still done in release mode. Do not use for expensive checks!
 *  guarantee_err(cond)             same as guarantee(cond), but also print errno error description
 *  guarantee_err(cond, msg, ...)   same as guarantee(cond, msg, ...), but also print errno error description
 *  guarantee_xerr(cond, err, msg, ...) same as guarantee_err(cond, msg, ...), but also allows to specify errno as err argument
 *                                  (useful for async io functions, which return negated errno)
 *
 * The names rassert* are used instead of assert* because /usr/include/assert.h undefines assert macro and redefines it with its own version
 * every single time it gets included.
 */

#ifndef NDEBUG
#define DEBUG_VAR
#else
#define DEBUG_VAR __attribute__((unused))
#endif

#define UNUSED __attribute__((unused))
#define MUST_USE __attribute__((warn_unused_result))

#define fail_due_to_user_error(msg, ...) do {  \
        report_user_error(msg, ##__VA_ARGS__); \
        BREAKPOINT;                            \
        exit(EXIT_FAILURE);                    \
    } while (0)

#define crash(msg, ...) do {                                        \
        report_fatal_error(__FILE__, __LINE__, msg, ##__VA_ARGS__); \
        BREAKPOINT; /* this used to be abort(), but it didn't cause VALGRIND to print a backtrace */ \
        abort();                                                    \
    } while (0)

#define nice_crash(...) do {          \
        fprintf(stderr, __VA_ARGS__); \
        exit(EXIT_FAILURE);           \
    } while (0)

#define crash_or_trap(msg, ...) do {                                \
        report_fatal_error(__FILE__, __LINE__, msg, ##__VA_ARGS__); \
        BREAKPOINT;                                                 \
    } while (0)

void report_fatal_error(const char*, int, const char*, ...) __attribute__((format (printf, 3, 4)));
void report_user_error(const char*, ...) __attribute__((format (printf, 1, 2)));

#define stringify(x) #x

#define format_assert_message(assert_type, cond) assert_type " failed: [" stringify(cond) "] "
#define guarantee(cond, msg...) do {    \
        if (!(cond)) {                  \
            crash_or_trap(format_assert_message("Guarantee", cond) msg); \
        }                               \
    } while (0)

#define nice_guarantee(cond, msg, ...) do { \
        if (!(cond)) {                      \
            nice_crash(msg, ##__VA_ARGS__); \
        }                                   \
    } while (0)

#define guarantee_xerr(cond, err, msg, args...) do {                            \
        if (!(cond)) {                                                          \
            if (err == 0) {                                                     \
                crash_or_trap(format_assert_message("Guarantee", cond) msg, ##args); \
            } else {                                                            \
                crash_or_trap(format_assert_message("Guarantee", cond) " (errno %d - %s) " msg, err, strerror(err), ##args);  \
            }                                                                   \
        }                                                                       \
    } while (0)
#define guarantee_err(cond, msg, args...) guarantee_xerr(cond, errno, msg, ##args)

#define unreachable(msg, ...) crash("Unreachable code: " msg, ##__VA_ARGS__)    // can't use crash_or_trap since code needs to depend on its noreturn property
#define not_implemented(msg, ...) crash_or_trap("Not implemented: " msg, ##__VA_ARGS__)

#ifdef NDEBUG
#define rassert(cond, msg...) ((void)(0))
#define rassert_err(cond, msg...) ((void)(0))
#else
#define rassert(cond, msg...) do {                                        \
        if (!(cond)) {                                                    \
            crash_or_trap(format_assert_message("Assertion", cond) msg);  \
        }                                                                 \
    } while (0)
#define rassert_err(cond, msg, args...) do {                                \
        if (!(cond)) {                                                      \
            if (errno == 0) {                                               \
                crash_or_trap(format_assert_message("Assert", cond) msg);   \
            } else {                                                        \
                crash_or_trap(format_assert_message("Assert", cond) " (errno %d - %s) " msg, errno, strerror(errno), ##args);  \
            }                                                               \
        }                                                                   \
    } while (0)
#endif

void install_generic_crash_handler();

// If you include errors.hpp before including a Boost library, then Boost assertion
// failures will be forwarded to the RethinkDB error mechanism.
#define BOOST_ENABLE_ASSERT_HANDLER
namespace boost {
void assertion_failed(char const * expr, char const * function, char const * file, long line);  // NOLINT(runtime/int)
}

void mcheck_init(void);
void mcheck_all(void);

// put this in a private: section.
#define DISABLE_COPYING(T)                      \
    T(const T&);                                \
    void operator=(const T&)

/* Put these after functions to indicate what they throw. In release mode, they
turn into noops so that the compiler doesn't have to generate exception-checking
code everywhere. If you need to add an exception specification for compatibility
with e.g. a virtual method, don't use these, or your code won't compile in
release mode. */
#ifdef NDEBUG
#define THROWS_NOTHING
#define THROWS_ONLY(...)
#else
#define THROWS_NOTHING throw ()
#define THROWS_ONLY(...) throw (__VA_ARGS__)
#endif

#endif /* ERRORS_HPP_ */
<|endoftext|>


<commit_before>/*=========================================================================

  Program:   Visualization Library
  Module:    Glyph3D.cc
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

Description:
---------------------------------------------------------------------------
This file is part of the Visualization Library. No part of this file
or its contents may be copied, reproduced or altered in any way
without the express written consent of the authors.

Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen 1993, 1994

=========================================================================*/
#include "Glyph3D.hh"
#include "Trans.hh"
#include "FVectors.hh"
#include "FNormals.hh"
#include "vlMath.hh"

// Description
// Construct object with scaling on, scaling mode is by scalar value,
// scale factor = 1.0, the range is (0,1), orient geometry is on, and
// orientation is by vector.
vlGlyph3D::vlGlyph3D()
{
  this->Source = NULL;
  this->Scaling = 1;
  this->ScaleMode = SCALE_BY_SCALAR;
  this->ScaleFactor = 1.0;
  this->Range[0] = 0.0;
  this->Range[1] = 1.0;
  this->Orient = 1;
  this->VectorMode = USE_VECTOR;
}

vlGlyph3D::~vlGlyph3D()
{
  if (this->Source)
    {
    this->Source->UnRegister(this);
    }
}

void vlGlyph3D::PrintSelf(ostream& os, vlIndent indent)
{
  if (this->ShouldIPrint(vlGlyph3D::GetClassName()))
    {
    vlDataSetToPolyFilter::PrintSelf(os,indent);

    os << indent << "Source: " << this->Source << "\n";
    os << indent << "Scaling: " << (this->Scaling ? "On\n" : "Off\n");
    os << indent << "Scale Mode: " << (this->ScaleMode == SCALE_BY_SCALAR ? "Scale by scalar\n" : "Scale by vector\n");
    os << indent << "Scale Factor: " << this->ScaleFactor << "\n";
    os << indent << "Range: (" << this->Range[0] << ", " << this->Range[1] << ")\n";
    os << indent << "Orient: " << (this->Orient ? "On\n" : "Off\n");

    os << indent << "Orient Mode: " << (this->VectorMode == USE_VECTOR ? "Orient by vector\n" : "Orient by normal\n");
    }
}

void vlGlyph3D::Execute()
{
  vlPointData *pd;
  vlScalars *inScalars;
  vlVectors *inVectors;
  vlNormals *inNormals, *sourceNormals;
  int numPts, numSourcePts, numSourceCells;
  int inPtId, i;
  vlPoints *sourcePts;
  vlCellArray *sourceCells;
  vlFloatPoints *newPts;
  vlFloatScalars *newScalars=NULL;
  vlFloatVectors *newVectors=NULL;
  vlFloatNormals *newNormals=NULL;
  float *x, s, *v, vNew[3];
  vlTransform trans;
  vlCell *cell;
  vlIdList *cellPts;
  int npts, pts[MAX_CELL_SIZE];
  int orient, scaleSource, ptIncr, cellId;
  float scale, den;
  vlMath math;
//
// Initialize
//
  this->Initialize();

  pd = this->Input->GetPointData();
  inScalars = pd->GetScalars();
  inVectors = pd->GetVectors();
  inNormals = pd->GetNormals();

  numPts = this->Input->GetNumberOfPoints();
//
// Allocate storage for output PolyData
//
  sourcePts = this->Source->GetPoints();
  numSourcePts = sourcePts->GetNumberOfPoints();
  numSourceCells = this->Source->GetNumberOfCells();
  sourceNormals = this->Source->GetPointData()->GetNormals();

  newPts = new vlFloatPoints(numPts*numSourcePts);
  if (inScalars != NULL)
    newScalars = new vlFloatScalars(numPts*numSourcePts);
  if (inVectors != NULL || inNormals != NULL )
    newVectors = new vlFloatVectors(numPts*numSourcePts);
  if (sourceNormals != NULL)
    newNormals = new vlFloatNormals(numPts*numSourcePts);

  // Setting up for calls to PolyData::InsertNextCell()
  if ( (sourceCells=this->Source->GetVerts())->GetNumberOfCells() > 0 )
    {
    this->SetVerts(new vlCellArray(numPts*sourceCells->GetSize()));
    }
  if ( (sourceCells=this->Source->GetLines())->GetNumberOfCells() > 0 )
    {
    this->SetLines(new vlCellArray(numPts*sourceCells->GetSize()));
    }
  if ( (sourceCells=this->Source->GetPolys())->GetNumberOfCells() > 0 )
    {
    this->SetPolys(new vlCellArray(numPts*sourceCells->GetSize()));
    }
  if ( (sourceCells=this->Source->GetStrips())->GetNumberOfCells() > 0 )
    {
    this->SetStrips(new vlCellArray(numPts*sourceCells->GetSize()));
    }
//
// Copy (input scalars) to (output scalars) and either (input vectors or
// normals) to (output vectors). All other point attributes are copied
// from Source.
//
  pd = this->Source->GetPointData();
  this->PointData.CopyScalarsOff();
  this->PointData.CopyVectorsOff();
  this->PointData.CopyNormalsOff();
  this->PointData.CopyAllocate(pd,numPts*numSourcePts);
//
// First copy all topology (transformation independent)
//
  for (inPtId=0; inPtId < numPts; inPtId++)
    {
    ptIncr = inPtId * numSourcePts;
    for (cellId=0; cellId < numSourceCells; cellId++)
      {
      cell = this->Source->GetCell(cellId);
      cellPts = cell->GetPointIds();
      npts = cellPts->GetNumberOfIds();
      for (i=0; i < npts; i++) pts[i] = cellPts->GetId(i) + ptIncr;
      this->InsertNextCell(cell->GetCellType(),npts,pts);
      }
    }
//
// Traverse all Input points, transforming Source points and copying
// point attributes.
//
  if ( this->VectorMode == USE_VECTOR && inVectors != NULL ||
  this->VectorMode == USE_NORMAL && inNormals != NULL )
    orient = 1;
  else
    orient = 0;

  if ( this->Scaling &&
  ((this->ScaleMode == SCALE_BY_SCALAR && inScalars != NULL) ||
  (this->ScaleMode == SCALE_BY_VECTOR && (inVectors || inNormals))) )
    scaleSource = 1;
  else
    scaleSource = 0;

  for (inPtId=0; inPtId < numPts; inPtId++)
    {
    ptIncr = inPtId * numSourcePts;

    trans.Identity();

    // translate Source to Input point
    x = this->Input->GetPoint(inPtId);
    trans.Translate(x[0], x[1], x[2]);

    if ( this->VectorMode == USE_NORMAL )
      v = inNormals->GetNormal(inPtId);
    else
      v = inVectors->GetVector(inPtId);
    scale = math.Norm(v);

    if ( orient )
      {
      // Copy Input vector
      for (i=0; i < numSourcePts; i++)
        newVectors->InsertVector(ptIncr+i,v);

      if ( this->Orient )
        {
        vNew[0] = (v[0]+scale) / 2.0;
        vNew[1] = v[1] / 2.0;
        vNew[2] = v[2] / 2.0;
        trans.RotateWXYZ(180.0,vNew[0],vNew[1],vNew[2]);
        }
      }

    // determine scale factor from scalars if appropriate
    if ( inScalars != NULL )
      {
      // Copy Input scalar
      for (i=0; i < numSourcePts; i++)
        newScalars->InsertScalar(ptIncr+i,scale);

      if ( this->ScaleMode == SCALE_BY_SCALAR )
        {
        if ( (den = this->Range[1] - this->Range[0]) == 0.0 ) den = 1.0;
        scale = inScalars->GetScalar(inPtId);

        scale = (scale < this->Range[0] ? this->Range[0] :
                 (scale > this->Range[1] ? this->Range[1] : scale));
        scale = (scale - this->Range[0]) / den;

        }
      }

    // scale data if appropriate
    if ( scaleSource )
      {
      scale *= this->ScaleFactor;
      if ( scale == 0,0 ) scale = 1.0e-10;
      trans.Scale(scale,scale,scale);
      }

    // multiply points and normals by resulting matrix
    trans.MultiplyPoints(sourcePts,newPts);
    if ( sourceNormals != NULL )
      trans.MultiplyNormals(sourceNormals,newNormals);

    // Copy point data from source
    for (i=0; i < numSourcePts; i++)
      this->PointData.CopyData(pd,i,ptIncr+i);
    }
//
// Update ourselves
//
  this->SetPoints(newPts);
  this->PointData.SetScalars(newScalars);
  this->PointData.SetVectors(newVectors);
  this->PointData.SetNormals(newNormals);
  this->Squeeze();
}

// Description:
// Override update method because execution can branch two ways (Input
// and Source)

void vlGlyph3D::Update()
{
  // make sure input is available
  if ( this->Input == NULL )
    {
    vlErrorMacro(<< "No input!");
    return;
    }

  if ( this->Source == NULL )
    {
    vlErrorMacro(<< "No data to copy");
    return;
    }

  // prevent chasing our tail
  if (this->Updating) return;

  this->Updating = 1;
  this->Input->Update();
  this->Source->Update();
  this->Updating = 0;

  if (this->Input->GetMTime() > this->GetMTime() || this->GetMTime() > this->ExecuteTime )
    {
    if ( this->StartMethod ) (*this->StartMethod)();
    this->Execute();
    this->ExecuteTime.Modified();
    if ( this->EndMethod ) (*this->EndMethod)();
    }
}
<commit_msg>ERR: Fixed type.<commit_after>/*=========================================================================

  Program:   Visualization Library
  Module:    Glyph3D.cc
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

Description:
---------------------------------------------------------------------------
This file is part of the Visualization Library. No part of this file
or its contents may be copied, reproduced or altered in any way
without the express written consent of the authors.

Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen 1993, 1994

=========================================================================*/
#include "Glyph3D.hh"
#include "Trans.hh"
#include "FVectors.hh"
#include "FNormals.hh"
#include "vlMath.hh"

// Description
// Construct object with scaling on, scaling mode is by scalar value,
// scale factor = 1.0, the range is (0,1), orient geometry is on, and
// orientation is by vector.
vlGlyph3D::vlGlyph3D()
{
  this->Source = NULL;
  this->Scaling = 1;
  this->ScaleMode = SCALE_BY_SCALAR;
  this->ScaleFactor = 1.0;
  this->Range[0] = 0.0;
  this->Range[1] = 1.0;
  this->Orient = 1;
  this->VectorMode = USE_VECTOR;
}

vlGlyph3D::~vlGlyph3D()
{
  if (this->Source)
    {
    this->Source->UnRegister(this);
    }
}

void vlGlyph3D::PrintSelf(ostream& os, vlIndent indent)
{
  if (this->ShouldIPrint(vlGlyph3D::GetClassName()))
    {
    vlDataSetToPolyFilter::PrintSelf(os,indent);

    os << indent << "Source: " << this->Source << "\n";
    os << indent << "Scaling: " << (this->Scaling ? "On\n" : "Off\n");
    os << indent << "Scale Mode: " << (this->ScaleMode == SCALE_BY_SCALAR ? "Scale by scalar\n" : "Scale by vector\n");
    os << indent << "Scale Factor: " << this->ScaleFactor << "\n";
    os << indent << "Range: (" << this->Range[0] << ", " << this->Range[1] << ")\n";
    os << indent << "Orient: " << (this->Orient ? "On\n" : "Off\n");

    os << indent << "Orient Mode: " << (this->VectorMode == USE_VECTOR ? "Orient by vector\n" : "Orient by normal\n");
    }
}

void vlGlyph3D::Execute()
{
  vlPointData *pd;
  vlScalars *inScalars;
  vlVectors *inVectors;
  vlNormals *inNormals, *sourceNormals;
  int numPts, numSourcePts, numSourceCells;
  int inPtId, i;
  vlPoints *sourcePts;
  vlCellArray *sourceCells;
  vlFloatPoints *newPts;
  vlFloatScalars *newScalars=NULL;
  vlFloatVectors *newVectors=NULL;
  vlFloatNormals *newNormals=NULL;
  float *x, s, *v, vNew[3];
  vlTransform trans;
  vlCell *cell;
  vlIdList *cellPts;
  int npts, pts[MAX_CELL_SIZE];
  int orient, scaleSource, ptIncr, cellId;
  float scale, den;
  vlMath math;
//
// Initialize
//
  this->Initialize();

  pd = this->Input->GetPointData();
  inScalars = pd->GetScalars();
  inVectors = pd->GetVectors();
  inNormals = pd->GetNormals();

  numPts = this->Input->GetNumberOfPoints();
//
// Allocate storage for output PolyData
//
  sourcePts = this->Source->GetPoints();
  numSourcePts = sourcePts->GetNumberOfPoints();
  numSourceCells = this->Source->GetNumberOfCells();
  sourceNormals = this->Source->GetPointData()->GetNormals();

  newPts = new vlFloatPoints(numPts*numSourcePts);
  if (inScalars != NULL)
    newScalars = new vlFloatScalars(numPts*numSourcePts);
  if (inVectors != NULL || inNormals != NULL )
    newVectors = new vlFloatVectors(numPts*numSourcePts);
  if (sourceNormals != NULL)
    newNormals = new vlFloatNormals(numPts*numSourcePts);

  // Setting up for calls to PolyData::InsertNextCell()
  if ( (sourceCells=this->Source->GetVerts())->GetNumberOfCells() > 0 )
    {
    this->SetVerts(new vlCellArray(numPts*sourceCells->GetSize()));
    }
  if ( (sourceCells=this->Source->GetLines())->GetNumberOfCells() > 0 )
    {
    this->SetLines(new vlCellArray(numPts*sourceCells->GetSize()));
    }
  if ( (sourceCells=this->Source->GetPolys())->GetNumberOfCells() > 0 )
    {
    this->SetPolys(new vlCellArray(numPts*sourceCells->GetSize()));
    }
  if ( (sourceCells=this->Source->GetStrips())->GetNumberOfCells() > 0 )
    {
    this->SetStrips(new vlCellArray(numPts*sourceCells->GetSize()));
    }
//
// Copy (input scalars) to (output scalars) and either (input vectors or
// normals) to (output vectors). All other point attributes are copied
// from Source.
//
  pd = this->Source->GetPointData();
  this->PointData.CopyScalarsOff();
  this->PointData.CopyVectorsOff();
  this->PointData.CopyNormalsOff();
  this->PointData.CopyAllocate(pd,numPts*numSourcePts);
//
// First copy all topology (transformation independent)
//
  for (inPtId=0; inPtId < numPts; inPtId++)
    {
    ptIncr = inPtId * numSourcePts;
    for (cellId=0; cellId < numSourceCells; cellId++)
      {
      cell = this->Source->GetCell(cellId);
      cellPts = cell->GetPointIds();
      npts = cellPts->GetNumberOfIds();
      for (i=0; i < npts; i++) pts[i] = cellPts->GetId(i) + ptIncr;
      this->InsertNextCell(cell->GetCellType(),npts,pts);
      }
    }
//
// Traverse all Input points, transforming Source points and copying
// point attributes.
//
  if ( this->VectorMode == USE_VECTOR && inVectors != NULL ||
  this->VectorMode == USE_NORMAL && inNormals != NULL )
    orient = 1;
  else
    orient = 0;

  if ( this->Scaling &&
  ((this->ScaleMode == SCALE_BY_SCALAR && inScalars != NULL) ||
  (this->ScaleMode == SCALE_BY_VECTOR && (inVectors || inNormals))) )
    scaleSource = 1;
  else
    scaleSource = 0;

  for (inPtId=0; inPtId < numPts; inPtId++)
    {
    ptIncr = inPtId * numSourcePts;

    trans.Identity();

    // translate Source to Input point
    x = this->Input->GetPoint(inPtId);
    trans.Translate(x[0], x[1], x[2]);

    if ( this->VectorMode == USE_NORMAL )
      v = inNormals->GetNormal(inPtId);
    else
      v = inVectors->GetVector(inPtId);
    scale = math.Norm(v);

    if ( orient )
      {
      // Copy Input vector
      for (i=0; i < numSourcePts; i++)
        newVectors->InsertVector(ptIncr+i,v);

      if ( this->Orient )
        {
        vNew[0] = (v[0]+scale) / 2.0;
        vNew[1] = v[1] / 2.0;
        vNew[2] = v[2] / 2.0;
        trans.RotateWXYZ(180.0,vNew[0],vNew[1],vNew[2]);
        }
      }

    // determine scale factor from scalars if appropriate
    if ( inScalars != NULL )
      {
      // Copy Input scalar
      for (i=0; i < numSourcePts; i++)
        newScalars->InsertScalar(ptIncr+i,scale);

      if ( this->ScaleMode == SCALE_BY_SCALAR )
        {
        if ( (den = this->Range[1] - this->Range[0]) == 0.0 ) den = 1.0;
        scale = inScalars->GetScalar(inPtId);

        scale = (scale < this->Range[0] ? this->Range[0] :
                 (scale > this->Range[1] ? this->Range[1] : scale));
        scale = (scale - this->Range[0]) / den;

        }
      }

    // scale data if appropriate
    if ( scaleSource )
      {
      scale *= this->ScaleFactor;
      if ( scale == 0.0 ) scale = 1.0e-10;
      trans.Scale(scale,scale,scale);
      }

    // multiply points and normals by resulting matrix
    trans.MultiplyPoints(sourcePts,newPts);
    if ( sourceNormals != NULL )
      trans.MultiplyNormals(sourceNormals,newNormals);

    // Copy point data from source
    for (i=0; i < numSourcePts; i++)
      this->PointData.CopyData(pd,i,ptIncr+i);
    }
//
// Update ourselves
//
  this->SetPoints(newPts);
  this->PointData.SetScalars(newScalars);
  this->PointData.SetVectors(newVectors);
  this->PointData.SetNormals(newNormals);
  this->Squeeze();
}

// Description:
// Override update method because execution can branch two ways (Input
// and Source)

void vlGlyph3D::Update()
{
  // make sure input is available
  if ( this->Input == NULL )
    {
    vlErrorMacro(<< "No input!");
    return;
    }

  if ( this->Source == NULL )
    {
    vlErrorMacro(<< "No data to copy");
    return;
    }

  // prevent chasing our tail
  if (this->Updating) return;

  this->Updating = 1;
  this->Input->Update();
  this->Source->Update();
  this->Updating = 0;

  if (this->Input->GetMTime() > this->GetMTime() || this->GetMTime() > this->ExecuteTime )
    {
    if ( this->StartMethod ) (*this->StartMethod)();
    this->Execute();
    this->ExecuteTime.Modified();
    if ( this->EndMethod ) (*this->EndMethod)();
    }
}
<|endoftext|>


<commit_before>//
// Copyright (c) 2012, University of Erlangen-Nuremberg
// Copyright (c) 2012, Siemens AG
// Copyright (c) 2010, ARM Limited
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this
//    list of conditions and the following disclaimer.
// 2. 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.
//
// 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 __KERNEL_HPP__
#define __KERNEL_HPP__

#include <vector>
#include "iterationspace.hpp"

namespace hipacc {
// get time in milliseconds
double hipacc_time_ms() {
    struct timeval tv;
    gettimeofday (&tv, NULL);

    return ((double)(tv.tv_sec) * 1e+3 + (double)(tv.tv_usec) * 1e-3);
}

template<typename data_t>
class Kernel {
    private:
        const IterationSpace<data_t> &iteration_space;
        Accessor<data_t> outImgAcc;
        ElementIterator iter;
        std::vector<AccessorBase *> images;

    public:
        Kernel(IterationSpace<data_t> &iteration_space) :
            iteration_space(iteration_space),
            outImgAcc(iteration_space.OutImg,
                        iteration_space.getWidth(), iteration_space.getHeight(),
                        iteration_space.getOffsetX(),
                        iteration_space.getOffsetY()),
            iter()
        {}

        virtual ~Kernel() {}
        virtual void kernel() = 0;

        void addAccessor(AccessorBase *Acc) { images.push_back(Acc); }

        void execute() {
            double time0, time1;
            ElementIterator end = iteration_space.end();
            iter = iteration_space.begin();

            // register input accessors
            for (std::vector<AccessorBase *>::iterator ei=images.begin(), ie=images.end();
                    ei!=ie; ++ei) {
                AccessorBase *Acc = *ei;
                Acc->setEI(&iter);
            }
            // register output accessors
            outImgAcc.setEI(&iter);

            // advance iterator and apply kernel to whole iteration space
            time0 = hipacc_time_ms();
            while (iter != end) {
                kernel();
                ++iter;
            }
            time1 = hipacc_time_ms();
            hipacc_last_timing = time1 - time0;

            // de-register input accessors
            for (std::vector<AccessorBase*>::iterator ei=images.begin(), ie=images.end();
                    ei!=ie; ++ei) {
                AccessorBase *Acc = *ei;
                Acc->setEI(NULL);
            }
            // de-register output accessors
            outImgAcc.setEI(NULL);

            // reset kernel iterator
            iter = ElementIterator();

        }

        // access output image
        data_t &output(void) {
            return outImgAcc();
        }

        // low-level access functions
        data_t &outputAtPixel(const int xf, const int yf) {
            return outImgAcc.getPixelFromImg(xf, yf);
        }

        int getX(void) {
            assert(iter!=ElementIterator() && "ElementIterator not set!");
            return iter.getX() - iter.getOffsetX();
        }

        int getY(void) {
            assert(iter!=ElementIterator() && "ElementIterator not set!");
            return iter.getY() - iter.getOffsetY();
        }
};

template<typename data_t>
class GlobalReduction {
    protected:
        Accessor<data_t> imgAcc;
        IterationSpace<data_t> redIS;
        data_t neutral;

    public:
        GlobalReduction(Image<data_t> &img, data_t neutral) :
            imgAcc(img, 0, 0, img.getWidth(), img.getHeight()),
            redIS(img),
            neutral(neutral)
        {}
        GlobalReduction(Accessor<data_t> &acc, data_t neutral) :
            imgAcc(acc),
            redIS(acc.img, acc.offset_x, acc.offset_y, acc.width, acc.height),
            neutral(neutral)
        {}

        virtual data_t reduce(data_t left, data_t right) = 0;

        data_t reduce(void) {
            data_t result = neutral;
            bool first = true;

            ElementIterator end = redIS.end();
            ElementIterator iter = redIS.begin();

            // register output accessors
            imgAcc.setEI(&iter);

            // advance iterator and apply kernel to whole iteration space
            while (iter != end) {
                data_t current = imgAcc();
                if (first) {
                    first = false;
                    result = reduce(neutral, current);
                } else {
                    result = reduce(result, current);
                }
                ++iter;
            }

            return result;
        }
};

template <typename data_t, typename Function>
data_t reduce(Image<data_t> &img, data_t neutral, const Function& fun) {
    data_t result = neutral;
    IterationSpace<data_t> redIS(img);
    Accessor<data_t> imgAcc(img);
    bool first = true;

    ElementIterator end = redIS.end();
    ElementIterator iter = redIS.begin();

    // register output accessors
    imgAcc.setEI(&iter);

    // advance iterator and apply kernel to whole iteration space
    while (iter != end) {
        data_t current = imgAcc();
        if (first) {
            first = false;
            result = fun(neutral, current);
        } else {
            result = fun(result, current);
        }
        ++iter;
    }

    // de-register output accessors
    imgAcc.setEI(NULL);

    return result;
}
} // end namespace hipacc

#endif // __KERNEL_HPP__

<commit_msg>Fix bug in C++ DSL implementation:<commit_after>//
// Copyright (c) 2012, University of Erlangen-Nuremberg
// Copyright (c) 2012, Siemens AG
// Copyright (c) 2010, ARM Limited
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this
//    list of conditions and the following disclaimer.
// 2. 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.
//
// 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 __KERNEL_HPP__
#define __KERNEL_HPP__

#include <vector>
#include "iterationspace.hpp"

namespace hipacc {
// get time in milliseconds
double hipacc_time_ms() {
    struct timeval tv;
    gettimeofday (&tv, NULL);

    return ((double)(tv.tv_sec) * 1e+3 + (double)(tv.tv_usec) * 1e-3);
}

template<typename data_t>
class Kernel {
    private:
        const IterationSpace<data_t> &iteration_space;
        Accessor<data_t> outImgAcc;
        ElementIterator iter;
        std::vector<AccessorBase *> images;

    public:
        Kernel(IterationSpace<data_t> &iteration_space) :
            iteration_space(iteration_space),
            outImgAcc(iteration_space.OutImg,
                        iteration_space.getWidth(), iteration_space.getHeight(),
                        iteration_space.getOffsetX(),
                        iteration_space.getOffsetY()),
            iter()
        {}

        virtual ~Kernel() {}
        virtual void kernel() = 0;

        void addAccessor(AccessorBase *Acc) { images.push_back(Acc); }

        void execute() {
            double time0, time1;
            ElementIterator end = iteration_space.end();
            iter = iteration_space.begin();

            // register input accessors
            for (std::vector<AccessorBase *>::iterator ei=images.begin(), ie=images.end();
                    ei!=ie; ++ei) {
                AccessorBase *Acc = *ei;
                Acc->setEI(&iter);
            }
            // register output accessors
            outImgAcc.setEI(&iter);

            // advance iterator and apply kernel to whole iteration space
            time0 = hipacc_time_ms();
            while (iter != end) {
                kernel();
                ++iter;
            }
            time1 = hipacc_time_ms();
            hipacc_last_timing = time1 - time0;

            // de-register input accessors
            for (std::vector<AccessorBase*>::iterator ei=images.begin(), ie=images.end();
                    ei!=ie; ++ei) {
                AccessorBase *Acc = *ei;
                Acc->setEI(NULL);
            }
            // de-register output accessors
            outImgAcc.setEI(NULL);

            // reset kernel iterator
            iter = ElementIterator();

        }

        // access output image
        data_t &output(void) {
            return outImgAcc();
        }

        // low-level access functions
        data_t &outputAtPixel(const int xf, const int yf) {
            return outImgAcc.getPixelFromImg(xf, yf);
        }

        int getX(void) {
            assert(iter!=ElementIterator() && "ElementIterator not set!");
            return iter.getX() - iter.getOffsetX();
        }

        int getY(void) {
            assert(iter!=ElementIterator() && "ElementIterator not set!");
            return iter.getY() - iter.getOffsetY();
        }
};

template<typename data_t>
class GlobalReduction {
    protected:
        Accessor<data_t> imgAcc;
        IterationSpace<data_t> redIS;
        data_t neutral;

    public:
        GlobalReduction(Image<data_t> &img, data_t neutral) :
            imgAcc(img, img.getWidth(), img.getHeight(), 0, 0),
            redIS(img),
            neutral(neutral)
        {}
        GlobalReduction(Accessor<data_t> &acc, data_t neutral) :
            imgAcc(acc),
            redIS(acc.img, acc.width, acc.height, acc.offset_x, acc.offset_y),
            neutral(neutral)
        {}

        virtual data_t reduce(data_t left, data_t right) = 0;

        data_t reduce(void) {
            data_t result = neutral;
            bool first = true;

            ElementIterator end = redIS.end();
            ElementIterator iter = redIS.begin();

            // register output accessors
            imgAcc.setEI(&iter);

            // advance iterator and apply kernel to whole iteration space
            while (iter != end) {
                data_t current = imgAcc();
                if (first) {
                    first = false;
                    result = reduce(neutral, current);
                } else {
                    result = reduce(result, current);
                }
                ++iter;
            }

            // de-register output accessors
            imgAcc.setEI(NULL);

            return result;
        }
};

template <typename data_t, typename Function>
data_t reduce(Image<data_t> &img, data_t neutral, const Function& fun) {
    data_t result = neutral;
    IterationSpace<data_t> redIS(img);
    Accessor<data_t> imgAcc(img);
    bool first = true;

    ElementIterator end = redIS.end();
    ElementIterator iter = redIS.begin();

    // register output accessors
    imgAcc.setEI(&iter);

    // advance iterator and apply kernel to whole iteration space
    while (iter != end) {
        data_t current = imgAcc();
        if (first) {
            first = false;
            result = fun(neutral, current);
        } else {
            result = fun(result, current);
        }
        ++iter;
    }

    // de-register output accessors
    imgAcc.setEI(NULL);

    return result;
}
} // end namespace hipacc

#endif // __KERNEL_HPP__

<|endoftext|>


<commit_before>#include "factor.h"

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <sstream>
#include <vector>

bool fact(std::vector <std::string> *out, int input, const char *otherFacts, int level, int iter = 0) {
        if (level == 0)
                return false;

        if (input < 0) input *=-1;
        for (int d = input - 1; d > 1; --d) {
                if (input % d == 0) {
                        char tmp1[256], tmp2[256];
                        sprintf(tmp1, "%d * %d%s%s", d, input / d, strlen(otherFacts) > 0 ? " * " : "", otherFacts);
                        sprintf(tmp2, "%s%s%d", otherFacts, strlen(otherFacts) > 0 ? " * " : "", input / d);
                        out->push_back(tmp1);
                        fact(out, d, tmp2, level - 1, iter + 1);
                        return true;
                }
        }
        return false;
}

std::string factHelper(int input, int iterations) {
        std::vector <std::string> out;
        std::ostringstream s;
        std::string equals;
        s << input << "\n";

        if (input >= 0)
            equals = " = ";
        else
            equals = " = -";

        if (!fact(&out, input, "", 20)) {
            s << equals << input;
        } else {
            for (int i = 0; i < iterations && i < static_cast<int>(out.size()); ++i)
                s << equals << out[i] << "\n";
        }
        return s.str();
}

Factorizer::Factorizer() {}

QString Factorizer::factorize(int in, int iterations) const {
    qDebug() << "factorize called" << in << iterations;

    QString result = factHelper(in, iterations).c_str();
    result.replace("*", "×");
    return result;
}
<commit_msg>Fix sign for negative primes.<commit_after>#include "factor.h"

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <sstream>
#include <vector>

bool fact(std::vector <std::string> *out, int input, const char *otherFacts, int level, int iter = 0) {
        if (level == 0)
                return false;

        if (input < 0) input *=-1;
        for (int d = input - 1; d > 1; --d) {
                if (input % d == 0) {
                        char tmp1[256], tmp2[256];
                        sprintf(tmp1, "%d * %d%s%s", d, input / d, strlen(otherFacts) > 0 ? " * " : "", otherFacts);
                        sprintf(tmp2, "%s%s%d", otherFacts, strlen(otherFacts) > 0 ? " * " : "", input / d);
                        out->push_back(tmp1);
                        fact(out, d, tmp2, level - 1, iter + 1);
                        return true;
                }
        }
        return false;
}

std::string factHelper(int input, int iterations) {
        std::vector <std::string> out;
        std::ostringstream s;
        std::string equals;
        s << input << "\n";

        if (input >= 0)
            equals = " = ";
        else
            equals = " = -";

        if (!fact(&out, input, "", 20)) {
            s << " = " << input;
        } else {
            for (int i = 0; i < iterations && i < static_cast<int>(out.size()); ++i)
                s << equals << out[i] << "\n";
        }
        return s.str();
}

Factorizer::Factorizer() {}

QString Factorizer::factorize(int in, int iterations) const {
    qDebug() << "factorize called" << in << iterations;

    QString result = factHelper(in, iterations).c_str();
    result.replace("*", "×");
    return result;
}
<|endoftext|>