LCOV - code coverage report
Current view: top level - AP_HAL_SITL - Semaphores.cpp (source / functions) Hit Total Coverage
Test: lcov.info Lines: 76 85 89.4 %
Date: 2026-09-09 11:02:08 Functions: 9 9 100.0 %

          Line data    Source code
       1             : #include <AP_HAL/AP_HAL.h>
       2             : 
       3             : #if CONFIG_HAL_BOARD == HAL_BOARD_SITL
       4             : 
       5             : #include "Semaphores.h"
       6             : #include "Scheduler.h"
       7             : 
       8             : extern const AP_HAL::HAL& hal;
       9             : 
      10             : using namespace HALSITL;
      11             : 
      12             : // construct a semaphore
      13      259093 : Semaphore::Semaphore()
      14             : {
      15             :     pthread_mutexattr_t attr;
      16      259093 :     pthread_mutexattr_init(&attr);
      17      259093 :     pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
      18      259093 :     pthread_mutex_init(&_lock, &attr);
      19      259093 : }
      20             : 
      21             : 
      22  5714936779 : bool Semaphore::give()
      23             : {
      24  5714936779 :     take_count--;
      25  5714936779 :     if (take_count == 0) {
      26  5679956696 :         owner = (pthread_t)-1;
      27             :     }
      28  5714936779 :     if (pthread_mutex_unlock(&_lock) != 0) {
      29           0 :         AP_HAL::panic("Bad semaphore usage");
      30             :     }
      31  5715597970 :     return true;
      32             : }
      33             : 
      34     3172223 : void Semaphore::check_owner() const
      35             : {
      36             :     // should probably make sure we're holding the semaphore here....
      37     3172223 :     if (owner != pthread_self()) {
      38           0 :         AP_HAL::panic("Wrong owner");
      39             :     }
      40     3172223 : }
      41             : 
      42  5604187459 : bool Semaphore::take(uint32_t timeout_ms)
      43             : {
      44  5604187459 :     if (timeout_ms == HAL_SEMAPHORE_BLOCK_FOREVER) {
      45  5603170424 :         if (pthread_mutex_lock(&_lock) == 0) {
      46  5603797930 :             owner = pthread_self();
      47  5603797930 :             take_count++;
      48  5603797930 :             return true;
      49             :         }
      50           0 :         return false;
      51             :     }
      52     1017035 :     if (take_nonblocking()) {
      53     1048405 :         owner = pthread_self();
      54     1048405 :         return true;
      55             :     }
      56           8 :     uint64_t start = AP_HAL::micros64();
      57             :     do {
      58           8 :         Scheduler::from(hal.scheduler)->set_in_semaphore_take_wait(true);
      59           8 :         hal.scheduler->delay_microseconds(200);
      60           8 :         Scheduler::from(hal.scheduler)->set_in_semaphore_take_wait(false);
      61           8 :         if (take_nonblocking()) {
      62           8 :             owner = pthread_self();
      63           8 :             return true;
      64             :         }
      65           0 :     } while ((AP_HAL::micros64() - start) < timeout_ms * 1000);
      66           0 :     return false;
      67             : }
      68             : 
      69   111920291 : bool Semaphore::take_nonblocking()
      70             : {
      71   111920291 :     if (pthread_mutex_trylock(&_lock) == 0) {
      72   111920319 :         owner = pthread_self();
      73   111920319 :         take_count++;
      74   111920319 :         return true;
      75             :     }
      76          27 :     return false;
      77             : }
      78             : 
      79             : 
      80             : /*
      81             :   binary semaphore using pthread condition variables
      82             :  */
      83             : 
      84        4298 : BinarySemaphore::BinarySemaphore(bool initial_state) :
      85        4298 :     AP_HAL::BinarySemaphore(initial_state)
      86             : {
      87        4298 :     pthread_cond_init(&cond, NULL);
      88        4298 :     pending = initial_state;
      89        4298 : }
      90             : 
      91       22743 : bool BinarySemaphore::wait(uint32_t timeout_us)
      92             : {
      93       22743 :     WITH_SEMAPHORE(mtx);
      94       22743 :     if (!pending) {
      95       45343 :         if (hal.scheduler->in_main_thread() ||
      96       22659 :             Scheduler::from(hal.scheduler)->semaphore_wait_hack_required()) {
      97             :             /*
      98             :               when in the main thread we need to do a busy wait to ensure
      99             :               the clock advances
     100             :             */
     101          25 :             uint64_t end_us = AP_HAL::micros64() + timeout_us;
     102          25 :             struct timespec ts {};
     103             :             do {
     104       30025 :                 if (pthread_cond_timedwait(&cond, &mtx._lock, &ts) == 0) {
     105           0 :                     pending = false;
     106           0 :                     return true;
     107             :                 }
     108       30025 :                 hal.scheduler->delay_microseconds(10);
     109       30025 :             } while (AP_HAL::micros64() < end_us);
     110          25 :             return false;
     111             :         }
     112             : 
     113             :         struct timespec ts;
     114       22659 :         if (clock_gettime(CLOCK_REALTIME, &ts) != 0) {
     115           0 :             return false;
     116             :         }
     117       22659 :         ts.tv_sec += timeout_us/1000000UL;
     118       22659 :         ts.tv_nsec += (timeout_us % 1000000U) * 1000UL;
     119       22659 :         if (ts.tv_nsec >= 1000000000L) {
     120          18 :             ts.tv_sec++;
     121          18 :             ts.tv_nsec -= 1000000000L;
     122             :         }
     123       22659 :         if (pthread_cond_timedwait(&cond, &mtx._lock, &ts) != 0) {
     124       22658 :             return false;
     125             :         }
     126             :     }
     127          59 :     pending = false;
     128          59 :     return true;
     129       22742 : }
     130             : 
     131      287161 : bool BinarySemaphore::wait_blocking(void)
     132             : {
     133      287161 :     WITH_SEMAPHORE(mtx);
     134      287161 :     if (!pending) {
     135      283525 :         if (pthread_cond_wait(&cond, &mtx._lock) != 0) {
     136           0 :             return false;
     137             :         }
     138             :     }
     139      287159 :     pending = false;
     140      287159 :     return true;
     141      287159 : }
     142             : 
     143      288377 : void BinarySemaphore::signal(void)
     144             : {
     145      288377 :     WITH_SEMAPHORE(mtx);
     146      288377 :     if (!pending) {
     147      287219 :         pending = true;
     148      287219 :         pthread_cond_signal(&cond);
     149             :     }
     150      288377 : }
     151             : 
     152             : #endif  // CONFIG_HAL_BOARD

Generated by: LCOV version 1.14