update TasAutoMutex & use.

Automatically initialise it.  Add a name per instance.  Add a default timeout of 40ticks - at which point it enters anyway and logs to serial the potential deadlock.
This commit is contained in:
Simon Hailes 2021-01-02 09:02:11 +00:00
parent 85dea8bbcc
commit 9fdeac8924
1 changed files with 28 additions and 16 deletions

View File

@ -120,18 +120,23 @@ String GetResetReason(void)
// automutex. // automutex.
// create a mute in your driver with: // create a mute in your driver with:
// void *mutex = nullptr; // void *mutex = nullptr;
// TasAutoMutex::init(&mutex);
// //
// then protect any function with // then protect any function with
// TasAutoMutex m(mutex); // TasAutoMutex m(&mutex, "somename");
// - mutex is automatically initialised if not already intialised.
// - it will be automagically released when the function is over. // - it will be automagically released when the function is over.
// - the same thread can take multiple times (recursive). // - the same thread can take multiple times (recursive).
// - advanced options m.give() and m.take() allow you fine control within a function. // - advanced options m.give() and m.take() allow you fine control within a function.
// - if take=false at creat, it will not be initially taken.
// - name is used in serial log of mutex deadlock.
// - maxWait in ticks is how long it will wait before failing in a deadlock scenario (and then emitting on serial)
class TasAutoMutex { class TasAutoMutex {
SemaphoreHandle_t mutex; SemaphoreHandle_t mutex;
bool taken; bool taken;
int maxWait;
const char *name;
public: public:
TasAutoMutex(void * mutex, bool take=true); TasAutoMutex(void ** mutex, const char *name = "", int maxWait = 40, bool take=true);
~TasAutoMutex(); ~TasAutoMutex();
void give(); void give();
void take(); void take();
@ -139,13 +144,20 @@ class TasAutoMutex {
}; };
////////////////////////////////////////// //////////////////////////////////////////
TasAutoMutex::TasAutoMutex(void * mutex, bool take) { TasAutoMutex::TasAutoMutex(void **mutex, const char *name, int maxWait, bool take) {
if (mutex) { if (mutex) {
if (take) { if (!(*mutex)){
xSemaphoreTakeRecursive(mutex, portMAX_DELAY); TasAutoMutex::init(mutex);
this->taken = true; }
this->mutex = (SemaphoreHandle_t)*mutex;
this->maxWait = maxWait;
this->name = name;
if (take) {
this->taken = xSemaphoreTakeRecursive(this->mutex, this->maxWait);
if (!this->taken){
Serial.printf("\r\nMutexfail %s\r\n", this->name);
}
} }
this->mutex = (SemaphoreHandle_t)mutex;
} else { } else {
this->mutex = (SemaphoreHandle_t)nullptr; this->mutex = (SemaphoreHandle_t)nullptr;
} }
@ -179,14 +191,17 @@ void TasAutoMutex::give() {
void TasAutoMutex::take() { void TasAutoMutex::take() {
if (this->mutex) { if (this->mutex) {
if (!this->taken) { if (!this->taken) {
xSemaphoreTakeRecursive(this->mutex, portMAX_DELAY); this->taken = xSemaphoreTakeRecursive(this->mutex, this->maxWait);
this->taken = true; if (!this->taken){
Serial.printf("\r\nMutexfail %s\r\n", this->name);
}
} }
} }
} }
#endif // ESP32 #endif // ESP32
/*********************************************************************************************\ /*********************************************************************************************\
* Miscellaneous * Miscellaneous
\*********************************************************************************************/ \*********************************************************************************************/
@ -2046,7 +2061,7 @@ bool NeedLogRefresh(uint32_t req_loglevel, uint32_t index) {
#ifdef ESP32 #ifdef ESP32
// this takes the mutex, and will be release when the class is destroyed - // this takes the mutex, and will be release when the class is destroyed -
// i.e. when the functon leaves You CAN call mutex.give() to leave early. // i.e. when the functon leaves You CAN call mutex.give() to leave early.
TasAutoMutex mutex(TasmotaGlobal.log_buffer_mutex); TasAutoMutex mutex(&TasmotaGlobal.log_buffer_mutex);
#endif // ESP32 #endif // ESP32
// Skip initial buffer fill // Skip initial buffer fill
@ -2067,7 +2082,7 @@ bool GetLog(uint32_t req_loglevel, uint32_t* index_p, char** entry_pp, size_t* l
#ifdef ESP32 #ifdef ESP32
// this takes the mutex, and will be release when the class is destroyed - // this takes the mutex, and will be release when the class is destroyed -
// i.e. when the functon leaves You CAN call mutex.give() to leave early. // i.e. when the functon leaves You CAN call mutex.give() to leave early.
TasAutoMutex mutex(TasmotaGlobal.log_buffer_mutex); TasAutoMutex mutex(&TasmotaGlobal.log_buffer_mutex);
#endif // ESP32 #endif // ESP32
if (!index) { // Dump all if (!index) { // Dump all
@ -2110,12 +2125,9 @@ bool GetLog(uint32_t req_loglevel, uint32_t* index_p, char** entry_pp, size_t* l
void AddLogData(uint32_t loglevel, const char* log_data) { void AddLogData(uint32_t loglevel, const char* log_data) {
#ifdef ESP32 #ifdef ESP32
if (!TasmotaGlobal.log_buffer_mutex) {
TasAutoMutex::init(&TasmotaGlobal.log_buffer_mutex);
}
// this takes the mutex, and will be release when the class is destroyed - // this takes the mutex, and will be release when the class is destroyed -
// i.e. when the functon leaves You CAN call mutex.give() to leave early. // i.e. when the functon leaves You CAN call mutex.give() to leave early.
TasAutoMutex mutex(TasmotaGlobal.log_buffer_mutex); TasAutoMutex mutex(&TasmotaGlobal.log_buffer_mutex);
#endif // ESP32 #endif // ESP32
char mxtime[14]; // "13:45:21.999 " char mxtime[14]; // "13:45:21.999 "