/** Code to execute in the thread. * Executes loop() in each cycle. This is the default implementation and if * you need a more specific behaviour you can override this run() method and * ignore loop(). * Although this method is declared virtual, it should not be overridden, other * than with the following trivial snippet: * @code * protected: virtual void run() { Thread::run(); } * @endcode * The reason not to do other changes is that it contains complex house keeping * code that the system relies on. The reason for still allowing the override is * solely to make reading back traces in your debugger easier. Because now there * the class name of the thread sub-class will appear in the back trace, while * it would not otherwise. */ void Thread::run() { if ( __op_mode == OPMODE_WAITFORWAKEUP ) { // Wait for initial wakeup // __sleep_mutex has been locked in entry() already! while (__pending_wakeups == 0) { __waiting_for_wakeup = true; __sleep_condition->wait(); } __pending_wakeups -= 1; __sleep_mutex->unlock(); } forever { loopinterrupt_antistarve_mutex->stopby(); loop_mutex->lock(); if ( ! finalize_prepared ) { __loop_done = false; loop(); } loop_mutex->unlock(); __loop_done_mutex->lock(); __loop_done = true; __loop_done_mutex->unlock(); __loop_done_waitcond->wake_all(); test_cancel(); if ( __op_mode == OPMODE_WAITFORWAKEUP ) { if ( __barrier ) { __sleep_mutex->lock(); Barrier *b = __barrier; __barrier = NULL; __sleep_mutex->unlock(); b->wait(); __sleep_mutex->lock(); } else { __sleep_mutex->lock(); } while (__pending_wakeups == 0) { __waiting_for_wakeup = true; __sleep_condition->wait(); } __pending_wakeups -= 1; __sleep_mutex->unlock(); } yield(); } }
int main(int argc, char *argv[]) { bool chook = false; int ferr; int loop = 10; TAD zargs[] = { { "-chook", TA_Bool, TA_NOMAX, &chook }, { "-client", TA_Ign, TA_NOMAX, NULL }, { "-loop", TA_Int, TA_NOMAX, &loop }, { "-maxth", TA_Int, MAX_THR, &maxth }, { "-server", TA_Ign, TA_NOMAX, NULL }, { "-tol", TA_Int, TA_NOMAX, &to_tol }, { "-v", TA_Bool, TA_NOMAX, &verbose }, { "", TA_End, TA_NOMAX, NULL } }; msfs_util_init(&argc, &argv, msg_debug_hook); arg_proc_args(zargs, false, argc, argv); if (chook) msg_debug_hook("c", "c"); util_test_start(true); ferr = msg_mon_process_startup(true); // system messages? TEST_CHK_FEOK(ferr); util_gethostname(my_name, sizeof(my_name)); #if 0 // reproduce bug 1570 // - add sleep(1) in sb_timer_setitimer when pv_to != 0 #endif test_cancel(); test_timers(); test_timers_alloc(); test_thread1(); test_cancel_cb(); test_timers_cb(); test_thread3(); #if 0 // reproduce bug 728 // - must add sleep(1) after call-to-sb_timer_comp_q_remove() in MSG_LISTEN_ test_thread2(); #endif ferr = msg_mon_process_shutdown(); TEST_CHK_FEOK(ferr); util_test_finish(true); return 0; }
void FawkesMainThread::loop() { if (!thread_manager_->timed_threads_exist()) { multi_logger_->log_debug("FawkesMainThread", "No timed threads exist, waiting"); try { thread_manager_->wait_for_timed_threads(); multi_logger_->log_debug("FawkesMainThread", "Timed threads have been added, " "running main loop now"); } catch (InterruptedException &e) { multi_logger_->log_debug("FawkesMainThread", "Waiting for timed threads interrupted"); return; } } plugin_manager_->lock(); try { if (time_wait_) { time_wait_->mark_start(); } loop_start_->stamp_systime(); CancelState old_state; set_cancel_state(CANCEL_DISABLED, &old_state); mainloop_mutex_->lock(); if (unlikely(mainloop_thread_ != NULL)) { try { if (likely(mainloop_thread_ != NULL)) { mainloop_thread_->wakeup(mainloop_barrier_); mainloop_barrier_->wait(); } } catch (Exception &e) { multi_logger_->log_warn("FawkesMainThread", e); } } else { uint num_hooks = syncpoints_start_hook_.size(); if (syncpoints_end_hook_.size() != num_hooks) { multi_logger_->log_error( "FawkesMainThread", "Hook syncpoints are not initialized properly, not waking up any threads!"); } else { for (uint i = 0; i < num_hooks; i++) { syncpoints_start_hook_[i]->emit("FawkesMainThread"); syncpoints_end_hook_[i]->reltime_wait_for_all("FawkesMainThread", 0, max_thread_time_nanosec_); } } } mainloop_mutex_->unlock(); set_cancel_state(old_state); test_cancel(); thread_manager_->try_recover(recovered_threads_); if (!recovered_threads_.empty()) { // threads have been recovered! //multi_logger_->log_error(name(), "Threads recovered %zu", recovered_threads_.size()); if (enable_looptime_warnings_) { if (recovered_threads_.size() == 1) { multi_logger_->log_warn("FawkesMainThread", "The thread %s could be " "recovered and resumes normal operation", recovered_threads_.front().c_str()); } else { std::string s; for (std::list<std::string>::iterator i = recovered_threads_.begin(); i != recovered_threads_.end(); ++i) { s += *i + " "; } multi_logger_->log_warn("FawkesMainThread", "The following threads could be " "recovered and resumed normal operation: %s", s.c_str()); } } recovered_threads_.clear(); } if (desired_loop_time_sec_ > 0) { loop_end_->stamp_systime(); float loop_time = *loop_end_ - loop_start_; if (enable_looptime_warnings_) { // give some extra 10% to eliminate frequent false warnings due to regular // time jitter (TimeWait might not be all that precise) if (loop_time > 1.1 * desired_loop_time_sec_) { multi_logger_->log_warn("FawkesMainThread", "Loop time exceeded, " "desired: %f sec (%u usec), actual: %f sec", desired_loop_time_sec_, desired_loop_time_usec_, loop_time); } } } plugin_manager_->unlock(); if (time_wait_) { time_wait_->wait_systime(); } else { yield(); } } catch (Exception &e) { multi_logger_->log_warn("FawkesMainThread", "Exception caught while executing default main " "loop, ignoring."); multi_logger_->log_warn("FawkesMainThread", e); } catch (std::exception &e) { multi_logger_->log_warn("FawkesMainThread", "STL Exception caught while executing default main " "loop, ignoring. (what: %s)", e.what()); } // catch ... is not a good idea, would catch cancellation exception // at least needs to be rethrown. }
/* at_splines_new_full modifies its 'bitmap' argument when it does the thin_image thing. */ at_spline_list_array_type * at_splines_new_full(at_bitmap_type * const bitmap, at_fitting_opts_type * const opts, at_msg_func msg_func, void * const msg_data, at_progress_func notify_progress, void * const progress_data, at_testcancel_func test_cancel, void * const testcancel_data) { at_spline_list_array_type * retval; image_header_type image_header; pixel_outline_list_type pixelOutlineList; at_exception_type exp; distance_map_type distanceMap; bool haveDistMap; exp = at_exception_new(msg_func, msg_data); image_header.width = at_bitmap_get_width(bitmap); image_header.height = at_bitmap_get_height(bitmap); if (opts->centerline) { if (opts->preserve_width) { /* Preserve line width prior to thinning. */ bool const paddedTrue = true; distanceMap = new_distance_map(*bitmap, 255, paddedTrue, &exp); haveDistMap = true; } else haveDistMap = false; thin_image(bitmap, opts->backgroundSpec, opts->background_color, &exp); } else haveDistMap = false; if (at_exception_got_fatal(&exp)) retval = NULL; else { if (opts->centerline) { pixel background_color; if (opts->backgroundSpec) background_color = opts->background_color; else PPM_ASSIGN(background_color, 255, 255, 255); pixelOutlineList = find_centerline_pixels(*bitmap, background_color, notify_progress, progress_data, test_cancel, testcancel_data, &exp); } else pixelOutlineList = find_outline_pixels(*bitmap, opts->backgroundSpec, opts->background_color, notify_progress, progress_data, test_cancel, testcancel_data, &exp); if (at_exception_got_fatal(&exp) || (test_cancel && test_cancel(testcancel_data))) retval = NULL; else { at_spline_list_array_type * splinesP; MALLOCVAR_NOFAIL(splinesP); fit_outlines_to_splines(pixelOutlineList, opts, haveDistMap ? &distanceMap : NULL, image_header.width, image_header.height, &exp, notify_progress, progress_data, test_cancel, testcancel_data, splinesP); if (at_exception_got_fatal(&exp) || (test_cancel && test_cancel(testcancel_data))) retval = NULL; else { if (notify_progress) notify_progress(1.0, progress_data); retval = splinesP; } free_pixel_outline_list(&pixelOutlineList); } if (haveDistMap) free_distance_map(&distanceMap); } return retval; }
void FawkesMainThread::loop() { if ( ! __thread_manager->timed_threads_exist() ) { __multi_logger->log_debug("FawkesMainThread", "No timed threads exist, waiting"); try { __thread_manager->wait_for_timed_threads(); __multi_logger->log_debug("FawkesMainThread", "Timed threads have been added, " "running main loop now"); } catch (InterruptedException &e) { __multi_logger->log_debug("FawkesMainThread", "Waiting for timed threads interrupted"); return; } } __plugin_manager->lock(); try { if ( __time_wait ) { __time_wait->mark_start(); } __loop_start->stamp_systime(); CancelState old_state; set_cancel_state(CANCEL_DISABLED, &old_state); __mainloop_mutex->lock(); if (unlikely(__mainloop_thread != NULL)) { try { if (likely(__mainloop_thread != NULL)) { __mainloop_thread->wakeup(__mainloop_barrier); __mainloop_barrier->wait(); } } catch (Exception &e) { __multi_logger->log_warn("FawkesMainThread", e); } } else { safe_wake(BlockedTimingAspect::WAKEUP_HOOK_PRE_LOOP, __max_thread_time_usec); safe_wake(BlockedTimingAspect::WAKEUP_HOOK_SENSOR_ACQUIRE, __max_thread_time_usec); safe_wake(BlockedTimingAspect::WAKEUP_HOOK_SENSOR_PREPARE, __max_thread_time_usec); safe_wake(BlockedTimingAspect::WAKEUP_HOOK_SENSOR_PROCESS, __max_thread_time_usec); safe_wake(BlockedTimingAspect::WAKEUP_HOOK_WORLDSTATE, __max_thread_time_usec); safe_wake(BlockedTimingAspect::WAKEUP_HOOK_THINK, __max_thread_time_usec); safe_wake(BlockedTimingAspect::WAKEUP_HOOK_SKILL, __max_thread_time_usec); safe_wake(BlockedTimingAspect::WAKEUP_HOOK_ACT, __max_thread_time_usec); safe_wake(BlockedTimingAspect::WAKEUP_HOOK_ACT_EXEC, __max_thread_time_usec); safe_wake(BlockedTimingAspect::WAKEUP_HOOK_POST_LOOP, __max_thread_time_usec); } __mainloop_mutex->unlock(); set_cancel_state(old_state); test_cancel(); __thread_manager->try_recover(__recovered_threads); if ( ! __recovered_threads.empty() ) { // threads have been recovered! //__multi_logger->log_error(name(), "Threads recovered %zu", __recovered_threads.size()); if(__enable_looptime_warnings) { if ( __recovered_threads.size() == 1 ) { __multi_logger->log_warn("FawkesMainThread", "The thread %s could be " "recovered and resumes normal operation", __recovered_threads.front().c_str()); } else { std::string s; for (std::list<std::string>::iterator i = __recovered_threads.begin(); i != __recovered_threads.end(); ++i) { s += *i + " "; } __multi_logger->log_warn("FawkesMainThread", "The following threads could be " "recovered and resumed normal operation: %s", s.c_str()); } } __recovered_threads.clear(); } if (__desired_loop_time_sec > 0) { __loop_end->stamp_systime(); float loop_time = *__loop_end - __loop_start; if(__enable_looptime_warnings) { // give some extra 10% to eliminate frequent false warnings due to regular // time jitter (TimeWait might not be all that precise) if (loop_time > 1.1 * __desired_loop_time_sec) { __multi_logger->log_warn("FawkesMainThread", "Loop time exceeded, " "desired: %f sec (%u usec), actual: %f sec", __desired_loop_time_sec, __desired_loop_time_usec, loop_time); } } } __plugin_manager->unlock(); if ( __time_wait ) { __time_wait->wait_systime(); } else { yield(); } } catch (Exception &e) { __multi_logger->log_warn("FawkesMainThread", "Exception caught while executing default main " "loop, ignoring."); __multi_logger->log_warn("FawkesMainThread", e); } catch (std::exception &e) { __multi_logger->log_warn("FawkesMainThread", "STL Exception caught while executing default main " "loop, ignoring. (what: %s)", e.what()); } // catch ... is not a good idea, would catch cancellation exception // at least needs to be rethrown. }