changeset 1874:039e6d5cf5b7 draft

improve spe tasklist pipeline IO thead priority
author Kohagura
date Mon, 30 Dec 2013 20:14:33 +0900
parents accb35bd3449
children 2f04c761bf9f
files TaskManager/Cell/CellTaskManagerImpl.cc TaskManager/ChangeLog TaskManager/kernel/ppe/CpuThreads.cc TaskManager/kernel/ppe/Sem.cc TaskManager/kernel/ppe/SemMailManager.cc TaskManager/kernel/ppe/SemMailManager.h TaskManager/test/schedparam/Makefile TaskManager/test/schedparam/schedparam.cc
diffstat 8 files changed, 244 insertions(+), 117 deletions(-) [+]
line wrap: on
line diff
--- a/TaskManager/Cell/CellTaskManagerImpl.cc	Sat Dec 28 19:30:42 2013 +0900
+++ b/TaskManager/Cell/CellTaskManagerImpl.cc	Mon Dec 30 20:14:33 2013 +0900
@@ -154,10 +154,7 @@
 void CellTaskManagerImpl::sendTaskList() {
     for (int id = 0; id < machineNum; id++) {
         mail_check(id);
-        if (!speTaskList[id]->empty()) {
-            continue; // まだ、走ってる
-        }
-        if (!taskListInfo[id]->empty()) {
+        if (speTaskList[id]->empty()) {
             // SPE に送る TaskList の準備
             send_taskList(id);
         }
@@ -171,7 +168,7 @@
 }
 
 void CellTaskManagerImpl::debug_check_spe_idle(
-                                               QueueInfo<HTask> * activeTaskQueue, int spe_running_) {
+            QueueInfo<HTask> * activeTaskQueue, int spe_running_) {
     printf("spu_idle! spe_running = %d : activeTaskQueue->length = %d \n",
            spe_running_, activeTaskQueue->length());
     HTaskPtr task = activeTaskQueue->getFirst();
@@ -264,10 +261,6 @@
             //  MY_SPE_STATUS_READY: SPE が持ってた Task 全て終了
             // freeAll する前に循環リストに戻す
             spe_running--;
-            if (!speTaskList[id]->empty()) {
-                speTaskList[id]->getLast()->next = speTaskList[id];
-                speTaskList[id]->freeAll();
-            }
             // printf("SPE %d status ready, %d running\n",id, spe_running);
         } else if (data == (memaddr) MY_SPE_COMMAND_MALLOC) {
             // MY_SPE_COMMAND_MALLOC   SPE からのmain memory request
@@ -278,8 +271,17 @@
 #ifdef TASK_LIST_MAIL
             // multi dimensionだったらcount downする 
             TaskListPtr list = (TaskListPtr)data;
-            if (--list->self->flag.dim_count == 0)
+            if (--list->self->flag.dim_count == 0) {
                 check_task_list_finish(schedTaskManager, list, waitTaskQueue);
+		if (speTaskList[id]->getFirst() == list) {
+		    speTaskList[id]->next = list->next;
+		    speTaskList[id]->free_(list);
+		}
+		if (taskListInfo[id]->getFirst() == list) {
+		    taskListInfo[id]->next = list->next;
+		    taskListInfo[id]->free_(list);
+		}
+	    }
 #else
             // 終了したタスク(PPEにあるのでアドレス)
             HTaskPtr task = (HTaskPtr) data;
--- a/TaskManager/ChangeLog	Sat Dec 28 19:30:42 2013 +0900
+++ b/TaskManager/ChangeLog	Mon Dec 30 20:14:33 2013 +0900
@@ -1,3 +1,17 @@
+2013-12-27 Masataka Kohagura <kohagura@cr.ie.u-ryukyu.ac.jp>
+
+	spe側のTaskListのpipelineの間が空いているので、それを埋める必要がある
+	speTaskListを処理している間に、次のTaskを送っておく。
+	speからTaskList終了mailがきたら、その場でspeTaskListの終了をcheckする。
+	speTaskListがemptyならば、speがTaskListInfoを実行中でもsetTaskListしてよい。
+	Task終了mailがきたときに、speTaskListとtasklistinfoのどちらかからTaskを取り除く必要がある。
+	それはTaskListのアドレスがあるので、自動的に行われる。
+	speはすでにTaskListInfo側を実行しているかも知れないが、speTaskListを調べてemptyならばそれを解放する。
+	
+	Semaphore では排他制御されているので、atomic increment の意味はない。 
+	Synchronied Mail の方では、1対1以外の場合は、atomic incrementする必要がある。(してない)
+
+
 2013-12-27 Masataka Kohagura <kohagura@cr.ie.u-ryukyu.ac.jp>
 
 	read / write を専用に行うCPU threadを用意する
--- a/TaskManager/kernel/ppe/CpuThreads.cc	Sat Dec 28 19:30:42 2013 +0900
+++ b/TaskManager/kernel/ppe/CpuThreads.cc	Mon Dec 30 20:14:33 2013 +0900
@@ -66,8 +66,14 @@
     manager->set_scheduler(c_scheduler);
     SchedRegister(ShowTime);
     SchedRegister(StartProfile);
-    if (argt->cpuid >= argt->cpu_num)
-        pthread_setschedparam(static_cast<CpuThreads*>(args)->threads[argt->cpuid], SCHED_OTHER, &(argt->priority));
+    if (argt->cpuid >= argt->cpu_num) {
+        // set IO thread priory maximum
+	int policy;
+	struct sched_param param;
+        pthread_getschedparam(pthread_self(), &policy, &param);
+        param.sched_priority = argt->priority = 1;
+        pthread_setschedparam(pthread_self(), policy, &param);
+    }
     
     argt->wait->sem_v();        //準備完了したスレッドができるたびに+1していく
 
--- a/TaskManager/kernel/ppe/Sem.cc	Sat Dec 28 19:30:42 2013 +0900
+++ b/TaskManager/kernel/ppe/Sem.cc	Mon Dec 30 20:14:33 2013 +0900
@@ -29,9 +29,9 @@
 		pthread_cond_wait(&sem->cond, &sem->mutex);
 	}
 	//atomic
-	//sem->value--;	//資源の確保
+	sem->value--;	//資源の確保
 	//count()のvalueを取得する際にアトミック操作が必要
-	__sync_fetch_and_sub(&sem->value,1);
+	//__sync_fetch_and_sub(&sem->value,1);
 	pthread_mutex_unlock(&sem->mutex);
 }
 
@@ -42,8 +42,8 @@
 {
 	pthread_mutex_lock(&sem->mutex);
 	//atomic
-	//sem->value++;	//資源の解放
-	__sync_fetch_and_add(&sem->value,1);
+	sem->value++;	//資源の解放
+	//__sync_fetch_and_add(&sem->value,1);
 
 	//資源の解放を知らせる
 	pthread_cond_signal(&sem->cond);
--- a/TaskManager/kernel/ppe/SemMailManager.cc	Sat Dec 28 19:30:42 2013 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,64 +0,0 @@
-#include <stdlib.h>
-#include "SemMailManager.h"
-
-void
-SemMailManager::calc_mask(unsigned int qsize)
-{
-    mask = 1;
-    while(qsize>mask) {
-	mask <<= 1;
-    }
-    size = mask;
-    mask--;
-}
-
-SemMailManager::SemMailManager(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内に現在入っている数
-
-}
-
-SemMailManager::~SemMailManager()
-{
-	free(queue);
-	delete queue_remain;
-	delete queue_count;
-}
-
-int 
-SemMailManager::count()
-{
-    return queue_count->count();
-}
-
-void 
-SemMailManager::send(memaddr data)
-{
-	queue_remain->sem_p();	//資源-1
-
-    queue[write++] = data;
-    //maskの範囲を超えた場合、0に戻す
-    write &= mask;
-
-    queue_count->sem_v();		//資源+1
-}
-
-memaddr 
-SemMailManager::recv()
-{
-	queue_count->sem_p();		//資源-1
-
-    memaddr data;
-	data = queue[read++];
-	read &= mask;
-
-	queue_remain->sem_v();	//資源+1
-
-    return data;
-}
-
-/* end */
--- a/TaskManager/kernel/ppe/SemMailManager.h	Sat Dec 28 19:30:42 2013 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,37 +0,0 @@
-#ifndef INCLUDED_SEM_MAIL_MANAGER
-#define INCLUDED_SEM_MAIL_MANAGER
-
-#include <pthread.h>
-#include "MailManager.h"
-#include "types.h"
-#include "Sem.h"
-
-class SemMailManager : public MailManager {
-public:
-    /* constructor */
-    SemMailManager(unsigned int qsize = 32) ;
-
-    ~SemMailManager();
-
-    /* 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 SemMailManager *SemMailManagerPtr;
-
-#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/TaskManager/test/schedparam/Makefile	Mon Dec 30 20:14:33 2013 +0900
@@ -0,0 +1,5 @@
+CC = clang++
+CPPFLAGS = -g -O0
+schedparam: schedparam.o
+	$(CC) -g -O0 -o $@ $<
+schedparam.o: schedparam.cc
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/TaskManager/test/schedparam/schedparam.cc	Mon Dec 30 20:14:33 2013 +0900
@@ -0,0 +1,201 @@
+#include <pthread.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+
+#define handle_error_en(en, msg) \
+        do { errno = en; perror(msg); exit(EXIT_FAILURE); } while (0)
+
+static void
+usage(const char *prog_name,const char *msg)
+{
+    if (msg != NULL)
+            fputs(msg, stderr);
+
+       fprintf(stderr, "Usage: %s [options]\n", prog_name);
+           fprintf(stderr, "Options are:\n");
+#define fpe(msg) fprintf(stderr, "\t%s", msg);          /* Shorter */
+       fpe("-a<policy><prio> Set scheduling policy and priority in\n");
+           fpe("                 thread attributes object\n");
+       fpe("                 <policy> can be\n");
+           fpe("                     f  SCHED_FIFO\n");
+       fpe("                     r  SCHED_RR\n");
+           fpe("                     o  SCHED_OTHER\n");
+       fpe("-A               Use default thread attributes object\n");
+           fpe("-i {e|s}         Set inherit scheduler attribute to\n");
+       fpe("                 'explicit' or 'inherit'\n");
+           fpe("-m<policy><prio> Set scheduling policy and priority on\n");
+       fpe("                 main thread before pthread_create() call\n");
+           exit(EXIT_FAILURE);
+}
+
+static int
+get_policy(char p, int *policy)
+{
+    switch (p) {
+        case 'f': *policy = SCHED_FIFO;     return 1;
+      case 'r': *policy = SCHED_RR;       return 1;
+    case 'o': *policy = SCHED_OTHER;    return 1;
+          default:  return 0;
+        }
+}
+
+static void
+display_sched_attr(int policy, struct sched_param *param)
+{
+    printf("    policy=%s, priority=%d\n",
+                (policy == SCHED_FIFO)  ? "SCHED_FIFO" :
+            (policy == SCHED_RR)    ? "SCHED_RR" :
+                (policy == SCHED_OTHER) ? "SCHED_OTHER" :
+            "???",
+                param->sched_priority);
+}
+
+static void
+display_thread_sched_attr(const char *msg)
+{
+    int policy, s;
+        struct sched_param param;
+
+   s = pthread_getschedparam(pthread_self(), &policy, &param);
+       if (s != 0)
+               handle_error_en(s, "pthread_getschedparam");
+
+          printf("%s\n", msg);
+      display_sched_attr(policy, &param);
+}
+
+static void *
+thread_start(void *arg)
+{
+    display_thread_sched_attr("Scheduler attributes of new thread");
+
+       return NULL;
+}
+
+int
+main(int argc, char *argv[])
+{
+    int s, opt, inheritsched, use_null_attrib, policy;
+        pthread_t thread;
+    pthread_attr_t attr;
+        pthread_attr_t *attrp;
+    char *attr_sched_str, *main_sched_str, *inheritsched_str;
+        struct sched_param param;
+
+   /* Process command-line options */
+
+   use_null_attrib = 0;
+       attr_sched_str = NULL;
+           main_sched_str = NULL;
+       inheritsched_str = NULL;
+
+          while ((opt = getopt(argc, argv, "a:Ai:m:")) != -1) {
+          switch (opt) {
+          case 'a': attr_sched_str = optarg;      break;
+            case 'A': use_null_attrib = 1;          break;
+              case 'i': inheritsched_str = optarg;    break;
+        case 'm': main_sched_str = optarg;      break;
+          default:  usage(argv[0], "Unrecognized option\n");
+            }
+      }
+
+     if (use_null_attrib &&
+                 (inheritsched_str != NULL || attr_sched_str != NULL))
+             usage(argv[0], "Can't specify -A with -i or -a\n");
+
+        /* Optionally set scheduling attributes of main thread,
+ *        and display the attributes */
+
+        if (main_sched_str != NULL) {
+        if (!get_policy(main_sched_str[0], &policy))
+            usage(argv[0], "Bad policy for main thread (-s)\n");
+        param.sched_priority = strtol(&main_sched_str[1], NULL, 0);
+
+       s = pthread_setschedparam(pthread_self(), policy, &param);
+               if (s != 0)
+                   handle_error_en(s, "pthread_setschedparam");
+           }
+
+   display_thread_sched_attr("Scheduler settings of main thread");
+       printf("\n");
+
+          /* Initialize thread attributes object according to options */
+
+          attrp = NULL;
+
+     if (!use_null_attrib) {
+             s = pthread_attr_init(&attr);
+             if (s != 0)
+                 handle_error_en(s, "pthread_attr_init");
+             attrp = &attr;
+         }
+
+        if (inheritsched_str != NULL) {
+        if (inheritsched_str[0] == 'e')
+            inheritsched = PTHREAD_EXPLICIT_SCHED;
+        else if (inheritsched_str[0] == 'i')
+            inheritsched = PTHREAD_INHERIT_SCHED;
+        else
+            usage(argv[0], "Value for -i must be 'e' or 'i'\n");
+
+       s = pthread_attr_setinheritsched(&attr, inheritsched);
+               if (s != 0)
+                   handle_error_en(s, "pthread_attr_setinheritsched");
+           }
+
+   if (attr_sched_str != NULL) {
+           if (!get_policy(attr_sched_str[0], &policy))
+               usage(argv[0],
+                           "Bad policy for 'attr' (-a)\n");
+           param.sched_priority = strtol(&attr_sched_str[1], NULL, 0);
+
+          s = pthread_attr_setschedpolicy(&attr, policy);
+          if (s != 0)
+              handle_error_en(s, "pthread_attr_setschedpolicy");
+          s = pthread_attr_setschedparam(&attr, &param);
+          if (s != 0)
+              handle_error_en(s, "pthread_attr_setschedparam");
+      }
+
+      /* If we initialized a thread attributes object, display
+       *        the scheduling attributes that were set in the object */
+
+      if (attrp != NULL) {
+              s = pthread_attr_getschedparam(&attr, &param);
+              if (s != 0)
+                  handle_error_en(s, "pthread_attr_getschedparam");
+              s = pthread_attr_getschedpolicy(&attr, &policy);
+              if (s != 0)
+                  handle_error_en(s, "pthread_attr_getschedpolicy");
+
+             printf("Scheduler settings in 'attr'\n");
+             display_sched_attr(policy, &param);
+
+            s = pthread_attr_getinheritsched(&attr, &inheritsched);
+            printf("    inheritsched is %s\n",
+                    (inheritsched == PTHREAD_INHERIT_SCHED)  ? "INHERIT" :
+                    (inheritsched == PTHREAD_EXPLICIT_SCHED) ? "EXPLICIT" :
+                    "???");
+            printf("\n");
+        }
+
+         /* Create a thread that will display its scheduling attributes */
+
+         s = pthread_create(&thread, attrp, &thread_start, NULL);
+     if (s != 0)
+             handle_error_en(s, "pthread_create");
+
+        /* Destroy unneeded thread attributes object */
+
+        s = pthread_attr_destroy(&attr);
+    if (s != 0)
+            handle_error_en(s, "pthread_attr_destroy");
+
+       s = pthread_join(thread, NULL);
+           if (s != 0)
+           handle_error_en(s, "pthread_join");
+
+      exit(EXIT_SUCCESS);
+}