Skip to content

Commit f0ac234

Browse files
committed
Prevent DeepSleepLock from leaving sleep locked
Add _lock_count to DeepSleepLock and use this to prevent deep sleep from staying locked when the DeepSleepLock objected is destroyed after an unbalanced number of calls to lock and unlock.
1 parent c60194f commit f0ac234

File tree

1 file changed

+24
-4
lines changed

1 file changed

+24
-4
lines changed

platform/DeepSleepLock.h

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@
1616
#ifndef MBED_DEEPSLEEPLOCK_H
1717
#define MBED_DEEPSLEEPLOCK_H
1818

19+
#include <limits.h>
1920
#include "platform/mbed_sleep.h"
21+
#include "platform/mbed_critical.h"
2022

2123
namespace mbed {
2224

@@ -36,29 +38,47 @@ namespace mbed {
3638
* @endcode
3739
*/
3840
class DeepSleepLock {
41+
private:
42+
uint16_t _lock_count;
43+
3944
public:
40-
DeepSleepLock()
45+
DeepSleepLock(): _lock_count(1)
4146
{
4247
sleep_manager_lock_deep_sleep();
4348
}
4449

4550
~DeepSleepLock()
4651
{
47-
sleep_manager_unlock_deep_sleep();
52+
if (_lock_count) {
53+
sleep_manager_unlock_deep_sleep();
54+
}
4855
}
4956

5057
/** Mark the start of a locked deep sleep section
5158
*/
5259
void lock()
5360
{
54-
sleep_manager_lock_deep_sleep();
61+
uint16_t count = core_util_atomic_incr_u16(&_lock_count, 1);
62+
if (1 == count) {
63+
sleep_manager_lock_deep_sleep();
64+
}
65+
if (0 == count) {
66+
error("DeepSleepLock overflow (> USHRT_MAX)");
67+
}
5568
}
5669

5770
/** Mark the end of a locked deep sleep section
5871
*/
5972
void unlock()
6073
{
61-
sleep_manager_unlock_deep_sleep();
74+
uint16_t count = core_util_atomic_decr_u16(&_lock_count, 1);
75+
if (count == 0) {
76+
sleep_manager_unlock_deep_sleep();
77+
}
78+
if (count == USHRT_MAX) {
79+
core_util_critical_section_exit();
80+
error("DeepSleepLock underflow (< 0)");
81+
}
6282
}
6383
};
6484

0 commit comments

Comments
 (0)