changeset 184:907bda4a1a14

fix
author gongo@gendarme.cr.ie.u-ryukyu.ac.jp
date Tue, 06 Jan 2009 15:39:48 +0900
parents df3cfc04e796
children bdc08777197e
files TaskManager/Cell/spe/SchedNop2Ready.cc TaskManager/Cell/spe/SchedTask.cc TaskManager/Cell/spe/SchedTaskList.cc TaskManager/Cell/spe/Scheduler.cc TaskManager/ChangeLog TaskManager/Makefile.def TaskManager/Test/test_render/Func.h TaskManager/Test/test_render/Makefile.def TaskManager/Test/test_render/spe/CreateSpan.cpp TaskManager/Test/test_render/spe/DrawSpan.cpp TaskManager/Test/test_render/spe/DrawSpan.h TaskManager/Test/test_render/spe/TileHash.cpp TaskManager/Test/test_render/spe/spe-main.cpp TaskManager/Test/test_render/task/CreateSpan.cpp TaskManager/Test/test_render/task/DrawSpan.cpp TaskManager/Test/test_render/task/DrawSpan.h TaskManager/Test/test_render/task/TileHash.cpp TaskManager/Test/test_render/task/task_init.cpp TaskManager/Test/test_render/viewer.cpp TaskManager/kernel/schedule/SchedNop2Ready.cc TaskManager/kernel/schedule/SchedTask.cc TaskManager/kernel/schedule/SchedTaskList.cc TaskManager/kernel/schedule/Scheduler.cc include/TaskManager/SchedTask.h include/TaskManager/SchedTaskList.h include/TaskManager/Scheduler.h
diffstat 26 files changed, 995 insertions(+), 282 deletions(-) [+]
line wrap: on
line diff
--- a/TaskManager/Cell/spe/SchedNop2Ready.cc	Tue Dec 23 16:27:07 2008 +0900
+++ b/TaskManager/Cell/spe/SchedNop2Ready.cc	Tue Jan 06 15:39:48 2009 +0900
@@ -20,20 +20,18 @@
 SchedTaskBase*
 SchedNop2Ready::next(Scheduler *m, SchedTaskBase *p)
 {
+    SchedTaskBase *nextSched;
+
     __debug("[SchedNop2Ready:%s]\n", __FUNCTION__);
     
     delete p;
 
-    // 追加されたタスクがあれば
-    if (scheduler->renewTop_taskList) {
-	TaskListPtr list = scheduler->renewTop_taskList;
-	scheduler->renewTop_taskList = scheduler->renewTop_taskList->next;
-	scheduler->renewCur_taskList = NULL;
-
-	list->next = NULL;
-	SchedTaskList *schd = new SchedTaskList((unsigned int)list, scheduler);
-	schd->flag_renewTaskList = 1;
-	return schd;
+    nextSched = scheduler->get_nextRenewTaskList(NULL, 0);
+	
+    // RenewTask がある
+    if (nextSched) {
+	printf("RenewTaskList start [SchedNop2Ready]\n");
+	return nextSched;
     } else {
 	scheduler->mail_write(MY_SPE_STATUS_READY);
 	return new SchedMail(scheduler);
--- a/TaskManager/Cell/spe/SchedTask.cc	Tue Dec 23 16:27:07 2008 +0900
+++ b/TaskManager/Cell/spe/SchedTask.cc	Tue Jan 06 15:39:48 2009 +0900
@@ -10,33 +10,35 @@
 extern Scheduler::TaskObject task_list[MAX_TASK_OBJECT];
 
 SchedTask*
-CreateSchedTask(TaskListPtr taskList, Scheduler *sched)
+createSchedTask(TaskPtr task)
 {
-    TaskPtr task = &taskList->tasks[sched->curIndex_taskList++];
-    
-    return task_list[task->command](taskList, task, sched->get_curReadBuf(),
-				    sched->get_curWriteBuf(), sched);
+    return task_list[task->command]();
 }
 
-SchedTask::SchedTask(TaskListPtr _list, TaskPtr _task, ListDataPtr rbuf,
-		     ListDataPtr wbuf, Scheduler* sc)
+SchedTask::SchedTask(void)
 {
-    __list        = _list;
-    __task        = _task;
-    __inListData  = rbuf;
-    __outListData = wbuf;
+    __list        = NULL;
+    __task        = NULL;
+    __inListData  = NULL;
+    __outListData = NULL;
     __readbuf     = NULL;
     __writebuf    = NULL;
-    __scheduler   = sc;
+    __scheduler   = NULL;
     __taskGroup   = NULL;
     __renew_flag  = 0;
-
-    smanager = new STaskManager(this);
+    __cur_index   = 0;
+    __flag_renewTask = SCHED_TASK_NORMAL;
+    
+    ex_init  = &SchedTask::ex_init_normal;
+    ex_read  = &SchedTask::ex_read_normal;
+    ex_exec  = &SchedTask::ex_exec_normal;
+    ex_write = &SchedTask::ex_write_normal;
+    ex_next  = &SchedTask::ex_next_normal;
 }
 
 SchedTask::~SchedTask(void)
 {
-    if (__flag_renewTask) {
+    if (__flag_renewTask == SCHED_TASK_RENEW) {
 	/**
 	 * __inListData と __outListData はタスク自身のものなので
 	 * 終わったら即 free する。
@@ -58,37 +60,66 @@
     delete smanager;
 }
 
+/**                                                                         
+ * このタスクを Renew Task とし、それに応じた関数をセットする
+ */
 void
-SchedTask::__init__(void)
+SchedTask::__setRenew(void)
 {
-    /**
-     * task->inData や task->outData が
-     * PPE のものか、SPE のものかって
-     * アドレスで判定できれば楽になると思うんだが。。。
-     */
-    if (__flag_renewTask == 0) {
-	__scheduler->dma_load(__inListData, (uint32)__task->inData,
-			      sizeof(ListData), DMA_READ_IN_LIST);
-	__scheduler->dma_load(__outListData, (uint32)__task->outData,
-			      sizeof(ListData), DMA_READ_OUT_LIST);
-	
-	__taskGroup = new TaskGroup;
-	__taskGroup->command = __task->self;
+    __flag_renewTask = SCHED_TASK_RENEW;
 
-	ex_read  = &SchedTask::ex_read_normal;
-	ex_exec  = &SchedTask::ex_exec_normal;
-	ex_write = &SchedTask::ex_write_normal;
-    } else {
-	__inListData = __task->inData;
-	__outListData = __task->outData;
-	__taskGroup = (TaskGroupPtr)__task->self;
-
-	ex_read  = &SchedTask::ex_read_renew;
-	ex_exec  = &SchedTask::ex_exec_renew;
-	ex_write = &SchedTask::ex_write_renew;
-    }
+    ex_init  = &SchedTask::ex_init_renew;
+    ex_read  = &SchedTask::ex_read_renew;
+    ex_exec  = &SchedTask::ex_exec_renew;
+    ex_write = &SchedTask::ex_write_renew;
+    ex_next  = &SchedTask::ex_next_renew;
 }
 
+void
+SchedTask::__init__(TaskListPtr _list, TaskPtr _task, int index,
+		    ListDataPtr rbuf, ListDataPtr wbuf, Scheduler* sc)
+{
+    __list        = _list;
+    __task        = _task;
+    __inListData  = rbuf;
+    __outListData = wbuf;
+    __scheduler   = sc;
+    __cur_index   = index;
+
+    smanager = new STaskManager(this);
+
+    __scheduler->mainMem_wait();
+
+    (this->*ex_init)();
+}
+
+/**
+ * PPE 内で生成されたタスクの ex_init()
+ */
+void
+SchedTask::ex_init_normal(void)
+{
+    __scheduler->dma_load(__inListData, (uint32)__task->inData,
+			  sizeof(ListData), DMA_READ_IN_LIST);
+    __scheduler->dma_load(__outListData, (uint32)__task->outData,
+			  sizeof(ListData), DMA_READ_OUT_LIST);
+    
+    __taskGroup = new TaskGroup;
+    __taskGroup->command = __task->self;
+}
+
+/**
+ * SPE 内で生成されたタスクの ex_init()
+ * 各データは SPE 内の create_task 時に生成もしくは引き継がれているので
+ * ex_init_normal() と違い、ここでは値を渡すだけ
+ */
+void
+SchedTask::ex_init_renew(void)
+{
+    __inListData = __task->inData;
+    __outListData = __task->outData;
+    __taskGroup = (TaskGroupPtr)__task->self;    
+}
 
 /**
  * [Todo]
@@ -263,24 +294,99 @@
 
     delete p;
 
-    if (__scheduler->curIndex_taskList < __list->length) {
-	SchedTask* schedTask = CreateSchedTask(__list, __scheduler);
-	schedTask->__flag_renewTask = this->__flag_renewTask;
-	schedTask->__init__();
+    return (this->*ex_next)();
+}
+
+SchedTaskBase*
+SchedTask::ex_next_normal(void)
+{
+    if (__cur_index < __list->length) {
+	SchedTaskBase *nextSched;
+
+	nextSched = __scheduler->get_nextRenewTaskList(__list, __cur_index);
+	
+	// RenewTask がある
+	if (nextSched) {
+	    return nextSched;
+	} else {
+	    TaskPtr nextTask
+		= &__list->tasks[__cur_index++];
+	    nextSched = createSchedTask(nextTask);
+	    ((SchedTask*)nextSched)->__init__(__list, nextTask, __cur_index,
+					      __scheduler->get_curReadBuf(),
+					      __scheduler->get_curWriteBuf(),
+					      __scheduler);
+
+	    /**
+	     * この理由は SchedTask:~SchedTask() で
+	     */
+	    __list = NULL;
+
+	    return nextSched;
+	}
+    } else {
+	uint32 nextList = (uint32)__list->next;
+	
+	if (nextList == 0) {
+	    return new SchedNop2Ready(__scheduler);
+	} else {
+	    return createSchedTaskList(nextList, __scheduler,
+				       SCHED_TASKLIST_NORMAL);
+	}
+    }
+}
+
+/**
+ *
+ */
+SchedTaskBase*
+SchedTask::ex_next_renew(void)
+{
+    TaskPtr nextTask;
+    SchedTask *nextSched;
+
+    if (__cur_index < __list->length) {
+	nextTask = &__list->tasks[__cur_index++];
+	nextSched = createSchedTask(nextTask);
+
+	// RenewTaskList を実行中なので
+	nextSched->__setRenew();
+	nextSched->__init__(__list, nextTask, __cur_index,
+			    __scheduler->get_curReadBuf(),
+			    __scheduler->get_curWriteBuf(),
+			    __scheduler);
 
 	/**
 	 * この理由は SchedTask:~SchedTask() で
 	 */
 	__list = NULL;
-
-	return schedTask;
+	return nextSched;
     } else {
 	uint32 nextList = (uint32)__list->next;
-
+	
 	if (nextList == 0) {
-	    return new SchedNop2Ready(__scheduler);
+	    TaskListPtr nextList = __scheduler->get_backupTaskList();
+
+	    // 中断した TaskList
+	    if (nextList) {
+		__cur_index = __scheduler->bakIndex_taskList;
+		
+		nextTask = &nextList->tasks[__cur_index++];
+		nextSched = createSchedTask(nextTask);
+		
+		nextSched->__init__(nextList, nextTask, __cur_index,
+				    __scheduler->get_curReadBuf(),
+				    __scheduler->get_curWriteBuf(),
+				    __scheduler);
+		return nextSched;
+	    } else {
+		return new SchedNop2Ready(__scheduler);
+	    }
 	} else {
-	    return new SchedTaskList(nextList, __scheduler);
+	    __scheduler->renewTop_taskList
+		= __scheduler->renewTop_taskList->next;
+	    return createSchedTaskList(nextList, __scheduler,
+				       SCHED_TASKLIST_RENEW);
 	}
     }
 }
@@ -309,6 +415,15 @@
 }
 
 /**
+ * get_input(index) のサイズを返す
+ */
+int
+SchedTask::get_inputSize(int index)
+{
+    return __inListData->element[index].size;
+}
+
+/**
  * write buffer の領域を返す。
  */
 void*
@@ -330,6 +445,15 @@
     return __outListData->element[index].addr;
 }
 
+/**
+ * get_output(index) のサイズを返す
+ */
+int
+SchedTask::get_outputSize(int index)
+{
+    return __outListData->element[index].size;
+}
+
 int
 SchedTask::get_param(int index)
 {
--- a/TaskManager/Cell/spe/SchedTaskList.cc	Tue Dec 23 16:27:07 2008 +0900
+++ b/TaskManager/Cell/spe/SchedTaskList.cc	Tue Jan 06 15:39:48 2009 +0900
@@ -1,4 +1,3 @@
-#include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include "SchedTaskList.h"
@@ -7,10 +6,27 @@
 #include "DmaManager.h"
 #include "error.h"
 
+/**
+ * SchedTaskList 菴
+ *
+ * @param[in] next_list 罨<絎茵 TaskList ≪
+ * @param[in] next_list <ゃ潟<≪≪鴻
+ *            SPE х≪鴻
+ *            SPE х翫DMA 綽荀<
+ *            0: <ゃ潟<≪, 1: SPE
+ */
+SchedTaskList*
+createSchedTaskList(uint32 next_list, Scheduler* scheduler, int renew_flag)
+{
+    SchedTaskList* sched = new SchedTaskList(next_list, scheduler);
+    sched->flag_renewTaskList = renew_flag;
+    return sched;
+}
+
 SchedTaskList::SchedTaskList(unsigned int addr, Scheduler *sched)
 {
     params_addr = addr;
-    list = sched->get_curListBuf();
+    list = NULL;
     scheduler = sched;
 
     flag_renewTaskList = 0;
@@ -22,33 +38,46 @@
 {
     __debug("[SchedTaskList:%s]\n", __FUNCTION__);
 
-    if (flag_renewTaskList == 0) {
-	scheduler->dma_load(list, params_addr, 
+    if (flag_renewTaskList == SCHED_TASKLIST_NORMAL) {
+	list = scheduler->get_curListBuf();
+	scheduler->dma_load(list, params_addr,
 			    sizeof(TaskList), DMA_READ_TASKLIST);
 	scheduler->dma_wait(DMA_READ_TASKLIST);
     } else {
 	list = (TaskListPtr)params_addr;
     }
-
-    scheduler->curIndex_taskList = 0;
-
-    scheduler->mainMem_wait();
 }
 
 SchedTaskBase*
 SchedTaskList::next(Scheduler *m, SchedTaskBase *p)
 {
+    SchedTaskBase *nextSched;
+
     __debug("[SchedTaskList:%s]\n", __FUNCTION__);
 
     delete p;
 
     if (list->length < 1) {
-	return new SchedNop2Ready(scheduler);
+	nextSched = new SchedNop2Ready(scheduler);
+
+	if (flag_renewTaskList == SCHED_TASKLIST_RENEW) {
+	    free(list);
+	}
+
     } else {
-	SchedTask* task = CreateSchedTask(list, m);
-	task->__flag_renewTask = this->flag_renewTaskList;
-	task->__init__();
-	return task;
+	TaskPtr nextTask = &list->tasks[0];
+	nextSched = createSchedTask(nextTask);
+
+	if (flag_renewTaskList == SCHED_TASKLIST_RENEW) {
+	    ((SchedTask*)nextSched)->__setRenew();
+	}
+	
+	((SchedTask*)nextSched)->__init__(list, nextTask, 1,
+					  scheduler->get_curReadBuf(),
+					  scheduler->get_curWriteBuf(),
+					  scheduler);
     }
+
+    return nextSched;
 }
 
--- a/TaskManager/Cell/spe/Scheduler.cc	Tue Dec 23 16:27:07 2008 +0900
+++ b/TaskManager/Cell/spe/Scheduler.cc	Tue Jan 06 15:39:48 2009 +0900
@@ -88,7 +88,6 @@
 Scheduler::get_curListBuf(void)
 {
     buffFlag_taskList ^= 1;
-    curIndex_taskList = 0;
 
     return buff_taskList[buffFlag_taskList];
 }
@@ -137,6 +136,46 @@
     }
 }
 
+/**
+ * 次に実行する Renew Task List を返す
+ *
+ * @param[in] curList 現在実行中の TaskList
+ *                    中断して RenewTaskList を行うため
+ *                    バックアップを取っておく
+ * @return next RenewTaskList
+ */
+SchedTaskList*
+Scheduler::get_nextRenewTaskList(TaskListPtr curList, int curIndex)
+{
+    if (renewTop_taskList) {
+	TaskListPtr list  = renewTop_taskList;
+	renewTop_taskList = renewTop_taskList->next;
+	renewCur_taskList = NULL;
+	
+	bak_curTaskList = curList;
+	bakIndex_taskList = curIndex;
+	
+	//list->next = NULL;
+	SchedTaskList *sched
+	    = createSchedTaskList((uint32)list, this, SCHED_TASKLIST_RENEW);
+	return sched;
+    } else {
+	return NULL;
+    }
+}
+
+/**
+ * RenewTaskList 実行前に中断した TaskList を返す
+ * NULL の場合、中断した TaskList は無い。
+ *
+ * @return TaskList
+ */
+TaskListPtr
+Scheduler::get_backupTaskList(void)
+{
+    return bak_curTaskList;
+}
+
 void
 Scheduler::dma_load(void *buf, uint32 addr, uint32 size, uint32 mask)
 {
--- a/TaskManager/ChangeLog	Tue Dec 23 16:27:07 2008 +0900
+++ b/TaskManager/ChangeLog	Tue Jan 06 15:39:48 2009 +0900
@@ -1,3 +1,45 @@
+2009-01-05  Wataru MIYAGUNI  <gongo@cr.ie.u-ryukyu.ac.jp>
+
+	* all : fix
+	Scheduler::curIndex_taskList ゃ
+	SchedTask 罕紊眼(SchedTask::__cur_index)
+	篌眼SchedTask::__init__()  cur_index ャ罕紊
+	
+2008-12-24  Wataru MIYAGUNI  <gongo@cr.ie.u-ryukyu.ac.jp>
+
+	* kernel/schedule/SchedTask.cc (SchedTask::ex_init_renew)
+	(SchedTask::ex_init_normal): add
+	(SchedTask::__init__): fix
+
+	init с ex_init 篏帥罕
+	潟潟鴻帥ф検綣違 __init__() 羝<罕
+	潟潟鴻帥綣違膓帥<∴Κ鴻吾
+	cャс
+
+	箴.
+	class Hoge : public SchedTask {
+	  Hoge(int i) : Task(i) {}
+	};
+
+	с篁障с Scheduler.h  SchedConstructor c吾
+	劫ャт罕綵≪
+	с箴
+
+	SchedTask -> Hoge -> Fuge c Fuge c帥鴻
+	篏筝障障 SchedTask 綣井検障с
+	cс潟潟鴻水
+	__init__() 綣違羝<罕障
+
+	(SchedTask::__set_renewFlag): add
+
+	сPPEх(normal)SPE х(renew) 
+	ゅ茵ex_xxx 荐絎
+
+	(SchedTask::get_inputSize, SchedTask::get_outputSize): add
+
+	≪鴻泣ゃ冴鴻
+
+	
 2008-12-23  Wataru MIYAGUNI  <gongo@cr.ie.u-ryukyu.ac.jp>
 
 	* Cell/spe/SchedTask.cc (SchedTask::get_outputAddr)
--- a/TaskManager/Makefile.def	Tue Dec 23 16:27:07 2008 +0900
+++ b/TaskManager/Makefile.def	Tue Jan 06 15:39:48 2009 +0900
@@ -25,7 +25,7 @@
 IMPL_CELL_OBJS = $(IMPL_CELL_SRCS:.cc=.o)
 
 CC     = g++   
-CFLAGS = -O9 -Wall `sdl-config --cflags` -g
+CFLAGS = -O0 -Wall `sdl-config --cflags` -g
 LIBS   = 
 
 INCLUDE = -I../include/TaskManager
\ No newline at end of file
--- a/TaskManager/Test/test_render/Func.h	Tue Dec 23 16:27:07 2008 +0900
+++ b/TaskManager/Test/test_render/Func.h	Tue Jan 06 15:39:48 2009 +0900
@@ -16,6 +16,7 @@
      TASK_CS_START,
      TASK_CS_RUN,
      TASK_DRAW_SPAN,
+     TASK_DRAW_SPAN2,
      TASK_DRAW_BACK,
      TASK_SET_TEXTURE,
      TASK_DUMMY,
--- a/TaskManager/Test/test_render/Makefile.def	Tue Dec 23 16:27:07 2008 +0900
+++ b/TaskManager/Test/test_render/Makefile.def	Tue Jan 06 15:39:48 2009 +0900
@@ -12,7 +12,7 @@
 #CERIUM = ../../..
 
 CC      = g++
-CFLAGS  = -O9 -g -Wall# -DDEBUG
+CFLAGS  = -O0 -g -Wall# -DDEBUG
 
 INCLUDE = -I$(CERIUM)/include/TaskManager -I.
 LIBS = -L$(CERIUM)/TaskManager
\ No newline at end of file
--- a/TaskManager/Test/test_render/spe/CreateSpan.cpp	Tue Dec 23 16:27:07 2008 +0900
+++ b/TaskManager/Test/test_render/spe/CreateSpan.cpp	Tue Jan 06 15:39:48 2009 +0900
@@ -128,8 +128,7 @@
 
 
 /**
- * span  width  Triangle  height 絲障
- * texture  width,height 罸鴻
+ * span  width,height  texture  width,height 罸鴻
  * span 祉篏帥 texture 罸羆
  *
  * @param[in] width      Width of span
@@ -385,7 +384,7 @@
 			     (int)(span->tex_width*tex_x_len),
 			     (int)(span->tex_height*tex_y_len), tex_scale_max);
 
-	//scale = (8 > tex_scale_max) ? tex_scale_max : 8;
+	scale = (8 > tex_scale_max) ? tex_scale_max : 8;
 	
 	uint32 *tapestry = getTapestry(tex_width, tex_height, scale, tex_addr);
 
@@ -432,11 +431,40 @@
 
 	for (int i = 0; i < pp->info.size; i++) {
 	    triPack = &pp->tri[i];
-
-	    // ф検吾鴻帥箙с祉祉
-	    // с緇絋鐚
+	    
+#if 0
 	    make_vertex(triPack, &vMin, &vMid, &vMax);
-
+#else
+	    if (triPack->ver1.y <= triPack->ver2.y) {
+		if (triPack->ver2.y <= triPack->ver3.y) {
+		    vMin = &triPack->ver1;
+		    vMid = &triPack->ver2;
+		    vMax = &triPack->ver3;
+		} else if (triPack->ver3.y <= triPack->ver1.y) {
+		    vMin = &triPack->ver3;
+		    vMid = &triPack->ver1;
+		    vMax = &triPack->ver2;
+		} else {
+		    vMin = &triPack->ver1;
+		    vMid = &triPack->ver3;
+		    vMax = &triPack->ver2;
+		}
+	    } else {
+		if (triPack->ver1.y <= triPack->ver3.y) {
+		    vMin = &triPack->ver2;
+		    vMid = &triPack->ver1;
+		    vMax = &triPack->ver3;
+		} else if (triPack->ver3.y <= triPack->ver2.y) {
+		    vMin = &triPack->ver3;
+		    vMid = &triPack->ver2;
+		    vMax = &triPack->ver1;
+		} else {
+		    vMin = &triPack->ver2;
+		    vMid = &triPack->ver3;
+		    vMax = &triPack->ver1;
+		}
+	    }
+#endif
 	    make_vMid10(vMid10, vMin, vMid, vMax);
 
 	    /**
--- a/TaskManager/Test/test_render/spe/DrawSpan.cpp	Tue Dec 23 16:27:07 2008 +0900
+++ b/TaskManager/Test/test_render/spe/DrawSpan.cpp	Tue Jan 06 15:39:48 2009 +0900
@@ -2,19 +2,15 @@
 #include <string.h>
 #include "DrawSpan.h"
 #include "polygon_pack.h"
-#include "SpanPack.h"
 #include "texture.h"
 #include "viewer_types.h"
-#include "TileHash.h"
+#include "Func.h"
 
 #define SPAN_PACK_LOAD 0
 #define TEX_LOAD 1
 
 SchedDefineTask(DrawSpan);
 
-static TileHashPtr hash;
-static TileListPtr tileList;
-
 /**
  * テクスチャは、TEXTURE_SPLIT_PIXEL^2 のブロックに分割する
  *
@@ -45,8 +41,8 @@
  * @param[in] twidth  Width of texture
  * @return block ID
  */
-static inline int
-get_tex_block(int tx, int ty, int twidth)
+int
+DrawSpan::getTexBlock(int tx, int ty, int twidth)
 {
      int blockX, blockY;
 
@@ -66,10 +62,10 @@
  * @param[in] tex_addr_top (tx,ty) で使うテクスチャの先頭address
  * @return block ID
  */
-static inline uint32*
-getTile(int tx, int ty, int tw, uint32 *tex_addr_top)
+uint32*
+DrawSpan::getTile(int tx, int ty, int tw, uint32 *tex_addr_top)
 {
-    int block = get_tex_block(tx, ty, tw);
+    int block = getTexBlock(tx, ty, tw);
     return tex_addr_top + block*TEXTURE_BLOCK_SIZE;
 }
 
@@ -81,54 +77,115 @@
     }
 }
 
+/**
+ * Span が使う Texture Tile があるか
+ *
+ * @retval != NULL 存在する
+ * @retval NULL    存在しない
+ */
+TilePtr
+DrawSpan::isAvailableTile(uint32 *addr)
+{
+    return hash->get(addr);
+}
+
+void
+DrawSpan::set_rgb(uint32 *addr)
+{
+    TilePtr tile;
+
+    if (!isAvailableTile(addr)) {
+	tile = tileList->nextTile();
+	/**
+	 * FIFO なので、もし前のが残っていれば削除
+	 */
+	hash->remove(tile->texture_addr);
+	
+	tile->texture_addr = addr;
+	
+	hash->put(tile->texture_addr, tile);
+	
+	smanager->dma_load(tile->pixel, (uint32)addr,
+			   sizeof(uint32)*TEXTURE_BLOCK_SIZE, TEX_LOAD);
+	
+	smanager->dma_wait(TEX_LOAD);
+    }
+}
+
+void
+DrawSpan::set_rgbs(uint32 *addr, uint32 *max_addr)
+{
+    uint32 start = (uint32)addr;
+    uint32 end = (uint32)max_addr;
+    uint32 length = end-start;
+    uint32 diff = sizeof(uint32)*TEXTURE_BLOCK_SIZE;
+    uint32 max_tile = 8;
+    
+    for (uint32 i = 0, j = 0; i <= length && j < max_tile; i += diff, j++) {
+	set_rgb((uint32*)(start + i));
+    }
+}
+
 Uint32
 DrawSpan::get_rgb(int tx, int ty, uint32 *addr)
 {
     TilePtr tile;
 
     tile = hash->get(addr);
-    if (tile == NULL) {
-	tile = tileList->nextTile();
-
-	/**
-	 * FIFO なので、もし前のが残っていれば削除
-	 */
-	hash->remove(tile->texture_addr);
-
-	tile->texture_addr = addr;
-
-	smanager->dma_load(tile->pixel, (uint32)addr,
-			   sizeof(uint32)*TEXTURE_BLOCK_SIZE, TEX_LOAD);
-
-	int index = hash->put(tile->texture_addr, tile);
-
-	/**
-	 * TODO:
-	 *   入らなかったやつは
-	 *   今までのやつを描画してから続きをするとか
-	 */
-	if (index < 0) {
-	    printf("[%p] Can't entry\n", tile);
-	    return 0xff0000;
-	}
-
-	smanager->dma_wait(TEX_LOAD);
-    }
-
     return tile->pixel[(TEXTURE_SPLIT_PIXEL)*ty+tx];
 }
 
+/**
+ * DrawSpan の再起動 (DrawSpanRenew 生成)
+ *
+ * @param[in] spack 現在処理している SpanPack
+ * @param[in] cur_span_x span->length_x != 1 の時の Span の処理で
+ *                       どこまで進んでいるか
+ */
+void
+DrawSpan::reboot(SpanPackPtr spack, int cur_span_x)
+{
+    TaskPtr renew_task = smanager->create_task(TASK_DRAW_SPAN2);
+    int rangey = smanager->get_param(2);
 
+    /**
+     * 共通の outData, param はそのまま渡す
+     */
+    for (int i = 0; i < rangey; i++) {
+	renew_task->add_outData(smanager->get_outputAddr(i),
+			   smanager->get_outputSize(i));
+    }
+
+    // rangex_start, rangex_end, rangey
+    renew_task->add_param(smanager->get_param(0));
+    renew_task->add_param(smanager->get_param(1)); 
+    renew_task->add_param(smanager->get_param(2));
+
+    /**
+     * SpanPack は続きから開始するので、
+     * 現在の状態をコピーしておく。
+     * spack は rbuf から取得してる可能性があり
+     * rbuf はシステムが自動的に free() するため
+     * アドレスだけ渡すのはNG
+     */ 
+    SpanPackPtr curr = (SpanPackPtr)smanager->allocate(sizeof(SpanPack));
+    memcpy(curr, spack, sizeof(SpanPack));
+    renew_task->add_param((int)curr);
+
+    renew_task->add_param(cur_span_x);
+
+    /**
+     * 再起動したタスクを待つ
+     */ 
+    smanager->wait_task(renew_task);
+
+    // next_spack は free() するので wait する
+    smanager->dma_wait(SPAN_PACK_LOAD);
+}
 
 int
 DrawSpan::run(void *rbuf, void *wbuf)
 {
-    SpanPack *spack = (SpanPack*)smanager->get_input(0);
-    SpanPack *next_spack =
-	(SpanPack*)smanager->allocate(sizeof(SpanPack));
-    SpanPack *free_spack = next_spack; // next_spack の free() 用
-    Span *span;
-
     hash = (TileHashPtr)smanager->global_get(GLOBAL_TEXTURE_HASH);
     tileList = (TileListPtr)smanager->global_get(GLOBAL_TILE_LIST);
 
@@ -141,7 +198,12 @@
     // y の範囲 (render_y + rangey - 1)
     int rangey        = smanager->get_param(2);
     
-    float *zRow = (float*)smanager->get_input(1);
+    float *zRow = (float*)smanager->allocate(sizeof(float)*rangex*rangey);
+
+    for (int i = 0; i < rangex*rangey; i++) {
+	zRow[i] = 65535.0f;
+    }
+
     int **linebuf = (int**)smanager->allocate(sizeof(int*)*rangey);
 
     for (int i = 0; i < rangey; i++) {
@@ -149,6 +211,11 @@
 	linebuf_init(linebuf[i], rangex, 0xffffffff);
     }
 
+    SpanPackPtr spack = (SpanPackPtr)smanager->get_input(0);
+    SpanPackPtr next_spack = (SpanPackPtr)smanager->allocate(sizeof(SpanPack));
+    SpanPackPtr free_spack = next_spack; // next_spack の free() 用
+    Span *span;
+
     do {
 	/**
 	 * SpanPack->next が存在する場合、
@@ -210,6 +277,20 @@
 		    tex_localx = tex_xpos % TEXTURE_SPLIT_PIXEL;
 		    tex_localy = tex_ypos % TEXTURE_SPLIT_PIXEL;
 		    
+		    /**
+		     * Tile が無い場合、一旦タスクはここで中断し、
+		     * Tile をロードするタスクを走らせた後に再起動する
+		     */
+		    if (!isAvailableTile(tex_addr)) {
+			spack->info.start = t;
+			//set_rgb(tex_addr);
+			set_rgbs(tex_addr,
+				 getTile(span->tex_width-1, tex_ypos,
+					 span->tex_width, span->tex_addr));
+			reboot(spack, 0);
+			goto FINISH;
+		    }
+
 		    rgb = get_rgb(tex_localx, tex_localy, tex_addr);
 
 		    zRow[localx + (rangex * localy)] = zpos;
@@ -239,6 +320,16 @@
 					   span->tex_width, span->tex_addr);
 			tex_localx = tex_xpos % TEXTURE_SPLIT_PIXEL;
 			tex_localy = tex_ypos % TEXTURE_SPLIT_PIXEL;
+
+			if (!isAvailableTile(tex_addr)) {
+			    spack->info.start = t;
+			    //set_rgb(tex_addr);
+			    set_rgbs(tex_addr,
+				     getTile(span->tex_width-1, tex_ypos,
+					     span->tex_width, span->tex_addr));
+			    reboot(spack, j);
+			    goto FINISH;
+			}
 			
 			rgb = get_rgb(tex_localx, tex_localy, tex_addr);
 		    
@@ -251,11 +342,13 @@
 
 	smanager->dma_wait(SPAN_PACK_LOAD);
 
-	SpanPack *tmp_spack = spack;
+	SpanPackPtr tmp_spack = spack;
 	spack = next_spack;
 	next_spack = tmp_spack;
     } while (spack);
 
+
+FINISH:
     free(free_spack);
     free(linebuf);
 
--- a/TaskManager/Test/test_render/spe/DrawSpan.h	Tue Dec 23 16:27:07 2008 +0900
+++ b/TaskManager/Test/test_render/spe/DrawSpan.h	Tue Jan 06 15:39:48 2009 +0900
@@ -9,6 +9,14 @@
 #  include "Tapestry.h"
 #endif
 
+#ifndef INCLUDED_SPAN_PACK
+#  include "SpanPack.h"
+#endif
+
+#ifndef INCLUDED_TEXTURE_HASH
+#  include "TileHash.h"
+#endif
+
 typedef int8_t          Sint8;
 typedef uint8_t         Uint8;
 typedef int16_t         Sint16;
@@ -21,10 +29,20 @@
 public:
     SchedConstructor(DrawSpan);
 
+    TileHashPtr hash;
+    TileListPtr tileList;
+
     int run(void *rbuf, void *wbuf);
 
     void linebuf_init(int *buf, int width, int rgb);    
+    void set_rgb(uint32 *addr);
+    void set_rgbs(uint32 *addr, uint32 *max_addr);
     Uint32 get_rgb(int tx, int ty, uint32 *addr);
+    TilePtr isAvailableTile(uint32 *addr);
+    uint32* getTile(int tx, int ty, int tw, uint32 *tex_addr_top);
+    int getTexBlock(int tx, int ty, int twidth);
+
+    void reboot(SpanPackPtr spack, int cur_span_x);
 };
 
 #endif
--- a/TaskManager/Test/test_render/spe/TileHash.cpp	Tue Dec 23 16:27:07 2008 +0900
+++ b/TaskManager/Test/test_render/spe/TileHash.cpp	Tue Jan 06 15:39:48 2009 +0900
@@ -1,3 +1,4 @@
+#include <stdio.h>
 #include <string.h>
 #include <stdlib.h>
 #include "TileHash.h"
--- a/TaskManager/Test/test_render/spe/spe-main.cpp	Tue Dec 23 16:27:07 2008 +0900
+++ b/TaskManager/Test/test_render/spe/spe-main.cpp	Tue Jan 06 15:39:48 2009 +0900
@@ -4,6 +4,7 @@
 SchedExternTask(LoadTexture);
 SchedExternTask(SetTexture);
 SchedExternTask(DrawSpan);
+SchedExternTask(DrawSpanRenew);
 SchedExternTask(DrawBack);
 
 SchedExternTask(CreateSpan);
@@ -15,6 +16,7 @@
     SchedRegisterTask(TASK_INIT_TEXTURE, LoadTexture);
     SchedRegisterTask(TASK_SET_TEXTURE, SetTexture);
     SchedRegisterTask(TASK_DRAW_SPAN, DrawSpan);
+    SchedRegisterTask(TASK_DRAW_SPAN2, DrawSpanRenew);
     SchedRegisterTask(TASK_DRAW_BACK, DrawBack);
 
     SchedRegisterTask(TASK_CREATE_SPAN, CreateSpan);
--- a/TaskManager/Test/test_render/task/CreateSpan.cpp	Tue Dec 23 16:27:07 2008 +0900
+++ b/TaskManager/Test/test_render/task/CreateSpan.cpp	Tue Jan 06 15:39:48 2009 +0900
@@ -384,7 +384,7 @@
 			     (int)(span->tex_width*tex_x_len),
 			     (int)(span->tex_height*tex_y_len), tex_scale_max);
 
-	//scale = (4 > tex_scale_max) ? tex_scale_max : 4;
+	scale = (8 > tex_scale_max) ? tex_scale_max : 8;
 	
 	uint32 *tapestry = getTapestry(tex_width, tex_height, scale, tex_addr);
 
--- a/TaskManager/Test/test_render/task/DrawSpan.cpp	Tue Dec 23 16:27:07 2008 +0900
+++ b/TaskManager/Test/test_render/task/DrawSpan.cpp	Tue Jan 06 15:39:48 2009 +0900
@@ -2,19 +2,15 @@
 #include <string.h>
 #include "DrawSpan.h"
 #include "polygon_pack.h"
-#include "SpanPack.h"
 #include "texture.h"
 #include "viewer_types.h"
-#include "TileHash.h"
+#include "Func.h"
 
 #define SPAN_PACK_LOAD 0
 #define TEX_LOAD 1
 
 SchedDefineTask(DrawSpan);
 
-static TileHashPtr hash;
-static TileListPtr tileList;
-
 /**
  * テクスチャは、TEXTURE_SPLIT_PIXEL^2 のブロックに分割する
  *
@@ -45,8 +41,8 @@
  * @param[in] twidth  Width of texture
  * @return block ID
  */
-static inline int
-get_tex_block(int tx, int ty, int twidth)
+int
+DrawSpan::getTexBlock(int tx, int ty, int twidth)
 {
      int blockX, blockY;
 
@@ -66,10 +62,10 @@
  * @param[in] tex_addr_top (tx,ty) で使うテクスチャの先頭address
  * @return block ID
  */
-static inline uint32*
-getTile(int tx, int ty, int tw, uint32 *tex_addr_top)
+uint32*
+DrawSpan::getTile(int tx, int ty, int tw, uint32 *tex_addr_top)
 {
-    int block = get_tex_block(tx, ty, tw);
+    int block = getTexBlock(tx, ty, tw);
     return tex_addr_top + block*TEXTURE_BLOCK_SIZE;
 }
 
@@ -81,54 +77,115 @@
     }
 }
 
+/**
+ * Span が使う Texture Tile があるか
+ *
+ * @retval != NULL 存在する
+ * @retval NULL    存在しない
+ */
+TilePtr
+DrawSpan::isAvailableTile(uint32 *addr)
+{
+    return hash->get(addr);
+}
+
+void
+DrawSpan::set_rgb(uint32 *addr)
+{
+    TilePtr tile;
+
+    if (!isAvailableTile(addr)) {
+	tile = tileList->nextTile();
+	/**
+	 * FIFO なので、もし前のが残っていれば削除
+	 */
+	hash->remove(tile->texture_addr);
+	
+	tile->texture_addr = addr;
+	
+	hash->put(tile->texture_addr, tile);
+	
+	smanager->dma_load(tile->pixel, (uint32)addr,
+			   sizeof(uint32)*TEXTURE_BLOCK_SIZE, TEX_LOAD);
+	
+	smanager->dma_wait(TEX_LOAD);
+    }
+}
+
+void
+DrawSpan::set_rgbs(uint32 *addr, uint32 *max_addr)
+{
+    uint32 start = (uint32)addr;
+    uint32 end = (uint32)max_addr;
+    uint32 length = end-start;
+    uint32 diff = sizeof(uint32)*TEXTURE_BLOCK_SIZE;
+    uint32 max_tile = 8;
+    
+    for (uint32 i = 0, j = 0; i <= length && j < max_tile; i += diff, j++) {
+	set_rgb((uint32*)(start + i));
+    }
+}
+
 Uint32
 DrawSpan::get_rgb(int tx, int ty, uint32 *addr)
 {
     TilePtr tile;
 
     tile = hash->get(addr);
-    if (tile == NULL) {
-	tile = tileList->nextTile();
-
-	/**
-	 * FIFO なので、もし前のが残っていれば削除
-	 */
-	hash->remove(tile->texture_addr);
-
-	tile->texture_addr = addr;
-
-	smanager->dma_load(tile->pixel, (uint32)addr,
-			   sizeof(uint32)*TEXTURE_BLOCK_SIZE, TEX_LOAD);
-
-	int index = hash->put(tile->texture_addr, tile);
-
-	/**
-	 * TODO:
-	 *   入らなかったやつは
-	 *   今までのやつを描画してから続きをするとか
-	 */
-	if (index < 0) {
-	    printf("[%p] Can't entry\n", tile);
-	    return 0xff0000;
-	}
-
-	smanager->dma_wait(TEX_LOAD);
-    }
-
     return tile->pixel[(TEXTURE_SPLIT_PIXEL)*ty+tx];
 }
 
+/**
+ * DrawSpan の再起動 (DrawSpanRenew 生成)
+ *
+ * @param[in] spack 現在処理している SpanPack
+ * @param[in] cur_span_x span->length_x != 1 の時の Span の処理で
+ *                       どこまで進んでいるか
+ */
+void
+DrawSpan::reboot(SpanPackPtr spack, int cur_span_x)
+{
+    TaskPtr renew_task = smanager->create_task(TASK_DRAW_SPAN2);
+    int rangey = smanager->get_param(2);
 
+    /**
+     * 共通の outData, param はそのまま渡す
+     */
+    for (int i = 0; i < rangey; i++) {
+	renew_task->add_outData(smanager->get_outputAddr(i),
+			   smanager->get_outputSize(i));
+    }
+
+    // rangex_start, rangex_end, rangey
+    renew_task->add_param(smanager->get_param(0));
+    renew_task->add_param(smanager->get_param(1)); 
+    renew_task->add_param(smanager->get_param(2));
+
+    /**
+     * SpanPack は続きから開始するので、
+     * 現在の状態をコピーしておく。
+     * spack は rbuf から取得してる可能性があり
+     * rbuf はシステムが自動的に free() するため
+     * アドレスだけ渡すのはNG
+     */ 
+    SpanPackPtr curr = (SpanPackPtr)smanager->allocate(sizeof(SpanPack));
+    memcpy(curr, spack, sizeof(SpanPack));
+    renew_task->add_param((int)curr);
+
+    renew_task->add_param(cur_span_x);
+
+    /**
+     * 再起動したタスクを待つ
+     */ 
+    smanager->wait_task(renew_task);
+
+    // next_spack は free() するので wait する
+    smanager->dma_wait(SPAN_PACK_LOAD);
+}
 
 int
 DrawSpan::run(void *rbuf, void *wbuf)
 {
-    SpanPack *spack = (SpanPack*)smanager->get_input(0);
-    SpanPack *next_spack =
-	(SpanPack*)smanager->allocate(sizeof(SpanPack));
-    SpanPack *free_spack = next_spack; // next_spack の free() 用
-    Span *span;
-
     hash = (TileHashPtr)smanager->global_get(GLOBAL_TEXTURE_HASH);
     tileList = (TileListPtr)smanager->global_get(GLOBAL_TILE_LIST);
 
@@ -141,7 +198,12 @@
     // y の範囲 (render_y + rangey - 1)
     int rangey        = smanager->get_param(2);
     
-    float *zRow = (float*)smanager->get_input(1);
+    float *zRow = (float*)smanager->allocate(sizeof(float)*rangex*rangey);
+
+    for (int i = 0; i < rangex*rangey; i++) {
+	zRow[i] = 65535.0f;
+    }
+
     int **linebuf = (int**)smanager->allocate(sizeof(int*)*rangey);
 
     for (int i = 0; i < rangey; i++) {
@@ -149,6 +211,11 @@
 	linebuf_init(linebuf[i], rangex, 0xffffffff);
     }
 
+    SpanPackPtr spack = (SpanPackPtr)smanager->get_input(0);
+    SpanPackPtr next_spack = (SpanPackPtr)smanager->allocate(sizeof(SpanPack));
+    SpanPackPtr free_spack = next_spack; // next_spack の free() 用
+    Span *span;
+
     do {
 	/**
 	 * SpanPack->next が存在する場合、
@@ -210,6 +277,20 @@
 		    tex_localx = tex_xpos % TEXTURE_SPLIT_PIXEL;
 		    tex_localy = tex_ypos % TEXTURE_SPLIT_PIXEL;
 		    
+		    /**
+		     * Tile が無い場合、一旦タスクはここで中断し、
+		     * Tile をロードするタスクを走らせた後に再起動する
+		     */
+		    if (!isAvailableTile(tex_addr)) {
+			spack->info.start = t;
+			//set_rgb(tex_addr);
+			set_rgbs(tex_addr,
+				 getTile(span->tex_width-1, tex_ypos,
+					 span->tex_width, span->tex_addr));
+			reboot(spack, 0);
+			goto FINISH;
+		    }
+
 		    rgb = get_rgb(tex_localx, tex_localy, tex_addr);
 
 		    zRow[localx + (rangex * localy)] = zpos;
@@ -239,6 +320,16 @@
 					   span->tex_width, span->tex_addr);
 			tex_localx = tex_xpos % TEXTURE_SPLIT_PIXEL;
 			tex_localy = tex_ypos % TEXTURE_SPLIT_PIXEL;
+
+			if (!isAvailableTile(tex_addr)) {
+			    spack->info.start = t;
+			    //set_rgb(tex_addr);
+			    set_rgbs(tex_addr,
+				     getTile(span->tex_width-1, tex_ypos,
+					     span->tex_width, span->tex_addr));
+			    reboot(spack, j);
+			    goto FINISH;
+			}
 			
 			rgb = get_rgb(tex_localx, tex_localy, tex_addr);
 		    
@@ -251,11 +342,13 @@
 
 	smanager->dma_wait(SPAN_PACK_LOAD);
 
-	SpanPack *tmp_spack = spack;
+	SpanPackPtr tmp_spack = spack;
 	spack = next_spack;
 	next_spack = tmp_spack;
     } while (spack);
 
+
+FINISH:
     free(free_spack);
     free(linebuf);
 
--- a/TaskManager/Test/test_render/task/DrawSpan.h	Tue Dec 23 16:27:07 2008 +0900
+++ b/TaskManager/Test/test_render/task/DrawSpan.h	Tue Jan 06 15:39:48 2009 +0900
@@ -9,6 +9,14 @@
 #  include "Tapestry.h"
 #endif
 
+#ifndef INCLUDED_SPAN_PACK
+#  include "SpanPack.h"
+#endif
+
+#ifndef INCLUDED_TEXTURE_HASH
+#  include "TileHash.h"
+#endif
+
 typedef int8_t          Sint8;
 typedef uint8_t         Uint8;
 typedef int16_t         Sint16;
@@ -21,10 +29,20 @@
 public:
     SchedConstructor(DrawSpan);
 
+    TileHashPtr hash;
+    TileListPtr tileList;
+
     int run(void *rbuf, void *wbuf);
 
     void linebuf_init(int *buf, int width, int rgb);    
+    void set_rgb(uint32 *addr);
+    void set_rgbs(uint32 *addr, uint32 *max_addr);
     Uint32 get_rgb(int tx, int ty, uint32 *addr);
+    TilePtr isAvailableTile(uint32 *addr);
+    uint32* getTile(int tx, int ty, int tw, uint32 *tex_addr_top);
+    int getTexBlock(int tx, int ty, int twidth);
+
+    void reboot(SpanPackPtr spack, int cur_span_x);
 };
 
 #endif
--- a/TaskManager/Test/test_render/task/TileHash.cpp	Tue Dec 23 16:27:07 2008 +0900
+++ b/TaskManager/Test/test_render/task/TileHash.cpp	Tue Jan 06 15:39:48 2009 +0900
@@ -1,3 +1,4 @@
+#include <stdio.h>
 #include <string.h>
 #include <stdlib.h>
 #include "TileHash.h"
--- a/TaskManager/Test/test_render/task/task_init.cpp	Tue Dec 23 16:27:07 2008 +0900
+++ b/TaskManager/Test/test_render/task/task_init.cpp	Tue Jan 06 15:39:48 2009 +0900
@@ -1,8 +1,4 @@
 #include "../Func.h"
-#include "polygon.h"
-#include "scene_graph_pack.h"
-#include "polygon_pack.h"
-#include "SpanPack.h"
 #include "Scheduler.h"
 
 SchedExternTask(Create_SGP);
@@ -12,6 +8,7 @@
 SchedExternTask(CreateSpan);
 
 SchedExternTask(DrawSpan);
+SchedExternTask(DrawSpanRenew);
 SchedExternTask(DrawBack);
 
 SchedExternTask(LoadTexture);
@@ -32,6 +29,7 @@
     SchedRegisterTask(TASK_CREATE_SPAN, CreateSpan);
 
     SchedRegisterTask(TASK_DRAW_SPAN, DrawSpan);
+    SchedRegisterTask(TASK_DRAW_SPAN2, DrawSpanRenew);
     SchedRegisterTask(TASK_DRAW_BACK, DrawBack);
 
     SchedRegisterTask(TASK_INIT_TEXTURE, LoadTexture);
--- a/TaskManager/Test/test_render/viewer.cpp	Tue Dec 23 16:27:07 2008 +0900
+++ b/TaskManager/Test/test_render/viewer.cpp	Tue Jan 06 15:39:48 2009 +0900
@@ -29,8 +29,6 @@
 int spackList_length;
 int spackList_length_align;
 
-static float *zRow;
-
 /**
  *
  */
@@ -206,12 +204,6 @@
     }
 
     task_next->spawn();
-    
-    zRow=(float*)manager->malloc(sizeof(float)*split_screen_w*split_screen_h);
-
-    for (int i = 0; i < split_screen_w*split_screen_h; i++) {
-	zRow[i] = 65535.0f; // __FLT_MAX__ с
-    }
 }
 
 void
@@ -333,9 +325,6 @@
 		// Draw SpanPack
 		task_draw = manager->create_task(TASK_DRAW_SPAN);
 		task_draw->add_inData(spack, sizeof(SpanPack));
-
-		task_draw->add_inData(zRow,
-				      sizeof(float)*(endx-startx+1)*rangey);
 	    } else {
 		// Draw Background (憜紂ゃ吟)
 		task_draw = manager->create_task(TASK_DRAW_BACK);
--- a/TaskManager/kernel/schedule/SchedNop2Ready.cc	Tue Dec 23 16:27:07 2008 +0900
+++ b/TaskManager/kernel/schedule/SchedNop2Ready.cc	Tue Jan 06 15:39:48 2009 +0900
@@ -20,20 +20,18 @@
 SchedTaskBase*
 SchedNop2Ready::next(Scheduler *m, SchedTaskBase *p)
 {
+    SchedTaskBase *nextSched;
+
     __debug("[SchedNop2Ready:%s]\n", __FUNCTION__);
     
     delete p;
 
-    // 追加されたタスクがあれば
-    if (scheduler->renewTop_taskList) {
-	TaskListPtr list = scheduler->renewTop_taskList;
-	scheduler->renewTop_taskList = scheduler->renewTop_taskList->next;
-	scheduler->renewCur_taskList = NULL;
-
-	list->next = NULL;
-	SchedTaskList *schd = new SchedTaskList((unsigned int)list, scheduler);
-	schd->flag_renewTaskList = 1;
-	return schd;
+    nextSched = scheduler->get_nextRenewTaskList(NULL, 0);
+	
+    // RenewTask がある
+    if (nextSched) {
+	printf("RenewTaskList start [SchedNop2Ready]\n");
+	return nextSched;
     } else {
 	scheduler->mail_write(MY_SPE_STATUS_READY);
 	return new SchedMail(scheduler);
--- a/TaskManager/kernel/schedule/SchedTask.cc	Tue Dec 23 16:27:07 2008 +0900
+++ b/TaskManager/kernel/schedule/SchedTask.cc	Tue Jan 06 15:39:48 2009 +0900
@@ -10,33 +10,35 @@
 extern Scheduler::TaskObject task_list[MAX_TASK_OBJECT];
 
 SchedTask*
-CreateSchedTask(TaskListPtr taskList, Scheduler *sched)
+createSchedTask(TaskPtr task)
 {
-    TaskPtr task = &taskList->tasks[sched->curIndex_taskList++];
-    
-    return task_list[task->command](taskList, task, sched->get_curReadBuf(),
-				    sched->get_curWriteBuf(), sched);
+    return task_list[task->command]();
 }
 
-SchedTask::SchedTask(TaskListPtr _list, TaskPtr _task, ListDataPtr rbuf,
-		     ListDataPtr wbuf, Scheduler* sc)
+SchedTask::SchedTask(void)
 {
-    __list        = _list;
-    __task        = _task;
-    __inListData  = rbuf;
-    __outListData = wbuf;
+    __list        = NULL;
+    __task        = NULL;
+    __inListData  = NULL;
+    __outListData = NULL;
     __readbuf     = NULL;
     __writebuf    = NULL;
-    __scheduler   = sc;
+    __scheduler   = NULL;
     __taskGroup   = NULL;
     __renew_flag  = 0;
-
-    smanager = new STaskManager(this);
+    __cur_index   = 0;
+    __flag_renewTask = SCHED_TASK_NORMAL;
+    
+    ex_init  = &SchedTask::ex_init_normal;
+    ex_read  = &SchedTask::ex_read_normal;
+    ex_exec  = &SchedTask::ex_exec_normal;
+    ex_write = &SchedTask::ex_write_normal;
+    ex_next  = &SchedTask::ex_next_normal;
 }
 
 SchedTask::~SchedTask(void)
 {
-    if (__flag_renewTask) {
+    if (__flag_renewTask == SCHED_TASK_RENEW) {
 	/**
 	 * __inListData と __outListData はタスク自身のものなので
 	 * 終わったら即 free する。
@@ -58,37 +60,66 @@
     delete smanager;
 }
 
+/**                                                                         
+ * このタスクを Renew Task とし、それに応じた関数をセットする
+ */
 void
-SchedTask::__init__(void)
+SchedTask::__setRenew(void)
 {
-    /**
-     * task->inData や task->outData が
-     * PPE のものか、SPE のものかって
-     * アドレスで判定できれば楽になると思うんだが。。。
-     */
-    if (__flag_renewTask == 0) {
-	__scheduler->dma_load(__inListData, (uint32)__task->inData,
-			      sizeof(ListData), DMA_READ_IN_LIST);
-	__scheduler->dma_load(__outListData, (uint32)__task->outData,
-			      sizeof(ListData), DMA_READ_OUT_LIST);
-	
-	__taskGroup = new TaskGroup;
-	__taskGroup->command = __task->self;
+    __flag_renewTask = SCHED_TASK_RENEW;
 
-	ex_read  = &SchedTask::ex_read_normal;
-	ex_exec  = &SchedTask::ex_exec_normal;
-	ex_write = &SchedTask::ex_write_normal;
-    } else {
-	__inListData = __task->inData;
-	__outListData = __task->outData;
-	__taskGroup = (TaskGroupPtr)__task->self;
-
-	ex_read  = &SchedTask::ex_read_renew;
-	ex_exec  = &SchedTask::ex_exec_renew;
-	ex_write = &SchedTask::ex_write_renew;
-    }
+    ex_init  = &SchedTask::ex_init_renew;
+    ex_read  = &SchedTask::ex_read_renew;
+    ex_exec  = &SchedTask::ex_exec_renew;
+    ex_write = &SchedTask::ex_write_renew;
+    ex_next  = &SchedTask::ex_next_renew;
 }
 
+void
+SchedTask::__init__(TaskListPtr _list, TaskPtr _task, int index,
+		    ListDataPtr rbuf, ListDataPtr wbuf, Scheduler* sc)
+{
+    __list        = _list;
+    __task        = _task;
+    __inListData  = rbuf;
+    __outListData = wbuf;
+    __scheduler   = sc;
+    __cur_index   = index;
+
+    smanager = new STaskManager(this);
+
+    __scheduler->mainMem_wait();
+
+    (this->*ex_init)();
+}
+
+/**
+ * PPE 内で生成されたタスクの ex_init()
+ */
+void
+SchedTask::ex_init_normal(void)
+{
+    __scheduler->dma_load(__inListData, (uint32)__task->inData,
+			  sizeof(ListData), DMA_READ_IN_LIST);
+    __scheduler->dma_load(__outListData, (uint32)__task->outData,
+			  sizeof(ListData), DMA_READ_OUT_LIST);
+    
+    __taskGroup = new TaskGroup;
+    __taskGroup->command = __task->self;
+}
+
+/**
+ * SPE 内で生成されたタスクの ex_init()
+ * 各データは SPE 内の create_task 時に生成もしくは引き継がれているので
+ * ex_init_normal() と違い、ここでは値を渡すだけ
+ */
+void
+SchedTask::ex_init_renew(void)
+{
+    __inListData = __task->inData;
+    __outListData = __task->outData;
+    __taskGroup = (TaskGroupPtr)__task->self;    
+}
 
 /**
  * [Todo]
@@ -263,24 +294,99 @@
 
     delete p;
 
-    if (__scheduler->curIndex_taskList < __list->length) {
-	SchedTask* schedTask = CreateSchedTask(__list, __scheduler);
-	schedTask->__flag_renewTask = this->__flag_renewTask;
-	schedTask->__init__();
+    return (this->*ex_next)();
+}
+
+SchedTaskBase*
+SchedTask::ex_next_normal(void)
+{
+    if (__cur_index < __list->length) {
+	SchedTaskBase *nextSched;
+
+	nextSched = __scheduler->get_nextRenewTaskList(__list, __cur_index);
+	
+	// RenewTask がある
+	if (nextSched) {
+	    return nextSched;
+	} else {
+	    TaskPtr nextTask
+		= &__list->tasks[__cur_index++];
+	    nextSched = createSchedTask(nextTask);
+	    ((SchedTask*)nextSched)->__init__(__list, nextTask, __cur_index,
+					      __scheduler->get_curReadBuf(),
+					      __scheduler->get_curWriteBuf(),
+					      __scheduler);
+
+	    /**
+	     * この理由は SchedTask:~SchedTask() で
+	     */
+	    __list = NULL;
+
+	    return nextSched;
+	}
+    } else {
+	uint32 nextList = (uint32)__list->next;
+	
+	if (nextList == 0) {
+	    return new SchedNop2Ready(__scheduler);
+	} else {
+	    return createSchedTaskList(nextList, __scheduler,
+				       SCHED_TASKLIST_NORMAL);
+	}
+    }
+}
+
+/**
+ *
+ */
+SchedTaskBase*
+SchedTask::ex_next_renew(void)
+{
+    TaskPtr nextTask;
+    SchedTask *nextSched;
+
+    if (__cur_index < __list->length) {
+	nextTask = &__list->tasks[__cur_index++];
+	nextSched = createSchedTask(nextTask);
+
+	// RenewTaskList を実行中なので
+	nextSched->__setRenew();
+	nextSched->__init__(__list, nextTask, __cur_index,
+			    __scheduler->get_curReadBuf(),
+			    __scheduler->get_curWriteBuf(),
+			    __scheduler);
 
 	/**
 	 * この理由は SchedTask:~SchedTask() で
 	 */
 	__list = NULL;
-
-	return schedTask;
+	return nextSched;
     } else {
 	uint32 nextList = (uint32)__list->next;
-
+	
 	if (nextList == 0) {
-	    return new SchedNop2Ready(__scheduler);
+	    TaskListPtr nextList = __scheduler->get_backupTaskList();
+
+	    // 中断した TaskList
+	    if (nextList) {
+		__cur_index = __scheduler->bakIndex_taskList;
+		
+		nextTask = &nextList->tasks[__cur_index++];
+		nextSched = createSchedTask(nextTask);
+		
+		nextSched->__init__(nextList, nextTask, __cur_index,
+				    __scheduler->get_curReadBuf(),
+				    __scheduler->get_curWriteBuf(),
+				    __scheduler);
+		return nextSched;
+	    } else {
+		return new SchedNop2Ready(__scheduler);
+	    }
 	} else {
-	    return new SchedTaskList(nextList, __scheduler);
+	    __scheduler->renewTop_taskList
+		= __scheduler->renewTop_taskList->next;
+	    return createSchedTaskList(nextList, __scheduler,
+				       SCHED_TASKLIST_RENEW);
 	}
     }
 }
@@ -309,6 +415,15 @@
 }
 
 /**
+ * get_input(index) のサイズを返す
+ */
+int
+SchedTask::get_inputSize(int index)
+{
+    return __inListData->element[index].size;
+}
+
+/**
  * write buffer の領域を返す。
  */
 void*
@@ -330,6 +445,15 @@
     return __outListData->element[index].addr;
 }
 
+/**
+ * get_output(index) のサイズを返す
+ */
+int
+SchedTask::get_outputSize(int index)
+{
+    return __outListData->element[index].size;
+}
+
 int
 SchedTask::get_param(int index)
 {
--- a/TaskManager/kernel/schedule/SchedTaskList.cc	Tue Dec 23 16:27:07 2008 +0900
+++ b/TaskManager/kernel/schedule/SchedTaskList.cc	Tue Jan 06 15:39:48 2009 +0900
@@ -6,10 +6,27 @@
 #include "DmaManager.h"
 #include "error.h"
 
+/**
+ * SchedTaskList 菴
+ *
+ * @param[in] next_list 罨<絎茵 TaskList ≪
+ * @param[in] next_list <ゃ潟<≪≪鴻
+ *            SPE х≪鴻
+ *            SPE х翫DMA 綽荀<
+ *            0: <ゃ潟<≪, 1: SPE
+ */
+SchedTaskList*
+createSchedTaskList(uint32 next_list, Scheduler* scheduler, int renew_flag)
+{
+    SchedTaskList* sched = new SchedTaskList(next_list, scheduler);
+    sched->flag_renewTaskList = renew_flag;
+    return sched;
+}
+
 SchedTaskList::SchedTaskList(unsigned int addr, Scheduler *sched)
 {
     params_addr = addr;
-    list = sched->get_curListBuf();
+    list = NULL;
     scheduler = sched;
 
     flag_renewTaskList = 0;
@@ -21,32 +38,46 @@
 {
     __debug("[SchedTaskList:%s]\n", __FUNCTION__);
 
-    if (flag_renewTaskList == 0) {
-	scheduler->dma_load(list,params_addr,sizeof(TaskList),DMA_READ_TASKLIST);
+    if (flag_renewTaskList == SCHED_TASKLIST_NORMAL) {
+	list = scheduler->get_curListBuf();
+	scheduler->dma_load(list, params_addr,
+			    sizeof(TaskList), DMA_READ_TASKLIST);
 	scheduler->dma_wait(DMA_READ_TASKLIST);
     } else {
 	list = (TaskListPtr)params_addr;
     }
-
-    scheduler->curIndex_taskList = 0;
-
-    scheduler->mainMem_wait();
 }
 
 SchedTaskBase*
 SchedTaskList::next(Scheduler *m, SchedTaskBase *p)
 {
+    SchedTaskBase *nextSched;
+
     __debug("[SchedTaskList:%s]\n", __FUNCTION__);
 
     delete p;
 
     if (list->length < 1) {
-	return new SchedNop2Ready(scheduler);
+	nextSched = new SchedNop2Ready(scheduler);
+
+	if (flag_renewTaskList == SCHED_TASKLIST_RENEW) {
+	    free(list);
+	}
+
     } else {
-	SchedTask* task = CreateSchedTask(list, m);
-	task->__flag_renewTask = this->flag_renewTaskList;
-	task->__init__();
-	return task;
+	TaskPtr nextTask = &list->tasks[0];
+	nextSched = createSchedTask(nextTask);
+
+	if (flag_renewTaskList == SCHED_TASKLIST_RENEW) {
+	    ((SchedTask*)nextSched)->__setRenew();
+	}
+	
+	((SchedTask*)nextSched)->__init__(list, nextTask, 1,
+					  scheduler->get_curReadBuf(),
+					  scheduler->get_curWriteBuf(),
+					  scheduler);
     }
+
+    return nextSched;
 }
 
--- a/TaskManager/kernel/schedule/Scheduler.cc	Tue Dec 23 16:27:07 2008 +0900
+++ b/TaskManager/kernel/schedule/Scheduler.cc	Tue Jan 06 15:39:48 2009 +0900
@@ -88,7 +88,6 @@
 Scheduler::get_curListBuf(void)
 {
     buffFlag_taskList ^= 1;
-    curIndex_taskList = 0;
 
     return buff_taskList[buffFlag_taskList];
 }
@@ -137,6 +136,46 @@
     }
 }
 
+/**
+ * 次に実行する Renew Task List を返す
+ *
+ * @param[in] curList 現在実行中の TaskList
+ *                    中断して RenewTaskList を行うため
+ *                    バックアップを取っておく
+ * @return next RenewTaskList
+ */
+SchedTaskList*
+Scheduler::get_nextRenewTaskList(TaskListPtr curList, int curIndex)
+{
+    if (renewTop_taskList) {
+	TaskListPtr list  = renewTop_taskList;
+	renewTop_taskList = renewTop_taskList->next;
+	renewCur_taskList = NULL;
+	
+	bak_curTaskList = curList;
+	bakIndex_taskList = curIndex;
+	
+	//list->next = NULL;
+	SchedTaskList *sched
+	    = createSchedTaskList((uint32)list, this, SCHED_TASKLIST_RENEW);
+	return sched;
+    } else {
+	return NULL;
+    }
+}
+
+/**
+ * RenewTaskList 実行前に中断した TaskList を返す
+ * NULL の場合、中断した TaskList は無い。
+ *
+ * @return TaskList
+ */
+TaskListPtr
+Scheduler::get_backupTaskList(void)
+{
+    return bak_curTaskList;
+}
+
 void
 Scheduler::dma_load(void *buf, uint32 addr, uint32 size, uint32 mask)
 {
--- a/include/TaskManager/SchedTask.h	Tue Dec 23 16:27:07 2008 +0900
+++ b/include/TaskManager/SchedTask.h	Tue Jan 06 15:39:48 2009 +0900
@@ -25,7 +25,7 @@
 class SchedTask : public SchedTaskBase {
 public:
     /* constructor */
-    SchedTask(TaskListPtr, TaskPtr, ListDataPtr, ListDataPtr, Scheduler*);
+    SchedTask(void);
     ~SchedTask(void);
 
     BASE_NEW_DELETE(SchedTask);
@@ -52,6 +52,9 @@
     void *__readbuf;
     void *__writebuf;
 
+    // Task の、Tasklist での位置。(task = &list[cur_index-1])
+    int __cur_index;
+
     // タスク内で生成されたタスクのグループ
     TaskGroup *__taskGroup;
 
@@ -65,12 +68,16 @@
     // SPE で生成されたものかによって、データの扱いが変わってくる。
     // そのために if (__flag_renewTask) を連発するのはよくないので
     // 関数ポインタで持っておく
+    void (SchedTask::*ex_init)(void);
     void (SchedTask::*ex_read)(void);
     void (SchedTask::*ex_exec)(void);
     void (SchedTask::*ex_write)(void);
+    SchedTaskBase* (SchedTask::*ex_next)(void);
     
     /* functions */
-    void __init__(void);
+    void __setRenew(void);
+    void __init__(TaskListPtr _list, TaskPtr _task, int index,
+		  ListDataPtr rbuf, ListDataPtr wbuf, Scheduler* sc);
 
     // override
     void read(void);
@@ -82,24 +89,37 @@
     // それぞれのタスクに対応した処理を記述する
     virtual int run(void* r, void *w) { return 0; }
 
+    //---  System API ---
+    SchedTask* get_nextTask(TaskListPtr list);
+    
     /**
-     * PPE で生成されたタスクに対する、read,exec,write の付属(?)処理
+     * PPE で生成されたタスクに対する
+     * __init__, read,exec,write,next の付属(?)処理
      */
+    void ex_init_normal(void);
     void ex_read_normal(void);
     void ex_exec_normal(void);
     void ex_write_normal(void);
+    SchedTaskBase* ex_next_normal(void);
 
     /**
-     * SPE で生成されたタスクに対する、read,exec,write の付属(?)処理
+     * SPE で生成されたタスクに対する
+     * __inti__, ead,exec,write,next の付属(?)処理
      */
+    void ex_init_renew(void);
     void ex_read_renew(void);
     void ex_exec_renew(void);
     void ex_write_renew(void);
+    SchedTaskBase* ex_next_renew(void);
 
+
+    //---  User API ---
     void* get_input(void *buff, int index);
     void* get_output(void *buff, int index);
     uint32 get_inputAddr(int index);
     uint32 get_outputAddr(int index);
+    int get_inputSize(int index);
+    int get_outputSize(int index);
     int get_param(int index);
 
     TaskPtr create_task(int cmd);
@@ -145,6 +165,14 @@
 	    return outer->get_outputAddr(index);
 	}
 
+	uint32 get_inputSize(int index) {
+	    return outer->get_inputSize(index);
+	}
+
+	uint32 get_outputSize(int index) {
+	    return outer->get_outputSize(index);
+	}
+
 	int get_param(int index) {
 	    return outer->get_param(index);
 	}
@@ -201,6 +229,9 @@
     STaskManager *smanager;
 };
 
+const int SCHED_TASK_NORMAL = 0;
+const int SCHED_TASK_RENEW  = 1;
+
 #endif
 
-extern SchedTask* CreateSchedTask(TaskListPtr, Scheduler *);
+extern SchedTask* createSchedTask(TaskPtr);
--- a/include/TaskManager/SchedTaskList.h	Tue Dec 23 16:27:07 2008 +0900
+++ b/include/TaskManager/SchedTaskList.h	Tue Jan 06 15:39:48 2009 +0900
@@ -42,4 +42,9 @@
 
 };
 
+const int SCHED_TASKLIST_NORMAL = 0;
+const int SCHED_TASKLIST_RENEW  = 1;
+
 #endif
+
+extern SchedTaskList* createSchedTaskList(uint32, Scheduler*, int);
--- a/include/TaskManager/Scheduler.h	Tue Dec 23 16:27:07 2008 +0900
+++ b/include/TaskManager/Scheduler.h	Tue Jan 06 15:39:48 2009 +0900
@@ -25,6 +25,10 @@
 #  include "SchedTask.h"
 #endif
 
+#ifndef INCLUDED_SCHED_TASKLIST
+#  include "SchedTaskList.h"
+#endif
+
 #ifndef INCLUDED_TASK_GROUP
 #  include "TaskGroup.h"
 #endif
@@ -37,6 +41,7 @@
 
 class SchedTaskBase;
 class SchedTask;
+class SchedTaskList;
 
 class Scheduler {
 public:
@@ -59,8 +64,18 @@
 
     /**
      * 実行中 TaskList の現在の位置 (list->tasks[index])
+     * 
+     * bakIndex_taskList がある理由
+     * taskList の途中で renew task が作られたとき、
+     * 即座に実行するため、TaskList -> RenewTaskList と移って処理する。
+     * RenewTaskList が終了したとき、再び TaskList に戻ってくるが
+     * Renew Task を生成した所から再スタートするため、
+     * taskList の index を覚えておく (backup)
+     * 同様に TaskList も覚えておく
      */
-    int curIndex_taskList;
+    int bakIndex_taskList;
+    TaskListPtr bak_curTaskList;
+    
 
     /**
      * タスク内で生成されたタスクを入れる
@@ -94,8 +109,7 @@
     void* mainMemList[MAX_MAINMEM_AREA];
 
     // Task Object Table
-    typedef SchedTask* (*TaskObject)(TaskListPtr, TaskPtr, ListDataPtr,
-				     ListDataPtr, Scheduler*);
+    typedef SchedTask* (*TaskObject)(void);
 
     DmaManager* connector;
 
@@ -115,6 +129,9 @@
     ListDataPtr get_curWriteBuf(void);
     TaskListPtr get_renewListBuf(void);
 
+    SchedTaskList* get_nextRenewTaskList(TaskListPtr curList, int curIndex);
+    TaskListPtr get_backupTaskList(void);
+
     // なんか名前が変だが。。。
     /* TaskGroup */
     TaskGroupPtr set_groupTask(uint32 command);
@@ -149,24 +166,18 @@
 extern void register_task(int cmd, Scheduler::TaskObject task);
 
 #define SchedConstructor(str)						\
-    str(TaskListPtr _tlist, TaskPtr _task,				\
-	ListDataPtr _rbuf, ListDataPtr _wbuf, Scheduler* _con)		\
-    :SchedTask(_tlist, _task, _rbuf, _wbuf, _con) {}			\
-									\
+    str(void) {}							\
     BASE_NEW_DELETE(str)						\
 
 #define SchedDefineTask(str)						\
-    SchedTask* createTask_##str(TaskListPtr list, TaskPtr task,		\
-				ListDataPtr rbuf, ListDataPtr wbuf,	\
-				Scheduler *sched)			\
+    SchedTask* createTask_##str(void)					\
     {									\
-	return new str(list, task, rbuf, wbuf, sched);			\
+	return new str();						\
     }
 
 #define SchedExternTask(str)						\
     extern								\
-    SchedTask* createTask_##str(TaskListPtr list, TaskPtr task,		\
-				ListDataPtr, ListDataPtr, Scheduler*);
+    SchedTask* createTask_##str(void);
 
 #define SchedRegisterTask(cmd, str)		\
     register_task(cmd, createTask_##str);