void File::becomeIfOutdated(File& basefile, int save) { if (modTime() < basefile.modTime()) { if (verbose) { fprintf(stderr, "Updating %s since outdated\n" " (local file mod time: %d; basefile mod time: %d)", path, modTime(), basefile.modTime()); } if (strcmp(path, program) == 0) { // The file we are about to overwrite has the same name as the // executing footprint. Moving/removing the file before the copy // seems to solve the "Segmentation fault" problem. char line[LINE_LENGTH]; if (save) { fprintf(stderr, "Saving old %s\n", path); sprintf(line, "mv %s %s.OLD", path, path); if (execute(line)) exit(-1); } else { fprintf(stderr, "Removing %s\n", path); sprintf(line, "rm %s", path); if (execute(line)) exit(-1); } become(basefile, 0); } else { become(basefile, save); } } else { if (verbose) { fprintf(stderr, "Not updating %s since not outdated\n" " (local file mod time: %d; basefile mod time: %d)", path, modTime(), basefile.modTime()); } } }
caf::behavior init_buffer() { // Initial send tasks auto pending_chunks = std::make_shared<int>(workers_.size()); auto pending_jobs = std::make_shared<int>(buffer_min_size_); send_job(); return { [=](const std::vector<uint16_t>& data, uint32_t id) { concat_data(data, id); if (! --*pending_chunks) { if (--*pending_jobs) { send_job(); *pending_chunks = workers_.size(); } else { become(main_phase()); } } }, [=](resize_atom, uint32_t w, uint32_t h) { resize(w,h); }, [=](limit_atom, normal_atom, uint32_t workers) { become(make_behavior()); send(this, calc_weights_atom::value, size_t{workers}); }, caf::others() >> [=] { std::cout << to_string(current_message()) << std::endl; } }; }
caf::behavior main_phase() { send(this, tick_atom::value); return { [=](const std::vector<uint16_t>& data, uint32_t id) { concat_data(data, id); }, [=](tick_atom) { delayed_send(this, tick_rate_, tick_atom::value); if (cache_.empty()) { std::cout << "[WARNING] Cache empty..." << std::endl; return; } send(sink_, image_width_, cache_.front()); cache_.pop(); send_job(); }, [=](resize_atom, uint32_t w, uint32_t h) { resize(w,h); }, [=](limit_atom, normal_atom, uint32_t workers) { become(make_behavior()); send(this, calc_weights_atom::value, size_t{workers}); }, caf::others() >> [=] { std::cout << to_string(current_message()) << std::endl; } }; }
void File::becomeIfConfirmed(File& basefile, int save) { char line[LINE_LENGTH]; fprintf(stderr, "Copy %s to %s [yn]? ", basefile.path, path); gets(line); if (line[0] == '\0' || line[0] == 'y' || line[0] == 'Y') { become(basefile, save); } }
void event_based_actor::initialize() { is_initialized(true); auto bhvr = make_behavior(); CAF_LOG_DEBUG_IF(!bhvr, "make_behavior() did not return a behavior, " << "has_behavior() = " << std::boolalpha << this->has_behavior()); if (bhvr) { // make_behavior() did return a behavior instead of using become() CAF_LOG_DEBUG("make_behavior() did return a valid behavior"); become(std::move(bhvr)); } }
/* start a new process */ extern process * noshell_proc_start(char **av, stream *inp, stream *outp, stream *errp, int newpg, char *who) { process *pp; int i, n; if ((pp = (process *)malloc(sizeof(process))) == 0) { if (inp != 0) stream_free(inp); if (outp != 0) stream_free(outp); if (errp != 0) stream_free(errp); return 0; } pp->std[0] = inp; pp->std[1] = outp; pp->std[2] = errp; switch (pp->pid = fork()) { case -1: proc_free(pp); return 0; case 0: if(newpg) sysdetach(); for (i=0; i<3; i++) if (pp->std[i] != 0){ close(Bfildes(pp->std[i]->fp)); while(pp->std[i]->fd < 3) pp->std[i]->fd = dup(pp->std[i]->fd, -1); } for (i=0; i<3; i++) if (pp->std[i] != 0) dup(pp->std[i]->fd, i); for (n = sysfiles(); i < n; i++) close(i); if(who) become(av, who); exec(av[0], av); perror("proc_start"); exits("proc_start"); default: for (i=0; i<3; i++) if (pp->std[i] != 0) { close(pp->std[i]->fd); pp->std[i]->fd = -1; } return pp; } }
void resize(uint32_t width, uint32_t height) { image_width_ = width; image_height_ = height; image_size_ = image_width_ * image_height_; stream_.init(width, height, default_min_real, default_max_real, default_min_imag, default_max_imag, default_zoom); become(make_behavior()); send(this, calc_weights_atom::value, workers_.size()); }
resumable::resume_result resume(detail::cs_thread*, execution_unit* host) override { auto d = static_cast<Derived*>(this); d->m_host = host; CPPA_LOG_TRACE("id = " << d->id()); auto done_cb = [&]() -> bool { CPPA_LOG_TRACE(""); d->bhvr_stack().clear(); d->bhvr_stack().cleanup(); d->on_exit(); if (!d->bhvr_stack().empty()) { CPPA_LOG_DEBUG("on_exit did set a new behavior in on_exit"); d->planned_exit_reason(exit_reason::not_exited); return false; // on_exit did set a new behavior } auto rsn = d->planned_exit_reason(); if (rsn == exit_reason::not_exited) { rsn = exit_reason::normal; d->planned_exit_reason(rsn); } d->cleanup(rsn); return true; }; auto actor_done = [&] { return d->bhvr_stack().empty() || d->planned_exit_reason() != exit_reason::not_exited; }; // actors without behavior or that have already defined // an exit reason must not be resumed CPPA_REQUIRE(!d->m_initialized || !actor_done()); if (!d->m_initialized) { d->m_initialized = true; auto bhvr = d->make_behavior(); if (bhvr) d->become(std::move(bhvr)); // else: make_behavior() might have just called become() if (actor_done() && done_cb()) return resume_result::done; // else: enter resume loop } try { for (;;) { auto ptr = d->next_message(); if (ptr) { if (d->invoke_message(ptr)) { if (actor_done() && done_cb()) { CPPA_LOG_DEBUG("actor exited"); return resume_result::done; } // continue from cache if current message was // handled, because the actor might have changed // its behavior to match 'old' messages now while (d->invoke_message_from_cache()) { if (actor_done() && done_cb()) { CPPA_LOG_DEBUG("actor exited"); return resume_result::done; } } } // add ptr to cache if invoke_message // did not reset it (i.e. skipped, but not dropped) if (ptr) { CPPA_LOG_DEBUG("add message to cache"); d->push_to_cache(std::move(ptr)); } } else { CPPA_LOG_DEBUG("no more element in mailbox; " "going to block"); if (d->mailbox().try_block()) { return resumable::resume_later; } // else: try again } } } catch (actor_exited& what) { CPPA_LOG_INFO("actor died because of exception: actor_exited, " "reason = " << what.reason()); if (d->exit_reason() == exit_reason::not_exited) { d->quit(what.reason()); } } catch (std::exception& e) { CPPA_LOG_WARNING("actor died because of exception: " << detail::demangle(typeid(e)) << ", what() = " << e.what()); if (d->exit_reason() == exit_reason::not_exited) { d->quit(exit_reason::unhandled_exception); } } catch (...) { CPPA_LOG_WARNING("actor died because of an unknown exception"); if (d->exit_reason() == exit_reason::not_exited) { d->quit(exit_reason::unhandled_exception); } } done_cb(); return resumable::done; }
/** * @brief Overrides abstract_event_based_actor::init() and sets * the initial actor behavior to <tt>Derived::init_state</tt>. */ void init() { become(&(static_cast<Derived*>(this)->init_state)); }
caf::behavior make_behavior() override { auto start_map = std::make_shared< std::map<caf::actor, std::chrono::time_point< std::chrono::high_resolution_clock> > >(); return { [=](init_atom, const std::vector<caf::actor>& all_workers) { std::cout << "init: " << all_workers.size() << std::endl; all_workers_.clear(); all_workers_.insert(std::begin(all_workers_), std::begin(all_workers), std::end(all_workers)); send(this, calc_weights_atom::value, all_workers_.size()); }, [=](calc_weights_atom, size_t workers_to_use) { // Clear all caches chunk_cache_.clear(); image_cache empty; std::swap(cache_, empty); start_map->clear(); workers_.clear(); // for (size_t i = 0; i < workers_to_use; ++i) workers_.emplace(all_workers_[i], 0); using hrc = std::chrono::high_resolution_clock; auto req = stream_.next(); // TODO: Get a image with much black uint32_t req_width = width(req); uint32_t req_height = height(req); auto req_min_re = min_re(req); auto req_max_re = max_re(req); auto req_min_im = min_im(req); auto req_max_im = max_im(req); uint32_t offset = 0; uint32_t rows = image_height_; for (auto& e : workers_) { auto& worker = e.first; start_map->emplace(worker, hrc::now()); send(worker, default_iterations, req_width, req_height, offset, rows, req_min_re, req_max_re, req_min_im, req_max_im); } }, [=](const std::vector<uint16_t>& data, uint32_t) { if (data.size() != image_size_) return; // old data TODO: Problem with 1 worker? auto sender = caf::actor_cast<caf::actor>(current_sender()); auto t2 = std::chrono::high_resolution_clock::now(); auto diff = std::chrono::duration_cast<std::chrono::milliseconds>(t2 - (*start_map)[sender]).count(); workers_[sender] = diff; start_map->erase(sender); if (start_map->empty()) { auto add = [](size_t lhs, const std::pair<caf::actor, double>& rhs) { return lhs + rhs.second; }; auto total_time = std::accumulate(workers_.begin(), workers_.end(), size_t{0}, add); for (auto& e : workers_) e.second = e.second / total_time; double time = diff; for (auto& e : workers_) { time *= e.second; break; } auto ms = static_cast<double>(std::chrono::milliseconds(static_cast<uint16_t>(time)).count()); auto sec = static_cast<double>(std::chrono::milliseconds(1000).count()); double fps = sec / ms; tick_rate_ = std::chrono::milliseconds(/*static_cast<uint16_t>(time) + 50*/1000); std::cout << "Assumed FPS: " << fps << std::endl; //buffer_min_size_ = fps < 1 ? static_cast<uint32_t>(1.0 / fps) // : static_cast<uint32_t>(fps); //buffer_min_size_ *= seconds_to_buffer_; // FIXME buffer_min_size_ = static_cast<uint32_t>(fps) + 1 * seconds_to_buffer_; buffer_max_size_ = buffer_min_size_ * 4; become(init_buffer()); } }, [=](resize_atom, uint32_t w, uint32_t h) { resize(w,h); }, [=](limit_atom, normal_atom, uint32_t workers) { send(this, calc_weights_atom::value, size_t{workers}); }, caf::others() >> [=] { std::cout << to_string(current_message()) << std::endl; } }; }
resumable::resume_result resume(execution_unit* new_host, size_t max_throughput) override { CAF_REQUIRE(max_throughput > 0); auto d = static_cast<Derived*>(this); CAF_LOG_TRACE("id = " << d->id()); d->host(new_host); auto done_cb = [&]() -> bool { CAF_LOG_TRACE(""); d->bhvr_stack().clear(); d->bhvr_stack().cleanup(); d->on_exit(); if (!d->bhvr_stack().empty()) { CAF_LOG_DEBUG("on_exit did set a new behavior"); d->planned_exit_reason(exit_reason::not_exited); return false; // on_exit did set a new behavior } auto rsn = d->planned_exit_reason(); if (rsn == exit_reason::not_exited) { rsn = exit_reason::normal; d->planned_exit_reason(rsn); } d->cleanup(rsn); return true; }; auto actor_done = [&]() -> bool { if (d->bhvr_stack().empty() || d->planned_exit_reason() != exit_reason::not_exited) { return done_cb(); } return false; }; // actors without behavior or that have already defined // an exit reason must not be resumed CAF_REQUIRE(!d->is_initialized() || (!d->bhvr_stack().empty() && d->planned_exit_reason() == exit_reason::not_exited)); std::exception_ptr eptr = nullptr; try { if (!d->is_initialized()) { CAF_LOG_DEBUG("initialize actor"); d->is_initialized(true); auto bhvr = d->make_behavior(); CAF_LOG_DEBUG_IF(!bhvr, "make_behavior() did not return a behavior, " << "bhvr_stack().empty() = " << std::boolalpha << d->bhvr_stack().empty()); if (bhvr) { // make_behavior() did return a behavior instead of using become() CAF_LOG_DEBUG("make_behavior() did return a valid behavior"); d->become(std::move(bhvr)); } if (actor_done()) { CAF_LOG_DEBUG("actor_done() returned true right " << "after make_behavior()"); return resume_result::done; } } // max_throughput = 0 means infinite for (size_t i = 0; i < max_throughput; ++i) { auto ptr = d->next_message(); if (ptr) { if (d->invoke_message(ptr)) { if (actor_done()) { CAF_LOG_DEBUG("actor exited"); return resume_result::done; } // continue from cache if current message was // handled, because the actor might have changed // its behavior to match 'old' messages now while (d->invoke_message_from_cache()) { if (actor_done()) { CAF_LOG_DEBUG("actor exited"); return resume_result::done; } } } // add ptr to cache if invoke_message // did not reset it (i.e. skipped, but not dropped) if (ptr) { CAF_LOG_DEBUG("add message to cache"); d->push_to_cache(std::move(ptr)); } } else { CAF_LOG_DEBUG("no more element in mailbox; going to block"); if (d->mailbox().try_block()) { return resumable::awaiting_message; } CAF_LOG_DEBUG("try_block() interrupted by new message"); } } if (!d->has_next_message() && d->mailbox().try_block()) { return resumable::awaiting_message; } // time's up return resumable::resume_later; } catch (actor_exited& what) { CAF_LOG_INFO("actor died because of exception: actor_exited, " "reason = " << what.reason()); if (d->exit_reason() == exit_reason::not_exited) { d->quit(what.reason()); } } catch (std::exception& e) { CAF_LOG_INFO("actor died because of an exception: " << detail::demangle(typeid(e)) << ", what() = " << e.what()); if (d->exit_reason() == exit_reason::not_exited) { d->quit(exit_reason::unhandled_exception); } eptr = std::current_exception(); } catch (...) { CAF_LOG_INFO("actor died because of an unknown exception"); if (d->exit_reason() == exit_reason::not_exited) { d->quit(exit_reason::unhandled_exception); } eptr = std::current_exception(); } if (eptr) { auto opt_reason = d->handle(eptr); if (opt_reason) { // use exit reason defined by custom handler d->planned_exit_reason(*opt_reason); } } if (!actor_done()) { // actor has been "revived", try running it again later return resumable::resume_later; } return resumable::done; }
inline void become(match_expr<Cases...> arg0, Args&&... args) { become(discard_behavior, match_expr_convert(std::move(arg0), std::forward<Args>(args)...)); }
/** * @brief Equal to <tt>become(discard_old, bhvr)</tt>. */ inline void become(behavior* bhvr) { become(discard_behavior, *bhvr); }
/** * @brief Sets the actor's behavior. */ inline void become(behavior bhvr) { become(discard_behavior, std::move(bhvr)); }