view TaskManager/Fifo/FifoDmaManager.cc @ 2022:fac44ad2867d draft

make a sound
author Masataka Kohagura <kohagura@cr.ie.u-ryukyu.ac.jp>
date Wed, 16 Jul 2014 02:50:32 +0900
parents 5238ca826d6e
children
line wrap: on
line source

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "FifoDmaManager.h"
#include "Scheduler.h"
#include "TaskManagerImpl.h"
#include "gettime.h"
#include "MailManager.h"

void 
FifoDmaManager::init()
{
    mail_queue1 = new MailManager();
    mail_queue2 = new MailManager();
}

void *
FifoDmaManager::dma_load(Scheduler *s, memaddr addr, uint32 size, uint32 mask)
{
    void *buf = 0;
    if (size == 0) return buf;

    unsigned long long wait = 0;
    (*this->start_dmawait_profile)(&start_time);

    buf = s->manager->allocate(size);
    memcpy(buf, (void*)addr, size);

    (*this->end_dmawait_profile)(&wait,&start_time,&stop_time);
    global_load_time += wait;
    dma_load_time += wait;

    return buf;
}

void *
FifoDmaManager::dma_load1(void *buf, memaddr addr, uint32 size, uint32 mask)
{
    if (size == 0) return buf;

    unsigned long long wait = 0;
    (*this->start_dmawait_profile)(&start_time);

    memcpy(buf, (void*)addr, size);

    (*this->end_dmawait_profile)(&wait,&start_time,&stop_time);
    global_load_time += wait;
    dma_load_time += wait;
    return buf;
}


void *
FifoDmaManager::get_writebuf(Scheduler *s,memaddr addr, uint32 size) 
{
    void *b = s->manager->allocate(size);
    return b;
}

void *
FifoDmaManager::dma_store(void *buf, memaddr addr, uint32 size, uint32 mask)
{
    if (size == 0) return buf;

    unsigned long long wait = 0;
    (*this->start_dmawait_profile)(&start_time);

    memcpy((void*)addr, buf, size);

    (*this->end_dmawait_profile)(&wait,&start_time,&stop_time);
    global_store_time += wait;
    dma_store_time += wait;

    return buf;
}

/**
 * mask で設定した DMA 転送の完了を待つ
 */
void
FifoDmaManager::dma_wait(uint32 mask)
{
}


void *
FifoDmaManager::dma_loadList(Scheduler *s, ListDataPtr list, uint32 mask)
{
    unsigned long long wait = 0;
    (*this->start_dmawait_profile)(&start_time);

    int list_size = list->length;
    long bound;

    void *buff = s->manager->allocate(list->size);
    bound = (long)(buff);

    for (int i = 0; i < list_size; i++) {
        ListElementPtr elm = &list->element[i];
        memcpy((void*)bound, (void*)elm->addr, elm->size);
        bound += elm->size;
    }

    (*this->end_dmawait_profile)(&wait,&start_time,&stop_time);
    global_load_time += wait;
    dma_loadList_time += wait;

    return buff;
}

void
FifoDmaManager::dma_storeList(ListDataPtr list, void *buff, uint32 mask)
{
    unsigned long long wait = 0;
    (*this->start_dmawait_profile)(&start_time);

    int list_size = list->length;
    memaddr bound;

    bound = (memaddr)(buff);

    for (int i = 0; i < list_size; i++) {
        ListElementPtr elm = &list->element[i];
        memcpy((void*)elm->addr, (void*)bound, elm->size);
        bound += elm->size;
    }

    (*this->end_dmawait_profile)(&wait,&start_time,&stop_time);
    global_store_time += wait;
    dma_storeList_time += wait;
}

void
FifoDmaManager::mail_write(memaddr data)
{
    unsigned long long wait = 0;
    (*this->start_dmawait_profile)(&start_time);

    mail_queue1->send(data);

    (*this->end_dmawait_profile)(&wait,&start_time,&stop_time);
    global_mail_time += wait;
    mail_write_time += wait;
}

void
FifoDmaManager::mail_write_finish_list(memaddr data)
{
    unsigned long long wait = 0;
    (*this->start_dmawait_profile)(&start_time);

    mail_queue1->send(data);

    (*this->end_dmawait_profile)(&wait,&start_time,&stop_time);
    global_mail_time += wait;
    mail_write_time += wait;
}

memaddr
FifoDmaManager::mail_read()
{
    unsigned long long wait = 0;
    (*this->start_dmawait_profile)(&start_time);

    memaddr data;
    data = mail_queue2->recv();

    (*this->end_dmawait_profile)(&wait,&start_time,&stop_time);
    global_mail_time += wait;
    mail_read_time += wait;

    return data;
}

memaddr
FifoDmaManager::task_list_mail_read()
{
    unsigned long long wait = 0;
    (*this->start_dmawait_profile)(&start_time);

    memaddr data;
    data = mail_queue2->recv();

    (*this->end_dmawait_profile)(&wait,&start_time,&stop_time);
    global_mail_time += wait;
    mail_read_time += wait;

    return data;
}

void
FifoDmaManager::mail_write_from_host(memaddr data)
{
    unsigned long long wait = 0;
    (*this->start_dmawait_profile)(&start_time);

    mail_queue2->send(data);

    (*this->end_dmawait_profile)(&wait,&start_time,&stop_time);
    global_mail_time += wait;
    mail_write_from_host_time += wait;
}

memaddr 
FifoDmaManager::mail_read_from_host() 
{
    unsigned long long wait = 0;
    (*this->start_dmawait_profile)(&start_time);

    memaddr data;
    data = mail_queue1->recv();

    (*this->end_dmawait_profile)(&wait,&start_time,&stop_time);
    global_mail_time += wait;
    mail_read_from_host_time += wait;

    return data;
}

int 
FifoDmaManager::has_mail_from_host() 
{ 
    return mail_queue1->count(); 
}

void
do_start_dmawait_profile(unsigned long long *start)
{
    *start = gettime();
}

void
do_end_dmawait_profile(unsigned long long *counter,unsigned long long *start,unsigned long long *stop)
{
    *stop = gettime();
    *counter += *stop - *start;
}

void null_start_dmawait_profile(unsigned long long *start) {}
void null_end_dmawait_profile(unsigned long long *counter,unsigned long long *start,unsigned long long *stop) {}

void
FifoDmaManager::start_profile()
{
    global_start_time = gettime();
    global_busy_time = 0;
    global_load_time = 0;
    global_store_time = 0;
    global_mail_time = 0;
    dma_load_time = 0;
    dma_store_time = 0;
    dma_loadList_time = 0;
    dma_storeList_time = 0;
    mail_read_time = 0;
    mail_write_time = 0;
    mail_read_from_host_time = 0;
    mail_write_from_host_time = 0;

    start_dmawait_profile = &do_start_dmawait_profile;
    end_dmawait_profile = &do_end_dmawait_profile;
    (*this->start_dmawait_profile)(&start_time);
}

void
FifoDmaManager::stop_profile()
{
    start_dmawait_profile = &null_start_dmawait_profile;
    end_dmawait_profile = &null_end_dmawait_profile;
}

void
FifoDmaManager::show_dma_wait(Scheduler *s, int cpu)
{
    unsigned long long all_time = gettime() - global_start_time;
    
    double busy = ((double)global_busy_time)/((double)all_time)*100.0;
    double load = ((double)global_load_time)/((double)all_time)*100.0;
    double store = ((double)global_store_time)/((double)all_time)*100.0;
    double mail = ((double)global_mail_time)/((double)all_time)*100.0;
    double read = ((double)mail_read_time)/((double)all_time)*100.0;
    double write = ((double)mail_write_time)/((double)all_time)*100.0;
    double read_from_host = ((double)mail_read_from_host_time)/((double)all_time)*100.0;
    double write_from_host = ((double)mail_write_from_host_time)/((double)all_time)*100.0;


    s->printf("cpu%d:\n busy_time = %lld(%.3g%%)\n"
              " load_time = %lld(%.3g%%), "
              " store_time = %lld(%.3g%%), "
              " mail_time = %lld(%.3g%%) \n"
              " mail_read_time = %lld(%.3g%%), "
              " mail_write_time = %lld(%.3g%%)\n"
              " mail_read_from_host_time = %lld(%.3g%%), "
              " mail_write_from_host_time = %lld(%.3g%%)\n"
              " all_time = %lld\n"
              ,cpu, global_busy_time, busy, 
              global_load_time, load,
              global_store_time, store,
              global_mail_time, mail,
              mail_read_time, read,
              mail_write_time, write,
              mail_read_from_host_time, read_from_host,
              mail_write_from_host_time, write_from_host,
              all_time);
    
    global_busy_time = 0;
    global_load_time = 0;
    global_store_time = 0;
    global_mail_time = 0;
    dma_load_time = 0;
    dma_store_time = 0;
    dma_loadList_time = 0;
    dma_storeList_time = 0;
    mail_read_time = 0;
    mail_write_time = 0;
    mail_read_from_host_time = 0;
    mail_write_from_host_time = 0;
}

uint32
FifoDmaManager::get_tag()
{
    static int tag = 16;
    tag ++;
    tag &= 0x0f;
    return tag+16;
}

/**
 *  DMA buffer offset in rbuf
 */
void
FifoDmaManager::bound(ListData *list)
{
    ListElement *elm = list->element;
    long *bound = list->bound;
    int offset=0;
    for(int i=0;i<list->length;i++) {
        bound[i] = offset;
        offset += elm[i].size;
    }
}

/* end */