Mercurial > hg > Game > Cerium
changeset 1202:4fc2e027077e draft
merge
author | Nobuyasu Oshiro <dimolto@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Thu, 14 Jul 2011 18:55:20 +0900 |
parents | dd52af319c40 (current diff) 726098b89619 (diff) |
children | f96a3dc9cd38 |
files | |
diffstat | 9 files changed, 213 insertions(+), 8 deletions(-) [+] |
line wrap: on
line diff
--- a/TaskManager/Fifo/FifoDmaManager.h Thu Jul 14 18:53:40 2011 +0900 +++ b/TaskManager/Fifo/FifoDmaManager.h Thu Jul 14 18:55:20 2011 +0900 @@ -4,7 +4,7 @@ #include "base.h" #include "DmaManager.h" #ifdef __CERIUM_PARALLEL__ -#include "SemMailManager.h" +#include "SynchronizedMailManager.h" #else #include "MailManager.h" #endif @@ -21,8 +21,8 @@ FifoDmaManager() { #ifdef __CERIUM_PARALLEL__ - mail_queue1 = new SemMailManager(); - mail_queue2 = new SemMailManager(); + mail_queue1 = new SynchronizedMailManager(); + mail_queue2 = new SynchronizedMailManager(); #else mail_queue1 = new MailManager(); mail_queue2 = new MailManager();
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/TaskManager/kernel/ppe/SynchronizedMailManager.cc Thu Jul 14 18:55:20 2011 +0900 @@ -0,0 +1,64 @@ +#include <stdlib.h> +#include "SynchronizedMailManager.h" + +void +SynchronizedMailManager::calc_mask(unsigned int qsize) +{ + mask = 1; + while(qsize>mask) { + mask <<= 1; + } + size = mask; + mask--; +} + +SynchronizedMailManager::SynchronizedMailManager(unsigned int qsize) { + read = write = 0; + calc_mask(qsize); + queue = Newq(memaddr,size); + + queue_remain = new Sem(size-1); //queue内に入る残りの数 + queue_count = new Sem(0); //queue内に現在入っている数 + +} + +SynchronizedMailManager::~SynchronizedMailManager() +{ + free(queue); + delete queue_remain; + delete queue_count; +} + +int +SynchronizedMailManager::count() +{ + return queue_count->count(); +} + +void +SynchronizedMailManager::send(memaddr data) +{ + queue_remain->sem_p(); //資源-1 + + queue[write++] = data; + //maskの範囲を超えた場合、0に戻す + write &= mask; + + queue_count->sem_v(); //資源+1 +} + +memaddr +SynchronizedMailManager::recv() +{ + queue_count->sem_p(); //資源-1 + + memaddr data; + data = queue[read++]; + read &= mask; + + queue_remain->sem_v(); //資源+1 + + return data; +} + +/* end */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/TaskManager/kernel/ppe/SynchronizedMailManager.h Thu Jul 14 18:55:20 2011 +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/TaskManager/test/SyncMailManagerTest/MailManagerTest.cc Thu Jul 14 18:55:20 2011 +0900 @@ -0,0 +1,85 @@ +#include <stdio.h> +#include "TaskManager/MailManager.h" +#include "TaskManager/SynchronizedMailManager.h" + +typedef struct _thread_arg { + MailManagerPtr m; + int size; +} thread_arg_t; + +static void +fail(const char *reason) +{ + printf("MailManagerTest failed %s", reason); +} + +static void +send_func(void *arg) +{ + thread_arg_t* targ = (thread_arg_t *)arg; + for(int i = 0; i < targ->size; i++) { + printf("send %d\n",i); + targ->m->send((memaddr)i); + } + return; +} + +static void +recv_func(void *arg) +{ + thread_arg_t* targ = (thread_arg_t *)arg; + for(int i = 0; i < targ->size; i++) { + if (targ->m->recv() != (memaddr)i) { + fail("read data fail\n"); + break; + } + printf("\t receive %d\n",i); + } + return; +} + +static void +tester(MailManagerPtr m, int size) +{ + //送信者スレッド作成 + thread_arg_t starg; + starg.m = m; + starg.size = size; + + pthread_t send; + pthread_create(&send, NULL, (void* (*)(void*))&send_func, (void*)&starg); + + //受信者スレッド作成 + thread_arg_t rtarg; + rtarg.m = m; + rtarg.size = size; + + pthread_t recv; + pthread_create(&recv, NULL, (void* (*)(void*))&recv_func, (void*)&rtarg); + + //終了待ち + pthread_join(send, NULL); + pthread_join(recv, NULL); +} + +static void +test1() { + MailManagerPtr m = new SynchronizedMailManager(2); + tester(m,16); + tester(m,32); + tester(m,48); + delete m; + MailManagerPtr m1 = new SynchronizedMailManager(32); + tester(m1,16); + tester(m1,48); + delete m1; +} + +int +main(int ac, const char *av[]) +{ + test1(); + printf("MailManagerTest succeed\n"); +} + +/* end */
--- a/example/Prime/Makefile.def Thu Jul 14 18:53:40 2011 +0900 +++ b/example/Prime/Makefile.def Thu Jul 14 18:55:20 2011 +0900 @@ -8,8 +8,8 @@ CERIUM = ../../../Cerium CC = g++ -m64 -CFLAGS = -O9 -Wall -#CFLAGS = -g -Wall +#CFLAGS = -O9 -Wall +CFLAGS = -g -Wall INCLUDE = -I${CERIUM}/include/TaskManager -I. -I.. LIBS = -L${CERIUM}/TaskManager
--- a/example/Prime/README Thu Jul 14 18:53:40 2011 +0900 +++ b/example/Prime/README Thu Jul 14 18:55:20 2011 +0900 @@ -1,15 +1,16 @@ - 概要 -指定された範囲の素数を出力するプログラムです。 +指定された範囲の素数を計算するプログラムです。 - 実行方法 -% ./prime [-num number] +% ./prime [-num number] [-print] -num 出力する素数の範囲 + -print 計算した素数を出力 - 実行例 (-cpu は Cerium 標準のオプションです) -% ./prime -num 100 -cpu 6 +% ./prime -num 100 -print -cpu 6 0 1 2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97
--- a/example/Prime/main.cc Thu Jul 14 18:53:40 2011 +0900 +++ b/example/Prime/main.cc Thu Jul 14 18:55:20 2011 +0900 @@ -11,6 +11,7 @@ extern TaskManager *manager; static int prime_num = 256; /* 素数を出力する範囲 */ +static int print_flag = -1; /* help文章 */ const char *usr_help_str = "Usage: ./prime [-cpu spe_num] [-num N]\n\ @@ -24,6 +25,9 @@ if (strcmp(argv[i], "-num") == 0) { prime_num = atoi(argv[++i]); } + else if (strcmp(argv[i], "-print") == 0) { + print_flag = 0; + } } return 0; } @@ -67,6 +71,8 @@ print->set_inData(0,output,sizeof(int)*prime_num); /* 出力する数を渡す */ print->set_param(0,(memaddr)prime_num); + /* printするかどうかを渡す */ + print->set_param(1,(memaddr)print_flag); /* PPEを使うように指示 */ print->set_cpu(CPU_PPE); /* タスクを登録 */
--- a/example/Prime/ppe/PrintTask.cc Thu Jul 14 18:53:40 2011 +0900 +++ b/example/Prime/ppe/PrintTask.cc Thu Jul 14 18:55:20 2011 +0900 @@ -8,6 +8,12 @@ static int print(SchedTask *smanager, void *rbuf, void *wbuf) { + int print_flag = (long)smanager->get_param(1); //プリントするかどうか + + if (print_flag < 0) { + return 0; + } + int length = (long)smanager->get_param(0); /* 出力する範囲 */ int *input = (int*)smanager->get_input(rbuf, 0); /* 出力する配列 */
--- a/example/Prime/spe/PrintTask.cc Thu Jul 14 18:53:40 2011 +0900 +++ b/example/Prime/spe/PrintTask.cc Thu Jul 14 18:55:20 2011 +0900 @@ -8,6 +8,12 @@ static int print(SchedTask *smanager, void *rbuf, void *wbuf) { + int print_flag = (long)smanager->get_param(1); //プリントするかどうか + + if (print_flag < 0) { + return 0; + } + int length = (int)smanager->get_param(0); /* 出力する範囲 */ int *input = (int*)smanager->get_input(rbuf, 0); /* 出力する配列 */