view TaskManager/kernel/ppe/HTaskInfo.cc @ 603:42c94f85c779

long -> memaddr (64 or 32)
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Sat, 07 Nov 2009 14:13:29 +0900
parents 1733f3cbfa28
children 0558abba673c
line wrap: on
line source

#include <stdio.h>
#include <stdlib.h>
#include "TaskManagerImpl.h"
#include "HTaskInfo.h"
#include "TaskQueueInfo.h"

// Singleton HTask Pool
HTaskInfo HTaskInfo::taskQueuePool;   

HTaskInfo::HTaskInfo() {
    // 最初の一つは自分
    first = last = this;
    next = prev = this;
    waiter = NULL;
}

void
HTaskInfo::freePool() { 
    for(HTaskPtr p = taskQueuePool.waiter; p; ) {
	HTaskPtr next = p->waiter;
	p->waiter = NULL;
	delete p->wait_me;
	delete p->wait_i;
	free(p);
	p = next;
    }
}

int
HTaskInfo::extend_pool(int num)
{
    HTaskPtr q = (HTaskPtr)malloc(sizeof(HTask)*(num+1));

    // First Queue is previous pool
    q->waiter = waiter; waiter = q;
    q++;

    /* Connect all free queue in the pool */
    HTaskPtr p = q;
    for (; num-- > 0; p++) {
	p->waiter = NULL;
	p->wait_me = new TaskQueueInfo();
	p->wait_i = new TaskQueueInfo();
	taskQueuePool.addLast(p);
    }

    return 0;
}

/**
 * Task をプールから取って来て返す
 *
 * @param [cmd] タスクコマンド
 */
HTaskPtr
HTaskInfo::create(int cmd)
{
    HTaskPtr q =  taskQueuePool.poll();
    if (! q)  {
	taskQueuePool.extend_pool(64);
	q = taskQueuePool.poll();
    }
    q->next = q->prev = NULL;
    q->waiter = NULL;

    q->command  = cmd;
    q->inData.clear();
    q->outData.clear();
    q->self = (memaddr) q;
    q->param_size = 0;

    q->post_func = NULL;
    q->mimpl     = NULL;
    q->cpu_type  = CPU_PPE;

    // q->wait_me.clear();
    // q->wait_i.clear();

    return q;
}

void
HTaskInfo::free_(HTaskPtr q)
{
    q->waiter = NULL;
    taskQueuePool.addLast(q);
}


/*!
  HTaskInfo は空にならない。最低1個は要素が入っていて
  1個目は特別扱いする。getFirst すると first->next を返す
 */

/*!
  最初の1個は特別扱いなので、それの後に追加していく
 */
void
HTaskInfo::addFirst(HTask* e)
{
    e->prev = first;
    e->next = first->next;
    first->next->prev = e;
    first->next = e;
}

void
HTaskInfo::addLast(HTask* 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;
}

HTask*
HTaskInfo::getFirst()
{
    if (empty()) return NULL;
    return first->next;
}

HTask*
HTaskInfo::getLast()
{
    if (empty()) return NULL;
    return last;
}

int
HTaskInfo::remove(HTask* 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 を返す。
 */

HTask*
HTaskInfo::poll()
{
    HTask* e = first->next;
    if (e == this) {
	return NULL;
    }
    remove(e);
    return e;
}

void
HTaskInfo::moveToFirst(HTask* e)
{
    remove(e);
    addFirst(e);
}

/*!
  リスト内の指定された位置にある要素を返す。
  要素数を超えた位置を指定した場合 NULL を返す。
 */

HTask*
HTaskInfo::get(int index)
{
    HTask* e = first->next;
    for (int i = 0; i < index; i++) {
	if (e == this) return NULL;
	e = e->next;
    }
    return e;
}

HTask*
HTaskInfo::find(HTask* task)
{
    HTask* e = first->next;
    for(;;) {
	if (e == this) return NULL;
	if (e == task) break;
	e = e->next;
    }
    return e;
}

int
HTaskInfo::empty()
{
    return next == this;
}

HTask*
HTaskInfo::getNext(HTask* q) 
{
    if (q->next==this) return NULL;
    return q->next;
}

int
HTaskInfo::length() 
{
    int i = 1;
    if (empty()) return 0;
    HTask* e = first;
    while((e = e->next) != this ) i++;
    return i;
}




/* end */