예제 #1
0
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());
        }
    }
}
예제 #2
0
 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;
     }
   };
 }
예제 #3
0
 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;
     }
   };
 }
예제 #4
0
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);
    }
}
예제 #5
0
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));
  }
}
예제 #6
0
/* 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;
	}
}
예제 #7
0
 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());
 }
예제 #8
0
 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;
 }
예제 #9
0
 /**
  * @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));
 }
예제 #10
0
 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;
 }
예제 #12
0
 inline void become(match_expr<Cases...> arg0, Args&&... args) {
     become(discard_behavior, match_expr_convert(std::move(arg0), std::forward<Args>(args)...));
 }
예제 #13
0
 /**
  * @brief Equal to <tt>become(discard_old, bhvr)</tt>.
  */
 inline void become(behavior* bhvr) {
     become(discard_behavior, *bhvr);
 }
예제 #14
0
 /**
  * @brief Sets the actor's behavior.
  */
 inline void become(behavior bhvr) {
     become(discard_behavior, std::move(bhvr));
 }