# HG changeset patch # User gongo@gendarme.cr.ie.u-ryukyu.ac.jp # Date 1231223988 -32400 # Node ID 907bda4a1a14bf563555d9af17eefd0372eb7938 # Parent df3cfc04e7968d8fa4cda51db7d8b433d85b5a77 fix diff -r df3cfc04e796 -r 907bda4a1a14 TaskManager/Cell/spe/SchedNop2Ready.cc --- 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); diff -r df3cfc04e796 -r 907bda4a1a14 TaskManager/Cell/spe/SchedTask.cc --- 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) { diff -r df3cfc04e796 -r 907bda4a1a14 TaskManager/Cell/spe/SchedTaskList.cc --- 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 #include #include #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; } diff -r df3cfc04e796 -r 907bda4a1a14 TaskManager/Cell/spe/Scheduler.cc --- 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) { diff -r df3cfc04e796 -r 907bda4a1a14 TaskManager/ChangeLog --- 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 + + * all : fix + Scheduler::curIndex_taskList ゃ + SchedTask 罕紊眼(SchedTask::__cur_index) + 篌眼SchedTask::__init__() cur_index ャ罕紊 + +2008-12-24 Wataru MIYAGUNI + + * 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 * Cell/spe/SchedTask.cc (SchedTask::get_outputAddr) diff -r df3cfc04e796 -r 907bda4a1a14 TaskManager/Makefile.def --- 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 diff -r df3cfc04e796 -r 907bda4a1a14 TaskManager/Test/test_render/Func.h --- 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, diff -r df3cfc04e796 -r 907bda4a1a14 TaskManager/Test/test_render/Makefile.def --- 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 diff -r df3cfc04e796 -r 907bda4a1a14 TaskManager/Test/test_render/spe/CreateSpan.cpp --- 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); /** diff -r df3cfc04e796 -r 907bda4a1a14 TaskManager/Test/test_render/spe/DrawSpan.cpp --- 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 #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); diff -r df3cfc04e796 -r 907bda4a1a14 TaskManager/Test/test_render/spe/DrawSpan.h --- 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 diff -r df3cfc04e796 -r 907bda4a1a14 TaskManager/Test/test_render/spe/TileHash.cpp --- 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 #include #include #include "TileHash.h" diff -r df3cfc04e796 -r 907bda4a1a14 TaskManager/Test/test_render/spe/spe-main.cpp --- 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); diff -r df3cfc04e796 -r 907bda4a1a14 TaskManager/Test/test_render/task/CreateSpan.cpp --- 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); diff -r df3cfc04e796 -r 907bda4a1a14 TaskManager/Test/test_render/task/DrawSpan.cpp --- 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 #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); diff -r df3cfc04e796 -r 907bda4a1a14 TaskManager/Test/test_render/task/DrawSpan.h --- 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 diff -r df3cfc04e796 -r 907bda4a1a14 TaskManager/Test/test_render/task/TileHash.cpp --- 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 #include #include #include "TileHash.h" diff -r df3cfc04e796 -r 907bda4a1a14 TaskManager/Test/test_render/task/task_init.cpp --- 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); diff -r df3cfc04e796 -r 907bda4a1a14 TaskManager/Test/test_render/viewer.cpp --- 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); diff -r df3cfc04e796 -r 907bda4a1a14 TaskManager/kernel/schedule/SchedNop2Ready.cc --- 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); diff -r df3cfc04e796 -r 907bda4a1a14 TaskManager/kernel/schedule/SchedTask.cc --- 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) { diff -r df3cfc04e796 -r 907bda4a1a14 TaskManager/kernel/schedule/SchedTaskList.cc --- 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; } diff -r df3cfc04e796 -r 907bda4a1a14 TaskManager/kernel/schedule/Scheduler.cc --- 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) { diff -r df3cfc04e796 -r 907bda4a1a14 include/TaskManager/SchedTask.h --- 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); diff -r df3cfc04e796 -r 907bda4a1a14 include/TaskManager/SchedTaskList.h --- 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); diff -r df3cfc04e796 -r 907bda4a1a14 include/TaskManager/Scheduler.h --- 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);