2019-01-23 15:43:52 +00:00
|
|
|
#ifndef MM_COND_H
|
|
|
|
#define MM_COND_H
|
|
|
|
|
|
|
|
/*
|
|
|
|
* machinarium.
|
|
|
|
*
|
|
|
|
* cooperative multitasking engine.
|
2020-04-02 11:00:56 +00:00
|
|
|
*/
|
2019-01-23 15:43:52 +00:00
|
|
|
|
|
|
|
typedef struct mm_cond mm_cond_t;
|
|
|
|
|
2020-12-28 10:43:31 +00:00
|
|
|
struct mm_cond {
|
2020-04-02 11:00:56 +00:00
|
|
|
uint64_t signal;
|
|
|
|
mm_call_t call;
|
2019-01-23 15:43:52 +00:00
|
|
|
mm_cond_t *propagate;
|
|
|
|
};
|
|
|
|
|
2020-12-28 10:43:31 +00:00
|
|
|
static inline void mm_cond_init(mm_cond_t *cond)
|
2019-01-23 15:43:52 +00:00
|
|
|
{
|
|
|
|
cond->propagate = NULL;
|
2020-12-28 10:43:31 +00:00
|
|
|
cond->signal = 0;
|
2019-01-23 15:43:52 +00:00
|
|
|
memset(&cond->call, 0, sizeof(cond->call));
|
|
|
|
}
|
|
|
|
|
2020-12-28 10:43:31 +00:00
|
|
|
static inline void mm_cond_signal(mm_cond_t *cond, mm_scheduler_t *sched)
|
2019-01-23 15:43:52 +00:00
|
|
|
{
|
|
|
|
if (cond->propagate)
|
|
|
|
mm_cond_signal(cond->propagate, sched);
|
|
|
|
if (cond->signal)
|
|
|
|
return;
|
|
|
|
cond->signal = 1;
|
|
|
|
if (cond->call.type == MM_CALL_COND)
|
|
|
|
mm_scheduler_wakeup(sched, cond->call.coroutine);
|
|
|
|
}
|
|
|
|
|
2020-12-28 10:43:31 +00:00
|
|
|
static inline int mm_cond_try(mm_cond_t *cond)
|
2019-01-23 15:43:52 +00:00
|
|
|
{
|
|
|
|
int signal = cond->signal;
|
|
|
|
if (signal)
|
|
|
|
cond->signal = 0;
|
|
|
|
return signal;
|
|
|
|
}
|
|
|
|
|
2020-12-28 10:43:31 +00:00
|
|
|
static inline int mm_cond_wait(mm_cond_t *cond, uint32_t time_ms)
|
2019-01-23 15:43:52 +00:00
|
|
|
{
|
|
|
|
if (cond->signal) {
|
|
|
|
cond->signal = 0;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
mm_call(&cond->call, MM_CALL_COND, time_ms);
|
|
|
|
if (cond->call.status != 0)
|
|
|
|
return -1;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif /* MM_COND_H */
|