[hypercos] [PATCH 2/4] task: Add task switch listener interface

  • From: Howard Chen <ibanezchen@xxxxxxxxx>
  • To: socware.help@xxxxxxxxx, hypercos@xxxxxxxxxxxxx
  • Date: Wed, 2 Nov 2016 10:29:20 +0800

---
 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


Other related posts:

  • » [hypercos] [PATCH 2/4] task: Add task switch listener interface - Howard Chen