---
include/task.h | 36 ++++++++++++++++++++++++++++++++++--
src/task.c | 18 ++++++++++++++----
2 files changed, 48 insertions(+), 6 deletions(-)
diff --git a/include/task.h b/include/task.h
index 4ba9334..920e205 100644
--- a/include/task.h
+++ b/include/task.h
@@ -34,6 +34,7 @@
#include "core.h"
#include "irq.h"
#include "dbg.h"
+#include "load.h"
#include "cpu/reg.h"
#include "cpu/_cpu.h"
@@ -59,8 +60,7 @@ typedef struct task {
char status; ///< task_status_t
char tm_out;
short pri; ///< initial thread priority
- unsigned sch;
- unsigned ut;
+ load_t load;
} task_t;
extern void (*task_gc) (task_t * t);
@@ -76,6 +76,16 @@ task_t *task_init(task_t * t,
#define task_new(_n,_e,_p,_sz,_sl,_pr) \
task_init(_alloc(sizeof(task_t)), _n, _e, _p, _alloc(_sz), _sz, _sl,
_pr)
+static inline void task_set_idle(task_t * t)
+{
+ t->load.wei = 0;
+}
+
+static inline int task_is_idle(task_t * t)
+{
+ return t->load.wei == 0;
+}
+
void _task_dest();
extern task_t *_task_cur, *_task_pend;
@@ -137,4 +147,26 @@ extern void (*task_ov) (task_t * t);
#include "cpu/_task.h"
+struct task_switch;
+
+typedef struct task_switch task_switch_t;
+
+typedef void (*task_switch_f) (struct task_switch * o, struct task * tn);
+
+struct task_switch {
+ lle_t ll;
+ task_switch_f notify;
+ void *priv;
+};
+
+static inline void task_switch_init(task_switch_t * o, task_switch_f notify,
+ void *priv)
+{
+ lle_init(&o->ll);
+ o->notify = notify;
+ o->priv = priv;
+}
+
+void task_switch_listen(task_switch_t * o);
+
#endif
diff --git a/src/task.c b/src/task.c
index 6cce6f3..21966ff 100644
--- a/src/task.c
+++ b/src/task.c
@@ -32,6 +32,7 @@
#include "sch.h"
#include "dbg.h"
#include "soc.h"
+#include "core.h"
#include "cpu/_cpu.h"
#include <string.h>
@@ -41,6 +42,8 @@ task_t *_task_cur, *_task_pend;
void (*task_gc) (task_t * t);
+static ll_t switch_listeners = LL_INIT(switch_listeners);
+
static int task_wait_timeout(void *p)
{
task_t *t = (task_t *) p;
@@ -101,6 +104,7 @@ task_t *task_init(task_t * t,
#ifdef CFG_STACK_CHK
*stack = 0xABBA;
#endif
+ t->load.wei = 1;
irq_restore(iflag);
if (_task_cur && _task_cur->pri > t->pri)
@@ -189,7 +193,7 @@ void task_pri(task_t * t, short pri)
reg_t **_task_switch_status(task_t * tn)
{
- unsigned now;
+ lle_t *lle;
task_t *t = _task_cur;
if (_task_cur->status == TASK_READY)
sch_add(_task_cur);
@@ -204,9 +208,10 @@ reg_t **_task_switch_status(task_t * tn)
#endif
dbg("T=:%c%c%c\r\n", tn->name[0], tn->name[1], tn->name[2]);
- now = soc_rtcs();
- _task_cur->ut += now - _task_cur->sch;
- tn->sch = now;
+ ll_for_each(&switch_listeners, lle) {
+ task_switch_t *l = lle_get(lle, task_switch_t, ll);
+ l->notify(l, tn);
+ }
_task_cur = tn;
_task_cur->slice_cur = _task_cur->slice;
@@ -222,3 +227,8 @@ void _task_switch_pend(task_t * tn)
cpu_req_switch();
}
}
+
+void task_switch_listen(task_switch_t * o)
+{
+ ll_addt(&switch_listeners, &o->ll);
+}
--
2.5.0