yay, linux bin semaph finished
This commit is contained in:
parent
60872f936c
commit
8676fcd9a9
127
osal/linux/BinarySemaphore.cpp
Normal file
127
osal/linux/BinarySemaphore.cpp
Normal file
@ -0,0 +1,127 @@
|
|||||||
|
#include <framework/osal/linux/BinarySemaphore.h>
|
||||||
|
#include <framework/serviceinterface/ServiceInterfaceStream.h>
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
#include <errno.h>
|
||||||
|
#include <string.h>
|
||||||
|
}
|
||||||
|
|
||||||
|
BinarySemaphore::BinarySemaphore() {
|
||||||
|
// Using unnamed semaphores for now
|
||||||
|
initSemaphore();
|
||||||
|
}
|
||||||
|
|
||||||
|
BinarySemaphore::~BinarySemaphore() {
|
||||||
|
sem_destroy(&handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
BinarySemaphore::BinarySemaphore(BinarySemaphore&& s) {
|
||||||
|
initSemaphore();
|
||||||
|
}
|
||||||
|
|
||||||
|
BinarySemaphore& BinarySemaphore::operator =(
|
||||||
|
BinarySemaphore&& s) {
|
||||||
|
initSemaphore();
|
||||||
|
return * this;
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t BinarySemaphore::acquire(uint32_t timeoutMs) {
|
||||||
|
int result = 0;
|
||||||
|
if(timeoutMs == SemaphoreIF::NO_TIMEOUT) {
|
||||||
|
result = sem_trywait(&handle);
|
||||||
|
}
|
||||||
|
if(timeoutMs == SemaphoreIF::MAX_TIMEOUT) {
|
||||||
|
result = sem_wait(&handle);
|
||||||
|
}
|
||||||
|
else if(timeoutMs > SemaphoreIF::NO_TIMEOUT){
|
||||||
|
timespec timeOut;
|
||||||
|
clock_gettime(CLOCK_REALTIME, &timeOut);
|
||||||
|
uint64_t nseconds = timeOut.tv_sec * 1000000000 + timeOut.tv_nsec;
|
||||||
|
nseconds += timeoutMs * 1000000;
|
||||||
|
timeOut.tv_sec = nseconds / 1000000000;
|
||||||
|
timeOut.tv_nsec = nseconds - timeOut.tv_sec * 1000000000;
|
||||||
|
result = sem_timedwait(&handle, &timeOut);
|
||||||
|
if(result != 0 and errno == EINVAL) {
|
||||||
|
sif::debug << "BinarySemaphore::acquire: Invalid time value possible"
|
||||||
|
<< std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(result == 0) {
|
||||||
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(result) {
|
||||||
|
case(EAGAIN):
|
||||||
|
// Operation could not be performed without blocking (for sem_trywait)
|
||||||
|
case(ETIMEDOUT):
|
||||||
|
// Semaphore is 0
|
||||||
|
return SemaphoreIF::SEMAPHORE_TIMEOUT;
|
||||||
|
case(EINVAL):
|
||||||
|
// Semaphore invalid
|
||||||
|
return SemaphoreIF::SEMAPHORE_INVALID;
|
||||||
|
case(EINTR):
|
||||||
|
// Call was interrupted by signal handler
|
||||||
|
sif::debug << "BinarySemaphore::acquire: Signal handler interrupted"
|
||||||
|
<< std::endl;
|
||||||
|
/* No break */
|
||||||
|
default:
|
||||||
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t BinarySemaphore::release() {
|
||||||
|
return release(&this->handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
ReturnValue_t BinarySemaphore::release(sem_t *handle) {
|
||||||
|
int result = sem_post(handle);
|
||||||
|
if(result == 0) {
|
||||||
|
return HasReturnvaluesIF::RETURN_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(errno) {
|
||||||
|
case(EINVAL):
|
||||||
|
// Semaphore invalid
|
||||||
|
return SemaphoreIF::SEMAPHORE_INVALID;
|
||||||
|
case(EOVERFLOW):
|
||||||
|
// SEM_MAX_VALUE overflow. This should never happen
|
||||||
|
default:
|
||||||
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t BinarySemaphore::getSemaphoreCounter() const {
|
||||||
|
// And another ugly cast :-D
|
||||||
|
return getSemaphoreCounter(const_cast<sem_t*>(&this->handle));
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t BinarySemaphore::getSemaphoreCounter(sem_t *handle) {
|
||||||
|
int value = 0;
|
||||||
|
int result = sem_getvalue(handle, &value);
|
||||||
|
if (result == 0) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
else if(result != 0 and errno == EINVAL) {
|
||||||
|
sif::debug << "BInarySemaphore::getSemaphoreCounter: Invalid"
|
||||||
|
" Semaphore." << std::endl;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// This should never happen.
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void BinarySemaphore::initSemaphore() {
|
||||||
|
auto result = sem_init(&handle, true, 1);
|
||||||
|
if(result == -1) {
|
||||||
|
switch(errno) {
|
||||||
|
case(EINVAL):
|
||||||
|
// Value excees SEM_VALUE_MAX
|
||||||
|
case(ENOSYS):
|
||||||
|
// System does not support process-shared semaphores
|
||||||
|
sif::error << "BinarySemaphore: Init failed with" << strerror(errno)
|
||||||
|
<< std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
68
osal/linux/BinarySemaphore.h
Normal file
68
osal/linux/BinarySemaphore.h
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
#ifndef FRAMEWORK_OSAL_FREERTOS_BINARYSEMPAHORE_H_
|
||||||
|
#define FRAMEWORK_OSAL_FREERTOS_BINARYSEMPAHORE_H_
|
||||||
|
|
||||||
|
#include <framework/returnvalues/HasReturnvaluesIF.h>
|
||||||
|
#include <framework/tasks/SemaphoreIF.h>
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
#include <semaphore.h>
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief OS Tool to achieve synchronization of between tasks or between
|
||||||
|
* task and ISR. The default semaphore implementation creates a
|
||||||
|
* binary semaphore, which can only be taken once.
|
||||||
|
* @details
|
||||||
|
* See: http://www.man7.org/linux/man-pages/man7/sem_overview.7.html
|
||||||
|
* @author R. Mueller
|
||||||
|
* @ingroup osal
|
||||||
|
*/
|
||||||
|
class BinarySemaphore: public SemaphoreIF,
|
||||||
|
public HasReturnvaluesIF {
|
||||||
|
public:
|
||||||
|
static const uint8_t INTERFACE_ID = CLASS_ID::SEMAPHORE_IF;
|
||||||
|
|
||||||
|
//! @brief Default ctor
|
||||||
|
BinarySemaphore();
|
||||||
|
//! @brief Copy ctor, deleted explicitely.
|
||||||
|
BinarySemaphore(const BinarySemaphore&) = delete;
|
||||||
|
//! @brief Copy assignment, deleted explicitely.
|
||||||
|
BinarySemaphore& operator=(const BinarySemaphore&) = delete;
|
||||||
|
//! @brief Move ctor
|
||||||
|
BinarySemaphore (BinarySemaphore &&);
|
||||||
|
//! @brief Move assignment
|
||||||
|
BinarySemaphore & operator=(BinarySemaphore &&);
|
||||||
|
//! @brief Destructor
|
||||||
|
virtual ~BinarySemaphore();
|
||||||
|
|
||||||
|
void initSemaphore();
|
||||||
|
|
||||||
|
uint8_t getSemaphoreCounter() const override;
|
||||||
|
static uint8_t getSemaphoreCounter(sem_t* handle);
|
||||||
|
/**
|
||||||
|
* Take the binary semaphore.
|
||||||
|
* If the semaphore has already been taken, the task will be blocked
|
||||||
|
* for a maximum of #timeoutMs or until the semaphore is given back,
|
||||||
|
* for example by an ISR or another task.
|
||||||
|
* @param timeoutMs
|
||||||
|
* @return -@c RETURN_OK on success
|
||||||
|
* -@c SemaphoreIF::SEMAPHORE_TIMEOUT on timeout
|
||||||
|
*/
|
||||||
|
ReturnValue_t acquire(uint32_t timeoutMs =
|
||||||
|
SemaphoreIF::NO_TIMEOUT) override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Release the binary semaphore.
|
||||||
|
* @return -@c RETURN_OK on success
|
||||||
|
* -@c SemaphoreIF::SEMAPHORE_NOT_OWNED if the semaphores is
|
||||||
|
* already available.
|
||||||
|
*/
|
||||||
|
ReturnValue_t release() override;
|
||||||
|
|
||||||
|
static ReturnValue_t release(sem_t* handle);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
sem_t handle;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* FRAMEWORK_OSAL_FREERTOS_BINARYSEMPAHORE_H_ */
|
@ -7,7 +7,7 @@
|
|||||||
#include <framework/osal/linux/MessageQueue.h>
|
#include <framework/osal/linux/MessageQueue.h>
|
||||||
|
|
||||||
|
|
||||||
MessageQueue::MessageQueue(size_t messageDepth, size_t maxMessageSize) :
|
MessageQueue::MessageQueue(size_t messageDepth, size_t maxMessageSize):
|
||||||
id(0), lastPartner(0), defaultDestination(NO_QUEUE) {
|
id(0), lastPartner(0), defaultDestination(NO_QUEUE) {
|
||||||
//debug << "MessageQueue::MessageQueue: Creating a queue" << std::endl;
|
//debug << "MessageQueue::MessageQueue: Creating a queue" << std::endl;
|
||||||
mq_attr attributes;
|
mq_attr attributes;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#ifndef OS_RTEMS_MUTEX_H_
|
#ifndef OS_LINUX_MUTEX_H_
|
||||||
#define OS_RTEMS_MUTEX_H_
|
#define OS_LINUX_MUTEX_H_
|
||||||
|
|
||||||
#include <framework/ipc/MutexIF.h>
|
#include <framework/ipc/MutexIF.h>
|
||||||
|
|
||||||
|
@ -20,18 +20,18 @@ SemaphoreFactory* SemaphoreFactory::instance() {
|
|||||||
return SemaphoreFactory::factoryInstance;
|
return SemaphoreFactory::factoryInstance;
|
||||||
}
|
}
|
||||||
|
|
||||||
SemaphoreIF* SemaphoreFactory::createBinarySemaphore() {
|
SemaphoreIF* SemaphoreFactory::createBinarySemaphore(uint32_t arguments) {
|
||||||
sif::error << "Semaphore not implemented for Linux yet" << std::endl;
|
sif::error << "Semaphore not implemented for Linux yet" << std::endl;
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
SemaphoreIF* SemaphoreFactory::createCountingSemaphore(uint8_t count,
|
SemaphoreIF* SemaphoreFactory::createCountingSemaphore(uint8_t count,
|
||||||
uint8_t initCount) {
|
uint8_t initCount, uint32_t arguments) {
|
||||||
sif::error << "Counting Semaphore not implemented for "
|
sif::error << "Counting Semaphore not implemented for "
|
||||||
"Linux yet" << std::endl;
|
"Linux yet" << std::endl;
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SemaphoreFactory::deleteMutex(SemaphoreIF* semaphore) {
|
void SemaphoreFactory::deleteSemaphore(SemaphoreIF* semaphore) {
|
||||||
delete semaphore;
|
delete semaphore;
|
||||||
}
|
}
|
||||||
|
@ -36,7 +36,7 @@ public:
|
|||||||
SemaphoreIF* createCountingSemaphore(const uint8_t maxCount,
|
SemaphoreIF* createCountingSemaphore(const uint8_t maxCount,
|
||||||
uint8_t initCount, uint32_t arguments = 0);
|
uint8_t initCount, uint32_t arguments = 0);
|
||||||
|
|
||||||
void deleteSemaphore(SemaphoreIF* mutex);
|
void deleteSemaphore(SemaphoreIF* semaphore);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/**
|
/**
|
||||||
|
@ -30,7 +30,7 @@ public:
|
|||||||
static constexpr ReturnValue_t SEMAPHORE_TIMEOUT = MAKE_RETURN_CODE(1);
|
static constexpr ReturnValue_t SEMAPHORE_TIMEOUT = MAKE_RETURN_CODE(1);
|
||||||
//! The current semaphore can not be given, because it is not owned
|
//! The current semaphore can not be given, because it is not owned
|
||||||
static constexpr ReturnValue_t SEMAPHORE_NOT_OWNED = MAKE_RETURN_CODE(2);
|
static constexpr ReturnValue_t SEMAPHORE_NOT_OWNED = MAKE_RETURN_CODE(2);
|
||||||
static constexpr ReturnValue_t SEMAPHORE_NULLPOINTER = MAKE_RETURN_CODE(3);
|
static constexpr ReturnValue_t SEMAPHORE_INVALID = MAKE_RETURN_CODE(3);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generic call to acquire a semaphore.
|
* Generic call to acquire a semaphore.
|
||||||
|
Loading…
Reference in New Issue
Block a user