Semaphores.cpp 1.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. #include <AP_HAL/AP_HAL.h>
  2. #if CONFIG_HAL_BOARD == HAL_BOARD_SITL
  3. #include "Semaphores.h"
  4. #include "Scheduler.h"
  5. extern const AP_HAL::HAL& hal;
  6. using namespace HALSITL;
  7. // construct a semaphore
  8. Semaphore::Semaphore()
  9. {
  10. pthread_mutex_init(&_lock, nullptr);
  11. }
  12. // construct a recursive semaphore (allows a thread to take it more than once)
  13. Semaphore_Recursive::Semaphore_Recursive()
  14. {
  15. pthread_mutexattr_t attr;
  16. pthread_mutexattr_init(&attr);
  17. pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
  18. pthread_mutex_init(&_lock, &attr);
  19. }
  20. bool Semaphore::give()
  21. {
  22. if (pthread_mutex_unlock(&_lock) != 0) {
  23. AP_HAL::panic("Bad semaphore usage");
  24. }
  25. return true;
  26. }
  27. bool Semaphore::take(uint32_t timeout_ms)
  28. {
  29. if (timeout_ms == HAL_SEMAPHORE_BLOCK_FOREVER) {
  30. return pthread_mutex_lock(&_lock) == 0;
  31. }
  32. if (take_nonblocking()) {
  33. return true;
  34. }
  35. uint64_t start = AP_HAL::micros64();
  36. do {
  37. Scheduler::from(hal.scheduler)->set_in_semaphore_take_wait(true);
  38. hal.scheduler->delay_microseconds(200);
  39. Scheduler::from(hal.scheduler)->set_in_semaphore_take_wait(false);
  40. if (take_nonblocking()) {
  41. return true;
  42. }
  43. } while ((AP_HAL::micros64() - start) < timeout_ms * 1000);
  44. return false;
  45. }
  46. bool Semaphore::take_nonblocking()
  47. {
  48. return pthread_mutex_trylock(&_lock) == 0;
  49. }
  50. #endif // CONFIG_HAL_BOARD