changeset 2:803d6bf22e6d default tip

second commit. it's far to complete..
author kent <kent@cr.ie.u-ryukyu.ac.jp>
date Tue, 22 Dec 2009 16:19:56 +0900
parents aef83aed7a07
children
files List.c List.h Task.cbc Task.h TaskManager.cbc TaskManager.h TaskQueue.c TaskScheduler.cbc TaskScheduler.h memo.txt test/list/Makefile test/list/testiter.c test/list/testlist.c test/manager/taskinit.cbc test/manager/taskinit.h test/manager/testmanager.cbc test/scheduler/test_sched.cbc
diffstat 17 files changed, 856 insertions(+), 279 deletions(-) [+]
line wrap: on
line diff
--- a/List.c	Sun Dec 20 20:46:53 2009 +0900
+++ b/List.c	Tue Dec 22 16:19:56 2009 +0900
@@ -1,22 +1,45 @@
 #include<stdlib.h>
+/* TODO: malloc.  */
+#include"List.h"
 
-#include"List.h"
+/*
+ *  doubly-linked list.
+ *  interfaces of these routines is based on glib.
+ *
+ *  Usage:
+ *  create new list.
+ *  	list = NULL
+ *  add new data
+ *  	list = _listAddFirst(list, data)
+ *  remove data from the list
+ *  	list = _listRemove(list, data)
+ *  get n-th data
+ *  	data = _listGetnthData(list, n)
+ *
+ *
+ *  NOTE:
+ *  Although `struct List' is a doubly-linked List, the List
+ *  is made as a Ring.  An User's variable is treated as a
+ *  head of the list.  And head->prev is last.  And then if
+ *  list have only one data, both next and prev field of
+ *  head will point to oneself.
+ *  If the variable is NULL, it means no data.
+ */
 
 List *
 _listAddFirst(List* top, void *data)
 {
 	List *newlist;
+	List *last;
+	newlist = malloc(sizeof(struct _List));
+	newlist->data = data;
+
 	if (!top) {
-		newlist = malloc(sizeof(struct _List));
-		newlist->data = data;
 		newlist->next = newlist;
 		newlist->prev = newlist;
 		return newlist;
 	}
-	List *last = top->prev;
-
-	newlist = malloc(sizeof(struct _List));
-	newlist->data = data;
+	last = top->prev;
 	newlist->next = top;
 	newlist->prev = last;
 
@@ -70,7 +93,7 @@
 	return top->prev->data;
 }
 
-void *
+List *
 _listMoveLasttoFirst(List *top)
 {
 	if (!top) return NULL;
@@ -78,7 +101,8 @@
 }
 
 void
-_listApply(List *top, ApplyFn fn, void *arg) {
+_listApply(List *top, ApplyFn fn, void *arg)
+{
 	List *t = top;
 	do {
 		fn(t->data, arg);
@@ -86,9 +110,93 @@
 	} while ( t!=top );
 }
 
+/*
+ *  Iterator's functions.
+ *
+ *  iter = _listIterator(list);
+ *  while ( (data=_listIterNext(iter)!=NULL ) {
+ *  	exe(data);
+ *  	if (data...) {
+ *  		list = _listIterRemove(iter);
+ *  	}
+ *  }
+ */
+ListIter *
+_listIterator(List *top)
+{
+	ListIter *iter;
+	iter = malloc(sizeof(struct _ListIter));
+	iter->head = top;
+	iter->next = top;
+	return iter;
+}
 
+void *
+_listIterNext(ListIter *iter)
+{
+	void *rtn;
+	if (!iter->next) return NULL;
+
+	rtn = iter->next->data;
+	iter->next = iter->next->next;
+	if (iter->next==iter->head) {
+		iter->next = NULL;
+	}
+	return rtn;
+}
+
+void
+_listIterEnd(ListIter *iter)
+{
+	free(iter);
+}
+
+List *
+_listIterRemoveCurrent(ListIter *iter)
+{
+	List *cur, *p, *n;
+	if (!iter->head) return NULL;
+	else if (!iter->next) cur = iter->head->prev;
+	else cur = iter->next->prev;
+
+	if (cur==iter->head) {
+		if (cur->next==iter->head) {
+			free(iter->head);
+			return NULL;
+		}
+		iter->head = iter->head->next;
+	}
+	cur->prev->next = cur->next;
+	cur->next->prev = cur->prev;
+
+	free(cur);
+	return iter->head;
+}
 
 
+/*
+ *  for DEBUG
+ */
 
+int
+_listRingCheck(List *head)
+{
+	List *cur = head;
 
+	if (cur->prev->next!=cur) return 0;
+	if (cur->next->prev!=cur) return 0;
+	do {
+		if (cur->prev->next!=cur) return 0;
+		if (cur->next->prev!=cur) return 0;
+		cur = cur->prev;
+	} while (cur!=head);
 
+	if (cur->prev->next!=cur) return 0;
+	if (cur->next->prev!=cur) return 0;
+	cur = cur->next;
+	if (cur->prev->next!=cur) return 0;
+	if (cur->next->prev!=cur) return 0;
+
+	return 1;
+}
+
--- a/List.h	Sun Dec 20 20:46:53 2009 +0900
+++ b/List.h	Tue Dec 22 16:19:56 2009 +0900
@@ -7,11 +7,25 @@
 	struct _List *prev;
 } List;
 
+typedef struct _ListIter {
+	struct _List *head;
+	struct _List *next;
+} ListIter;
+
 List * _listAddFirst(List*, void *);
 List * _listRemove(List *, void *);
 void * _listGetnthData(List *, int);
+void * _listGetLastData(List *);
+List * _listMoveLasttoFirst(List *);
 
 typedef int (*ApplyFn)(void*,void*);
 void _listApply(List *, ApplyFn, void *);
 
+
+ListIter * _listIterator(List *);
+void * _listIterNext(ListIter *);
+void _listIterEnd(ListIter *);
+List * _listIterRemoveCurrent(ListIter *);
+
+
 #endif /* !_LIST_H */
--- a/Task.cbc	Sun Dec 20 20:46:53 2009 +0900
+++ b/Task.cbc	Tue Dec 22 16:19:56 2009 +0900
@@ -1,107 +1,46 @@
-
-
-typedef __code (*Scheduler)();
-typedef __code (*Taskrun)(Scheduler, void*, void*);
-
-typedef struct _Task {
-	Taskrun run;
+#include <stdlib.h>
+#include "List.h"
+#include "Task.h"
 
-	TaskList waiter;	// List of tasks waiting for me :-P
-	TaskList waitee;	// List of tasks keep me waiting :-(
-} Task;
-
-
-typedef struct _TaskList {
-	Task *task;
-	struct _TaskList *next;
-	struct _TaskList *prev;
-} TaskList;
 
 /*
- * use this function like below.
- *   list = listAddFirst(list, task);
+ *  User interfaces.
  */
-TaskList *
-listAddFirst(TaskList* top, Task *task)
+
+Task *
+createTask(int id, char *name)
 {
-	if (!top) {
-		newlist = malloc(sizeof(struct _TaskList));
-		newlist->task = task;
-		newlist->next = newlist;
-		newlist->prev = newlist;
-		return newlist;
-	}
-	TaskList *last = top->prev;
+	Task *task;
+	if (!name) name = "(no name)";
 
-	newlist = malloc(sizeof(struct _TaskList));
-	newlist->task = task;
-	newlist->next = top;
-	newlist->prev = last;
+	task = malloc(sizeof(Task));
+	task->id = id;
+	task->rbuff = NULL;
+	task->wbuff = NULL;
+	task->waiter = NULL;
+	task->waitee = NULL;
+	task->name = name;
+	task->cpu = ANY;
+	task->rsize = 0;
+	task->wsize = 0;
 
-	top->prev = newlist;
-	last->next = newlist;
-	return newlist;
+	return task;
 }
 
-TaskList *
-listAddLast(TaskList* top, Task *task)
+void
+taskSetData(Task *task, void *rbuff, int rsize, void *wbuff, int wsize)
 {
-	/*
-	if (!top) {
-		newlist = malloc(sizeof(struct _TaskList));
-		newlist->task = task;
-		newlist->next = newlist;
-		newlist->prev = newlist;
-		return newlist;
-	}
-	TaskList *last = top->prev;
-
-	newlist = malloc(sizeof(struct _TaskList));
-	newlist->task = task;
-	newlist->next = top;
-	newlist->prev = last;
-
-	top->prev = newlist;
-	last->next = newlist;
-	return newlist;
-	*/
+	task->rbuff = rbuff;
+	task->wbuff = wbuff;
+	task->rsize = rsize;
+	task->wsize = wsize;
 }
 
-TaskList *
-listRemove(TaskList *top, Task *task)
+void
+taskSetWait(Task *a, Task *b)
 {
-	TaskList *t;
-	if (top->task==task) {
-		if (top->next==top) {
-			free(top);
-			return NULL;
-		}
-		TaskList *newtop = top->next;
-		top->next->prev = top->prev;
-		top->prev->next = top->next;
-		free(top);
-		return newtop;
-	}
-	for (t=top->next; t!=top; t=t->next) {
-		if (t->task==task) {
-			t->next->prev = t->prev;
-			t->prev->next = t->next;
-			free(t);
-			return top;
-		}
-	}
-	return top;
+	/* set a waiting for b.  */
+	a->waitee = _listAddFirst(a->waitee, b);
+	b->waiter = _listAddFirst(b->waiter, a);
 }
 
-typedef int (*ApplyFn)(Task*,void*);
-
-listApply(TaskList *top, ApplyFn fn, void *arg) {
-	t = top;
-	do {
-		fn(t->task, arg);
-		t = t->next;
-	} while ( t!=top );
-}
-
-
-
--- a/Task.h	Sun Dec 20 20:46:53 2009 +0900
+++ b/Task.h	Tue Dec 22 16:19:56 2009 +0900
@@ -1,16 +1,56 @@
 #ifndef _TASK_H
 #define _TASK_H
+// ユーザ側でもこのヘッダファイルをインクルードする
+#include "List.h"
 
-typedef __code (*Taskrun)(__code(*)(void*,void*,void*), void*, void*);
-typedef __code (*Scheduler)(__code(*)(void*,void*,void*), void*, void*);
+/* used by User'sTask.  */
+typedef __code (*Taskrun)(void*, void*, void*);
+//typedef __code (*Scheduler)(TaskScheduler*,__code(*)(void*,void*,void*), void*, void*);
+//typedef __code (*Taskrun)(_code(*)(void*,void*,void*), void*, void*);
+//typedef __code (*Scheduler)(__code(*)(void*,void*,void*), void*, void*);
 //typedef __code (*Scheduler)(Taskrun, void*, void*);
 //typedef __code (*Taskrun)(Scheduler, void*, void*);
 #define END (NULL)
 
+/* C++CeriumでのTaskObjectにあたる  */
+typedef struct _TaskType {
+	Taskrun code;
+	char *name;
+} TaskType;
+
+
+/* defined by user automatically.  */
+extern const int max_tasktype;
+extern const TaskType tasktypes[];
+
 enum cpu {
-	ANY = 0,
+	ANY = 0, // not implemented yet.
 	MAIN,
 	SUB,
 };
 
+/* C++CeriumでのHTaskにあたるのかな  */
+typedef struct _Task {
+	char *name;		// task name.
+	int typeid;		// index of tasktypes array.
+	int id;			// task identifier.
+
+	void *rbuff;
+	void *wbuff;
+	int rsize;
+	int wsize;
+	List *waiter;	// List of tasks waiting for me :-P
+	List *waitee;	// List of tasks keep me waiting :-(
+
+	enum cpu cpu;
+} Task;
+
+/* user interfaces.  */
+extern Task * createTask (int, char *);
+extern void taskSetData (Task *, void *, int, void *, int);
+extern void taskSetWait (Task *, Task *);
+
+extern __code (*scheduler)(void*,Taskrun,void*,void*);
+
 #endif /* _TASK_H */
+
--- a/TaskManager.cbc	Sun Dec 20 20:46:53 2009 +0900
+++ b/TaskManager.cbc	Tue Dec 22 16:19:56 2009 +0900
@@ -1,78 +1,187 @@
+#include <assert.h>
 #include "TaskManager.h"
+#include "Task.h"
+#include "List.h"
+// TODO: malloc
 
-TaskQueue waitingQueue;
-TaskQueue activeQueue;
+extern __code checkEvent(TaskManager *);
+extern __code executeTask(TaskManager*, ListIter*, Task*);
+
+typedef List TaskList;
 
 /*
  * TaskManager's main loop.
  *
  *   while (1) {
- *   	checkFinishedTask();  // to scheduler.
- *   	wait2active();
- *   	while (actQisnotempty) {
- *   		task = pollFirst(actQ);
- *   		executeTask(task);  // to scheduler.
+ *   	while switch checkEvent() {
+ *   	newTask:
+ *   		add task to waiting.
+ *   	finishTask:
+ *   		remove task from active.
+ *   	}
+ *   	foreach task in waitinglist {
+ *   		if (!task_has_waitee) {
+ *   			move task to active from waiting.
+ *   			executeTask(task)
+ *   		}
+ *   	}
+ *   }
+ *
+ *   CPUがfullでないかをTaskManager側でケアするならこっちに変更かな
+ *   while (1) {
+ *   	while switch checkAction() {
+ *   	newTask:
+ *   		add task to waiting or ready.
+ *   	finishTask:
+ *   		remove task from running.
+ *   	}
+ *   	if (cpu ready) {
+ *   		foreach task in readylist {
+ *   			executeTask(task)
+ *  			move task to running from ready.
+ *   		}
+ *   	}
+ *   	foreach task in waitinglist {
+ *   		if (!task_has_waitee) {
+ *   			if (CPU ready) {
+ *   				executeTask(task)
+ *   				move task to running from waiting.
+ *   			} else {
+ *   				move task to running from ready.
+ *   			}
+ *   		}
  *   	}
  *   }
  */
-__code TManagerStart()
-/* active, waitngタスクリストを整理  */
+
+/* statics  */
+__code initTaskManager (__code(*ret)(TaskManager*,void*), void *arg);
+__code start (TaskManager *manager);
+__code addNewTask (TaskManager *manager, Task *task);
+__code finishTask (TaskManager *manager, Task *task);
+__code noEvent (TaskManager *manager);
+__code getTask (TaskManager *manager, ListIter *iter);
+__code executed (TaskManager *manager, ListIter *iter, Task *task);
+__code cannotExecute (TaskManager *manager, Task *task);
+__code finishTask_1 (TaskManager *manager, Task *task);
+__code finishTask_iter (TaskManager *manager, Task *task, ListIter *iter);
+__code finishTask_end (TaskManager *manager, Task *task);
+void setData (Task *task, void *rbuff, size_t rs, void *wbuff, size_t ws);
+
+__code
+initTaskManager(__code(*ret)(TaskManager*,void*), void *arg)
 {
-	list = activeQueue;
-	goto executeTasklist(list);
+	TaskManager *manager;
+	manager = malloc(sizeof(TaskManager));
+	goto ret(manager, arg);
+}
+
+__code
+start(TaskManager *manager)
+{
+	goto checkEvent(manager);
+}
+__code
+addNewTask(TaskManager *manager, Task *task)
+{
+	/* receive a Task which has already been created in AbstractLayer.  */
+	/* but It must be freed in TaskManager.  */
+	manager->waitingList = _listAddFirst(manager->waitingList, task);
+	goto start(manager);
+}
+
+__code
+finishTask(TaskManager *manager, Task *task)
+{
+	goto finishTask_1(manager, task);
+}
+
+__code
+noEvent(TaskManager *manager)
+{
+	ListIter *iter;
+	iter = _listIterator(manager->waitingList);
+	goto getTask(manager, iter);
 }
 
-__code executeTasklist()
-/*   */
+__code
+getTask(TaskManager *manager, ListIter *iter)
 {
-	if (0 < activeQueue->length) {
-		goto TManagerLoop();
-	}
-	task = pollFirst(activeQueue);
-
-	/*
-	 * rbuff, wbuffの用意
-	 */
-	goto task->run(TManagerReturnEntry, rbuff, wbuff);
-	/* Taskへ  */
+	Task *task;
+	task = (Task*)_listIterNext(iter);
+	if (!task)
+		/* iteration finished.  */
+		goto start(manager);
+	if (task->waitee)
+		/* the task has been waiting yet.  */
+		goto getTask(manager, iter);
+	else
+		/* the task is ready!  */
+		goto executeTask(manager, iter, task);
 }
 
-__code TManagerReturnEntry()
-/* Taskから戻ってくるコードセグメント */
+__code
+executed(TaskManager *manager, ListIter *iter, Task *task)
 {
-	/*
-	 * 依存していたtaskに通知?
-	 */
-	goto executeTasklist(list->cdr);
+	manager->waitingList = _listIterRemoveCurrent(iter);
+	manager->activeList = _listAddFirst(manager->activeList, task);
+	goto getTask(manager, iter);
+}
+/*
+__code cannotExecute(TaskManager *manager, Task *task) { }
+*/
+
+
+__code
+finishTask_1(TaskManager *manager, Task *task)
+{
+	ListIter *iter;
+
+	manager->activeList = _listRemove(manager->activeList, task);
+	iter = _listIterator(task->waiter);
+	goto finishTask_iter(manager, task, iter);
 }
 
-__code TManagerLoop()
+__code
+finishTask_iter(TaskManager *manager, Task *task, ListIter *iter)
 {
-	/*
-	 * waitingTaskからactiveTaskへ
-	 */
+	Task *waiter;
+	waiter = _listIterNext(iter);
+	if (waiter) {
+		waiter->waitee = _listRemove(waiter->waitee, task);
+		task->waiter = _listIterRemoveCurrent(iter);
+		goto finishTask_iter(manager, task, iter);
+	} else {
+		_listIterEnd(iter);
+		goto finishTask_end(manager, task);
+	}
+}
 
-	goto TManagerStart();
+__code
+finishTask_end(TaskManager *manager, Task *task)
+{
+	/* TODO: free(task)  */
+	assert (!task->waiter);
+	assert (!task->waitee);
+	free(task);
+	goto start(manager);
 }
 
 
-__code sched()
-{
-	TaskList *t = waiter;
-	Task *t;
-	for (; t!=;);
-}
+
 
 
 /* belows is Interfaces for Users.  */
-/* it may be replace to code segment.  but how?  */
+/* it may be  to code segment.  but how?  */
+/* and may be moved to AbstractLayer.  */
 
-Task *newTask(TaskTypeID typeid)
+Task *newTask(int typeid)
 {
-	static int id=0;	// 今は使ってない… 使う?
-	task = allocate(sizeof(Task));
+	Task *task;
+	static int id=0;
+	task = malloc(sizeof(Task));
 
-	task->tasktype = tasktypes[typeid];
+	//task->tasktype = tasktypes[typeid];
 	task->id = id;
 	task->waiter = NULL;
 	task->waitee = NULL;
@@ -84,12 +193,8 @@
 {
 	task->rbuff = rbuff;
 	task->wbuff = wbuff;
-	task->rsize = rsize;
-	task->wsize = wsize;
-}
-
-void spawn(Task *task) 
-{
+	task->rsize = rs;
+	task->wsize = ws;
 }
 
 
--- a/TaskManager.h	Sun Dec 20 20:46:53 2009 +0900
+++ b/TaskManager.h	Tue Dec 22 16:19:56 2009 +0900
@@ -2,7 +2,20 @@
 #define _TASKMANAGER_H
 #include <stdlib.h>
 #include "List.h"
+#include "Task.h"
 
+typedef struct _TaskManager {
+	List *waitingList;
+	List *activeList;
+} TaskManager;
+
+__code initTaskManager(__code(*ret)(TaskManager*,void*), void *arg);
+__code addNewTask(TaskManager *, Task *);
+__code finishTask(TaskManager *, Task *);
+__code noEvent(TaskManager *);
+__code getTask(TaskManager *, ListIter *);
+__code executed(TaskManager *, ListIter *, Task *);
+#if 0
 typedef List TaskList;
 typedef uint32_t TaskTypeID;
 
@@ -31,5 +44,6 @@
 /* but generated by Cerium automatically.  */
 extern int max_tasktypes;
 extern TaskType taskTypes[];
+#endif
 
 #endif /* !_TASKMANAGER_H */
--- a/TaskQueue.c	Sun Dec 20 20:46:53 2009 +0900
+++ b/TaskQueue.c	Tue Dec 22 16:19:56 2009 +0900
@@ -1,17 +1,19 @@
-#include"TaskList.h"
+#include <stdlib.h>
+// TODO: malloc
+#include "List.h"
+#include "Queue.h"
 
-typedef struct _TaskQueue {
-	TaskList *head;
-	TaskList *tail;
+typedef struct _Queue {
+	List *head;
+	List *tail;
 	int length;
-} TaskQueue;
+} Queue;
 
-TaskQueue *
-newTaskQueue()
+Queue *
+newQueue()
 {
-	TaskQueue *queue;
-	/* TODO: mallocはあとで独自実装に書き直し!  */
-	malloc(sizeof(struct _TaskQueue));
+	Queue *queue;
+	malloc(sizeof(struct _Queue));
 	queue->head = NULL;
 	queue->tail = NULL;
 	queue->length = 0;
@@ -19,11 +21,11 @@
 }
 
 void
-queueAddFirst(TaskQueue *queue, Task *)
+_QaddFirst(Queue *queue, void *)
 {
-	TaskList *oldhead = queue->head;
-	TaskList *newlist;
-	newlist = malloc(sizeof(struct _TaskList));
+	List *oldhead = queue->head;
+	List *newlist;
+	newlist = malloc(sizeof(struct _List));
 
 	if (oldhead) {
 		oldhead->prev = newlist;
@@ -36,11 +38,11 @@
 }
 
 void
-queueAddLast(TaskQueue *queue, Task *task)
+_QaddLast(Queue *queue, void *task)
 {
-	TaskList *oldtail = queue->tail;
-	TaskList *newlist;
-	newlist = malloc(sizeof(struct _TaskList));
+	List *oldtail = queue->tail;
+	List *newlist;
+	newlist = malloc(sizeof(struct _List));
 
 	if (oldtail) {
 		oldtail->next = newlist;
@@ -52,12 +54,12 @@
 	return ;
 }
 
-Task *
-queuePollFirst(TaskQueue *queue)
+void *
+_QpollFirst(Queue *queue)
 {
-	TaskList *first = queue->head;
-	TaskList *second;
-	Task *task;
+	List *first = queue->head;
+	List *second;
+	void *task;
 	if (!first) return NULL;
 
 	second = first->next;
@@ -70,12 +72,12 @@
 	return task;
 }
 
-Task *
-queuePollLast(TaskQueue *queue)
+void *
+_QpollLast(Queue *queue)
 {
-	TaskList *first = queue->tail;
-	TaskList *second;
-	Task *task;
+	List *first = queue->tail;
+	List *second;
+	void *task;
 	if (!first) return NULL;
 
 	second = first->prev;
--- a/TaskScheduler.cbc	Sun Dec 20 20:46:53 2009 +0900
+++ b/TaskScheduler.cbc	Tue Dec 22 16:19:56 2009 +0900
@@ -4,96 +4,88 @@
 #include "TaskScheduler.h"
 #include "List.h"
 
-enum {
+enum wait{
 	NOWAIT=0,
 	WAIT=1,
 };
-__code checkNewCode();
+extern __code checkNewCode(TaskScheduler *, enum wait);
+
+__code (*scheduler)(void*,Taskrun,void*,void*);
 
 typedef List SchedTaskList;
 #define addSchedTask(a,b) (SchedTaskList*)_listAddFirst((List*)(a),(void*)(b))
 #define removeTask(a,b) (SchedTaskList*)_listRemove((List*)(a),(void*)(b))
 // inline functionのがいいか
 
-typedef struct _segment {
-	ID id;  // task identifier;
-	Taskrun nextcode;
-	void *rbuff;
-	void *wbuff;
-} SchedTask;
+__code schedEntry(TaskScheduler *tsched, Taskrun nextcode, void *rbuff, void *wbuff);
 
-typedef struct _scheduler {
-	/* it may be Singleton.  */
-
-	SchedTask *running;
-	SchedTaskList *runnable;
-
-} TaskScheduler;
-
-__code schedEntry(Taskrun nextcode, void *rbuff, void *wbuff);
-
-static TaskScheduler *schedule;
+//static TaskScheduler *tsched;
 
 extern void *allocate(size_t);
 __code
-initScheduler(__code (*ret)(void *), void *arg)
+initScheduler(__code (*ret)(TaskScheduler*,void*), void *arg)
 {
-	schedule = allocate(sizeof(TaskScheduler));
-	schedule->runnable = NULL;
-	schedule->running = NULL;
-	goto ret(arg);
+	TaskScheduler *tsched;
+	tsched = allocate(sizeof(TaskScheduler));
+	tsched->runnable = NULL;
+	tsched->running = NULL;
+	//tsched->schedule = SchedEntry;
+	scheduler = schedEntry;
+	goto ret(tsched, arg);
 }
 
 __code
-addCode(ID id, Taskrun code0, void *rbuff, void *wbuff)
+addCode(TaskScheduler *tsched, ID id, Taskrun code0, void *rbuff, void *wbuff)
 {
-	SchedTask *newcs;
-	newcs = allocate(sizeof(SchedTask));
-	newcs->nextcode = code0;
-	newcs->rbuff = rbuff; //taskの遷移で引数が変化しないならいならい
-	newcs->wbuff = wbuff;
+	SchedTask *newst;
+	newst = allocate(sizeof(SchedTask)); //これはAbstractLayerで生成してもいいのだが…
+	newst->nextcode = code0;
+	newst->rbuff = rbuff; //taskの遷移で引数が変化しないならいならい
+	newst->wbuff = wbuff;
 
-	schedule->runnable = addSchedTask(schedule->runnable, newcs);
+	/* regist new task to runnable list.  */
+	tsched->runnable = addSchedTask(tsched->runnable, newst);
 
-	goto selectCode();
+	goto selectCode(tsched);
 }
 
 __code
-selectCode()
+selectCode(TaskScheduler *tsched)
 {
 	SchedTask *task;
-	if (schedule->runnable) {
-		task = _listGetLastData(schedule->runnable);
-		schedule->running = task;
+	if (tsched->runnable) {
+		task = (SchedTask*)_listGetLastData(tsched->runnable);
+		tsched->running = task;
 
-		goto task->nextcode((void*)schedEntry, task->rbuff, task->wbuff);
+		/* goto user-defined task.  */
+		goto task->nextcode(tsched, task->rbuff, task->wbuff);
 	} else {
+		/* no task we have.  */
 		//goto checkNewCode();
-		goto checkNewCode(WAIT);
+		goto checkNewCode(tsched, WAIT);
 	}
 }
 
 __code
-schedEntry(Taskrun nextcode, void *rbuff, void *wbuff)
+schedEntry(TaskScheduler *tsched, Taskrun nextcode, void *rbuff, void *wbuff)
 {
-	/* nextcode==NULLならTaskは終わったと判断  */
-	/* scheduled  */
+	/* schedulerd  */
 	if ( nextcode==NULL ) {
-		ID id = schedule->running->id;
-		schedule->runnable =
-			removeTask(schedule->runnable, schedule->running);
-		free(schedule->running);
-		schedule->running = NULL;
-		goto exitCode(id);
+		/* the task finished.  */
+		ID id = tsched->running->id;
+		tsched->runnable =
+			removeTask(tsched->runnable, tsched->running);
+		free(tsched->running);
+		tsched->running = NULL;
+		goto exitCode(tsched, id);
 	} else {
-		SchedTaskList list;
 		/* save the next code segment for the task.  */
-		schedule->running->nextcode = nextcode;
-		schedule->running->rbuff = rbuff;
-		schedule->running->wbuff = wbuff;
+		tsched->running->nextcode = nextcode;
+		tsched->running->rbuff = rbuff;
+		tsched->running->wbuff = wbuff;
 		/* move last task to first to be fair.  */
-		schedule->runnable = _listMoveLasttoFirst(schedule->runnable);
-		goto checkNewCode(NOWAIT);
+		tsched->runnable = _listMoveLasttoFirst(tsched->runnable);
+		goto checkNewCode(tsched, NOWAIT);
 	}
 }
 
--- a/TaskScheduler.h	Sun Dec 20 20:46:53 2009 +0900
+++ b/TaskScheduler.h	Tue Dec 22 16:19:56 2009 +0900
@@ -1,11 +1,26 @@
 #ifndef _TASKSCHEDULER_H
 #define _TASKSCHEDULER_H
 #include <stdint.h>
+#include "List.h"
 #include "Task.h"
 typedef uint32_t ID;
 
-__code initScheduler(__code (*)(void *), void *);
-__code addCode(ID, Taskrun, void *, void *);
-__code selectCode();
+typedef struct _SchedTask {
+	ID id;  // task identifier;
+	Taskrun nextcode;
+	void *rbuff;
+	void *wbuff;
+} SchedTask;
+
+typedef struct _scheduler {
+	SchedTask *running;
+	List *runnable;
+	//Scheduler schedule;
+} TaskScheduler;
+
+
+__code initScheduler(__code (*)(TaskScheduler *,void *), void *);
+__code addCode(TaskScheduler *, ID, Taskrun, void *, void *);
+__code selectCode(TaskScheduler *);
 
 #endif /* _TASKSCHEDULER_H */
--- a/memo.txt	Sun Dec 20 20:46:53 2009 +0900
+++ b/memo.txt	Tue Dec 22 16:19:56 2009 +0900
@@ -25,19 +25,39 @@
 		o ?set_depend	(used by wait_for of Task)
 		o spawn_task	(used by spawn of Task)
 
-Scheduler
+TaskScheduler
 	o TaskManagerに指示されたTaskを実際に実行する
 	o CPU管理
-	o 実行環境毎にコードがちがう
-	  (pthread用、Cell用、クラスタ用、Fifo..)
-	o 一度に指示されたものを実行する必要はない
 	o Taskが終了したらTaskManagerに通知する
-	* TaskManagerのためのインターフェイス
-		o initialize
-		o executeTask(Task *)
-		o checkFInishedTask
-		o numTask
-		o numCPU
+	* AbstractLayerからのインターフェイス
+		o initScheduler()
+		o addCode(SchedTask *)
+		o selectCode()
+
+AbstractLayer
+	o TaskManagerとSchedulerの中間レイヤ
+	o 実行環境ごとに全部違う Cell, Fifo, pthread, cluster..
+	o TaskManagerに指示されたタスクをSchedulerに渡す
+	o その際、clusterやCellならデータの転送処理などを受け持つ
+	o Schedulerから終了したタスクの通知も受け付ける
+	* Schedulerとのインタフェイス
+		-> checkNewCode()
+		-> exitCode()
+		<- initScheduler()
+		<- addCode()
+		<- selectCode()
+	* TaskManagerとのインタフェイス
+		o checkAction()
+			-> TM::addNewTask()
+			-> TM::finishTask()
+			-> TM::noAction()
+		o executeTask(Task*) 
+			-> TM::executeTaskret() // なんかいい名前を…
+	* Userインタフェイス(Fifoやpthreadの場合は直接TaskManagerでもいい)
+		o newTask()
+		o spawn()
+		o setData()
+		o allocate()
 
 MailManager
 	o Schedulerとおなじく環境依存
--- a/test/list/Makefile	Sun Dec 20 20:46:53 2009 +0900
+++ b/test/list/Makefile	Tue Dec 22 16:19:56 2009 +0900
@@ -3,10 +3,13 @@
 INCLUDE = -I../../
 CFLAGS = -g -O0 $(INCLUDE)
 
+all: testlist testiter
 
 .c.o:
 	$(CC) -c $(CFLAGS) -o $@ $<
 
 testlist: testlist.o ../../List.o
 	$(CC) -o $@ $^
+testiter: testiter.o ../../List.o
+	$(CC) -o $@ $^
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/list/testiter.c	Tue Dec 22 16:19:56 2009 +0900
@@ -0,0 +1,84 @@
+#include<stdio.h>
+#include<stdlib.h>
+#include<string.h>
+#include<assert.h>
+
+#include"List.h"
+
+void printList(List *list);
+int test0();
+int _listRingCheck(List *head);
+
+int
+main(int argc, char **argv)
+{
+	test0();
+	return 0;
+}
+
+int
+test0()
+{
+	char *data = "abcdefghijklmnopqrstuvwxyz";
+	List *list=NULL;
+	ListIter *iter=NULL;
+	int i;
+	char input;
+
+	for (i=0; data[i]!='\0'; i++) {
+		list = _listAddFirst(list, (void*)data[i]);
+	}
+	printList(list);
+	assert(_listRingCheck(list));
+
+
+	iter = _listIterator(list);
+	while ((data=_listIterNext(iter))!=NULL) {
+		int c=(int)data;
+		printf("%c ", c);
+	}
+	_listIterEnd(iter);
+	printf("\n");
+
+
+	i=0;
+	iter = _listIterator(list);
+	while ((data=_listIterNext(iter))!=NULL) {
+		if (i%2==1) {
+			list = _listIterRemoveCurrent(iter);
+		}
+		i++;
+	}
+	_listIterEnd(iter);
+	printf("\n");
+	assert(_listRingCheck(list));
+
+	iter = _listIterator(list);
+	while ((data=_listIterNext(iter))!=NULL) {
+		int c=(int)data;
+		printf("%c ", c);
+	}
+	_listIterEnd(iter);
+	printf("\n");
+
+	return 0;
+}
+
+
+int printOne(void *data,void *arg)
+{
+	char c = (char)data;
+	printf("%c ", c);
+	return 1;
+}
+void
+printList(List *list)
+{
+	_listApply(list, printOne, NULL);
+	printf("\n");
+}
+
+
+
+
+
--- a/test/list/testlist.c	Sun Dec 20 20:46:53 2009 +0900
+++ b/test/list/testlist.c	Tue Dec 22 16:19:56 2009 +0900
@@ -28,6 +28,12 @@
 				printf("%s\n", s);
 				list = _listRemove(list, s);
 			}
+		} else if (strncmp(buff, "s:", 2)==0) {
+			int count;
+			count = atoi(buff+2);
+			for (;count>0; count--) {
+				list = _listMoveLasttoFirst(list);
+			}
 		} else {
 			newstr = strdup(buff);
 			list = _listAddFirst(list, newstr);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/manager/taskinit.cbc	Tue Dec 22 16:19:56 2009 +0900
@@ -0,0 +1,1 @@
+../../taskinit.cbc
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/manager/taskinit.h	Tue Dec 22 16:19:56 2009 +0900
@@ -0,0 +1,1 @@
+../../taskinit.h
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/manager/testmanager.cbc	Tue Dec 22 16:19:56 2009 +0900
@@ -0,0 +1,138 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "List.h"
+#include "Task.h"
+#include "TaskManager.h"
+
+#include "taskinit.h"
+
+#define __DEBUG(f, args...) \
+	fprintf(stderr, "in %s: "f, __FUNCTION__, ## args)
+
+
+extern int main (int, char **);
+extern __code teststart ();
+__code retinit(TaskManager *, void *);
+extern __code checkEvent ();
+extern __code executeTask (TaskManager *, ListIter *, Task *);
+
+__code end();
+
+
+#define NUM 16
+Task *tasks[NUM];
+int stat[NUM];
+
+__code taskA(Scheduler scheduler, void *rbuff, void *wbuff)
+{
+	goto scheduler(END, NULL, NULL);
+}
+__code taskB(Scheduler scheduler, void *rbuff, void *wbuff)
+{
+	goto scheduler(END, NULL, NULL);
+}
+
+
+int
+main(int argc, char **argv)
+{
+	goto teststart();
+	return 0;
+}
+
+__code
+teststart()
+{
+	int i;
+	/*
+	tasks[0] = createTask(TASK_A, NULL);
+	tasks[1] = createTask(TASK_B, NULL);
+	tasks[2] = createTask(TASK_B, NULL);
+	tasks[3] = createTask(TASK_A, NULL);
+	tasks[4] = createTask(TASK_B, NULL);
+	tasks[5] = createTask(TASK_B, NULL);
+	tasks[6] = createTask(TASK_B, NULL);
+	taskSetWait(tasks[2], tasks[0]);
+	taskSetWait(tasks[3], tasks[0]);
+	taskSetWait(tasks[3], tasks[1]);
+	taskSetWait(tasks[4], tasks[2]);
+	taskSetWait(tasks[5], tasks[2]);
+	taskSetWait(tasks[5], tasks[3]);
+	taskSetWait(tasks[6], tasks[4]);
+	taskSetWait(tasks[6], tasks[5]);
+	*/
+	for (i=0; i<NUM; i++) {
+		tasks[i] = createTask(TASK_A, NULL);
+	}
+	taskSetWait(tasks[0], tasks[1]);
+	for (i=1; 2*i<NUM; i++) {
+		taskSetWait(tasks[i], tasks[2*i]);
+		if (2*i+1<NUM)
+			taskSetWait(tasks[i], tasks[2*i+1]);
+	}
+
+	goto initTaskManager(retinit, NULL);
+}
+
+__code
+retinit(TaskManager *manager, void *arg)
+{
+	goto checkEvent(manager);
+}
+
+__code
+checkEvent(TaskManager *manager)
+{
+	int i;
+	static int count=0;
+	if (count<NUM) {
+		count++;
+		__DEBUG("new task %d added\n", NUM-count);
+		goto addNewTask(manager, tasks[NUM-count]);
+	}
+	for (i=0; i<NUM; i++) {
+		if (stat[i]==1) {
+			stat[i]=2;
+			__DEBUG("finish task %d\n", i);
+			goto finishTask(manager, tasks[i]);
+		}
+	}
+
+	for (i=0; i<NUM; i++) {
+		if (stat[i]!=2) break;
+	}
+
+	if (i==NUM) {
+		__DEBUG("all tasks finished.\n");
+		goto end();
+	}
+
+	__DEBUG("noevent.\n");
+	goto noEvent(manager);
+}
+
+__code
+end()
+{
+	exit(0);
+}
+
+__code
+executeTask(TaskManager *manager, ListIter *iter, Task *task)
+{
+	int i;
+	const TaskType *type;
+	type = &tasktypes[task->typeid];
+
+	__DEBUG("task %s[%s] is executed.\n", task->name, type->name);
+	for (i=0; i<NUM; i++) {
+		if (tasks[i]==task) {
+			stat[i] = 1;
+		}
+	}
+
+	goto executed(manager, iter, task);
+	//goto code(scheduler, task->rbuff, task->wbuff);
+}
+
--- a/test/scheduler/test_sched.cbc	Sun Dec 20 20:46:53 2009 +0900
+++ b/test/scheduler/test_sched.cbc	Tue Dec 22 16:19:56 2009 +0900
@@ -2,24 +2,104 @@
 #include <stdlib.h>
 
 #include "Task.h"
-#include "TaskScheduler.h"
 
 #define __DEBUG(f, args...) \
 	fprintf(stderr, "in %s: "f, __FUNCTION__, ## args)
 
-__code task0(Scheduler scheduler, void *rbuff, void *wbuff);
-__code task1 (Scheduler scheduler, void *rbuff, void *wbuff);
-__code task2 (Scheduler scheduler, void *rbuff, void *wbuff);
+
+void * allocate (size_t size);
+
+__code taskA_0(void *tsched, void *rbuff, void *wbuff);
+__code taskA_1(void *tsched, void *rbuff, void *wbuff);
+__code taskA_2(void *tsched, void *rbuff, void *wbuff);
+__code task0 (void *tsched, void *rbuff, void *wbuff);
+__code task1 (void *tsched, void *rbuff, void *wbuff);
+__code task2 (void *tsched, void *rbuff, void *wbuff);
 int main (int argc, char **argv);
-__code startcode (void *arg);
-__code checkNewCode ();
-__code exitCode ();
-
+__code startcode (void *tsched, void *arg);
+__code checkNewCode (void *tsched, int wait);
+__code exitCode (void *tsched, int id);
 void * allocate (size_t size);
 
 #define NUM 3
 __code
-task0(Scheduler scheduler, void *rbuff, void *wbuff)
+taskA_0(void *tsched, void *rbuff, void *wbuff)
+{
+	int i,j;
+	double *t;
+	int *count=rbuff;
+
+	t = wbuff;
+	double *result[NUM] = { t, t+3, t+6  };
+	for (i=0; i<NUM; i++) {
+		for (j=0; j<NUM; j++) {
+			if (i==j) result[i][j] = 1.0;
+			else result[i][j] = 0.0;
+		}
+	}
+
+	t = (double*)(count+1);
+	double *base[NUM] = { t, t+3, t+6  };
+	printf("count = %d\n", *count);
+	printf("base = \n");
+	for (i=0; i<NUM; i++) {
+		printf("%lf, %lf, %lf\n", base[i][0], base[i][1], base[i][2]);
+	}
+
+	goto scheduler(tsched, taskA_1,rbuff,wbuff);
+}
+__code
+taskA_1(void *tsched, void *rbuff, void *wbuff)
+{
+	int i,j,k;
+	int *count = rbuff;
+	double *t;
+	double prod[NUM][NUM];
+
+	t = (double*)(count+1);
+	double *base[NUM] = { t, t+3, t+6  };
+	t = wbuff;
+	double *result[NUM] = { t, t+3, t+6  };
+
+	if (*count <= 0) {
+		//__DEBUG("task end\n", *count);
+		goto scheduler(tsched, taskA_2,rbuff,wbuff);
+	}
+	for (i=0; i<NUM; i++) {
+		for (j=0; j<NUM; j++) {
+			prod[i][j] = 0;
+			for (k=0; k<NUM; k++) {
+				prod[i][j] += result[j][k] * base[k][i];
+			}
+		}
+	}
+	for (i=0; i<NUM; i++) {
+		for (j=0; j<NUM; j++) {
+			result[i][j] = prod[i][j];
+		}
+	}
+
+	//__DEBUG("count=%d\n", *count);
+	(*count)--;
+	goto scheduler(tsched, taskA_1, rbuff, wbuff);
+}
+__code
+taskA_2(void *tsched, void *rbuff, void *wbuff)
+{
+	int i;
+	double *t;
+
+	t = wbuff;
+	double *result[NUM] = { t, t+3, t+6  };
+	printf("result = \n");
+	for (i=0; i<NUM; i++) {
+		printf("%lf, %lf, %lf\n", result[i][0], result[i][1], result[i][2]);
+	}
+
+	goto scheduler(tsched, END,NULL,NULL);
+}
+__code
+task0(void *tsched, void *rbuff, void *wbuff)
 {
 	int i,j;
 	double *in = rbuff;
@@ -40,10 +120,10 @@
 	__DEBUG("%3.2lf %3.2lf %3.2lf\n", in[0],in[1],in[2]);
 	__DEBUG("%3.2lf %3.2lf %3.2lf\n", out[0],out[1],out[2]);
 	//goto task1(scheduler, wbuff, rbuff);
-	goto scheduler(task1, wbuff, rbuff);
+	goto scheduler(tsched, task1, wbuff, rbuff);
 }
 __code
-task1(Scheduler scheduler, void *rbuff, void *wbuff)
+task1(void *tsched, void *rbuff, void *wbuff)
 {
 	int i,j;
 	double *in = rbuff;
@@ -63,11 +143,11 @@
 	__DEBUG("%p %p\n", rbuff, wbuff);
 	__DEBUG("%3.2lf %3.2lf %3.2lf\n", in[0],in[1],in[2]);
 	__DEBUG("%3.2lf %3.2lf %3.2lf\n", out[0],out[1],out[2]);
-	//goto task2(scheduler, wbuff, rbuff);
-	goto scheduler(task2, wbuff, rbuff);
+	//goto task2(tsched, wbuff, rbuff);
+	goto scheduler(tsched, task2, wbuff, rbuff);
 }
 __code
-task2(Scheduler scheduler, void *rbuff, void *wbuff)
+task2(void *tsched, void *rbuff, void *wbuff)
 {
 	int i,j;
 	double *in = rbuff;
@@ -87,59 +167,73 @@
 	__DEBUG("%p %p\n", rbuff, wbuff);
 	__DEBUG("%3.2lf %3.2lf %3.2lf\n", in[0],in[1],in[2]);
 	__DEBUG("%3.2lf %3.2lf %3.2lf\n", out[0],out[1],out[2]);
-	goto scheduler(END, rbuff, wbuff);
+	goto scheduler(tsched, END, rbuff, wbuff);
 }
 
+#include "TaskScheduler.h"
 
 int
 main(int argc, char **argv)
 {
 	__DEBUG("\n");
 	goto initScheduler(startcode, NULL);
-
 	return 0;
 }
 
 __code
-startcode(void *arg) {
+startcode(void *tsched, void *arg) {
+	int i,j;
 	double *readbuff, *writebuff;
-	readbuff = malloc(sizeof(double)*NUM);
-	writebuff = malloc(sizeof(double)*NUM);
+	readbuff = malloc(sizeof(int)+sizeof(double)*NUM*NUM);
+	writebuff = malloc(sizeof(double)*NUM*NUM);
+
+	int *count = (int*)readbuff;
+	double *t = (double*)(count+1);
+	double *base[NUM] = { t, t+3, t+6 };
 
-	readbuff[0] = 2.00;
-	readbuff[1] = 3.00;
-	readbuff[2] = 4.00;
+	*count = 2;
+	for (i=0; i<NUM; i++) {
+		for (j=0; j<NUM; j++) {
+			if (i==j) base[i][j] = 1.0;
+			else base[i][j] = 0.0;
+		}
+	}
+	base[0][0] = 2.0;
+	base[2][1] = 0.5;
+
 	__DEBUG("id=0 added.\n");
-	goto addCode(0, task0, readbuff, writebuff);
+	goto addCode(tsched, 0, taskA_0, readbuff, writebuff);
 }
 
 __code
-checkNewCode(int wait)
+checkNewCode(void *tsched, int wait)
 {
 	static int t = 0;
 	double *readbuff, *writebuff;
-	readbuff = malloc(sizeof(double)*NUM);
-	writebuff = malloc(sizeof(double)*NUM);
 
 	if (wait) {
 		__DEBUG("all tasks finished\n");
 		exit(0);
 	}
 
+	/*
 	if (t==0) {
+		readbuff = malloc(sizeof(double)*NUM);
+		writebuff = malloc(sizeof(double)*NUM);
 		t++;
 		__DEBUG("id=1 added.\n");
-		goto addCode(1, task0, readbuff, writebuff);
+		goto addCode(tsched, 1, taskA, readbuff, writebuff);
 	}
+	*/
 	__DEBUG("no code added.\n");
-	goto selectCode();
+	goto selectCode(tsched);
 }
 
 __code
-exitCode(int id)
+exitCode(void *tsched, int id)
 {
 	__DEBUG("exit task%d\n", id);
-	goto selectCode();
+	goto selectCode(tsched);
 }
 
 void *
@@ -155,3 +249,4 @@
 	
 
 
+