Split off RecursiveMutex from Mutex (#437)
* Split off RecursiveMutex from Mutex * Fix * Code quality
This commit is contained in:
committed by
GitHub
parent
f48654d3dc
commit
3fc2ff8bc6
@@ -1,34 +1,25 @@
|
||||
/**
|
||||
* @file mutex.h
|
||||
* @file Mutex.h
|
||||
* Mutex
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "Check.h"
|
||||
#include "Lock.h"
|
||||
#include "RtosCompatSemaphore.h"
|
||||
#include "Thread.h"
|
||||
#include "kernel/Kernel.h"
|
||||
|
||||
#include <memory>
|
||||
#include <cassert>
|
||||
|
||||
namespace tt {
|
||||
|
||||
/**
|
||||
* Wrapper for FreeRTOS xSemaphoreCreateMutex and xSemaphoreCreateRecursiveMutex
|
||||
* Wrapper for FreeRTOS xSemaphoreCreateMutex
|
||||
* Cannot be used in IRQ mode (within ISR context)
|
||||
*/
|
||||
class Mutex final : public Lock {
|
||||
|
||||
public:
|
||||
/**
|
||||
* A "Normal" mutex can only be locked once. Even from within the same task/thread.
|
||||
* A "Recursive" mutex can be locked again from the same task/thread.
|
||||
*/
|
||||
enum class Type {
|
||||
Normal,
|
||||
Recursive,
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
struct SemaphoreHandleDeleter {
|
||||
@@ -38,29 +29,40 @@ private:
|
||||
}
|
||||
};
|
||||
|
||||
std::unique_ptr<std::remove_pointer_t<QueueHandle_t>, SemaphoreHandleDeleter> handle;
|
||||
Type type;
|
||||
std::unique_ptr<std::remove_pointer_t<QueueHandle_t>, SemaphoreHandleDeleter> handle = std::unique_ptr<std::remove_pointer_t<QueueHandle_t>, SemaphoreHandleDeleter>(xSemaphoreCreateMutex());
|
||||
|
||||
public:
|
||||
|
||||
using Lock::lock;
|
||||
|
||||
explicit Mutex(Type type = Type::Normal);
|
||||
explicit Mutex() {
|
||||
assert(handle != nullptr);
|
||||
}
|
||||
|
||||
~Mutex() override = default;
|
||||
|
||||
/** Attempt to lock the mutex. Blocks until timeout passes or lock is acquired.
|
||||
* @param[in] timeout
|
||||
* @return success result
|
||||
*/
|
||||
bool lock(TickType_t timeout) const override;
|
||||
bool lock(TickType_t timeout) const override {
|
||||
assert(!kernel::isIsr());
|
||||
return xSemaphoreTake(handle.get(), timeout) == pdPASS;
|
||||
}
|
||||
|
||||
/** Attempt to unlock the mutex.
|
||||
* @return success result
|
||||
*/
|
||||
bool unlock() const override;
|
||||
bool unlock() const override {
|
||||
assert(!kernel::isIsr());
|
||||
return xSemaphoreGive(handle.get()) == pdPASS;
|
||||
}
|
||||
|
||||
/** @return the owner of the thread */
|
||||
ThreadId getOwner() const;
|
||||
ThreadId getOwner() const {
|
||||
assert(!kernel::isIsr());
|
||||
return xSemaphoreGetMutexHolder(handle.get());
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace
|
||||
} // namespace tt
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
/**
|
||||
* @file RecursiveMutex.h
|
||||
* RecursiveMutex
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "Lock.h"
|
||||
#include "RtosCompatSemaphore.h"
|
||||
#include "Thread.h"
|
||||
#include "kernel/Kernel.h"
|
||||
#include <memory>
|
||||
#include <cassert>
|
||||
|
||||
namespace tt {
|
||||
|
||||
/**
|
||||
* Wrapper for FreeRTOS xSemaphoreCreateRecursiveMutex
|
||||
* Cannot be used in IRQ mode (within ISR context)
|
||||
*/
|
||||
class RecursiveMutex final : public Lock {
|
||||
|
||||
private:
|
||||
|
||||
struct SemaphoreHandleDeleter {
|
||||
void operator()(QueueHandle_t handleToDelete) {
|
||||
assert(!kernel::isIsr());
|
||||
vSemaphoreDelete(handleToDelete);
|
||||
}
|
||||
};
|
||||
|
||||
std::unique_ptr<std::remove_pointer_t<QueueHandle_t>, SemaphoreHandleDeleter> handle = std::unique_ptr<std::remove_pointer_t<QueueHandle_t>, SemaphoreHandleDeleter>(xSemaphoreCreateRecursiveMutex());
|
||||
|
||||
public:
|
||||
|
||||
using Lock::lock;
|
||||
|
||||
explicit RecursiveMutex() {
|
||||
assert(handle != nullptr);
|
||||
}
|
||||
|
||||
~RecursiveMutex() override = default;
|
||||
|
||||
/** Attempt to lock the mutex. Blocks until timeout passes or lock is acquired.
|
||||
* @param[in] timeout
|
||||
* @return success result
|
||||
*/
|
||||
bool lock(TickType_t timeout) const override {
|
||||
assert(!kernel::isIsr());
|
||||
return xSemaphoreTakeRecursive(handle.get(), timeout) == pdPASS;
|
||||
}
|
||||
|
||||
/** Attempt to unlock the mutex.
|
||||
* @return success result
|
||||
*/
|
||||
bool unlock() const override {
|
||||
assert(!kernel::isIsr());
|
||||
return xSemaphoreGiveRecursive(handle.get()) == pdPASS;
|
||||
}
|
||||
|
||||
/** @return the owner of the thread */
|
||||
ThreadId getOwner() const {
|
||||
assert(!kernel::isIsr());
|
||||
return xSemaphoreGetMutexHolder(handle.get());
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace
|
||||
Reference in New Issue
Block a user