Mercurial > hg > Game > Cerium
changeset 1559:c60caac2f345 draft
fix fft
line wrap: on
line diff
--- a/example/fft/ppe/butterfly.cc Sat Mar 09 21:21:56 2013 +0900 +++ b/example/fft/ppe/butterfly.cc Sat Mar 09 21:23:40 2013 +0900 @@ -12,7 +12,6 @@ { cl_float2* x = (cl_float2*)s->get_input(rbuf,0); cl_float2* w = (cl_float2*)s->get_input(rbuf,1); - int* m = (int*)s->get_input(rbuf,2); int* n = (int*)s->get_input(rbuf,3); int* iter = (int*)s->get_input(rbuf,4); cl_uint* flag = (cl_uint*)s->get_input(rbuf,5);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/TaskManager/AddrList.h Sat Mar 09 21:23:40 2013 +0900 @@ -0,0 +1,20 @@ +#ifndef INCLUDED_ADDR_LIST +#define INCLUDED_ADDR_LIST + +#include "types.h" + +/* + + MainMemory 側の MemorySegment に近いかも? + Iterator で使う、MainMemory 側の アドレスリスト + + */ + +typedef struct AddrList { + + memaddr addr; + AddrList *next; + +}AddrList, *AddrListPtr; // 8 + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/TaskManager/CellDmaManager.h Sat Mar 09 21:23:40 2013 +0900 @@ -0,0 +1,78 @@ +#ifndef INCLUDED_CELL_DMA_MANAGER +#define INCLUDED_CELL_DMA_MANAGER + +#include "base.h" +#include "types.h" +#include "DmaManager.h" +#include "MailManager.h" +#include "TaskManagerImpl.h" + +#include <spu_mfcio.h> +#include <spu_intrinsics.h> + +#define SPU_PROFILE 1 + +class Scheduler; + +class CellDmaManager : public DmaManager { +public: + BASE_NEW_DELETE(CellDmaManager); + + typedef struct dma_list { + uint32 addr; // should be memaddr, but in Cell's specification... + uint32 size; + } __attribute__ ((aligned (DEFAULT_ALIGNMENT))) DmaList, *DmaListPtr; + + + CellDmaManager() ; + + /* variables */ + unsigned int wait_time, busy_time, alloc_busy_time; + unsigned long long global_busy_time, global_wait_time, global_mail_time, mainMemalloc_time; + unsigned long long task_list_mail_time; + unsigned long long mail_read_time, mail_write_time; + unsigned long long task_list_mail_read_time, finish_mail_write_time; + int task_list_read_count; + + /* functions */ + void *dma_load(Scheduler *s, memaddr addr, uint32 size, uint32 mask); + void *dma_load1(void *buf, memaddr addr, uint32 size, uint32 mask); + void *dma_store(Scheduler *s,void *buf, memaddr addr, uint32 size, uint32 mask); + + void *get_writebuf(Scheduler *s, memaddr addr, uint32 size); + + void dma_wait(uint32 mask) ; + void dma_wait(uint32 mask, int cmd) ; + void (CellDmaManager::*start_dmawait_profile)(); + void (CellDmaManager::*end_dmawait_profile)(unsigned long long *counter); + void start_profile(); + void stop_profile(); + + + void show_dma_wait(Scheduler *s, int cpu); + + void mail_write(memaddr data); + void mail_write_finish_list(memaddr data); + memaddr mail_read(); + memaddr task_list_mail_read(); + void *dma_loadList(Scheduler *s,ListDataPtr list, uint32 mask); + void dma_storeList(ListDataPtr, void *buff, uint32 mask); + uint32 get_tag(); + void bound(ListData *); + void *get_writebuf(Scheduler *s, ListDataPtr, uint32 size) ; + + + private: + + void do_start_dmawait_profile(); + void do_end_dmawait_profile(unsigned long long *counter); + void null_start_dmawait_profile(); + void null_end_dmawait_profile(unsigned long long *counter); + + MailManagerPtr mail_queue; + + +/* end */ +} ; + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/TaskManager/CellScheduler.h Sat Mar 09 21:23:40 2013 +0900 @@ -0,0 +1,22 @@ +#ifndef INCLUDED_CELL_SCHEDULER +#define INCLUDED_CELL_SCHEDULER + +#include "base.h" +#include "Scheduler.h" + +class CellScheduler : public Scheduler { +public: + BASE_NEW_DELETE(CellScheduler); + + void init_impl(int useRefDma); + + void *allocate(int size); + void mainMem_alloc(int id, int size); + void mainMem_wait(void); + uint32 get_tag(); + +private: + int mainMemNum; +} ; + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/TaskManager/CellTaskManagerImpl.h Sat Mar 09 21:23:40 2013 +0900 @@ -0,0 +1,52 @@ +#ifndef INCLUDED_CELL_TASK_MANAGER_IMPL +#define INCLUDED_CELL_TASK_MANAGER_IMPL + +#include "TaskManagerImpl.h" +#include "FifoTaskManagerImpl.h" +#ifdef __CERIUM_CELL__ +#include "SpeThreads.h" +#else +#include "CpuThreads.h" +#endif + +class CellTaskManagerImpl : public TaskManagerImpl { +public: + /* constructor */ + CellTaskManagerImpl(int num, Threads *cpus) : TaskManagerImpl(num) {speThreads = cpus;} + ~CellTaskManagerImpl(); + + /* variables */ + QueueInfo<TaskList> **taskListInfo; + QueueInfo<TaskList> **speTaskList; // running task + + Threads *speThreads; + FifoTaskManagerImpl *ppeManager; + int spe_running; + int spuIdle; + + /* functions */ + // system + void init(int spuIdle,int useRefDma, int export_task_log); + void run(); + void poll(); + void poll1(int spu_limit); + void poll2(int spu_limit); + void mail_check(int id); + TaskListPtr createTaskList(); + //void set_runTaskList(*QueueInfo<HTask>); + void set_runTaskList(QueueInfo<HTask>* activeTaskQueue); + void sendTaskList(); + void append_activeTask(HTaskPtr); + void show_profile() ; + void start_profile() ; + void export_task_log() ; + void polling(); + void debug_check_spe_idle(QueueInfo<HTask> * activeTaskQueue, int spe_running_); + void print_arch(); +private: + void send_taskList(int id); + void show_dead_lock_info(); + +}; + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/TaskManager/CpuThreads.h Sat Mar 09 21:23:40 2013 +0900 @@ -0,0 +1,49 @@ +#ifndef INCLUDED_CPU_THREADS +#define INCLUDED_CPU_THREADS + +#include <pthread.h> +#include "Threads.h" +#include "TaskManagerImpl.h" +#include "MainScheduler.h" +#include "Sem.h" + +typedef struct cpu_arg { + int cpuid; + // should be syncrhonized + MainScheduler *scheduler; + TaskManagerImpl *manager; + SemPtr wait; + int useRefDma; +} cpu_thread_arg_t; + +class GpuThreads; + +class CpuThreads : public Threads { + public: + /* constructor */ + CpuThreads(int num = 1, int useRefDma = 0, int start_id = 0); + ~CpuThreads(); + static void *cpu_thread_run(void *args); + + /* functions */ + virtual void init(); + virtual int get_mail(int speid, int count, memaddr *ret); // BLOCKING + virtual int has_mail(int speid, int count, memaddr *ret); // NONBLOCK + virtual void send_mail(int speid, int num, memaddr *data); // BLOCKING + virtual void add_output_tasklist(int command, memaddr buff, int alloc_size); + virtual int is_gpu(int cpuid); + +private: + /* variables */ + pthread_t *threads; + cpu_thread_arg_t *args; + SemPtr wait; //スレッド生成時の待ち用 + int cpu_num; + int use_refdma; + int id_offset; +#ifdef __CERIUM_GPU__ + GpuThreads *gpu; +#endif +}; + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/TaskManager/DmaManager.h Sat Mar 09 21:23:40 2013 +0900 @@ -0,0 +1,48 @@ +#ifndef INCLUDED_DMA_MANAGER +#define INCLUDED_DMA_MANAGER + +#include "base.h" +#include "ListData.h" +#include "types.h" + +enum dma_tag { + DMA_READ = 25, + DMA_READ2 = 26, + DMA_WRITE = 27, +// DMA_READ_IN_LIST = 29, +// DMA_READ_OUT_LIST = 30, + DMA_READ_TASKLIST = 31, +}; + +class Scheduler; + +class DmaManager { +public: + virtual ~DmaManager() {}; + + BASE_NEW_DELETE(DmaManager); + + // API for DMA transfer + virtual void *dma_load(Scheduler *s, memaddr addr, uint32 size, uint32 mask) { return 0; } + virtual void *dma_load1(void *buf, memaddr addr, uint32 size, uint32 mask) { return 0; } + virtual void *dma_store(void *buf,memaddr addr, uint32 size, uint32 mask) { return 0; } + virtual void free_(void *buf) { free(buf); } + virtual void *get_writebuf(Scheduler *s, memaddr addr, uint32 size) { return 0; } + virtual void dma_wait(uint32 mask) {} + virtual void show_dma_wait(Scheduler *s, int cpu) {} + virtual void start_profile() {} + + // API for SPU inbound/outbound mailbox + virtual void mail_write(memaddr data) {} + virtual void mail_write_finish_list(memaddr data) {} + virtual memaddr mail_read() { return 0; } + virtual memaddr task_list_mail_read() { return 0; } + + // API for MFC list DMA transfer + virtual void *dma_loadList(Scheduler *s, ListDataPtr list, uint32 mask) { return 0; } + virtual void dma_storeList(ListDataPtr, void *buff, uint32 mask) {} + virtual uint32 get_tag() { return 0;} + virtual void bound(ListData *) {} +}; + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/TaskManager/ExportTaskLog.h Sat Mar 09 21:23:40 2013 +0900 @@ -0,0 +1,28 @@ +#ifndef included_exporttasklog +#define included_exporttasklog + +#include <stdio.h> +#include "TaskLog.h" +#include "QueueInfo.h" + +class ExportTaskLog { +public: + ExportTaskLog(QueueInfo<TaskLog> *_tasklog); + virtual ~ExportTaskLog(); + +public: + void open(); + void printOut(); + void close(); + +private: + QueueInfo<TaskLog> *tasklog; + FILE *fp; + + static const char* const FILENAME; + +}; + + + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/TaskManager/FifoDmaManager.h Sat Mar 09 21:23:40 2013 +0900 @@ -0,0 +1,85 @@ +#ifndef INCLUDED_FIFO_DMA_MANAGER +#define INCLUDED_FIFO_DMA_MANAGER + +#include "base.h" +#include "DmaManager.h" + +#ifdef __CERIUM_PARALLEL__ +#include "SynchronizedMailManager.h" +#else +#include "MailManager.h" +#endif + +class FifoDmaManager : public DmaManager { + +protected: + /* variables */ + MailManagerPtr mail_queue1; + MailManagerPtr mail_queue2; + +public: + BASE_NEW_DELETE(FifoDmaManager); + + FifoDmaManager() { +#ifdef __CERIUM_PARALLEL__ + mail_queue1 = new SynchronizedMailManager(); + mail_queue2 = new SynchronizedMailManager(); +#else + mail_queue1 = new MailManager(); + mail_queue2 = new MailManager(); +#endif + start_dmawait_profile = &FifoDmaManager::null_start_dmawait_profile; + end_dmawait_profile = &FifoDmaManager::null_end_dmawait_profile; + } + + ~FifoDmaManager() { + delete mail_queue1; + delete mail_queue2; + } + + /* variables */ +protected: + unsigned long long start_time, stop_time; + unsigned long long global_busy_time, global_load_time, global_store_time, global_mail_time; + unsigned long long dma_load_time, dma_store_time, dma_loadList_time, dma_storeList_time; + unsigned long long mail_read_time, mail_write_time; + unsigned long long mail_read_from_host_time, mail_write_from_host_time; + + /* functions */ +public: + virtual void *dma_load(Scheduler *s, memaddr addr, uint32 size, uint32 mask); + virtual void *dma_load1(void *buf, memaddr addr, uint32 size, uint32 mask); + virtual void *dma_store(void *buf, memaddr addr, uint32 size, uint32 mask); + virtual void dma_wait(uint32 mask) ; + virtual void *get_writebuf(Scheduler *s, memaddr addr, uint32 size) ; + void (FifoDmaManager::*start_dmawait_profile)(); + void (FifoDmaManager::*end_dmawait_profile)(unsigned long long *counter); + void start_profile(); + void stop_profile(); + + void show_dma_wait(Scheduler *s, int cpu); + + void mail_write(memaddr data); + void mail_write_finish_list(memaddr data); + memaddr mail_read(); + memaddr task_list_mail_read(); + + void mail_write_from_host(memaddr data); + memaddr mail_read_from_host(); + int has_mail_from_host(); + + virtual void *dma_loadList(Scheduler *s, ListDataPtr list, uint32 mask); + virtual void dma_storeList(ListDataPtr, void *buff, uint32 mask); + + uint32 get_tag(); + virtual void bound(ListData *); + +private: + void do_start_dmawait_profile(); + void do_end_dmawait_profile(unsigned long long *counter); + void null_start_dmawait_profile(); + void null_end_dmawait_profile(unsigned long long *counter); + +}; + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/TaskManager/FifoTaskManagerImpl.h Sat Mar 09 21:23:40 2013 +0900 @@ -0,0 +1,51 @@ +#ifndef INCLUDED_FIFO_TASK_MANAGER_IMPL +#define INCLUDED_FIFO_TASK_MANAGER_IMPL + +#include "TaskManagerImpl.h" +#include "MainScheduler.h" +#include "Scheduler.h" +#include "CpuThreads.h" + +class FifoTaskManagerImpl : public TaskManagerImpl { +public: + /* constructor */ + FifoTaskManagerImpl(int num) : TaskManagerImpl(num) {} + ~FifoTaskManagerImpl(void); + + /* variables */ + int machineNum; + QueueInfo<TaskList> *taskListInfo; + QueueInfo<TaskList> *ppeTaskList; // running task + + MailManager *mailManager; + MainScheduler *mainScheduler; + + /* functions */ + // call by system + void init(int spuIdle, int useRefDma, int export_task_log); + void init(MainScheduler*, TaskManagerImpl*, int); + void poll(); // called from CellTaskManagerImpl + void poll1(); // single CPU run called from CellTaskManagerImpl + void run(); + void show_profile(); + void start_profile(); + void export_task_log(); + void polling(); + TaskListPtr createTaskList(); + + void mail_check(); + + void set_runTaskList(QueueInfo<HTask>* activeTaskQueue); + //void set_runTaskList(); + void sendTaskList(); + + void print_arch(); + + // call by user +private: + void set_runTaskList1(QueueInfo<HTask>* activeTaskQueue); + +}; + + +#endif /* INCLUDED_FIFO_TASK_MANAGER_IMPL */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/TaskManager/Finish.h Sat Mar 09 21:23:40 2013 +0900 @@ -0,0 +1,7 @@ +#ifndef INCLUDED_SYSTASK_FINISH +#define INCLUDED_SYSTASK_FINISH + +#include "SchedTask.h" + + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/TaskManager/GpuError.h Sat Mar 09 21:23:40 2013 +0900 @@ -0,0 +1,62 @@ +const char* convert_error_status(cl_uint status){ + static const struct { + const cl_uint status; + const char *status_string; + } Error_Status[] = { + {CL_SUCCESS, "CL_SUCCESS"} + ,{CL_DEVICE_NOT_FOUND, "CL_DEVICE_NOT_FOUND"} + ,{CL_DEVICE_NOT_AVAILABLE, "CL_DEVICE_NOT_AVAILABLE"} + ,{CL_COMPILER_NOT_AVAILABLE, "CL_COMPILER_NOT_AVAILABLE"} + ,{CL_MEM_OBJECT_ALLOCATION_FAILURE, "CL_MEM_OBJECT_ALLOCATION_FAILURE"} + ,{CL_OUT_OF_RESOURCES, "CL_OUT_OF_RESOURCES"} + ,{CL_OUT_OF_HOST_MEMORY, "CL_OUT_OF_HOST_MEMORY"} + ,{CL_PROFILING_INFO_NOT_AVAILABLE, "CL_PROFILING_INFO_NOT_AVAILABLE"} + ,{CL_MEM_COPY_OVERLAP, "CL_MEM_COPY_OVERLAP"} + ,{CL_IMAGE_FORMAT_MISMATCH, "CL_IMAGE_FORMAT_MISMATCH"} + ,{CL_IMAGE_FORMAT_NOT_SUPPORTED, "CL_IMAGE_FORMAT_NOT_SUPPORTED"} + ,{CL_BUILD_PROGRAM_FAILURE, "CL_BUILD_PROGRAM_FAILURE"} + ,{CL_MAP_FAILURE, "CL_MAP_FAILURE"} + ,{CL_INVALID_VALUE, "CL_INVALID_VALUE"} + ,{CL_INVALID_DEVICE_TYPE, "CL_INVALID_DEVICE_TYPE"} + ,{CL_INVALID_PLATFORM, "CL_INVALID_PLATFORM"} + ,{CL_INVALID_DEVICE, "CL_INVALID_DEVICE"} + ,{CL_INVALID_CONTEXT, "CL_INVALID_CONTEXT"} + ,{CL_INVALID_QUEUE_PROPERTIES, "CL_INVALID_QUEUE_PROPERTIES"} + ,{CL_INVALID_COMMAND_QUEUE, "CL_INVALID_COMMAND_QUEUE"} + ,{CL_INVALID_HOST_PTR, "CL_INVALID_HOST_PTR"} + ,{CL_INVALID_MEM_OBJECT, "CL_INVALID_MEM_OBJECT"} + ,{CL_INVALID_IMAGE_FORMAT_DESCRIPTOR, "CL_INVALID_IMAGE_FORMAT_DESCRIPTOR"} + ,{CL_INVALID_IMAGE_SIZE, "CL_INVALID_IMAGE_SIZE"} + ,{CL_INVALID_SAMPLER, "CL_INVALID_SAMPLER"} + ,{CL_INVALID_BINARY, "CL_INVALID_BINARY"} + ,{CL_INVALID_BUILD_OPTIONS, "CL_INVALID_BUILD_OPTIONS"} + ,{CL_INVALID_PROGRAM, "CL_INVALID_PROGRAM"} + ,{CL_INVALID_PROGRAM_EXECUTABLE, "CL_INVALID_PROGRAM_EXECUTABLE"} + ,{CL_INVALID_KERNEL_NAME, "CL_INVALID_KERNEL_NAME"} + ,{CL_INVALID_KERNEL_DEFINITION, "CL_INVALID_KERNEL_DEFINITION"} + ,{CL_INVALID_KERNEL, "CL_INVALID_KERNEL"} + ,{CL_INVALID_ARG_INDEX, "CL_INVALID_ARG_INDEX"} + ,{CL_INVALID_ARG_VALUE, "CL_INVALID_ARG_VALUE"} + ,{CL_INVALID_ARG_SIZE, "CL_INVALID_ARG_SIZE"} + ,{CL_INVALID_KERNEL_ARGS, "CL_INVALID_KERNEL_ARGS"} + ,{CL_INVALID_WORK_DIMENSION, "CL_INVALID_WORK_DIMENSION"} + ,{CL_INVALID_WORK_GROUP_SIZE, "CL_INVALID_WORK_GROUP_SIZE"} + ,{CL_INVALID_WORK_ITEM_SIZE, "CL_INVALID_WORK_ITEM_SIZE"} + ,{CL_INVALID_GLOBAL_OFFSET, "CL_INVALID_GLOBAL_OFFSET"} + ,{CL_INVALID_EVENT_WAIT_LIST, "CL_INVALID_EVENT_WAIT_LIST"} + ,{CL_INVALID_EVENT, "CL_INVALID_EVENT"} + ,{CL_INVALID_OPERATION, "CL_INVALID_OPERATION"} + ,{CL_INVALID_GL_OBJECT, "CL_INVALID_GL_OBJECT"} + ,{CL_INVALID_BUFFER_SIZE, "CL_INVALID_BUFFER_SIZE"} + ,{CL_INVALID_MIP_LEVEL, "CL_INVALID_MIP_LEVEL"} + ,{0, NULL} + }; + const char* message; + + for(int i=0; Error_Status[i].status_string !=NULL; i++){ + if (Error_Status[i].status == status) { + message = Error_Status[i].status_string; + } + } + return message; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/TaskManager/GpuFunc.h Sat Mar 09 21:23:40 2013 +0900 @@ -0,0 +1,7 @@ + +enum { +#include "SysTasks.h" + mogyo, + Twice, + // Func1, +};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/TaskManager/GpuScheduler.h Sat Mar 09 21:23:40 2013 +0900 @@ -0,0 +1,59 @@ +#ifndef INCLUDED_GPU_SCHEDULER +#define INCLUDED_GPU_SCHEDULER + +#include "Scheduler.h" +#include "FifoDmaManager.h" +#include "GpuThreads.h" +#include "HTask.h" + +#ifdef __APPLE__ +#include <OpenCL/opencl.h> +#else +#include <CL/cl.h> +#endif + +typedef struct nd_range { + cl_uint dimension; + size_t gws[3]; + size_t lws[3]; +} ND_RANGE_T, *ND_RANGE_T_PTR; + +class GpuScheduler : public Scheduler { +public: + GpuScheduler(); + virtual ~GpuScheduler(); + void init_impl(int useRefDma); + void init_gpu(); + void run(); + + void mail_write_from_host(memaddr data) { + fifoDmaManager->mail_write_from_host(data); + } + + memaddr mail_read_from_host() { + return fifoDmaManager->mail_read_from_host(); + } + + int has_mail_from_host() { + return fifoDmaManager->has_mail_from_host(); + } + + cl_platform_id platform_id; + cl_device_id device_id; + cl_uint ret_num_platforms; + cl_uint ret_num_devices; + cl_context context; + cl_command_queue command_queue; + cl_int ret; +private: + FifoDmaManager *fifoDmaManager; + void load_kernel(int cmd); + +}; + +#define GpuSchedRegister(str, filename, functionname) \ + gpu_register_task(str, filename, functionname); +#endif + +extern void gpu_register_task(int cmd,const char* filename,const char* functionname); +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/TaskManager/GpuThreads.h Sat Mar 09 21:23:40 2013 +0900 @@ -0,0 +1,51 @@ +#ifndef INCLUDED_GPU_THREADS +#define INCLUDED_GPU_THREADS + +#include <pthread.h> +#include "Threads.h" +#include "GpuScheduler.h" +#include "Sem.h" + +#ifdef __APPLE__ +#include <OpenCL/opencl.h> +#else +#include <CL/cl.h> +#endif + +class GpuScheduler; + +typedef struct gpu_arg { + int cpuid; + // should be syncrhonized + GpuScheduler *scheduler; + TaskManagerImpl *manager; + SemPtr wait; + int useRefDma; +} gpu_thread_arg_t; + +class GpuThreads : public Threads { + public: + /* + static GpuThreads* getInstance() { + static GpuThreads singleton; + return &singleton; + }*/ + GpuThreads(int useRefDma); + ~GpuThreads(); + + void init(); + static void *gpu_thread_run(void *args); + + int get_mail(int speid, int count, memaddr *ret); + int has_mail(int speid, int count, memaddr *ret); + void send_mail(int speid, int num, memaddr *data); + void add_output_tasklist(int command, memaddr buff, int alloc_size); + void set_wait(SemPtr); + + private: + gpu_thread_arg_t *args; + pthread_t *threads; + int use_refdma; +}; + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/TaskManager/HTask.h Sat Mar 09 21:23:40 2013 +0900 @@ -0,0 +1,164 @@ +#ifndef INCLUDED_HTASK +#define INCLUDED_HTASK + +#include "base.h" +#include "types.h" +#include "Task.h" +#include "TaskList.h" +#include "TaskQueue.h" +#include "QueueInfo.h" +#include "TaskLog.h" +//#include <stdio.h> + +class TaskManagerImpl; +class SchedTask; + +typedef void (*PostFunction)(SchedTask *s, void *read, void *write); + +extern QueueInfo<TaskQueue>* taskQueuePool; + +/*! + @class + + @brief + + Cerium の Task で、spawn() でキューに格納されて順次実行される。 + cpu の指定があれば並列に実行される。 + 特定の Task を待ち合わせる事が可能。 + Task の入出力は dma などで copy される。 + */ + +#include "SimpleTask.h" + +class HTask : public SimpleTask { +public: + BASE_NEW_DELETE(HTask); + + QueueInfo<TaskQueue> *wait_me; // List of task waiting for me + QueueInfo<TaskQueue> *wait_i; // List of task for which I am waiting + PostFunction post_func; + void *post_arg1; + void *post_arg2; + CPU_TYPE cpu_type; + TaskManagerImpl *mimpl; + TaskPtr last; + + int export_task_log; + TaskLog *tasklog; + + HTask *waiter; + HTask *next; + HTask *prev; + + struct htask_flag { + unsigned no_auto_free:1; // bit 0 auto free flag (0 .. auto, 1 manual) + unsigned flip:1; // use read write buffers for all + unsigned nd_range:1; // openCL nd_range + } flag; + + void spawn(); + void wait_for(HTask *); + void set_cpu(CPU_TYPE type); + void set_post(PostFunction func, void *read, void *write); + Task *create_task_array(int task_id, int num_task, int num_param, int num_inData, int num_outData); + Task *next_task_array(int task_id, Task *t); + Task *next_task_array(int id, Task *t, int param_count, int inData_count, int outData_count); + void spawn_task_array(Task *t); + + HTask *init(int cmd, memaddr rbuf, int rs, memaddr wbuf, int ws) { + init(cmd); + set_input(rbuf, rs); + set_output(wbuf, ws); + return this; + } + + void initOnce() { + wait_me = new QueueInfo<TaskQueue>(taskQueuePool); + wait_i = new QueueInfo<TaskQueue>(taskQueuePool); + } + + void freeOnce() { + delete wait_me; + delete wait_i; + } + + private: + +// compatibility + public: // functions + void set_inData_t(int index, memaddr addr, int size) { +#ifdef EARLY_TOUCH + if ((unsigned long)addr&0xf) { + printf("inData is not aligned. command = %d, index = %d, addr = 0x%lx, size = %d\n", + command, index, (unsigned long)addr, size); + } + char *p = (char *)addr; char b = *p; + p = (char *)(addr+size-1); b += *p; +#endif + Task *t = ((TaskList*)rbuf)->tasks; + t->set_inData_t(index, addr,size); + } + void set_outData_t(int index, memaddr addr, int size) { +#ifdef EARLY_TOUCH + if ((unsigned long)addr&0xf) { + printf("inData is not aligned. command = %d, index = %d, addr = 0x%lx, size = %d\n", + command, index, (unsigned long)addr, size); + } + char *p = (char *)addr; char b = *p; + p = (char *)(addr+size-1); b += *p; +#endif + Task *t = ((TaskList*)rbuf)->tasks; + t->set_outData_t(index, addr,size); + } + void set_param_t(int index, memaddr param) { + Task *t = ((TaskList*)rbuf)->tasks; + t->set_param_t(index, param); + } + + void no_auto_free() { + flag.no_auto_free = 1; + } + void auto_free() { + flag.no_auto_free = 0; + } + + void flip() { + flag.flip = 1; + } + void no_flip() { + flag.flip = 0; + } + void nd_range() { + flag.nd_range = 1; + } + + htask_flag get_flag(){ + return flag; + } + + void init() { + next = prev = NULL; + waiter = NULL; + } + + void init(int cmd) { + command = cmd; + flag.no_auto_free = 0; + flag.flip = 0; + flag.nd_range = 0; + self = (memaddr) this; + + post_func = NULL; + mimpl = NULL; + cpu_type = CPU_PPE; + + post_arg1 = NULL; + post_arg2 = NULL; + } +#define set_param(index,param) set_param_t(index, (memaddr) (param)) + +} __attribute__ ((aligned (DEFAULT_ALIGNMENT))); + +typedef HTask* HTaskPtr; + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/TaskManager/ListData.h Sat Mar 09 21:23:40 2013 +0900 @@ -0,0 +1,50 @@ +#ifndef INCLUDED_LIST_DATA +#define INCLUDED_LIST_DATA + +#include "base.h" +#include "types.h" + +#define MAX_LIST_DMA_SIZE 8 + +class ListElement { +public: + BASE_NEW_DELETE(ListElement); + + int size; +#ifdef __CERIUM_CELL__ + uint32 addr; // Cell の仕様なんでどうしようもない... + // PowerPC 64bit だと動かない可能性も高いんだが... +#else + memaddr addr; +#endif +}; + +typedef ListElement* ListElementPtr; + +class ListData { +public: + BASE_NEW_DELETE(ListData); + + int length; // The number of data (4) + int size; // Total size of data (4) + int *bound; + ListElement *element; + + void clear(void) { + length = 0; + size = 0; + } + +/* + void print(Scheduler *s) { + s->printf("inList length %d size %d\n",length, size); + for(int i=0;i<length;i++) { + s->printf("inList element[%d] size %d addr %lx\n",i, element[i].size, (unsigned long)element[i].addr); + } + } +*/ +}; + +typedef ListData* ListDataPtr; + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/TaskManager/MailManager.h Sat Mar 09 21:23:40 2013 +0900 @@ -0,0 +1,32 @@ +#ifndef INCLUDED_MAIL_MANAGER +#define INCLUDED_MAIL_MANAGER + +#include "types.h" + +class MailManager { +public: + /* constructor */ + MailManager(unsigned int qsize = 32) ; + + virtual ~MailManager(); + + /* functions */ + virtual void send(memaddr data); + virtual memaddr recv(); + virtual int count(); + +private: + /* variables */ + memaddr *queue; + unsigned int size; + unsigned int read; + unsigned int write; + unsigned int mask; + + void calc_mask(unsigned int qsize); + void extend(); +} ; + +typedef MailManager *MailManagerPtr; + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/TaskManager/MainScheduler.h Sat Mar 09 21:23:40 2013 +0900 @@ -0,0 +1,29 @@ +#ifndef INCLUDED_MAIN_SCHEDULER +#define INCLUDED_MAIN_SCHEDULER + +#include "Scheduler.h" +#include "FifoDmaManager.h" + +class MainScheduler : public Scheduler { +protected: + FifoDmaManager *fifoDmaManager; +public: + ~MainScheduler(void) {} + void init_impl(int useRefDma); + void mainMem_alloc(int id, int size); + + void mail_write_from_host(memaddr data) { + fifoDmaManager->mail_write_from_host(data); + } + + memaddr mail_read_from_host() { + return fifoDmaManager->mail_read_from_host(); + } + + int has_mail_from_host() { + return fifoDmaManager->has_mail_from_host(); + } + +}; + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/TaskManager/MemHash.h Sat Mar 09 21:23:40 2013 +0900 @@ -0,0 +1,31 @@ +#ifndef INCLUDED_MEM_HASH +#define INCLUDED_MEM_HASH + +#include "MemorySegment.h" + +class MemHash { +public: + MemHash(void); + +private: + MemorySegmentPtr *table; + +public: + void clear(void); + unsigned int hash(memaddr data); + int put(memaddr addr, MemorySegmentPtr ms); + MemorySegmentPtr get(memaddr addr); + void remove(memaddr addr); +}; + +typedef MemHash* MemHashPtr; + +const int hashSize = 263; +//const int hashSize = 1; + +const int tableSize = sizeof(MemorySegmentPtr)*hashSize; + +#endif + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/TaskManager/MemIterator.h Sat Mar 09 21:23:40 2013 +0900 @@ -0,0 +1,53 @@ +#ifndef INCLUDED_MEMORY_ITERATOR +#define INCLUDED_MEMORY_ITERATOR + +#include "MemList.h" +#include "MemorySegment.h" +#include "AddrList.h" +#include "SchedTask.h" + +enum { + + READ_WRITE, + READ, + WRITE, + +}; + +class MemIterator { +public: + + // 走査する アドレスリスト + AddrListPtr addr_list; + + // 扱う MemorySegment のリスト + MemList *mem_list; + + // ms の stage + MemorySegmentPtr read_ms; + MemorySegmentPtr exec_ms; + MemorySegmentPtr write_ms; + MemorySegmentPtr free_ms; + + SchedTask *smanager; + + MemIterator(AddrListPtr add_list, MemList *mem_list, int cmd, SchedTask *smanager); + ~MemIterator(); + + + MemorySegmentPtr (MemIterator::*get_ms)(void); + + int hasNext(void); + + MemorySegmentPtr get_read_write_ms(void); + MemorySegmentPtr get_read_ms(void); + MemorySegmentPtr get_write_ms(void); + + void collect_ms(void); + void overwrite_list(AddrListPtr list); + +}; + +typedef MemIterator *MemIteratorPtr; + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/TaskManager/MemList.h Sat Mar 09 21:23:40 2013 +0900 @@ -0,0 +1,36 @@ +#ifndef MEMLIST +#define MEMLIST + +#include <stdlib.h> +#include "MemorySegment.h" + +class MemList : public MemorySegment { +public: + MemorySegment* pool; + MemorySegment* first; + MemorySegment* last; + + // TaskManager 側で create する + //MemList* createMemList(uint32 size, uint32 count); + + MemList(MemorySegment* ms) { + first = last = this; + next = prev = this; + pool = ms; + } + + ~MemList() { + free(pool); + } + + void addFirst(MemorySegment* e); + void addLast(MemorySegment* e); + MemorySegment* getFirst(); + MemorySegment* getLast(); + int remove(MemorySegment* e); + MemorySegment* poll(); + void moveToFirst(MemorySegment* e); // or use(); + MemorySegment* get(int index); +}; + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/TaskManager/MemorySegment.h Sat Mar 09 21:23:40 2013 +0900 @@ -0,0 +1,17 @@ +#ifndef MEMLSEG +#define MEMLSEG +#include "types.h" + +class MemorySegment { +public: + MemorySegment* next; + MemorySegment* prev; + uint16 tag; + uint16 size; + memaddr address; + void* data; +}; + +typedef MemorySegment *MemorySegmentPtr; + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/TaskManager/PreRefDmaManager.h Sat Mar 09 21:23:40 2013 +0900 @@ -0,0 +1,14 @@ +#ifndef INCLUDED_PRE_REFERENCED_DMA_MANAGER +#define INCLUDED_PRE_REFERENCED_DMA_MANAGER + +#include "ReferencedDmaManager.h" + +class PreRefDmaManager : public ReferencedDmaManager { + +public: + /* functions */ + virtual void *dma_load(Scheduler *s, memaddr addr, uint32 size, uint32 mask); + virtual void free_(void *buf); +} ; + +#endif/* PRE_REFERENCED_DMA_MANAGER */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/TaskManager/QueueInfo.h Sat Mar 09 21:23:40 2013 +0900 @@ -0,0 +1,335 @@ +#ifndef INCLUDED_QUEUE_INFO +#define INCLUDED_QUEUE_INFO + +#include "base.h" +#include "types.h" + +#if 0 +template <typename T> class Queue : T { +public: + + T(); + + T *waiter; + T *next; + T *prev; + + void initOnce(); // to initialize object in pool + void freeOnce(); // to destroy object in pool + + // virual void init(); +}; +#endif + +template <typename T> class QueueInfo : public T { + +public: + /* constructor */ + + /** + singleton queuePool constructor + Do not use this as a Queue + */ + QueueInfo<T>(){ + queueInfoInit(); + } + /** + normal constructor requires + */ + QueueInfo<T>(QueueInfo<T> *p) { + queueInfoInit(); + queuePool = p; + } + + BASE_NEW_DELETE(QueueInfo); + + /* functions */ + T *create(); + + void free_(T *queue); + + void addFirst(T* e); + void addLast(T* e); + T* getFirst(); + T* getLast(); + int remove(T* e); + T* poll(); + void moveToFirst(T* e); // or use(); + T* get(int index); + T* find(T *task); + int empty(); + void freePool() ; + void freeAll(); + + // Iterator + T* getNext(T* q) ; + int length(); + +private: + /* variables */ + + /* we cannot use static in template */ + /* static */ QueueInfo<T> *queuePool; + T* first; + T* last; + + /* functions */ + int extend_pool(int num); + void destroy(); + void queueInfoInit(); +} ; + + + +#ifdef CHECK +#include <stdio.h> +#endif +#include <stdlib.h> + + +/** + Use singleton queuePool constructor + all queueInfo should share this as a pool. + + exteren QueueInfo<H> pool; + QueueInfo<H> pool = new QueueInfo<H>(); + + use this in non initialize envrionment is wrong. +*/ + +template<typename T>void QueueInfo<T>::queueInfoInit() { + // 最初の一つは自分 + first = last = this; + this->next = this->prev = this; + this->waiter = NULL; +} + +template<typename T>void +QueueInfo<T>::freePool() { + for(T * p = queuePool->waiter; p; ) { + T * next = p->waiter; + p->waiter = NULL; + p->freeOnce(); + free(p); + p = next; + } +} + +/** + all pools are shared among QueueInfo (separated by size and type). + it automatically extended by 64. + */ +template<typename T>int +QueueInfo<T>::extend_pool(int num) +{ +#ifdef CHECK + if (queuePool) fprintf(stderr, "don't use queuePool directly"); +#endif + + T* q = (T*)malloc(sizeof(T)*(num+1)+DEFAULT_ALIGNMENT); + + // First Queue is previous pool + q->waiter = this->waiter; + this->waiter = q; + q = (T*)ROUND_UP_ALIGN((long)q, DEFAULT_ALIGNMENT); + q++; + + /* Connect all free queue in the pool */ + T* p = q; + for (; num-- > 0;) { + p->waiter = NULL; + p->initOnce(); + addLast(p); + p = (T*)ROUND_UP_ALIGN((long)(p+1),DEFAULT_ALIGNMENT); + } + + return 0; + +} + +/** + * Task をプールから取って来て返す + * + * @param [cmd] タスクコマンド + */ +template<typename T>T * +QueueInfo<T>::create() +{ + T * q = queuePool->poll(); + if (! q) { + queuePool->extend_pool(64); + q = queuePool->poll(); + } + q->init(); + return q; +} + + +template<typename T>void +QueueInfo<T>::free_(T * q) +{ + q->waiter = NULL; + queuePool->addLast(q); +} + + +/*! + QueueInfo<T> は空にならない。最低1個は要素が入っていて + 1個目は特別扱いする。getFirst すると first->next を返す + */ + +/*! + 最初の1個は特別扱いなので、それの後に追加していく + */ +template<typename T>void +QueueInfo<T>::addFirst(T* e) +{ + e->prev = first; + e->next = first->next; + first->next->prev = e; + first->next = e; +} + +template<typename T>void +QueueInfo<T>::addLast(T* e) +{ +#ifdef CHECK + if (find(e)) { + fprintf(stderr,"Add duplicate task %0x\n",(int)e); + return; + // ... + } +#endif + e->next = first; + e->prev = last; + last->next = e; + last = e; +} + +template<typename T>T* +QueueInfo<T>::getFirst() +{ + if (empty()) return NULL; + return first->next; +} + +template<typename T>T* +QueueInfo<T>::getLast() +{ + if (empty()) return NULL; + return last; +} + +template<typename T>int +QueueInfo<T>::remove(T* e) +{ +#ifdef CHECK + if (!find(e)) { + fprintf(stderr,"Remove non existing task %0x\n",(int)e); + return 0; + // ... + } +#endif + e->prev->next = e->next; + e->next->prev = e->prev; + + if (first->next == e) { + first->next = e->next; + } + if (last == e) { + last = e->prev; + } + + e->prev = NULL; + e->next = NULL; + + return 1; +} + +/*! + リストの先頭を取得および削除する。リストが空の場合は NULL を返す。 + */ + +template<typename T>T* +QueueInfo<T>::poll() +{ + T* e = first->next; + if (e == this) { + return NULL; + } + remove(e); + return e; +} + +template<typename T>void +QueueInfo<T>::moveToFirst(T* e) +{ + remove(e); + addFirst(e); +} + +/*! + リスト内の指定された位置にある要素を返す。 + 要素数を超えた位置を指定した場合 NULL を返す。 + */ + +template<typename T>T* +QueueInfo<T>::get(int index) +{ + T* e = first->next; + for (int i = 0; i < index; i++) { + if (e->next == this) return NULL; + e = e->next; + } + return e; +} + +template<typename T>T* +QueueInfo<T>::find(T* task) +{ + T* e = first->next; + for(;;) { + if (e == this) return NULL; + if (e == task) break; + e = e->next; + } + return e; +} + +template<typename T>int +QueueInfo<T>::empty() +{ + return this->next == this; +} + +template<typename T>T* +QueueInfo<T>::getNext(T* q) +{ + if (q->next==this) return NULL; + return q->next; +} + +template<typename T>int +QueueInfo<T>::length() +{ + int i = 0; + if (empty()) return 0; + T* e = first; + while((e = e->next) != this ) i++; + return i; +} + +template<typename T>void +QueueInfo<T>::freeAll() +{ + T* t; + while((t=poll())) free_(t); +} + + + +/* end */ + + + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/TaskManager/ReferencedDmaManager.h Sat Mar 09 21:23:40 2013 +0900 @@ -0,0 +1,21 @@ +#ifndef INCLUDED_REFERENCED_DMA_MANAGER +#define INCLUDED_REFERENCED_DMA_MANAGER + +#include "FifoDmaManager.h" + +class ReferencedDmaManager : public FifoDmaManager { + +public: + /* functions */ + virtual void *dma_load(Scheduler *s, memaddr addr, uint32 size, uint32 mask); + virtual void *dma_load1(void *buf, memaddr addr, uint32 size, uint32 mask); + virtual void *dma_loadList(Scheduler *s, ListDataPtr list, uint32 mask); + virtual void *dma_store(void *buf, memaddr addr, uint32 size, uint32 mask); + virtual void dma_storeList(ListDataPtr list, void *buff, uint32 mask); + virtual void *get_writebuf(Scheduler *s,memaddr addr, uint32 size); + + virtual void free_(void *buff); + virtual void bound(ListData *list); +} ; + +#endif/* REFERENCED_DMA_MANAGER */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/TaskManager/SchedExit.h Sat Mar 09 21:23:40 2013 +0900 @@ -0,0 +1,18 @@ +#ifndef INCLUDED_SCHED_EXIT +#define INCLUDED_SCHED_EXIT + +#include "base.h" +#include "Scheduler.h" +#include "SchedTaskBase.h" + + +class SchedExit : public SchedTaskBase { +public: + BASE_NEW_DELETE(SchedExit); + /* functions */ + SchedTaskBase* next(Scheduler *, SchedTaskBase *); + const char * name() { return "Exit" ; }; + +}; + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/TaskManager/SchedMail.h Sat Mar 09 21:23:40 2013 +0900 @@ -0,0 +1,22 @@ +#ifndef INCLUDED_SCHED_MAIL +#define INCLUDED_SCHED_MAIL + +#include "base.h" +#include "Scheduler.h" +#include "SchedTaskBase.h" + +#include "error.h" + +class SchedMail : public SchedTaskBase { +public: + /* constructor */ + BASE_NEW_DELETE(SchedMail); + + /* functions */ + SchedTaskBase* next(Scheduler *, SchedTaskBase *); + const char * name() { return "Mail" ; }; + + +}; + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/TaskManager/SchedNop.h Sat Mar 09 21:23:40 2013 +0900 @@ -0,0 +1,20 @@ +#ifndef INCLUDED_SCHED_NOP +#define INCLUDED_SCHED_NOP + +#include "base.h" +#include "Scheduler.h" +#include "SchedTaskBase.h" + +#include "error.h" + +class SchedNop : public SchedTaskBase { +public: + BASE_NEW_DELETE(SchedNop); + + /* functions */ + SchedTaskBase* next(Scheduler *, SchedTaskBase *); + const char * name() { return "Nop" ; }; + +}; + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/TaskManager/SchedNop2Ready.h Sat Mar 09 21:23:40 2013 +0900 @@ -0,0 +1,34 @@ +#ifndef INCLUDED_SCHED_NOP2READY +#define INCLUDED_SCHED_NOP2READY + +#include "base.h" +#include "Scheduler.h" +#include "SchedTaskBase.h" +#include "SchedNop.h" + +#include "error.h" + +class SchedNop2Ready : public SchedNop { +public: + /* constructor */ + SchedNop2Ready(Scheduler*); + + BASE_NEW_DELETE(SchedNop2Ready); + + /* variables */ + Scheduler* scheduler; + + /* functions */ + void exec(void); + void write(void); + SchedTaskBase* next(Scheduler *, SchedTaskBase *); + const char * name() { return "Nop2" ; }; + + +#if DEBUG + void read(void) { __debug("[SchedNop2Ready:%s]\n", __FUNCTION__); } + //void write(void) { __debug("[SchedNop2Ready:%s]\n", __FUNCTION__); } +#endif +}; + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/TaskManager/SchedTask.h Sat Mar 09 21:23:40 2013 +0900 @@ -0,0 +1,139 @@ +#ifndef INCLUDED_SCHED_TASK +#define INCLUDED_SCHED_TASK + +#include "base.h" +#include "Scheduler.h" +#include "SchedTaskBase.h" +#include "ListData.h" +#include "HTask.h" +#include "MemList.h" + + +class SchedTask : public SchedTaskBase { +public: + /* constructor */ + SchedTask(); + virtual ~SchedTask(); + + BASE_NEW_DELETE(SchedTask); + + /* variables */ + + /* functions */ + + // override + void read(); + void exec(); + void write(); + SchedTaskBase* next(Scheduler *, SchedTaskBase *); + const char * name() { return "SchedTask" ; }; + + + // タスクの処理は、task_list に登録された C の関数によっておこなう + +public: + /* functions */ + + void init(TaskListPtr _list, TaskPtr _task, + Scheduler* sc, int tag); + + //--- User API --- + int read_size() ; + int write_size(); + void setup_outputData(); + + void* get_input(void *buff, int index); + void* get_output(void *buff, int index); + memaddr get_param(int index); + memaddr get_inputAddr(int index); + memaddr get_outputAddr(int index); + // 書き出しを追加する API がない... + int get_inputSize(int index); + int get_outputSize(int index); + + void set_outputSize(int index, int size); + + int get_cpuid(); + + void* global_alloc(int id, int size); + void* global_get(int id); + void global_set(int id, void *addr); + void global_free(int id); + MemList* createMemList(int size, int count); + + void mainMem_alloc(int id, int size); + void mainMem_wait(); + memaddr mainMem_get(int id); + + MemorySegment * get_segment(memaddr addr, MemList *m); + MemorySegment * get_free_segment(memaddr addr, MemList *m); + void overwrite_segment(MemorySegment *s, memaddr addr); + // uint32 get_tag(); + void put_segment(MemorySegment *s); + void wait_segment(MemorySegment *s); + + + + void *allocate(int size); + void free_(void *p) ; + void free_htask(HTask *p) ; + + void polling(); + + /* これは禁止するべき */ + void *dma_load(void *buf, memaddr addr, uint32 size, uint32 mask); + void dma_store(void *buf,memaddr addr, uint32 size, uint32 mask); + void dma_wait(uint32 mask); + void *get_load_buf(uint32 size) ; + void free_load_buf(void *buf) ; + + void show_dma_wait(); + void start_profile(); + + + /*! + SPU用の get_input, get_output + */ + void* get_input(int index) { + return get_input(readbuf, index); + } + + void* get_output(int index) { + return get_output(writebuf, index); + } + + /** + * swap read / write buffer + * output が read buffer の書き換えならば、memcpy せずに + * swap するだけで良い。size は同じである必要がある。 + */ + void swap() { + void * tmp = readbuf; + readbuf = writebuf; + writebuf = tmp; + } + + + // user + HTaskPtr create_task(int cmd); + HTaskPtr create_task(int cmd, memaddr r, long rs, memaddr w, long ws); + HTaskPtr create_task_array(int id, int num_task, int num_param, int num_inData, int num_outData); + + void set_task_depend(HTaskPtr master, HTaskPtr slave); + void spawn_task(HTaskPtr); + void set_task_cpu(HTaskPtr, CPU_TYPE); + void* allocate(int size,int align); + Scheduler* get_scheduler(); + long get_random(); + + int printf(const char * format, ...); + + + +} ; + + +extern void loadSchedTask(Scheduler *scheduler,TaskPtr task); + +#endif +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/TaskManager/SchedTaskBase.h Sat Mar 09 21:23:40 2013 +0900 @@ -0,0 +1,125 @@ +#ifndef INCLUDED_SCHED_TASK_BASE +#define INCLUDED_SCHED_TASK_BASE + +#include "base.h" +//#include <stdio.h> +#include <stdlib.h> + +class TaskManagerImpl; +class Scheduler; +class MemorySegment; +class MemList; +class HTask; + +class SchedTaskBase { +public: + /* constructor */ + // void *called ; // for debug + SchedTaskBase() { + // called = __builtin_return_address(1); + } + virtual ~SchedTaskBase() {} + + BASE_NEW_DELETE(SchedTaskBase); + + // noaction in default + // virtual void load() {} + virtual void read() {} + virtual void exec() {} + virtual void write() {} + virtual SchedTaskBase* next(Scheduler *, SchedTaskBase*) {return 0;} + + virtual void setup_outputData() {}; + virtual const char * name() { return "Base" ; }; + + /* functions */ + virtual void* get_output(void *buff, int index) { return 0; } + virtual void* get_input(void *buff, int index) { return 0;} + virtual memaddr get_param(int index) { return 0;} + virtual int read_size() { return 0;} + virtual int printf(const char * format, ...) {return 0;}; + + virtual memaddr get_inputAddr(int index) {return 0;} + virtual memaddr get_outputAddr(int index) {return 0;} + virtual int get_inputSize(int index) {return 0;} + virtual int get_outputSize(int index) {return 0;} + virtual void set_outputSize(int index, int size) {}; + + virtual int get_cpuid() {return 0;} + + virtual void* global_alloc(int id, int size) {return 0;} + virtual void* global_get(int id) {return 0;} + virtual void global_set(int id, void *addr) {} + virtual void global_free(int id) {} + virtual MemList* createMemList(int size, int count) {return 0;} + + virtual void mainMem_alloc(int id, int size) {} + virtual void mainMem_wait() {} + virtual memaddr mainMem_get(int id) {return 0; } + + virtual MemorySegment * get_segment(memaddr addr, MemList *m) {return 0; } + virtual void put_segment(MemorySegment *s) {} + virtual void wait_segment(MemorySegment *s) {} + + virtual void *allocate(int size) {return 0; } + virtual void free_(void *p) {} + // virtual void polling(); + + /* これは禁止するべき */ + virtual void *dma_load(void *buf, memaddr addr, uint32 size, uint32 mask) {return buf;} + virtual void dma_store(void *buf,memaddr addr, uint32 size, uint32 mask) {} + virtual void dma_wait(uint32 mask) {} + + virtual void show_dma_wait() {} + virtual void start_profile() {} + virtual void* allocate(int size,int align) {return 0;} + virtual Scheduler* get_scheduler() {return 0;} + virtual long get_random() {return 0;} + virtual void free_htask(HTask *h) {} + + /* variables */ + + // SchedTask は、すべて同じ大きさであるべきなので、継承するクラスには、 + // 変数を置かない。ここに、すべて置く。virtual も含めて。 + + // Task を実行するスケジューラ自身 + Scheduler *scheduler; + // Task を作成管理するマネージャー + TaskManagerImpl *manager; + DmaManager* connector; + + TaskPtr atask; + + // 現在スケジューラが実行している TaskList と、このタスクに対応する Task + TaskListPtr list; + // Task の、Tasklist での位置 + TaskPtr cur_index; + + int tag; + + memaddr waiter; + + /** + * read データ、write 用のバッファ + * readbuf には タスク登録時に設定した入力データが入っている。 + * writebuf にデータを描き込んでおくと、 + * タスク登録時に設定した出力先に書き込む + */ + void *readbuf; + void *writebuf; +#define DefaultBoundSize (8) + int din[DefaultBoundSize]; + int dout[DefaultBoundSize]; + + /* system call */ + + FILE *stdout_; + FILE *stderr_; + FILE *stdin_; + + ListData inListData; + ListData outListData; + +} ; + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/TaskManager/SchedTaskList.h Sat Mar 09 21:23:40 2013 +0900 @@ -0,0 +1,30 @@ +#ifndef INCLUDED_SCHED_TASKLIST +#define INCLUDED_SCHED_TASKLIST + +#include "base.h" +#include "Scheduler.h" +#include "SchedTask.h" +#include "TaskList.h" + +#include "error.h" + +class SchedTaskList : public SchedTask { +public: + /* constructor */ + SchedTaskList(memaddr addr, Scheduler *sched, int tag); + + BASE_NEW_DELETE(SchedTaskList); + + /* override functions */ + void read(); + void exec(); + void write(); + const char * name() { return "TaskList" ; }; + + + +}; + + +#endif +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/TaskManager/Scheduler.h Sat Mar 09 21:23:40 2013 +0900 @@ -0,0 +1,240 @@ +#ifndef INCLUDED_SCHEDULER +#define INCLUDED_SCHEDULER + +#include <stdlib.h> +#include <stdarg.h> +#include "base.h" +#include "TaskList.h" +#include "ListData.h" +#include "DmaManager.h" +#include "SchedTaskBase.h" +#include "MemList.h" +#include "MemHash.h" +#include "types.h" + +#ifdef __CERIUM_GPU__ +#ifdef __APPLE__ +#include <OpenCL/opencl.h> +#else +#include <CL/cl.h> +#endif +#endif + +#define MAX_USER_TASK 100 +#define MAX_SYSTEM_TASK 2 +#define MAX_TASK_OBJECT MAX_USER_TASK + MAX_SYSTEM_TASK +#define MAX_GLOBAL_AREA 32 +#define MAX_MAINMEM_AREA 32 + +class SchedTaskBase; +class SchedTask; +class SchedTaskList; +class TaskManagerImpl; +class HTask; + +typedef int (*TaskObjectRun)(SchedTask* smanager, void* r, void *w); + +typedef struct gpu_task_object { +#ifdef __CERIUM_GPU__ + cl_program *program; +#endif +} GpuTaskObject; + +// Task Object Table +// this is named TaskObjectRun but it is not an object. +// It is a pointer to an object creation function +// 大きいので、SPEには置かない方が本当は良い... +// get_segment で取って来るのが、おそらくは正しい。 +typedef struct task_object { + CPU_TYPE cpu_type; + TaskObjectRun run; + memaddr location; // location address in a.out + memaddr end; + uint32 entry_offset; // offset for create(); + MemorySegment *segment; + const char *name; + void (*load)(Scheduler *,int); + void (*wait)(Scheduler *,int); + + GpuTaskObject *gputask; + +} __attribute__ ((aligned (DEFAULT_ALIGNMENT))) //sizeはどれくらい? + TaskObject, *TaskObjectPtr; + +extern "C" { + extern long random(); +} + +class Scheduler { +private: + TaskManagerImpl* manager_tmp; + +public: + virtual ~Scheduler(); + BASE_NEW_DELETE(Scheduler); + + /* variables */ + int id; + MemHash *hash; + + // double buffering + TaskListPtr buff_taskList[2]; + + int buffFlag_taskList; + + /* GlobalMemoryList */ + /* global among Tasks in the same CPU */ + void* globalList[MAX_GLOBAL_AREA]; + + /* MainMemory Allocate Command List */ + memaddr mainMemList[MAX_MAINMEM_AREA]; + + /* Code Area */ + MemList *code_segment_pool; + + DmaManager* connector; + TaskManagerImpl* manager; + + + /* functions */ + void init(TaskManagerImpl *m, int useRefDma=0, int export_task_log=0); + virtual void run(){}; + void run(SchedTaskBase* task1); + + virtual void init_impl(int useRefDma) {}; + void finish(); + + TaskListPtr get_curListBuf(); + TaskListPtr get_renewListBuf(); + + void set_backupTaskList(TaskListPtr cur_taskList); + void set_backupTaskListIndex(int cur_index); + SchedTaskList* get_nextRenewTaskList(); + TaskListPtr get_backupTaskList(); + int get_backupTaskListIndex(); + + + /* GlobalMemory */ + void* global_alloc(int id, int size); + void* global_get(int id); + void global_set(int id, void *addr); + void global_free(int id); + //MemList* createMemList(int size, int count); + MemList* createMemList(int size, int count); + void free_(void *p) { free(p); } + + virtual void mainMem_alloc(int id, int size) {}; + virtual void mainMem_wait() {}; + memaddr mainMem_get(int id); + + MemorySegment * get_segment(memaddr addr, MemList *m); + MemorySegment * get_segment(memaddr addr, MemList *m, int size); + MemorySegment * get_free_segment(memaddr addr, MemList *m); + void overwrite_segment(MemorySegment *s, memaddr addr); + + void allocate_code_segment(int size, int count,struct tbl *table); + + void put_segment(MemorySegment *s); + void wait_segment(MemorySegment *s); + + /* manager */ + + void set_manager(TaskManagerImpl *m) { + manager = m; + }; + + /* user */ + + long get_random() ; + Scheduler *get_scheduler() { return this; }; + int printf(const char *format, ...); + int vprintf0(const char *format, va_list ap); + +} ; + +extern void register_task(int cmd, TaskObjectRun run, const char *str); +extern void register_dynamic_task(int cmd, + memaddr start, int size, TaskObjectRun run, + int entry_offset, + const char *str); + +struct tbl { + unsigned int vma; + unsigned int size; + unsigned int file_offset; + unsigned int buf; +}; + +extern TaskObject task_list[MAX_TASK_OBJECT]; + +int null_run(SchedTask* smanager, void* r, void *w); +void null_loader(Scheduler *m, int task_id); + +extern int entry_cmd[MAX_TASK_OBJECT]; + +inline void +loadSchedTask(Scheduler *scheduler,int command) +{ + task_list[command].load(scheduler,command); +} + +#endif + + + +#define SchedConstructor(str) \ + str() {} \ + BASE_NEW_DELETE(str) \ + +#define SchedDefineTask(str) SchedDefineTask1(str,run) \ + +#define SchedDefineTask1(str,run) \ + static int run(SchedTask *smanager, void *rbuf, void *wbuf); \ + extern "C" { \ + int runTask_##str(SchedTask *smanager, void *rbuf, void *wbuf) \ + { \ + return run(smanager, rbuf, wbuf); \ + } \ + } + +#define SchedExternTask(str) \ + extern "C" { \ + extern int runTask_##str(SchedTask *manager, void *rbuf, void *wbuf) ; \ + } + +#define SchedRegisterTask(cmd, str) \ + register_task(cmd, runTask_##str, #str); + +#define SchedRegister(str) \ + register_task(str, runTask_##str, #str); + +#define SchedDefineDynamicTask(str,segment) \ + SchedDefineTask(str) + +#ifndef NO_OVERLAY +#define SchedExternDynamicTask(str,segment) \ + extern "C" { \ + extern unsigned long long _EAR_; \ + extern struct tbl _ovly_table[]; \ + extern int runTask_##str(SchedTask *manager, void *rbuf, void *wbuf) ; \ + } +#else +#define SchedExternDynamicTask(str,segment) SchedExternTask(str) +#endif + + +#ifndef NO_OVERLAY +#define SchedRegisterDynamicTask(cmd, str, segment) \ + register_dynamic_task(cmd, (memaddr)(_EAR_+_ovly_table[segment].file_offset), \ + _ovly_table[segment].size, \ + runTask_##str, \ + runTask_##str##_offset, \ + #str); +#define SchedRegisterDynamic(str, segment) SchedRegisterDynamicTask(str, str, segment) +#else +#define SchedRegisterDynamicTask(cmd, str, segment) SchedRegisterTask(cmd, str) +#define SchedRegisterDynamic(str, segment) SchedRegisterDynamicTask(str, str, segment) +#endif + + +/* end */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/TaskManager/Sem.h Sat Mar 09 21:23:40 2013 +0900 @@ -0,0 +1,27 @@ +#ifndef INCLUDED_SEM +#define INCLUDED_SEM + +#include <pthread.h> + +typedef struct sem_t { + volatile int value; //セマフォ変数 + pthread_mutex_t mutex; //セマフォ操作用のロック + pthread_cond_t cond; //待ち合わせ用の条件変数 +} sem_t, *sem_ptr; + +class Sem { +public: + /* constructor */ + Sem(int value); + ~Sem(); + void sem_p(); + void sem_v(); + int count(); + /* variables */ +private: + sem_t *sem; +}; + +typedef Sem *SemPtr; + +#endif /* INCLUDED_SEM */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/TaskManager/SemMailManager.h Sat Mar 09 21:23:40 2013 +0900 @@ -0,0 +1,37 @@ +#ifndef INCLUDED_SEM_MAIL_MANAGER +#define INCLUDED_SEM_MAIL_MANAGER + +#include <pthread.h> +#include "MailManager.h" +#include "types.h" +#include "Sem.h" + +class SemMailManager : public MailManager { +public: + /* constructor */ + SemMailManager(unsigned int qsize = 32) ; + + ~SemMailManager(); + + /* functions */ + void send(memaddr data); + memaddr recv(); + int count(); + +private: + /* variables */ + memaddr *queue; + SemPtr queue_remain; + SemPtr queue_count; + unsigned int size; + unsigned int read; + unsigned int write; + unsigned int mask; + + void calc_mask(unsigned int qsize); + void extend(); +} ; + +typedef SemMailManager *SemMailManagerPtr; + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/TaskManager/ShowTime.h Sat Mar 09 21:23:40 2013 +0900 @@ -0,0 +1,7 @@ +#ifndef INCLUDED_TASK_SHOW_TIME +#define INCLUDED_TASK_SHOW_TIME + +#include "SchedTask.h" + + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/TaskManager/SimpleTask.h Sat Mar 09 21:23:40 2013 +0900 @@ -0,0 +1,42 @@ +#ifndef INCLUDED_SIPMLE_TASK +#define INCLUDED_SIPMLE_TASK + +#include "base.h" +#include "types.h" + +#define MAX_PARAMS 8 + +class SimpleTask { +public: // variables + + BASE_NEW_DELETE(SimpleTask); + int command; // 4 byte + memaddr self; // 4 byte (or 8byte on 64bit mode) + + memaddr rbuf; + memaddr wbuf; + int r_size; + int w_size; + memaddr from; + memaddr param; // sizeof(SimpleTask)==32 + + +public: // functions + SimpleTask() {}; + + SimpleTask(int r, memaddr read, int w, memaddr write) { + r_size = r; rbuf = read; + w_size = w; wbuf = write; + }; + + void set_input(memaddr i,int size) { r_size = size; rbuf= i; } + void set_output(memaddr o,int size) { w_size = size; wbuf= o; } + void set_param(memaddr data) { param = data; } + memaddr get_param() { return param; } + +} __attribute__ ((aligned (DEFAULT_ALIGNMENT))); + +typedef SimpleTask *SimpleTaskPtr; + +#endif +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/TaskManager/SpeTaskManagerImpl.h Sat Mar 09 21:23:40 2013 +0900 @@ -0,0 +1,46 @@ +#ifndef INCLUDED_SPE_TASK_MANAGER_IMPL +#define INCLUDED_SPE_TASK_MANAGER_IMPL + +#include "TaskManagerImpl.h" +#include "MainScheduler.h" +#include "Scheduler.h" +#include "TaskList.h" + +class SpeTaskManagerImpl : public TaskManagerImpl { +public: + /* constructor */ + BASE_NEW_DELETE(SpeTaskManagerImpl); + + SpeTaskManagerImpl() ; + ~SpeTaskManagerImpl(); + + /* functions */ + // call by system + void init(int spuIdle,int useRefDma, int export_task_log); + void run(); + void start_profile(); + void show_profile(); + void export_task_log(); + HTaskPtr create_task(int cmd,void *from); + HTaskPtr create_task(int cmd, memaddr rbuf, long r_size, memaddr wbuf, long w_size,void *from); + HTaskPtr create_task_array(int id, int num_task, int num_param, int num_inData, int num_outData,void *from); + + TaskListPtr createTaskList() { return 0; } + void set_task_depend(HTaskPtr master, HTaskPtr slave); + void spawn_task(HTaskPtr); + void set_task_cpu(HTaskPtr, CPU_TYPE); + void polling() {} + void free_htask(HTaskPtr htask) {} + void print_arch(); + +#ifdef __CERIUM_GPU__ + + SpeTaskManagerImpl(int i); + void append_activeTask(HTask* p); + void append_waitTask(HTask* p); + +#endif +} ; + + +#endif /* INCLUDED_SPE_TASK_MANAGER_IMPL */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/TaskManager/SpeThreads.h Sat Mar 09 21:23:40 2013 +0900 @@ -0,0 +1,40 @@ +#ifndef INCLUDED_SPE_THREADS +#define INCLUDED_SPE_THREADS + +#include <libspe2.h> +#include <pthread.h> +#include "Threads.h" + +#define SPE_ELF "spe-main" + +typedef struct arg { + int speid; + spe_context_ptr_t ctx; +} thread_arg_t; + + +class SpeThreads : public Threads { +public: + /* constructor */ + SpeThreads(int num = 1); + ~SpeThreads(void); + + /* functions */ + void init(void); + int get_mail(int speid, int count, memaddr *ret); // BLOCKING + int has_mail(int speid, int count, memaddr *ret); // NONBLOCK + void send_mail(int speid, int num, memaddr *data); // BLOCKING + static void *spe_thread_run(void *arg); + static void *frontend_thread_run(void *arg); + void add_output_tasklist(int command, memaddr buff, int alloc_size); + +private: + /* variables */ + spe_program_handle_t *spe_handle; + spe_context_ptr_t *spe_ctx; + pthread_t *threads; + thread_arg_t *args; + int cpu_num; +}; + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/TaskManager/Start.h Sat Mar 09 21:23:40 2013 +0900 @@ -0,0 +1,7 @@ +#ifndef INCLUDED_SYSTASK_START +#define INCLUDED_SYSTASK_START + +#include "SchedTask.h" + + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/TaskManager/SynchronizedMailManager.h Sat Mar 09 21:23:40 2013 +0900 @@ -0,0 +1,37 @@ +#ifndef INCLUDED_SYNC_MAIL_MANAGER +#define INCLUDED_SYNC_MAIL_MANAGER + +#include <pthread.h> +#include "MailManager.h" +#include "types.h" +#include "Sem.h" + +class SynchronizedMailManager : public MailManager { +public: + /* constructor */ + SynchronizedMailManager(unsigned int qsize = 32) ; + + ~SynchronizedMailManager(); + + /* functions */ + void send(memaddr data); + memaddr recv(); + int count(); + +private: + /* variables */ + memaddr *queue; + SemPtr queue_remain; + SemPtr queue_count; + unsigned int size; + unsigned int read; + unsigned int write; + unsigned int mask; + + void calc_mask(unsigned int qsize); + void extend(); +} ; + +typedef SynchronizedMailManager *SynchronizedMailManagerPtr; + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/TaskManager/SysFunc.h Sat Mar 09 21:23:40 2013 +0900 @@ -0,0 +1,8 @@ +#ifndef SYSFUNCH +#define SYSFUNCH + +enum systask { +#include "SysTasks.h" +}; + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/TaskManager/SysTask.h Sat Mar 09 21:23:40 2013 +0900 @@ -0,0 +1,1 @@ +extern void systask_register();
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/TaskManager/SysTasks.h Sat Mar 09 21:23:40 2013 +0900 @@ -0,0 +1,5 @@ +StartTask, +FinishTask, +ShowTime, +StartProfile, +#define Dummy StartTask
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/TaskManager/Task.h Sat Mar 09 21:23:40 2013 +0900 @@ -0,0 +1,149 @@ +#ifndef INCLUDED_TASK +#define INCLUDED_TASK + +#include "base.h" +#include "types.h" +#include "ListData.h" +#include "SimpleTask.h" + +class SchedTask; +class Scheduler; + +class Task { + public: // variables + int task_size; + int command; + int param_count; + int inData_count; + int outData_count; + int inData_offset; + int outData_offset; + void *data[] __attribute__ ((aligned (DEFAULT_ALIGNMENT))); + + public: // functions + + void print(Scheduler *s); + + memaddr *param(int index) { + memaddr p = (memaddr)data + sizeof(memaddr)*index; + return (memaddr *)p; + } + + ListElement *inData(int index) { + memaddr p = (memaddr)data + inData_offset; + p += sizeof(ListElement)*index; + return (ListElement*)p; + } + + ListElement *outData(int index) { + memaddr p = (memaddr)data + outData_offset; + p += sizeof(ListElement)* index; + return (ListElement*)p; + } + + static int calc_size(int params, int ins, int outs) { + int size = round_up16(sizeof(Task)) + + round_up16(sizeof(memaddr)*params) + + round_up16(sizeof(ListElement)*ins) + + round_up16(sizeof(ListElement)*outs); + return size; + } + + void init(int task_id, int params, int ins, int outs) { + set_task_id(task_id); + param_count = params; + inData_count = ins; + outData_count = outs; + inData_offset = round_up16(sizeof(memaddr)*params); + outData_offset = round_up16(inData_offset+sizeof(ListElement)*ins); + //task_size = round_up16(sizeof(Task)+outData_offset+sizeof(ListElement)*outs); + + task_size = round_up16(sizeof(Task)) + + round_up16(sizeof(memaddr)*params) + + round_up16(sizeof(ListElement)*ins) + + round_up16(sizeof(ListElement)*outs); + + } + + int size() { + return task_size; + } + + int inData_total_size() { + int size = 0; + ListElement *in= inData(0); + for(int i=0; i< inData_count; i++) { + size += in[i].size; + } + return size; + } + int outData_total_size() { + int size = 0; + ListElement *out= outData(0); + for(int i=0; i< outData_count; i++) { + size += out[i].size; + } + return size; + } + + void set_inData_t( int index, memaddr addr, int size) { + ListElement *list = inData(index); +#ifdef EARLY_TOUCH + if ((unsigned long)addr&0xf) { + printf("inData is not aligned. command = %d, index = %d, addr = 0x%lx, size = %d\n", + command, index, (unsigned long)addr, size); + } + char *p = (char *)addr; int b = *p; + p = (char *)(addr+size-1); b += *p; +#endif + +#ifdef __CERIUM_CELL__ + list->addr = (uint32)addr; +#else + list->addr = addr; +#endif + list->size = size; + } + + void set_outData_t(int index, memaddr addr, int size) { + ListElement *list = outData(index); +#ifdef EARLY_TOUCH + if ((unsigned long)addr&0xf) { + printf("inData is not aligned. command = %d, index = %d, addr = 0x%lx, size = %d\n", + command, index, (unsigned long)addr, size); + } + char *p = (char *)addr; int b = *p; + p = (char *)(addr+size-1); b += *p; +#endif +#ifdef __CERIUM_CELL__ + list->addr = (uint32)addr; +#else + list->addr = addr; +#endif + list->size = size; + } + void set_task_id(int id) { command = id; } + void set_param_t(int index, memaddr param) { + memaddr *p = (memaddr*)this->param(index); + *p = param; + } + + Task * next() + { + char *p = (char*)this; + p += size(); + return (Task*)p; + } + + +#define set_param(index,param) set_param_t(index, (memaddr) (param)) + +#define set_inData(index, addr, size) \ + set_inData_t(index, (memaddr)(addr), (size)); +#define set_outData(index, addr, size) \ + set_outData_t(index, (memaddr)(addr), (size)); +} __attribute__ ((aligned (DEFAULT_ALIGNMENT))) ; + +typedef Task* TaskPtr; + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/TaskManager/TaskList.h Sat Mar 09 21:23:40 2013 +0900 @@ -0,0 +1,34 @@ +#ifndef INCLUDED_TASKLIST +#define INCLUDED_TASKLIST + +#include "base.h" +#include "Task.h" + +class HTask; + +#define TASK_MAX_SIZE 31 + +class TaskList { // 1024 byte +public: + BASE_NEW_DELETE(TaskList); + + long lastTask; // 4 byte + TaskList *next; // 4 byte + TaskList *prev; // 4 byte + TaskList *waiter; // 4 byte + HTask *self; // 4 byte + long dummy[3]; // 16 byte + Task tasks[TASK_MAX_SIZE]; // 32*TASK_MAX_SIZE + + + TaskPtr last() { return (TaskPtr)(((memaddr)tasks)+lastTask); } + void set_last(Task *t) { lastTask = ((memaddr)t) - ((memaddr)tasks); } + void init() { lastTask = ((memaddr)&tasks[TASK_MAX_SIZE])-(memaddr)(tasks); waiter=this; } + void initOnce() { } + void freeOnce() {} + +} ; + +typedef TaskList* TaskListPtr; + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/TaskManager/TaskLog.h Sat Mar 09 21:23:40 2013 +0900 @@ -0,0 +1,51 @@ +#ifndef INCLUDED_TASKLOG +#define INCLUDED_TASKLOG + +#include "QueueInfo.h" + +struct waitTask { + int task_id; + int cmd; + + waitTask *next; + waitTask *prev; + waitTask *waiter; +}; + +static int task_id; + +class TaskLog { +public: + /* variables */ + int mtask_id; + int cmd; + QueueInfo<waitTask> wait_for_list; + unsigned long long create_time; + unsigned long long execute_time; + unsigned long long finish_time; + + TaskLog *next; + TaskLog *prev; + TaskLog *waiter; + + /* constructor */ + TaskLog() { + mtask_id = task_id; + task_id++; + create_time = 0; + execute_time = 0; + finish_time = 0; + } + + void set_cmd(int _cmd) { + cmd = _cmd; + } + + +private: + // Unique id + + +}; + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/TaskManager/TaskManager.h Sat Mar 09 21:23:40 2013 +0900 @@ -0,0 +1,51 @@ +#ifndef INCLUDED_TASK_MANAGER +#define INCLUDED_TASK_MANAGER + +#include "TaskManagerImpl.h" +#include "MemList.h" +#include "HTask.h" + +class Scheduler; +class MemList; + +class TaskManager { +public: + /* constructor */ + TaskManager(int num); // The number of threads + ~TaskManager(); + + /* variables */ + TaskManagerImpl *m_impl; + void (*tm_end)(TaskManager *manager); + + /* user function */ + HTaskPtr create_task(int cmd); + HTaskPtr create_task(int cmd, memaddr r, long rs, memaddr w, long ws); + HTaskPtr create_task_array(int id, int num_task, int num_param, int num_inData, int num_outData); + + void run(); + void *allocate(int size); + void set_TMend(void (*endf)(TaskManager *manager)); + int get_cpuNum(); + int get_random(); + Scheduler *get_scheduler(); + MemList* createMemList(int size, int count); + + void start_profile() { m_impl->start_profile(); } + void show_profile() { m_impl->show_profile(); } + void export_task_log() { m_impl->export_task_log(); } + + SchedTask *get_schedTask() { + return m_impl->schedTaskManager; + } + + /* functions */ + void init(int spuIdle, int export_task_log, int useRefDma); + void finish(); + void error(const char* str); +private: + int machineNum; +} ; + +#endif +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/TaskManager/TaskManagerImpl.h Sat Mar 09 21:23:40 2013 +0900 @@ -0,0 +1,118 @@ +#ifndef INCLUDED_TASK_MANAGER_IMPL +#define INCLUDED_TASK_MANAGER_IMPL + +#include "MailManager.h" +#include "ListData.h" +#include "QueueInfo.h" +#include "TaskQueue.h" +#include "HTask.h" +#include "Scheduler.h" +#include "TaskLog.h" +class MemList; + +extern QueueInfo<TaskQueue> *taskQueuePool ; +extern QueueInfo<HTask> *htaskPool ; +extern QueueInfo<TaskList> *taskListPool; +extern QueueInfo<TaskLog> *taskLogQueue; + + + +class TaskManagerImpl { +public: + + /* variables */ + int machineNum; + QueueInfo<HTask> *activeTaskQueue; + QueueInfo<HTask> *waitTaskQueue; + + QueueInfo<TaskQueue> *taskQueueImpl; + QueueInfo<HTask> *htaskImpl; + + SchedTask *schedTaskManager; + Scheduler *scheduler; + TaskManagerImpl *others; + int _export_task_log; + + /* constructor */ + TaskManagerImpl(int num = 0) ; + + virtual ~TaskManagerImpl() { } + + /* functions */ + // system + virtual void init(int,int,int) = 0; + virtual void run() = 0; + virtual void start_profile() = 0; + virtual void show_profile() = 0; + virtual void export_task_log(){} + virtual void append_activeTask(HTaskPtr); + virtual void append_waitTask(HTaskPtr); + virtual void polling() = 0; + virtual void print_arch() = 0; + + void check_task_finish(HTaskPtr task, QueueInfo<HTask> *wait_queue); + void check_task_list_finish(SchedTask *s, TaskListPtr list, QueueInfo<HTask> *wait_queue); + + void systask_init(); + + // user + virtual HTaskPtr create_task(int cmd,void *from); + virtual HTaskPtr create_task(int cmd, memaddr rbuf, long r_size, memaddr wbuf, long w_size,void *from); + virtual HTaskPtr create_task_array(int id, int num_task, int num_param, int num_inData, int num_outData,void *from); + virtual TaskListPtr createTaskList() = 0; + const char *get_task_name(int cmd); + const char *get_task_name(TaskPtr task); + const char *get_task_name(SimpleTaskPtr simpletask); + const char *get_task_name(SchedTaskBase *schedtask); + const char *get_task_name(HTaskPtr htask); + const char *get_task_name(HTaskPtr htask, int index); + virtual void set_task_depend(HTaskPtr master, HTaskPtr slave); + virtual void spawn_task(HTaskPtr); + virtual void set_task_cpu(HTaskPtr, CPU_TYPE); + void set_taskList(HTaskPtr htask, QueueInfo<TaskList> * taskList); + + void free_htask(HTaskPtr htask) { +#if !defined(__SPU__) + if (htask->self) { + htask->flag.no_auto_free = 0; + return; + } + htaskImpl->free_(htask); +#endif + } + + void* allocate(int size, int alignment) + { + + void *buff = 0; + if (size==0) return 0; +#if defined(__SPU__) || ! defined(HAS_POSIX_MEMALIGN) + buff = malloc(size); +#else + posix_memalign(&buff, alignment, size); +#endif + if (buff==0) + get_scheduler()->printf("Can't allocate memory\n"); + return buff; + } + + void* allocate(int size) + { + + void *buff = 0; + if (size==0) return 0; +#if defined(__SPU__) || ! defined(HAS_POSIX_MEMALIGN) + buff = malloc(size); +#else + posix_memalign(&buff, DEFAULT_ALIGNMENT, size); +#endif + if (buff==0) + get_scheduler()->printf("Can't allocate memory\n"); + return buff; + } + + Scheduler* get_scheduler() { return scheduler; } + void set_scheduler(Scheduler *s) { scheduler = s; } +} __attribute__ ((aligned (DEFAULT_ALIGNMENT))); +extern void error(const char* error_message); +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/TaskManager/TaskQueue.h Sat Mar 09 21:23:40 2013 +0900 @@ -0,0 +1,38 @@ +#ifndef INCLUDED_TASK_QUEUE +#define INCLUDED_TASK_QUEUE + +#include "base.h" +#include "types.h" + +class HTask; + +class TaskQueue { + + /** + HTask 間の dependency を表すリスト。HTask の wait_me と wait_i がこれ。 + */ +public: + TaskQueue(HTask *q = NULL); + + BASE_NEW_DELETE(TaskQueue); + + HTask *task; + TaskQueue *waiter; + + TaskQueue *next; + TaskQueue *prev; + + void init() { } + void initOnce() { } + void freeOnce() {} + + TaskQueue *init(HTask *task) { + this->task = task; + return this; + } + +} ; + +typedef TaskQueue* TaskQueuePtr; + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/TaskManager/Threads.h Sat Mar 09 21:23:40 2013 +0900 @@ -0,0 +1,30 @@ +#ifndef INCLUDED_THREADS +#define INCLUDED_THREADS + +#include <pthread.h> +#include "base.h" +#include "types.h" + + +class Threads { +public: + BASE_NEW_DELETE(Threads); + + /* constructor */ + Threads(int num = 1) {}; + virtual ~Threads() {}; + + /* functions */ + virtual void init() = 0; + virtual int get_mail(int speid, int count, memaddr *ret) = 0; // BLOCKING + virtual int has_mail(int speid, int count, memaddr *ret) = 0; // NONBLOCK + virtual void send_mail(int speid, int num, memaddr *data) = 0; // BLOCKING + virtual void add_output_tasklist(int command, memaddr buff, int alloc_size) = 0; + virtual int is_gpu(int cpuid) { return 0; } + + /* variables */ + pthread_t *threads; + int cpu_num; +} ; + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/TaskManager/base.h Sat Mar 09 21:23:40 2013 +0900 @@ -0,0 +1,27 @@ +#ifndef INCLUDED_BASE_H_ + +#include <new> +#include <stdlib.h> +#include <stdio.h> + + +#ifdef __SPU__ +# define BASE_NEW_DELETE(T) \ + /* override new/detele */ \ + static void* operator new(size_t size) { \ + if ((int)size == 0) { \ + size = 1; \ + } \ + \ + void *ptr = malloc(size); \ + return ptr; \ + } \ + static void operator delete(void* rawMemory, size_t size) { \ + free(rawMemory); \ + } \ + +#else +# define BASE_NEW_DELETE(T) +#endif + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/TaskManager/error.h Sat Mar 09 21:23:40 2013 +0900 @@ -0,0 +1,30 @@ +#ifndef CERIUM_ERR +#define CERIUM_ERR + +#ifdef DEBUG +# include <stdio.h> +# define __debugs(s, ...) do { \ + s->printf(__VA_ARGS__); \ + } while (0) +#else /* DEBUG */ +# define __debug(...) +#endif + +#ifdef DEBUG +# include <stdio.h> +# define __debugs_ppe(s, ...) do { \ + s->printf("[PPE] ", __VA_ARGS__); \ + } while (0) +#else /* DEBUG */ +# define __debug_ppe(...) +#endif + +#ifdef DEBUG +# include <stdio.h> +# define __debugs_spe(s, ...) do { \ + s->printf("[SPE] ", __VA_ARGS__); \ + } while (0) +#else /* DEBUG */ +# define __debug_spe(...) +#endif +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/TaskManager/gettime.h Sat Mar 09 21:23:40 2013 +0900 @@ -0,0 +1,32 @@ +#ifndef GETTIME_H_ +#define GETTIME_H_ + +#include <time.h> +#ifdef __APPLE__ +#include <sys/time.h> +#endif +/** + * Mac OS X側には、clock_gettimeがないので、gettimeofdayを使う + */ +inline unsigned long long gettime() { + + unsigned long long time = 0; +#ifdef __CERIUM_FIFO__ // ?? + struct timespec ts; + +#ifndef __APPLE__ + clock_gettime(CLOCK_REALTIME, &ts); +#else + struct timeval tv; + gettimeofday(&tv, NULL); + ts.tv_sec = tv.tv_sec; + ts.tv_nsec = tv.tv_usec * 1000; +#endif + + time = ((ts.tv_sec << 32) | ts.tv_nsec ); +#endif // __CERIUM_FIFO__ + return time; + +} + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/TaskManager/rdtsc.h Sat Mar 09 21:23:40 2013 +0900 @@ -0,0 +1,16 @@ +#ifndef RDTSC_H_ +#define RDTSC_H_ + +/* + * rdtsc is Read Time Stamp Counter + */ + +inline unsigned long long rdtsc() { + unsigned long long ret = 0; +#ifdef __CERIUM_FIFO__ // ?? + __asm__ volatile ("rdtsc" : "=A" (ret)); +#endif // __CERIUM_FIFO__ + return ret; +} + +#endif /* RDTSC_H_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/TaskManager/types.h Sat Mar 09 21:23:40 2013 +0900 @@ -0,0 +1,82 @@ +#ifndef INCLUDED_TYPES +#define INCLUDED_TYPES + +#include <stdint.h> + +typedef uint16_t uint16; +typedef uint32_t uint32; +typedef uint64_t uint64; + +// HOST main memory address +// SPU's (void *) is always 32bit (actually 18bit (256kbyte)) +// memaddr is different from (void *) in SPU. +// +#ifdef __SPU__ +#if ABIBIT>32 +typedef uint64_t memaddr; +#else +typedef uint32_t memaddr; +#endif +#else +typedef char* memaddr; +#endif + + +#define Newq(Type,Count) ((Type *)malloc(sizeof(Type)*Count)) +#define ReAlloc(Pointer,Type,Count) ((Type *)realloc((void*)Pointer,sizeof(Type)*Count)) + + +#define SPE_ALIGNMENT 16 +#define SPE_ALIGNMENT_FULL 128 +#define SPE_ALIGN __attribute__((aligned(SPE_ALIGNMENT))) +#define SPE_ALIGN_FULL __attribute__((aligned(SPE_ALIGNMENT_FULL)) +#define ROUND_UP_ALIGN(value, alignment) \ + (((value) + ((alignment) - 1))&(~((alignment)-1))) +#define DEFAULT_ALIGNMENT SPE_ALIGNMENT +//#define DEFAULT_ALIGNMENT SPE_ALIGNMENT_FULL + +#define DMA_MAX_SIZE 16384 + +#define round_up16(value) ROUND_UP_ALIGN(value, 16) +#define round_up128(value) ROUND_UP_ALIGN(value, 128) + +#define TaskArray (-1) +#define TaskArray1 (-2) + +// SPU 依存 (よろしくないが...) + +// ここも typedef しとくか? +enum { +// どの方向かで enum 分けるだろjk... +// PPE -> SPE + MY_SPE_NOP = 0, + MY_SPE_COMMAND_EXIT, + MY_SPE_COMMAND_GO, + +// SPE -> PPE + MY_SPE_STATUS_BUSY, + MY_SPE_STATUS_READY, + MY_SPE_COMMAND_MALLOC, +}; + +#define MAX_USE_SPE_NUM 32 + +typedef enum { + CPU_PPE = 0, // default + GPU_0 = 1, + GPU_1 = 2, + GPU_2 = 3, + GPU_3 = 4, + CPU_SPE = 5, + SPE_ANY = CPU_SPE, + SPE_0 = 6, + SPE_1 = 7, + SPE_2 = 8, + SPE_3 = 9, + SPE_4 = 10, + SPE_5 = 11, + + +} CPU_TYPE; + +#endif