Skip to content

Commit 4575ad3

Browse files
committed
Add Chrono support to Queue,MemoryPool,Mail
1 parent f6e8eca commit 4575ad3

File tree

3 files changed

+273
-29
lines changed

3 files changed

+273
-29
lines changed

rtos/Mail.h

Lines changed: 97 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ class Mail : private mbed::NonCopyable<Mail<T, queue_sz> > {
7070
*
7171
* @note You cannot call this function from ISR context.
7272
*/
73-
Mail() { };
73+
Mail() = default;
7474

7575
/** Check if the mail queue is empty.
7676
*
@@ -112,17 +112,49 @@ class Mail : private mbed::NonCopyable<Mail<T, queue_sz> > {
112112
return _pool.alloc();
113113
}
114114

115+
/** Allocate a memory block of type T, optionally blocking.
116+
*
117+
* @param rel_time Timeout value, or Kernel::wait_for_u32_forever.
118+
*
119+
* @return Pointer to memory block that you can fill with mail or nullptr in case error.
120+
*
121+
* @note You may call this function from ISR context if the millisec parameter is set to 0.
122+
*/
123+
T *alloc_for(Kernel::Clock::duration_u32 rel_time)
124+
{
125+
return _pool.alloc_for(rel_time);
126+
}
127+
115128
/** Allocate a memory block of type T, optionally blocking.
116129
*
117130
* @param millisec Timeout value, or osWaitForever.
118131
*
119132
* @return Pointer to memory block that you can fill with mail or nullptr in case error.
120133
*
121134
* @note You may call this function from ISR context if the millisec parameter is set to 0.
135+
* @deprecated Pass a chrono duration, not an integer millisecond count. For example use `5s` rather than `5000`.
122136
*/
137+
MBED_DEPRECATED_SINCE("mbed-os-6.0.0", "Pass a chrono duration, not an integer millisecond count. For example use `5s` rather than `5000`.")
123138
T *alloc_for(uint32_t millisec)
124139
{
125-
return _pool.alloc_for(millisec);
140+
return alloc_for(std::chrono::duration<uint32_t, std::milli>(millisec));
141+
}
142+
143+
/** Allocate a memory block of type T, blocking.
144+
*
145+
* @param abs_time Absolute timeout time, referenced to Kernel::Clock.
146+
*
147+
* @return Pointer to memory block that you can fill with mail or nullptr in case error.
148+
*
149+
* @note You cannot call this function from ISR context.
150+
* @note the underlying RTOS may have a limit to the maximum wait time
151+
* due to internal 32-bit computations, but this is guaranteed to work if the
152+
* wait is <= 0x7fffffff milliseconds (~24 days). If the limit is exceeded,
153+
* the wait will time out earlier than specified.
154+
*/
155+
T *alloc_until(Kernel::Clock::time_point abs_time)
156+
{
157+
return _pool.alloc_until(abs_time);
126158
}
127159

128160
/** Allocate a memory block of type T, blocking.
@@ -136,10 +168,13 @@ class Mail : private mbed::NonCopyable<Mail<T, queue_sz> > {
136168
* due to internal 32-bit computations, but this is guaranteed to work if the
137169
* wait is <= 0x7fffffff milliseconds (~24 days). If the limit is exceeded,
138170
* the wait will time out earlier than specified.
171+
* @deprecated Pass a chrono time_point, not an integer millisecond count. For example use `Kernel::Clock::now() + 5s`
172+
* rather than `Kernel::get_ms_count() + 5000`.
139173
*/
174+
MBED_DEPRECATED_SINCE("mbed-os-6.0.0", "Pass a chrono time_point, not an integer millisecond count. For example use `Kernel::Clock::now() + 5s` rather than `Kernel::get_ms_count() + 5000`.")
140175
T *alloc_until(uint64_t millisec)
141176
{
142-
return _pool.alloc_until(millisec);
177+
return alloc_until(Kernel::Clock::time_point(std::chrono::duration<uint64_t, std::milli>(millisec)));
143178
}
144179

145180
/** Allocate a memory block of type T, and set memory block to zero.
@@ -156,17 +191,49 @@ class Mail : private mbed::NonCopyable<Mail<T, queue_sz> > {
156191
return _pool.calloc();
157192
}
158193

194+
/** Allocate a memory block of type T, optionally blocking, and set memory block to zero.
195+
*
196+
* @param rel_time Timeout value, or Kernel::wait_for_u32_forever.
197+
*
198+
* @return Pointer to memory block that you can fill with mail or nullptr in case error.
199+
*
200+
* @note You may call this function from ISR context if the rel_time parameter is set to 0.
201+
*/
202+
T *calloc_for(Kernel::Clock::duration_u32 rel_time)
203+
{
204+
return _pool.alloc_for(rel_time);
205+
}
206+
159207
/** Allocate a memory block of type T, optionally blocking, and set memory block to zero.
160208
*
161209
* @param millisec Timeout value, or osWaitForever.
162210
*
163211
* @return Pointer to memory block that you can fill with mail or nullptr in case error.
164212
*
165213
* @note You may call this function from ISR context if the millisec parameter is set to 0.
214+
* @deprecated Pass a chrono duration, not an integer millisecond count. For example use `5s` rather than `5000`.
166215
*/
216+
MBED_DEPRECATED_SINCE("mbed-os-6.0.0", "Pass a chrono duration, not an integer millisecond count. For example use `5s` rather than `5000`.")
167217
T *calloc_for(uint32_t millisec)
168218
{
169-
return _pool.calloc_for(millisec);
219+
return calloc_for(std::chrono::duration<uint32_t, std::milli>(millisec));
220+
}
221+
222+
/** Allocate a memory block of type T, blocking, and set memory block to zero.
223+
*
224+
* @param abs_time Absolute timeout time, referenced to Kernel::Clock.
225+
*
226+
* @return Pointer to memory block that you can fill with mail or nullptr in case error.
227+
*
228+
* @note You cannot call this function from ISR context.
229+
* @note the underlying RTOS may have a limit to the maximum wait time
230+
* due to internal 32-bit computations, but this is guaranteed to work if the
231+
* wait is <= 0x7fffffff milliseconds (~24 days). If the limit is exceeded,
232+
* the wait will time out earlier than specified.
233+
*/
234+
T *calloc_until(Kernel::Clock::time_point abs_time)
235+
{
236+
return _pool.calloc_until(abs_time);
170237
}
171238

172239
/** Allocate a memory block of type T, blocking, and set memory block to zero.
@@ -180,10 +247,13 @@ class Mail : private mbed::NonCopyable<Mail<T, queue_sz> > {
180247
* due to internal 32-bit computations, but this is guaranteed to work if the
181248
* wait is <= 0x7fffffff milliseconds (~24 days). If the limit is exceeded,
182249
* the wait will time out earlier than specified.
250+
* @deprecated Pass a chrono time_point, not an integer millisecond count. For example use `Kernel::Clock::now() + 5s`
251+
* rather than `Kernel::get_ms_count() + 5000`.
183252
*/
253+
MBED_DEPRECATED_SINCE("mbed-os-6.0.0", "Pass a chrono time_point, not an integer millisecond count. For example use `Kernel::Clock::now() + 5s` rather than `Kernel::get_ms_count() + 5000`.")
184254
T *calloc_until(uint64_t millisec)
185255
{
186-
return _pool.calloc_until(millisec);
256+
return calloc_until(Kernel::Clock::time_point(std::chrono::duration<uint64_t, std::milli>(millisec)));
187257
}
188258

189259
/** Put a mail in the queue.
@@ -201,7 +271,26 @@ class Mail : private mbed::NonCopyable<Mail<T, queue_sz> > {
201271

202272
/** Get a mail from the queue.
203273
*
204-
* @param millisec Timeout value (default: osWaitForever).
274+
* @param millisec Timeout value.
275+
*
276+
* @return Event that contains mail information or error code.
277+
* @retval osEventMessage Message received.
278+
* @retval osOK No mail is available (and no timeout was specified).
279+
* @retval osEventTimeout No mail has arrived during the given timeout period.
280+
* @retval osErrorParameter A parameter is invalid or outside of a permitted range.
281+
*
282+
* @note You may call this function from ISR context if the millisec parameter is set to 0.
283+
* @deprecated Pass a chrono duration, not an integer millisecond count. For example use `5s` rather than `5000`.
284+
*/
285+
MBED_DEPRECATED_SINCE("mbed-os-6.0.0", "Pass a chrono duration, not an integer millisecond count. For example use `5s` rather than `5000`.")
286+
osEvent get(uint32_t millisec)
287+
{
288+
return get(std::chrono::duration<uint32_t, std::milli>(millisec));
289+
}
290+
291+
/** Get a mail from the queue.
292+
*
293+
* @param rel_time Timeout value (default: Kernel::wait_for_u32_forever).
205294
*
206295
* @return Event that contains mail information and status code. The status code
207296
* is stored in the status member:
@@ -212,9 +301,9 @@ class Mail : private mbed::NonCopyable<Mail<T, queue_sz> > {
212301
*
213302
* @note You may call this function from ISR context if the millisec parameter is set to 0.
214303
*/
215-
osEvent get(uint32_t millisec = osWaitForever)
304+
osEvent get(Kernel::Clock::duration_u32 rel_time = Kernel::wait_for_u32_forever)
216305
{
217-
osEvent evt = _queue.get(millisec);
306+
osEvent evt = _queue.get(rel_time);
218307
if (evt.status == osEventMessage) {
219308
evt.status = osEventMail;
220309
}

rtos/MemoryPool.h

Lines changed: 83 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -94,15 +94,38 @@ class MemoryPool : private mbed::NonCopyable<MemoryPool<T, pool_sz> > {
9494
return (T *)osMemoryPoolAlloc(_id, 0);
9595
}
9696

97+
/** Allocate a memory block from a memory pool, without blocking.
98+
@return address of the allocated memory block or nullptr in case of no memory available.
99+
100+
@note You may call this function from ISR context.
101+
*/
102+
T *try_alloc(void)
103+
{
104+
return (T *)osMemoryPoolAlloc(_id, 0);
105+
}
106+
97107
/** Allocate a memory block from a memory pool, optionally blocking.
98108
@param millisec timeout value (osWaitForever to wait forever)
99109
@return address of the allocated memory block or nullptr in case of no memory available.
100110
101111
@note You may call this function from ISR context if the millisec parameter is set to 0.
112+
@deprecated Pass a chrono duration, not an integer millisecond count. For example use `5s` rather than `5000`.
102113
*/
114+
MBED_DEPRECATED_SINCE("mbed-os-6.0.0", "Pass a chrono duration, not an integer millisecond count. For example use `5s` rather than `5000`.")
103115
T *alloc_for(uint32_t millisec)
104116
{
105-
return (T *)osMemoryPoolAlloc(_id, millisec);
117+
return alloc_for(std::chrono::duration<uint32_t, std::milli>(millisec));
118+
}
119+
120+
/** Allocate a memory block from a memory pool, optionally blocking.
121+
@param rel_time timeout value (Kernel::wait_for_u32_forever to wait forever)
122+
@return address of the allocated memory block or nullptr in case of no memory available.
123+
124+
@note You may call this function from ISR context if the rel_time parameter is set to 0.
125+
*/
126+
T *alloc_for(Kernel::Clock::duration_u32 rel_time)
127+
{
128+
return (T *)osMemoryPoolAlloc(_id, rel_time.count());
106129
}
107130

108131
/** Allocate a memory block from a memory pool, blocking.
@@ -114,21 +137,38 @@ class MemoryPool : private mbed::NonCopyable<MemoryPool<T, pool_sz> > {
114137
due to internal 32-bit computations, but this is guaranteed to work if the
115138
wait is <= 0x7fffffff milliseconds (~24 days). If the limit is exceeded,
116139
the wait will time out earlier than specified.
140+
@deprecated Pass a chrono time_point, not an integer millisecond count. For example use `Kernel::Clock::now() + 5s`
141+
rather than `Kernel::get_ms_count() + 5000`.
117142
*/
143+
MBED_DEPRECATED_SINCE("mbed-os-6.0.0", "Pass a chrono time_point, not an integer millisecond count. For example use `Kernel::Clock::now() + 5s` rather than `Kernel::get_ms_count() + 5000`.")
118144
T *alloc_until(uint64_t millisec)
119145
{
120-
uint64_t now = Kernel::get_ms_count();
121-
uint32_t delay;
122-
if (now >= millisec) {
123-
delay = 0;
124-
} else if (millisec - now >= osWaitForever) {
125-
delay = osWaitForever - 1;
146+
return alloc_until(Kernel::Clock::time_point(std::chrono::duration<uint64_t, std::milli>(millisec)));
147+
}
148+
149+
/** Allocate a memory block from a memory pool, blocking.
150+
@param abs_time absolute timeout time, referenced to Kernel::Clock.
151+
@return address of the allocated memory block or nullptr in case of no memory available.
152+
153+
@note You cannot call this function from ISR context.
154+
@note the underlying RTOS may have a limit to the maximum wait time
155+
due to internal 32-bit computations, but this is guaranteed to work if the
156+
wait is <= 0x7fffffff milliseconds (~24 days). If the limit is exceeded,
157+
the wait will time out earlier than specified.
158+
*/
159+
T *alloc_until(Kernel::Clock::time_point abs_time)
160+
{
161+
Kernel::Clock::time_point now = Kernel::Clock::now();
162+
Kernel::Clock::duration_u32 rel_time;
163+
if (now >= abs_time) {
164+
rel_time = rel_time.zero();
165+
} else if (abs_time - now > Kernel::wait_for_u32_max) {
166+
rel_time = Kernel::wait_for_u32_max;
126167
} else {
127-
delay = millisec - now;
168+
rel_time = abs_time - now;
128169
}
129-
return alloc_for(delay);
170+
return alloc_for(rel_time);
130171
}
131-
132172
/** Allocate a memory block from a memory pool, without blocking, and set memory block to zero.
133173
@return address of the allocated memory block or nullptr in case of no memory available.
134174
@@ -148,10 +188,23 @@ class MemoryPool : private mbed::NonCopyable<MemoryPool<T, pool_sz> > {
148188
@return address of the allocated memory block or nullptr in case of no memory available.
149189
150190
@note You may call this function from ISR context if the millisec parameter is set to 0.
191+
@deprecated Pass a chrono duration, not an integer millisecond count. For example use `5s` rather than `5000`.
151192
*/
193+
MBED_DEPRECATED_SINCE("mbed-os-6.0.0", "Pass a chrono duration, not an integer millisecond count. For example use `5s` rather than `5000`.")
152194
T *calloc_for(uint32_t millisec)
153195
{
154-
T *item = alloc_for(millisec);
196+
return calloc_for(std::chrono::duration<uint32_t, std::milli>(millisec));
197+
}
198+
199+
/** Allocate a memory block from a memory pool, optionally blocking, and set memory block to zero.
200+
@param rel_time timeout value (Kernel::wait_for_u32_forever to wait forever)
201+
@return address of the allocated memory block or nullptr in case of no memory available.
202+
203+
@note You may call this function from ISR context if the rel_time parameter is set to 0.
204+
*/
205+
T *calloc_for(Kernel::Clock::duration_u32 rel_time)
206+
{
207+
T *item = alloc_for(rel_time);
155208
if (item != nullptr) {
156209
memset(item, 0, sizeof(T));
157210
}
@@ -167,10 +220,28 @@ class MemoryPool : private mbed::NonCopyable<MemoryPool<T, pool_sz> > {
167220
due to internal 32-bit computations, but this is guaranteed to work if the
168221
wait is <= 0x7fffffff milliseconds (~24 days). If the limit is exceeded,
169222
the wait will time out earlier than specified.
223+
@deprecated Pass a chrono time_point, not an integer millisecond count. For example use `Kernel::Clock::now() + 5s`
224+
rather than `Kernel::get_ms_count() + 5000`.
170225
*/
226+
MBED_DEPRECATED_SINCE("mbed-os-6.0.0", "Pass a chrono time_point, not an integer millisecond count. For example use `Kernel::Clock::now() + 5s` rather than `Kernel::get_ms_count() + 5000`.")
171227
T *calloc_until(uint64_t millisec)
172228
{
173-
T *item = alloc_until(millisec);
229+
return alloc_until(Kernel::Clock::time_point(std::chrono::duration<uint64_t, std::milli>(millisec)));
230+
}
231+
232+
/** Allocate a memory block from a memory pool, blocking, and set memory block to zero.
233+
@param abs_time absolute timeout time, referenced to Kernel::Clock.
234+
@return address of the allocated memory block or nullptr in case of no memory available.
235+
236+
@note You cannot call this function from ISR context.
237+
@note the underlying RTOS may have a limit to the maximum wait time
238+
due to internal 32-bit computations, but this is guaranteed to work if the
239+
wait is <= 0x7fffffff milliseconds (~24 days). If the limit is exceeded,
240+
the wait will time out earlier than specified.
241+
*/
242+
T *calloc_until(Kernel::Clock::time_point abs_time)
243+
{
244+
T *item = alloc_until(abs_time);
174245
if (item != nullptr) {
175246
memset(item, 0, sizeof(T));
176247
}

0 commit comments

Comments
 (0)