Skip to content

Commit c7394fa

Browse files
committed
pbio/os: Add await once.
Similar to PROCESS_PAUSE() but without posting an event to itself like Contiki does. It is basically the same as awaiting 0ms, but without the need to allocate a timer. Also restore this for the charger, which used PROCESS_PAUSE() here initially.
1 parent d06724e commit c7394fa

File tree

2 files changed

+37
-3
lines changed

2 files changed

+37
-3
lines changed

lib/pbio/drv/charger/charger_mp2639a.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -186,13 +186,13 @@ pbio_error_t pbdrv_charger_mp2639a_process_thread(pbio_os_state_t *state, void *
186186

187187
#if PBDRV_CONFIG_CHARGER_MP2639A_MODE_PWM
188188
while (pbdrv_pwm_get_dev(platform.mode_pwm_id, &mode_pwm) != PBIO_SUCCESS) {
189-
AWAIT_MS(state, &timer, 1);
189+
AWAIT_ONCE(state);
190190
}
191191
#endif
192192

193193
#if PBDRV_CONFIG_CHARGER_MP2639A_ISET_PWM
194194
while (pbdrv_pwm_get_dev(platform.iset_pwm_id, &iset_pwm) != PBIO_SUCCESS) {
195-
AWAIT_MS(state, &timer, 1);
195+
AWAIT_ONCE(state);
196196
}
197197
#endif
198198

lib/pbio/include/pbio/os.h

+35-1
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ struct _pbio_os_process_t {
138138
*
139139
* @param [in] state Protothread state.
140140
*/
141-
#define ASYNC_BEGIN(state) { PB_LC_RESUME(state)
141+
#define ASYNC_BEGIN(state) { char do_yield_now = 0; if (do_yield_now) {;} PB_LC_RESUME(state)
142142

143143
/**
144144
* Declare the end of a protothread and returns with given code.
@@ -180,6 +180,13 @@ struct _pbio_os_process_t {
180180
} \
181181
} while (0)
182182

183+
/**
184+
* Awaits a protothread until it is done.
185+
*
186+
* @param [in] state Protothread state.
187+
* @param [in] child Protothread state of the child.
188+
* @param [in] statement The statement to await.
189+
*/
183190
#define AWAIT(state, child, statement) \
184191
do { \
185192
ASYNC_INIT((child)); \
@@ -189,6 +196,15 @@ struct _pbio_os_process_t {
189196
} \
190197
} while (0)
191198

199+
/**
200+
* Awaits two protothreads until one of them is done.
201+
*
202+
* @param [in] state Protothread state.
203+
* @param [in] child1 Protothread state of the first child.
204+
* @param [in] child2 Protothread state of the second child.
205+
* @param [in] statement1 The first statement to await.
206+
* @param [in] statement2 The second statement to await.
207+
*/
192208
#define AWAIT_RACE(state, child1, child2, statement1, statement2) \
193209
do { \
194210
ASYNC_INIT((child1)); \
@@ -199,6 +215,24 @@ struct _pbio_os_process_t {
199215
} \
200216
} while (0)
201217

218+
/**
219+
* Yields the protothread once and polls to request handling again immediately.
220+
*
221+
* Should be used sparingly as it can cause busy waiting. Processes will keep
222+
* running, but there is always another event pending.
223+
*
224+
* @param [in] state Protothread state.
225+
*/
226+
#define AWAIT_ONCE(state) \
227+
do { \
228+
do_yield_now = 1; \
229+
PB_LC_SET(state); \
230+
if (do_yield_now) { \
231+
pbio_os_request_poll(); \
232+
return PBIO_ERROR_AGAIN; \
233+
} \
234+
} while (0)
235+
202236
#define AWAIT_MS(state, timer, duration) \
203237
do { \
204238
pbio_os_timer_set(timer, duration); \

0 commit comments

Comments
 (0)