Scheduler.cpp 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355
  1. #include <AP_HAL/AP_HAL.h>
  2. #include "AP_HAL_SITL.h"
  3. #include "Scheduler.h"
  4. #include "UARTDriver.h"
  5. #include <sys/time.h>
  6. #include <fenv.h>
  7. #include <AP_BoardConfig/AP_BoardConfig.h>
  8. #if defined (__clang__)
  9. #include <stdlib.h>
  10. #else
  11. #include <malloc.h>
  12. #endif
  13. #include <AP_RCProtocol/AP_RCProtocol.h>
  14. using namespace HALSITL;
  15. extern const AP_HAL::HAL& hal;
  16. AP_HAL::Proc Scheduler::_failsafe = nullptr;
  17. AP_HAL::MemberProc Scheduler::_timer_proc[SITL_SCHEDULER_MAX_TIMER_PROCS] = {nullptr};
  18. uint8_t Scheduler::_num_timer_procs = 0;
  19. bool Scheduler::_in_timer_proc = false;
  20. AP_HAL::MemberProc Scheduler::_io_proc[SITL_SCHEDULER_MAX_TIMER_PROCS] = {nullptr};
  21. uint8_t Scheduler::_num_io_procs = 0;
  22. bool Scheduler::_in_io_proc = false;
  23. bool Scheduler::_should_reboot = false;
  24. bool Scheduler::_in_semaphore_take_wait = false;
  25. Scheduler::thread_attr *Scheduler::threads;
  26. HAL_Semaphore Scheduler::_thread_sem;
  27. Scheduler::Scheduler(SITL_State *sitlState) :
  28. _sitlState(sitlState),
  29. _stopped_clock_usec(0)
  30. {
  31. }
  32. void Scheduler::init()
  33. {
  34. _main_ctx = pthread_self();
  35. }
  36. bool Scheduler::in_main_thread() const
  37. {
  38. if (!_in_timer_proc && !_in_io_proc && pthread_self() == _main_ctx) {
  39. return true;
  40. }
  41. return false;
  42. }
  43. /*
  44. * semaphore_wait_hack_required - possibly move time input step
  45. * forward even if we are currently pretending to be the IO or timer
  46. * threads.
  47. *
  48. * Without this, if another thread has taken a semaphore (e.g. the
  49. * Object Avoidance thread), and an "IO process" tries to take that
  50. * semaphore with a timeout specified, then we end up not advancing
  51. * time (due to the logic in SITL_State::wait_clock) and thus taking
  52. * the semaphore never times out - meaning we essentially deadlock.
  53. */
  54. bool Scheduler::semaphore_wait_hack_required()
  55. {
  56. if (pthread_self() != _main_ctx) {
  57. // only the main thread ever moves stuff forwards
  58. return false;
  59. }
  60. return _in_semaphore_take_wait;
  61. }
  62. void Scheduler::delay_microseconds(uint16_t usec)
  63. {
  64. uint64_t start = AP_HAL::micros64();
  65. do {
  66. uint64_t dtime = AP_HAL::micros64() - start;
  67. if (dtime >= usec) {
  68. break;
  69. }
  70. _sitlState->wait_clock(start + usec);
  71. } while (true);
  72. }
  73. void Scheduler::delay(uint16_t ms)
  74. {
  75. uint32_t start = AP_HAL::millis();
  76. uint32_t now = start;
  77. do {
  78. delay_microseconds(1000);
  79. if (_min_delay_cb_ms <= (ms - (now - start))) {
  80. if (in_main_thread()) {
  81. call_delay_cb();
  82. }
  83. }
  84. now = AP_HAL::millis();
  85. } while (now - start < ms);
  86. }
  87. void Scheduler::register_timer_process(AP_HAL::MemberProc proc)
  88. {
  89. for (uint8_t i = 0; i < _num_timer_procs; i++) {
  90. if (_timer_proc[i] == proc) {
  91. return;
  92. }
  93. }
  94. if (_num_timer_procs < SITL_SCHEDULER_MAX_TIMER_PROCS) {
  95. _timer_proc[_num_timer_procs] = proc;
  96. _num_timer_procs++;
  97. }
  98. }
  99. void Scheduler::register_io_process(AP_HAL::MemberProc proc)
  100. {
  101. for (uint8_t i = 0; i < _num_io_procs; i++) {
  102. if (_io_proc[i] == proc) {
  103. return;
  104. }
  105. }
  106. if (_num_io_procs < SITL_SCHEDULER_MAX_TIMER_PROCS) {
  107. _io_proc[_num_io_procs] = proc;
  108. _num_io_procs++;
  109. }
  110. }
  111. void Scheduler::register_timer_failsafe(AP_HAL::Proc failsafe, uint32_t period_us)
  112. {
  113. _failsafe = failsafe;
  114. }
  115. void Scheduler::system_initialized() {
  116. if (_initialized) {
  117. AP_HAL::panic(
  118. "PANIC: scheduler system initialized called more than once");
  119. }
  120. int exceptions = FE_OVERFLOW | FE_DIVBYZERO;
  121. #ifndef __i386__
  122. // i386 with gcc doesn't work with FE_INVALID
  123. exceptions |= FE_INVALID;
  124. #endif
  125. if (_sitlState->_sitl == nullptr || _sitlState->_sitl->float_exception) {
  126. feenableexcept(exceptions);
  127. } else {
  128. feclearexcept(exceptions);
  129. }
  130. _initialized = true;
  131. }
  132. void Scheduler::sitl_end_atomic() {
  133. if (_nested_atomic_ctr == 0) {
  134. hal.uartA->printf("NESTED ATOMIC ERROR\n");
  135. } else {
  136. _nested_atomic_ctr--;
  137. }
  138. }
  139. void Scheduler::reboot(bool hold_in_bootloader)
  140. {
  141. if (AP_BoardConfig::in_sensor_config_error()) {
  142. // the _should_reboot flag set below is not checked by the
  143. // sensor-config-error loop, so force the reboot here:
  144. HAL_SITL::actually_reboot();
  145. abort();
  146. }
  147. _should_reboot = true;
  148. }
  149. void Scheduler::_run_timer_procs()
  150. {
  151. if (_in_timer_proc) {
  152. // the timer calls took longer than the period of the
  153. // timer. This is bad, and may indicate a serious
  154. // driver failure. We can't just call the drivers
  155. // again, as we could run out of stack. So we only
  156. // call the _failsafe call. It's job is to detect if
  157. // the drivers or the main loop are indeed dead and to
  158. // activate whatever failsafe it thinks may help if
  159. // need be. We assume the failsafe code can't
  160. // block. If it does then we will recurse and die when
  161. // we run out of stack
  162. if (_failsafe != nullptr) {
  163. _failsafe();
  164. }
  165. return;
  166. }
  167. _in_timer_proc = true;
  168. // now call the timer based drivers
  169. for (int i = 0; i < _num_timer_procs; i++) {
  170. if (_timer_proc[i]) {
  171. _timer_proc[i]();
  172. }
  173. }
  174. // and the failsafe, if one is setup
  175. if (_failsafe != nullptr) {
  176. _failsafe();
  177. }
  178. _in_timer_proc = false;
  179. }
  180. void Scheduler::_run_io_procs()
  181. {
  182. if (_in_io_proc) {
  183. return;
  184. }
  185. _in_io_proc = true;
  186. // now call the IO based drivers
  187. for (int i = 0; i < _num_io_procs; i++) {
  188. if (_io_proc[i]) {
  189. _io_proc[i]();
  190. }
  191. }
  192. _in_io_proc = false;
  193. hal.uartA->_timer_tick();
  194. hal.uartB->_timer_tick();
  195. hal.uartC->_timer_tick();
  196. hal.uartD->_timer_tick();
  197. hal.uartE->_timer_tick();
  198. hal.uartF->_timer_tick();
  199. hal.uartG->_timer_tick();
  200. hal.uartH->_timer_tick();
  201. hal.storage->_timer_tick();
  202. check_thread_stacks();
  203. AP::RC().update();
  204. }
  205. /*
  206. set simulation timestamp
  207. */
  208. void Scheduler::stop_clock(uint64_t time_usec)
  209. {
  210. _stopped_clock_usec = time_usec;
  211. if (time_usec - _last_io_run > 10000) {
  212. _last_io_run = time_usec;
  213. _run_io_procs();
  214. }
  215. }
  216. /*
  217. trampoline for thread create
  218. */
  219. void *Scheduler::thread_create_trampoline(void *ctx)
  220. {
  221. struct thread_attr *a = (struct thread_attr *)ctx;
  222. a->f[0]();
  223. WITH_SEMAPHORE(_thread_sem);
  224. if (threads == a) {
  225. threads = a->next;
  226. } else {
  227. for (struct thread_attr *p=threads; p->next; p=p->next) {
  228. if (p->next == a) {
  229. p->next = p->next->next;
  230. break;
  231. }
  232. }
  233. }
  234. free(a->stack);
  235. free(a->f);
  236. delete a;
  237. return nullptr;
  238. }
  239. #ifndef PTHREAD_STACK_MIN
  240. #define PTHREAD_STACK_MIN 16384U
  241. #endif
  242. /*
  243. create a new thread
  244. */
  245. bool Scheduler::thread_create(AP_HAL::MemberProc proc, const char *name, uint32_t stack_size, priority_base base, int8_t priority)
  246. {
  247. WITH_SEMAPHORE(_thread_sem);
  248. // even an empty thread takes 2500 bytes on Linux, so always add 2300, giving us 200 bytes
  249. // safety margin
  250. stack_size += 2300;
  251. pthread_t thread {};
  252. const uint32_t alloc_stack = MAX(size_t(PTHREAD_STACK_MIN),stack_size);
  253. struct thread_attr *a = new struct thread_attr;
  254. if (!a) {
  255. return false;
  256. }
  257. // take a copy of the MemberProc, it is freed after thread exits
  258. a->f = (AP_HAL::MemberProc *)malloc(sizeof(proc));
  259. if (!a->f) {
  260. goto failed;
  261. }
  262. if (posix_memalign(&a->stack, 4096, alloc_stack) != 0) {
  263. goto failed;
  264. }
  265. if (!a->stack) {
  266. goto failed;
  267. }
  268. memset(a->stack, stackfill, alloc_stack);
  269. a->stack_min = (const uint8_t *)((((uint8_t *)a->stack) + alloc_stack) - stack_size);
  270. a->stack_size = stack_size;
  271. a->f[0] = proc;
  272. a->name = name;
  273. pthread_attr_init(&a->attr);
  274. #if !defined(__CYGWIN__) && !defined(__CYGWIN64__)
  275. if (pthread_attr_setstack(&a->attr, a->stack, alloc_stack) != 0) {
  276. AP_HAL::panic("Failed to set stack of size %u for thread %s", alloc_stack, name);
  277. }
  278. #endif
  279. if (pthread_create(&thread, &a->attr, thread_create_trampoline, a) != 0) {
  280. goto failed;
  281. }
  282. a->next = threads;
  283. threads = a;
  284. return true;
  285. failed:
  286. if (a->stack) {
  287. free(a->stack);
  288. }
  289. if (a->f) {
  290. free(a->f);
  291. }
  292. delete a;
  293. return false;
  294. }
  295. /*
  296. check for stack overflow
  297. */
  298. void Scheduler::check_thread_stacks(void)
  299. {
  300. WITH_SEMAPHORE(_thread_sem);
  301. for (struct thread_attr *p=threads; p; p=p->next) {
  302. const uint8_t ncheck = 8;
  303. for (uint8_t i=0; i<ncheck; i++) {
  304. if (p->stack_min[i] != stackfill) {
  305. AP_HAL::panic("stack overflow in thread %s\n", p->name);
  306. }
  307. }
  308. }
  309. }