changeset 1186:4c209dd223cd draft

fix MailManager and Semaphore
author Daichi TOMA
date Mon, 04 Jul 2011 14:11:26 +0900
parents 5a9bee9cc8c9
children d4311f83377a
files TaskManager/Makefile.parallel TaskManager/kernel/ppe/MailManager.cc TaskManager/kernel/ppe/MailManager.h TaskManager/kernel/ppe/Sem.cc TaskManager/kernel/ppe/Sem.h TaskManager/test/MailManagerTest.cc TaskManager/test/Makefile
diffstat 7 files changed, 82 insertions(+), 64 deletions(-) [+]
line wrap: on
line diff
--- a/TaskManager/Makefile.parallel	Tue Jun 28 17:51:11 2011 +0900
+++ b/TaskManager/Makefile.parallel	Mon Jul 04 14:11:26 2011 +0900
@@ -1,5 +1,5 @@
 include ./Makefile.def
-TARGET = libParallelManager.a
+TARGET = libFifoManager.a
 CFLAGS += -DHAS_POSIX_MEMALIGN
 
 .SUFFIXES: .cc .o
--- a/TaskManager/kernel/ppe/MailManager.cc	Tue Jun 28 17:51:11 2011 +0900
+++ b/TaskManager/kernel/ppe/MailManager.cc	Mon Jul 04 14:11:26 2011 +0900
@@ -17,77 +17,46 @@
     calc_mask(qsize);
     queue = Newq(memaddr,size);
 
-    mutex_s = new pthread_mutex_t;	//sendのロック用
-    mutex_r = new pthread_mutex_t;	//recvのロック用
-    pthread_mutex_init(mutex_s, NULL);
-    pthread_mutex_init(mutex_r, NULL);
-
-    remain  = new Sem(0);			//queue内のアイテム数を管理
+    queue_remain  = new Sem(size-1);			//queue内にあと入る数
+    queue_count	= new Sem(0);				//queue内に現在入っている数
 
 }
 
 MailManager::~MailManager()
 {
 	free(queue);
-
-	pthread_mutex_destroy(mutex_s);
-	pthread_mutex_destroy(mutex_r);
-
-	delete mutex_s;
-	delete mutex_r;
-	delete remain;
+	delete queue_remain;
+	delete queue_count;
 }
 
 int 
 MailManager::count()
 {
-    return (write+size-read)&mask;
-}
-
-void 
-MailManager::extend()
-{
-    memaddr *newq = Newq(memaddr,size*2);
-    unsigned int i = 0;
-    while(i<size) {
-	newq[i++] = queue[read++];
-	read &= mask;
-    }
-    read = 0; write = i;
-    calc_mask(size*2);
-    free(queue);
-    queue = newq;
+    return queue_count->count();
 }
 
 void 
 MailManager::send(memaddr data)
 {
-	pthread_mutex_lock(mutex_s);
+	queue_remain->sem_p();	//資源-1
 
     queue[write++] = data;
+    //maskの範囲を超えた場合、0に戻す
     write &= mask;
-    if (write==read) {
-	extend();
-    }
 
-    pthread_mutex_unlock(mutex_s);
-    remain->sem_v();		//資源を解放
+    queue_count->sem_v();		//資源+1
 }
 
 memaddr 
 MailManager::recv()
 {
-	pthread_mutex_lock(mutex_r);
+	queue_count->sem_p();		//資源-1
 
-	remain->sem_p();		//資源の確保
     memaddr data;
-    if (count()>0) {
 	data = queue[read++];
 	read &= mask;
-    } else {
-	data = 0;
-    }
-    pthread_mutex_unlock(mutex_r);
+
+	queue_remain->sem_v();	//資源+1
 
     return data;
 }
--- a/TaskManager/kernel/ppe/MailManager.h	Tue Jun 28 17:51:11 2011 +0900
+++ b/TaskManager/kernel/ppe/MailManager.h	Mon Jul 04 14:11:26 2011 +0900
@@ -20,9 +20,8 @@
 private:
     /* variables */
     memaddr *queue;
-    pthread_mutex_t *mutex_s;
-    pthread_mutex_t *mutex_r;
-    SemPtr remain;
+    SemPtr queue_remain;
+    SemPtr queue_count;
     unsigned int size;
     unsigned int read;
     unsigned int write;
--- a/TaskManager/kernel/ppe/Sem.cc	Tue Jun 28 17:51:11 2011 +0900
+++ b/TaskManager/kernel/ppe/Sem.cc	Mon Jul 04 14:11:26 2011 +0900
@@ -28,7 +28,9 @@
 	while(sem->value == 0) {
 		pthread_cond_wait(&sem->cond, &sem->mutex);
 	}
-	sem->value--;	//資源の確保
+	//atomic
+	//sem->value--;	//資源の確保
+	__sync_fetch_and_sub(&sem->value,1);
 	pthread_mutex_unlock(&sem->mutex);
 }
 
@@ -38,9 +40,20 @@
 Sem::sem_v()
 {
 	pthread_mutex_lock(&sem->mutex);
-	sem->value++;	//資源の解放
-	pthread_mutex_unlock(&sem->mutex);
+	//atomic
+	//sem->value++;	//資源の解放
+	__sync_fetch_and_add(&sem->value,1);
 
 	//資源の解放を知らせる
 	pthread_cond_signal(&sem->cond);
+	pthread_mutex_unlock(&sem->mutex);
+
 }
+
+int
+Sem::count()
+{
+	//semの値を返せばよい。
+	//atomic
+	return sem->value;
+}
--- a/TaskManager/kernel/ppe/Sem.h	Tue Jun 28 17:51:11 2011 +0900
+++ b/TaskManager/kernel/ppe/Sem.h	Mon Jul 04 14:11:26 2011 +0900
@@ -16,6 +16,7 @@
 	~Sem();
 	void sem_p();
 	void sem_v();
+	int  count();
 	/* variables */
 private:
 	sem_t *sem;
--- a/TaskManager/test/MailManagerTest.cc	Tue Jun 28 17:51:11 2011 +0900
+++ b/TaskManager/test/MailManagerTest.cc	Mon Jul 04 14:11:26 2011 +0900
@@ -1,6 +1,11 @@
 #include <stdio.h>
 #include "TaskManager/MailManager.h"
 
+typedef struct _thread_arg {
+	MailManagerPtr m;
+	int size;
+} thread_arg_t;
+
 static void
 fail(const char *reason)
 {
@@ -8,30 +13,62 @@
 }
 
 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;
 
-    for(int i=0;i<size;i++) {
-	m->send((memaddr)i);
-    }
-    for(int i=0;i<size;i++) {
-	if (m->count()==0) { 
-	    fail("early read fail\n"); break;
-	}
-	if (m->recv()!=(memaddr)i) { 
-	    fail("read data fail\n"); break;
-	}
-    }
+	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 MailManager();
+    MailManagerPtr m = new MailManager(2);
     tester(m,16);
     tester(m,32);
     tester(m,48);
     delete m; 
-    MailManagerPtr m1 = new MailManager(40);
+    MailManagerPtr m1 = new MailManager(32);
     tester(m1,16);
     tester(m1,48);
     delete m1;
--- a/TaskManager/test/Makefile	Tue Jun 28 17:51:11 2011 +0900
+++ b/TaskManager/test/Makefile	Mon Jul 04 14:11:26 2011 +0900
@@ -6,8 +6,7 @@
 
 $(TARGET) :
 
-#LIBS += ../libFifoManager.a
-LIBS += ../libParallelManager.a
+LIBS += ../libFifoManager.a
 
 MailManagerTest : MailManagerTest.o
 	$(CC) $(CFLAGS) -o $@ $? $(LIBS)