F´ Flight Software - C/C++ Documentation
A framework for building embedded system applications to NASA flight quality standards.
CountingSemaphore.cpp
Go to the documentation of this file.
1 // ======================================================================
2 // \title Os/Posix/CountingSemaphore.cpp
3 // \brief Posix implementations for Os::CountingSemaphore
4 // ======================================================================
6 #include <cerrno>
7 #include <ctime>
8 #include "Fw/Types/Assert.hpp"
9 #include "Os/Posix/error.hpp"
10 
11 namespace Os {
12 namespace Posix {
13 namespace Semaphore {
14 
16  // Default all pthread semaphores to only be visible to single application (since F' FSW is a single application)
17  int status = sem_init(&this->m_handle.m_semaphore, 0, initial_count);
18  FW_ASSERT(status == 0, static_cast<FwAssertArgType>(status));
19 }
20 
22  (void)sem_destroy(&this->m_handle.m_semaphore);
23 }
24 
26  int status = 0;
27  // @non-terminating@: retry on EINTR
28  do {
29  status = sem_wait(&this->m_handle.m_semaphore);
30  } while (status != 0 && errno == EINTR);
31  FW_ASSERT(status == 0 || errno != 0, status);
32  return status == 0 ? Status::OP_OK : posix_status_to_semaphore_status(errno);
33 }
34 
36  struct timespec abstime{};
37  int clock_status = clock_gettime(CLOCK_REALTIME, &abstime);
38  FW_ASSERT(clock_status == 0, static_cast<FwAssertArgType>(clock_status));
39 
40  abstime.tv_sec += interval.getSeconds();
41  abstime.tv_nsec += static_cast<long>(interval.getUSeconds()) * 1000L;
42 
43  if (abstime.tv_nsec >= 1000000000L) {
44  abstime.tv_sec += abstime.tv_nsec / 1000000000L;
45  abstime.tv_nsec = abstime.tv_nsec % 1000000000L;
46  }
47 
48  int status = 0;
49  // @non-terminating@: retry on EINTR
50  do {
51  status = sem_timedwait(&this->m_handle.m_semaphore, &abstime);
52  } while (status != 0 && errno == EINTR);
53  FW_ASSERT(status == 0 || errno != 0, status);
54  return status == 0 ? Status::OP_OK : posix_status_to_semaphore_status(errno);
55 }
56 
58  int status = sem_trywait(&this->m_handle.m_semaphore);
59  FW_ASSERT(status == 0 || errno != 0, status);
60  return status == 0 ? Status::OP_OK : posix_status_to_semaphore_status(errno);
61 }
62 
64  int status = sem_post(&this->m_handle.m_semaphore);
65  FW_ASSERT(status == 0 || errno != 0, status);
66  return status == 0 ? Status::OP_OK : posix_status_to_semaphore_status(errno);
67 }
68 
70  return &m_handle;
71 }
72 
73 } // namespace Semaphore
74 } // namespace Posix
75 } // namespace Os
PosixCountingSemaphore::Status tryWait() override
non-blocking attempt to decrement the semaphore
Operation succeeded.
Definition: Os.hpp:27
CountingSemaphore::Status posix_status_to_semaphore_status(int posix_status)
Definition: error.cpp:204
PosixCountingSemaphore::Status post() override
post (increment) the semaphore, potentially waking a waiting thread
U32 getUSeconds() const
PosixCountingSemaphore::Status wait() override
wait (decrement) the semaphore, blocking if count is zero
PosixCountingSemaphore::Status waitTimeout(const Fw::TimeInterval &interval) override
wait on the semaphore with a timeout
CountingSemaphoreHandle * getHandle() override
return the underlying semaphore handle (implementation specific)
#define FW_ASSERT(...)
Definition: Assert.hpp:14
U32 getSeconds() const