view TaskManager/kernel/schedule/Scheduler.h @ 1548:614a3f62c881 draft

add set work item size function
author Yuhi TOMARI <yuhi@cr.ie.u-ryukyu.ac.jp>
date Fri, 15 Feb 2013 07:37:04 +0900
parents 18b63e697c61
children 046695c73cb0
line wrap: on
line source

#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 */