Пример #1
0
/** 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();
  }
}
Пример #2
0
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;
}
Пример #3
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.
}
Пример #4
0
/* 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;
}
Пример #5
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 {
      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.
}