Skip to content

Commit e99a9fa

Browse files
committed
Add support for static mutexes
Add PlatformMutexStatic which is lazily initialized in static context which allows it to be garbage collected. The lazy initialization also allows it to be used earlier than normal mutexes.
1 parent c55c07a commit e99a9fa

File tree

8 files changed

+59
-7
lines changed

8 files changed

+59
-7
lines changed

hal/api/AnalogIn.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ class AnalogIn {
118118
}
119119

120120
analogin_t _adc;
121-
static PlatformMutex _mutex;
121+
static PlatformMutexStatic _mutex;
122122
};
123123

124124
} // namespace mbed

hal/api/FileBase.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ class FileBase {
6565
/* disallow copy constructor and assignment operators */
6666
private:
6767
static FileBase *_head;
68-
static PlatformMutex _mutex;
68+
static PlatformMutexStatic _mutex;
6969

7070
FileBase *_next;
7171
const char * const _name;

hal/api/I2C.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@ class I2C {
181181
i2c_t _i2c;
182182
static I2C *_owner;
183183
int _hz;
184-
static PlatformMutex _mutex;
184+
static PlatformMutexStatic _mutex;
185185
};
186186

187187
} // namespace mbed

hal/api/platform.h

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "device.h"
2222
#include "PinNames.h"
2323
#include "PeripheralNames.h"
24+
#include "critical.h"
2425

2526
#include <cstddef>
2627
#include <cstdlib>
@@ -54,4 +55,55 @@ class PlatformMutex {
5455

5556
#endif
5657

58+
/** The static version of a PlatformMutex
59+
*
60+
* This class must only be used in a static context -
61+
* this class must never be allocated or created on the
62+
* stack.
63+
*
64+
* This class is lazily initialized on first use.
65+
* This class is a POD type so if it is not used it will
66+
* be garbage collected.
67+
*/
68+
struct PlatformMutexStatic {
69+
PlatformMutex* _mutex;
70+
71+
void _init() {
72+
PlatformMutex* current = _mutex;
73+
PlatformMutex* new_mutex;
74+
75+
if (NULL == current) {
76+
bool done = false;
77+
new_mutex = new PlatformMutex;
78+
while (!done) {
79+
done = core_util_atomic_cas_ptr((void**)&_mutex, (void**)&current, (void*)new_mutex);
80+
if (current != NULL) {
81+
// Mutex was created on another thread first
82+
// so delete ours
83+
delete new_mutex;
84+
break;
85+
}
86+
}
87+
}
88+
}
89+
90+
/** Wait until this Mutex becomes available.
91+
*/
92+
void lock() {
93+
if (NULL == _mutex) {
94+
_init();
95+
}
96+
_mutex->lock();
97+
}
98+
99+
/** Unlock the mutex that has previously been locked by the same thread
100+
*/
101+
void unlock() {
102+
if (NULL == _mutex) {
103+
_init();
104+
}
105+
_mutex->unlock();
106+
}
107+
};
108+
57109
#endif

hal/common/AnalogIn.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222

2323
namespace mbed {
2424

25-
PlatformMutex AnalogIn::_mutex;
25+
PlatformMutexStatic AnalogIn::_mutex;
2626

2727
};
2828

hal/common/FileBase.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
namespace mbed {
1919

2020
FileBase *FileBase::_head = NULL;
21-
PlatformMutex FileBase::_mutex;
21+
PlatformMutexStatic FileBase::_mutex;
2222

2323
FileBase::FileBase(const char *name, PathType t) : _next(NULL),
2424
_name(name),

hal/common/I2C.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
namespace mbed {
2121

2222
I2C *I2C::_owner = NULL;
23-
PlatformMutex I2C::_mutex;
23+
PlatformMutexStatic I2C::_mutex;
2424

2525
I2C::I2C(PinName sda, PinName scl) :
2626
#if DEVICE_I2C_ASYNCH

hal/common/retarget.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ extern const char __stderr_name[] = "/stderr";
7272
* (or rather index+3, as filehandles 0-2 are stdin/out/err).
7373
*/
7474
static FileHandle *filehandles[OPEN_MAX];
75-
static PlatformMutex filehandle_mutex;
75+
static PlatformMutexStatic filehandle_mutex;
7676

7777
FileHandle::~FileHandle() {
7878
filehandle_mutex.lock();

0 commit comments

Comments
 (0)