Skip to content

Commit cc14246

Browse files
committed
Add Chrono support to Queue,MemoryPool,Mail
1 parent 53485bc commit cc14246

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
@@ -66,7 +66,7 @@ class Mail : private mbed::NonCopyable<Mail<T, queue_sz> > {
6666
*
6767
* @note You cannot call this function from ISR context.
6868
*/
69-
Mail() { };
69+
Mail() = default;
7070

7171
/** Check if the mail queue is empty.
7272
*
@@ -108,17 +108,49 @@ class Mail : private mbed::NonCopyable<Mail<T, queue_sz> > {
108108
return _pool.alloc();
109109
}
110110

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

124156
/** Allocate a memory block of type T, blocking.
@@ -132,10 +164,13 @@ class Mail : private mbed::NonCopyable<Mail<T, queue_sz> > {
132164
* due to internal 32-bit computations, but this is guaranteed to work if the
133165
* wait is <= 0x7fffffff milliseconds (~24 days). If the limit is exceeded,
134166
* the wait will time out earlier than specified.
167+
* @deprecated Pass a chrono time_point, not an integer millisecond count. For example use `Kernel::Clock::now() + 5s`
168+
* rather than `Kernel::get_ms_count() + 5000`.
135169
*/
170+
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`.")
136171
T *alloc_until(uint64_t millisec)
137172
{
138-
return _pool.alloc_until(millisec);
173+
return alloc_until(Kernel::Clock::time_point(std::chrono::duration<uint64_t, std::milli>(millisec)));
139174
}
140175

141176
/** Allocate a memory block of type T, and set memory block to zero.
@@ -152,17 +187,49 @@ class Mail : private mbed::NonCopyable<Mail<T, queue_sz> > {
152187
return _pool.calloc();
153188
}
154189

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

168235
/** Allocate a memory block of type T, blocking, and set memory block to zero.
@@ -176,10 +243,13 @@ class Mail : private mbed::NonCopyable<Mail<T, queue_sz> > {
176243
* due to internal 32-bit computations, but this is guaranteed to work if the
177244
* wait is <= 0x7fffffff milliseconds (~24 days). If the limit is exceeded,
178245
* the wait will time out earlier than specified.
246+
* @deprecated Pass a chrono time_point, not an integer millisecond count. For example use `Kernel::Clock::now() + 5s`
247+
* rather than `Kernel::get_ms_count() + 5000`.
179248
*/
249+
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`.")
180250
T *calloc_until(uint64_t millisec)
181251
{
182-
return _pool.calloc_until(millisec);
252+
return calloc_until(Kernel::Clock::time_point(std::chrono::duration<uint64_t, std::milli>(millisec)));
183253
}
184254

185255
/** Put a mail in the queue.
@@ -197,7 +267,26 @@ class Mail : private mbed::NonCopyable<Mail<T, queue_sz> > {
197267

198268
/** Get a mail from the queue.
199269
*
200-
* @param millisec Timeout value (default: osWaitForever).
270+
* @param millisec Timeout value.
271+
*
272+
* @return Event that contains mail information or error code.
273+
* @retval osEventMessage Message received.
274+
* @retval osOK No mail is available (and no timeout was specified).
275+
* @retval osEventTimeout No mail has arrived during the given timeout period.
276+
* @retval osErrorParameter A parameter is invalid or outside of a permitted range.
277+
*
278+
* @note You may call this function from ISR context if the millisec parameter is set to 0.
279+
* @deprecated Pass a chrono duration, not an integer millisecond count. For example use `5s` rather than `5000`.
280+
*/
281+
MBED_DEPRECATED_SINCE("mbed-os-6.0.0", "Pass a chrono duration, not an integer millisecond count. For example use `5s` rather than `5000`.")
282+
osEvent get(uint32_t millisec)
283+
{
284+
return get(std::chrono::duration<uint32_t, std::milli>(millisec));
285+
}
286+
287+
/** Get a mail from the queue.
288+
*
289+
* @param rel_time Timeout value (default: Kernel::wait_for_u32_forever).
201290
*
202291
* @return Event that contains mail information or error code.
203292
* @retval osEventMessage Message received.
@@ -207,9 +296,9 @@ class Mail : private mbed::NonCopyable<Mail<T, queue_sz> > {
207296
*
208297
* @note You may call this function from ISR context if the millisec parameter is set to 0.
209298
*/
210-
osEvent get(uint32_t millisec = osWaitForever)
299+
osEvent get(Kernel::Clock::duration_u32 rel_time = Kernel::wait_for_u32_forever)
211300
{
212-
osEvent evt = _queue.get(millisec);
301+
osEvent evt = _queue.get(rel_time);
213302
if (evt.status == osEventMessage) {
214303
evt.status = osEventMail;
215304
}

rtos/MemoryPool.h

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

93+
/** Allocate a memory block from a memory pool, without blocking.
94+
@return address of the allocated memory block or nullptr in case of no memory available.
95+
96+
@note You may call this function from ISR context.
97+
*/
98+
T *try_alloc(void)
99+
{
100+
return (T *)osMemoryPoolAlloc(_id, 0);
101+
}
102+
93103
/** Allocate a memory block from a memory pool, optionally blocking.
94104
@param millisec timeout value (osWaitForever to wait forever)
95105
@return address of the allocated memory block or nullptr in case of no memory available.
96106
97107
@note You may call this function from ISR context if the millisec parameter is set to 0.
108+
@deprecated Pass a chrono duration, not an integer millisecond count. For example use `5s` rather than `5000`.
98109
*/
110+
MBED_DEPRECATED_SINCE("mbed-os-6.0.0", "Pass a chrono duration, not an integer millisecond count. For example use `5s` rather than `5000`.")
99111
T *alloc_for(uint32_t millisec)
100112
{
101-
return (T *)osMemoryPoolAlloc(_id, millisec);
113+
return alloc_for(std::chrono::duration<uint32_t, std::milli>(millisec));
114+
}
115+
116+
/** Allocate a memory block from a memory pool, optionally blocking.
117+
@param rel_time timeout value (Kernel::wait_for_u32_forever to wait forever)
118+
@return address of the allocated memory block or nullptr in case of no memory available.
119+
120+
@note You may call this function from ISR context if the rel_time parameter is set to 0.
121+
*/
122+
T *alloc_for(Kernel::Clock::duration_u32 rel_time)
123+
{
124+
return (T *)osMemoryPoolAlloc(_id, rel_time.count());
102125
}
103126

104127
/** Allocate a memory block from a memory pool, blocking.
@@ -110,21 +133,38 @@ class MemoryPool : private mbed::NonCopyable<MemoryPool<T, pool_sz> > {
110133
due to internal 32-bit computations, but this is guaranteed to work if the
111134
wait is <= 0x7fffffff milliseconds (~24 days). If the limit is exceeded,
112135
the wait will time out earlier than specified.
136+
@deprecated Pass a chrono time_point, not an integer millisecond count. For example use `Kernel::Clock::now() + 5s`
137+
rather than `Kernel::get_ms_count() + 5000`.
113138
*/
139+
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`.")
114140
T *alloc_until(uint64_t millisec)
115141
{
116-
uint64_t now = Kernel::get_ms_count();
117-
uint32_t delay;
118-
if (now >= millisec) {
119-
delay = 0;
120-
} else if (millisec - now >= osWaitForever) {
121-
delay = osWaitForever - 1;
142+
return alloc_until(Kernel::Clock::time_point(std::chrono::duration<uint64_t, std::milli>(millisec)));
143+
}
144+
145+
/** Allocate a memory block from a memory pool, blocking.
146+
@param abs_time absolute timeout time, referenced to Kernel::Clock.
147+
@return address of the allocated memory block or nullptr in case of no memory available.
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+
Kernel::Clock::time_point now = Kernel::Clock::now();
158+
Kernel::Clock::duration_u32 rel_time;
159+
if (now >= abs_time) {
160+
rel_time = rel_time.zero();
161+
} else if (abs_time - now > Kernel::wait_for_u32_max) {
162+
rel_time = Kernel::wait_for_u32_max;
122163
} else {
123-
delay = millisec - now;
164+
rel_time = abs_time - now;
124165
}
125-
return alloc_for(delay);
166+
return alloc_for(rel_time);
126167
}
127-
128168
/** Allocate a memory block from a memory pool, without blocking, and set memory block to zero.
129169
@return address of the allocated memory block or nullptr in case of no memory available.
130170
@@ -144,10 +184,23 @@ class MemoryPool : private mbed::NonCopyable<MemoryPool<T, pool_sz> > {
144184
@return address of the allocated memory block or nullptr in case of no memory available.
145185
146186
@note You may call this function from ISR context if the millisec parameter is set to 0.
187+
@deprecated Pass a chrono duration, not an integer millisecond count. For example use `5s` rather than `5000`.
147188
*/
189+
MBED_DEPRECATED_SINCE("mbed-os-6.0.0", "Pass a chrono duration, not an integer millisecond count. For example use `5s` rather than `5000`.")
148190
T *calloc_for(uint32_t millisec)
149191
{
150-
T *item = alloc_for(millisec);
192+
return calloc_for(std::chrono::duration<uint32_t, std::milli>(millisec));
193+
}
194+
195+
/** Allocate a memory block from a memory pool, optionally blocking, and set memory block to zero.
196+
@param rel_time timeout value (Kernel::wait_for_u32_forever to wait forever)
197+
@return address of the allocated memory block or nullptr in case of no memory available.
198+
199+
@note You may call this function from ISR context if the rel_time parameter is set to 0.
200+
*/
201+
T *calloc_for(Kernel::Clock::duration_u32 rel_time)
202+
{
203+
T *item = alloc_for(rel_time);
151204
if (item != nullptr) {
152205
memset(item, 0, sizeof(T));
153206
}
@@ -163,10 +216,28 @@ class MemoryPool : private mbed::NonCopyable<MemoryPool<T, pool_sz> > {
163216
due to internal 32-bit computations, but this is guaranteed to work if the
164217
wait is <= 0x7fffffff milliseconds (~24 days). If the limit is exceeded,
165218
the wait will time out earlier than specified.
219+
@deprecated Pass a chrono time_point, not an integer millisecond count. For example use `Kernel::Clock::now() + 5s`
220+
rather than `Kernel::get_ms_count() + 5000`.
166221
*/
222+
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`.")
167223
T *calloc_until(uint64_t millisec)
168224
{
169-
T *item = alloc_until(millisec);
225+
return alloc_until(Kernel::Clock::time_point(std::chrono::duration<uint64_t, std::milli>(millisec)));
226+
}
227+
228+
/** Allocate a memory block from a memory pool, blocking, and set memory block to zero.
229+
@param abs_time absolute timeout time, referenced to Kernel::Clock.
230+
@return address of the allocated memory block or nullptr in case of no memory available.
231+
232+
@note You cannot call this function from ISR context.
233+
@note the underlying RTOS may have a limit to the maximum wait time
234+
due to internal 32-bit computations, but this is guaranteed to work if the
235+
wait is <= 0x7fffffff milliseconds (~24 days). If the limit is exceeded,
236+
the wait will time out earlier than specified.
237+
*/
238+
T *calloc_until(Kernel::Clock::time_point abs_time)
239+
{
240+
T *item = alloc_until(abs_time);
170241
if (item != nullptr) {
171242
memset(item, 0, sizeof(T));
172243
}

0 commit comments

Comments
 (0)