Skip to content

Commit 7f7e9a7

Browse files
author
dave
committed
#28 spin lock improvements for ESP32 and mbed to detect thread usage.
1 parent 9f9fa9e commit 7f7e9a7

File tree

3 files changed

+35
-8
lines changed

3 files changed

+35
-8
lines changed

src/SimpleSpinLock.cpp

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,13 @@
66
#include "SimpleSpinLock.h"
77

88
bool SimpleSpinLock::tryLock() {
9-
// if our task already owns the lock then we are good.
10-
return (locked && initiatingTask && taskManager.getRunningTask() == initiatingTask);
9+
#if defined(IOA_MULTITHREADED)
10+
if(locked && getCurrentThreadId() != currentThread) return false;
11+
return (locked && taskManager.getRunningTask() == initiatingTask);
12+
#else
13+
// We are not on RTOS, if our task already owns the lock then we are good.
14+
return (locked && taskManager.getRunningTask() == initiatingTask);
15+
#endif
1116
}
1217

1318
bool SimpleSpinLock::spinLock(unsigned long iterations) {
@@ -20,6 +25,9 @@ bool SimpleSpinLock::spinLock(unsigned long iterations) {
2025
while(iterations) {
2126
if (tm_internal::atomicSwapBool(&locked, false, true)) {
2227
tm_internal::atomicWritePtr(&initiatingTask, taskManager.getRunningTask());
28+
#if defined(IOA_MULTITHREADED)
29+
currentThread = (void*)getCurrentThreadId();
30+
#endif
2331
++count;
2432
return true;
2533
}
@@ -42,6 +50,11 @@ void SimpleSpinLock::unlock() {
4250
if(count == 0) {
4351
tm_internal::atomicWritePtr(&initiatingTask, nullptr);
4452
tm_internal::atomicWriteBool(&locked, false);
53+
54+
#if defined(IOA_MULTITHREADED)
55+
currentThread = nullptr;
56+
#endif
57+
4558
}
4659
}
4760

src/SimpleSpinLock.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,11 @@
1616
class SimpleSpinLock {
1717
private:
1818
tm_internal::TimerTaskAtomicPtr initiatingTask;
19-
volatile uint8_t count;
19+
#if defined(IOA_MULTITHREADED)
20+
volatile void* currentThread = nullptr;
21+
#endif
2022
tm_internal::TmAtomicBool locked;
21-
23+
volatile uint8_t count;
2224
public:
2325
/**
2426
* Construct a lock that represents this object

src/TaskPlatformDeps.h

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,24 @@ class TimerTask;
1111

1212
#if defined(__MBED__) || defined(ARDUINO_ARDUINO_NANO33BLE)
1313

14+
#if !defined(TM_DONT_USE_CAPTURE)
1415
#define TM_ALLOW_CAPTURED_LAMBDA
16+
#endif
1517

1618
// check if this is Arduino mbed or regular mbed.
1719
#if defined(ARDUINO_ARDUINO_NANO33BLE)
1820
# define IOA_USE_ARDUINO
1921
# define ARDUINO_MBED_MODE
2022
# include "Arduino.h"
23+
# define IOA_MULTITHREADED
24+
#include "rtos/rtos.h"
25+
inline void* getCurrentThreadId() { return rtos::ThisThread::get_id(); }
2126
#else
2227
# define IOA_USE_MBED
2328
# include "mbed.h"
29+
# define IOA_MULTITHREADED
30+
inline void* getCurrentThreadId() { return ThisThread::get_id(); }
31+
2432
# if !defined(PIO_NEEDS_RTOS_WORKAROUND)
2533
# include "rtos.h"
2634
# endif // PIO_NEED_RTOS_WORKAROUND
@@ -81,8 +89,9 @@ namespace tm_internal {
8189
#include "Arduino.h"
8290
typedef uint8_t pintype_t;
8391
# define IOA_USE_ARDUINO
92+
#if !defined(TM_DONT_USE_CAPTURE)
8493
# define TM_ALLOW_CAPTURED_LAMBDA
85-
94+
#endif
8695

8796
#if defined(ESP8266)
8897
#include <atomic>
@@ -151,6 +160,9 @@ namespace tm_internal {
151160
}
152161
}
153162
#else
163+
# define IOA_MULTITHREADED
164+
inline void* getCurrentThreadId() { return xTaskGetCurrentTaskHandle() ; }
165+
154166
namespace tm_internal {
155167

156168
typedef TimerTask* volatile TimerTaskAtomicPtr;
@@ -261,7 +273,7 @@ inline void atomicWritePtr(TimerTaskAtomicPtr* pPtr, TimerTask* newValue) {
261273

262274
// for all mbed and ESP boards we already enable lambda captures, SAMD is a known extra case that works.
263275
// we can only enable on larger boards with enough memory to take the extra size of the structures.
264-
#if !defined(TM_DONT_USE_LAMBDA) && defined(ARDUINO_ARCH_SAMD)
276+
#if !defined(TM_DONT_USE_CAPTURE) && defined(ARDUINO_ARCH_SAMD)
265277
# define TM_ALLOW_CAPTURED_LAMBDA
266278
#endif
267279

@@ -345,10 +357,10 @@ namespace tm_internal {
345357
// Here we have one last go at determining if we should enable capture lambdas by checking if the functional include
346358
// is available, we only do so if we are on GCC > 5
347359
//
348-
# if !defined(TM_ALLOW_CAPTURED_LAMBDA) && __GNUC__ >= 5
360+
# if !defined(TM_ALLOW_CAPTURED_LAMBDA) && !defined(TM_DONT_USE_CAPTURE) && __GNUC__ >= 5
349361
#if __has_include(<functional>)
350362
# define TM_ALLOW_CAPTURED_LAMBDA
351-
#endif
363+
#endif // _has_include
352364
#endif // GCC>=5 and !TM_ALLOW_CAPTURED_LAMBDA
353365

354366
#endif //TASKMANGERIO_PLATFORMDETERMINATION_H

0 commit comments

Comments
 (0)