From 35d1afe01c066026d3e7dd2fdcea49f8eec92ec9 Mon Sep 17 00:00:00 2001
From: Torsten Merz <mer114@moon-ph.nexus.csiro.au>
Date: Wed, 25 Sep 2019 23:56:54 +1000
Subject: [PATCH] optimised smi multi core locking mechanism

---
 smi/src/rt_def.h       |  1 +
 smi/src/smi.c          | 21 +++++++++++++++++----
 smi/src/smi_def.h      | 10 ++++++++--
 smi/src/smi_nrt.c      |  1 +
 smi/src/taskdisp_nrt.c | 36 ++++++++++++++++++++++++++++++++++--
 5 files changed, 61 insertions(+), 8 deletions(-)

diff --git a/smi/src/rt_def.h b/smi/src/rt_def.h
index d71f23c..2b39eaf 100644
--- a/smi/src/rt_def.h
+++ b/smi/src/rt_def.h
@@ -95,6 +95,7 @@ typedef volatile struct {
 
         taskStateStruct taskState[MAX_NUMBER_OF_TASK_STATES];  
         taskStateSysVarStruct taskStateSysVar[MAX_NUMBER_OF_TASK_STATES];  
+        controlFlagsStruct controlFlags[MAX_NUMBER_OF_TASK_STATES];  
 
         unsigned int smiLock;        
         int intTest;
diff --git a/smi/src/smi.c b/smi/src/smi.c
index e7867c9..a2e0c45 100644
--- a/smi/src/smi.c
+++ b/smi/src/smi.c
@@ -247,7 +247,8 @@ if (t2-t1>maxGettime) maxGettime=t2-t1;
 */
         __sync_fetch_and_and(&(shm->smiLock),0);
 //rt_printf("in=%d ",  __sync_fetch_and_add(&(shm->smiLock),0));        
-
+/*
+t1=GETTIME;
 	for (i=0;i<shm->numberOfTaskStates;i++) {
 	 if (__sync_fetch_and_add(&(shm->taskStateSysVar[i].copy),0)) {
 	  int j;
@@ -259,7 +260,8 @@ if (t2-t1>maxGettime) maxGettime=t2-t1;
           __sync_fetch_and_and(&(shm->taskStateSysVar[i].copy),0);
 	 }
         }
-
+t2=GETTIME;        rt_printf("%lld ",(t2-t1)/1000);
+*/
   shm->numberOfCurrentLeafStates=0;
 
   for (i=0;i<2*MAX_NUMBER_OF_CONCURRENT_STATES;i++) {
@@ -306,12 +308,23 @@ if (t2-t1>maxGettime) maxGettime=t2-t1;
           currentTaskStateFlags[shm->numberOfCurrentLeafStates]|=TASK_TIMEOUT;
         if ((shm->taskStateSysVar[atomicStateVariables[i].taskStateVar].flags&TASK_BUSY)!=0)
           currentTaskStateFlags[shm->numberOfCurrentLeafStates]|=TASK_BUSY;
-// the following three lines were commented -> ?
+        if (__sync_fetch_and_and(&(shm->taskStateSysVar[atomicStateVariables[i].taskStateVar].exit),0)==ATOMIC_UNLOCKED) {  
+//rt_printf("bbbb->%d ",__sync_fetch_and_add(&(shm->taskStateSysVar[atomicStateVariables[i].taskStateVar].exit),0));
+           shm->taskStateSysVar[atomicStateVariables[i].taskStateVar].flags|=TASK_EXIT;           
+           for (j=0;j<MAX_NUMBER_OF_CONTROL_FLAGS_PER_STATE;j++) {
+             shm->taskState[atomicStateVariables[i].taskStateVar].outputControlFlag[j]
+             =shm->controlFlags[atomicStateVariables[i].taskStateVar].outputControlFlag[j];                 
+             shm->taskState[atomicStateVariables[i].taskStateVar].inputControlFlag[j]
+             =shm->controlFlags[atomicStateVariables[i].taskStateVar].inputControlFlag[j];                   
+           }
+        }
         if ((shm->taskStateSysVar[atomicStateVariables[i].taskStateVar].flags&TASK_EXIT)!=0)
-          currentTaskStateFlags[shm->numberOfCurrentLeafStates]|=TASK_EXIT;          
+           currentTaskStateFlags[shm->numberOfCurrentLeafStates]|=TASK_EXIT;          
         else 
         if (atomicStateVariables[i].exit==1)
           currentTaskStateFlags[shm->numberOfCurrentLeafStates]|=TASK_EXIT;
+if (shm->taskStateSysVar[atomicStateVariables[i].taskStateVar].nrt==0 ||
+__sync_fetch_and_and(&(shm->taskStateSysVar[atomicStateVariables[i].taskStateVar].exit),1)==ATOMIC_UNLOCKED)
         for (j=0;j<MAX_NUMBER_OF_CONTROL_FLAGS_PER_STATE;j++) {
           if (shm->taskState[atomicStateVariables[i].taskStateVar].outputControlFlag[j]==1) {
            currentTaskStateFlags[shm->numberOfCurrentLeafStates]|=(1<<(j+8));
diff --git a/smi/src/smi_def.h b/smi/src/smi_def.h
index 379830d..08e7519 100644
--- a/smi/src/smi_def.h
+++ b/smi/src/smi_def.h
@@ -57,6 +57,12 @@ typedef volatile struct {
   int outputControlFlag[MAX_NUMBER_OF_CONTROL_FLAGS_PER_STATE]; 
 } taskStateStruct;
 
+typedef volatile struct { 
+  signed char inputControlFlag[MAX_NUMBER_OF_CONTROL_FLAGS_PER_STATE];
+  signed char outputControlFlag[MAX_NUMBER_OF_CONTROL_FLAGS_PER_STATE]; 
+} controlFlagsStruct;
+
+
 #define TASK_TIMEOUT	0x10
 typedef volatile struct { 
 #define TASK_EXEC	0x01
@@ -64,8 +70,8 @@ typedef volatile struct {
 #define TASK_ACTIVE	0x04
 #define TASK_BUSY	0x08
 #define TASK_SMI	0x20
-  unsigned int copy;
-  signed char outputControlFlagTmp[MAX_NUMBER_OF_CONTROL_FLAGS_PER_STATE];   
+  int exit;
+//  signed char outputControlFlagTmp[MAX_NUMBER_OF_CONTROL_FLAGS_PER_STATE];   
   int flags;  
   taskIDType taskID;
   processType process;
diff --git a/smi/src/smi_nrt.c b/smi/src/smi_nrt.c
index 92820bf..b8728f5 100644
--- a/smi/src/smi_nrt.c
+++ b/smi/src/smi_nrt.c
@@ -195,6 +195,7 @@ printf("new format\n");
           } else shm->taskStateSysVar[shm->esmStateTransfer.taskStateVar].dataPort[i]=NA;
         }
         shm->taskStateSysVar[shm->esmStateTransfer.taskStateVar].flags=0;        
+        shm->taskStateSysVar[shm->esmStateTransfer.taskStateVar].exit=0;                
     
         if (index+1>=numberBufferSize) {
           error=12;
diff --git a/smi/src/taskdisp_nrt.c b/smi/src/taskdisp_nrt.c
index 9a2b2eb..a626575 100644
--- a/smi/src/taskdisp_nrt.c
+++ b/smi/src/taskdisp_nrt.c
@@ -216,7 +216,36 @@ usleep(10000);
              usleep(STD_SLEEP);	                           
             } else smiLock=1;
            } 
-	  
+
+//	   if ((shm->taskStateSysVar[i].flags&TASK_EXEC)!=0) 
+	   if ((taskStateSysVarTmp.flags&TASK_EXEC)!=0)
+           {
+//	    execTask(&shm->taskState[i],&shm->taskStateSysVar[i],shm->taskStateSysVar[i].taskID);
+	    execTask(&taskStateTmp,&taskStateSysVarTmp,taskStateSysVarTmp.taskID);
+/*
+            memcpy((unsigned char*)&(shm->taskState[i]),	     
+	     (unsigned char*)&taskStateTmp,
+              sizeof(taskStateStruct));	  
+*/
+            for (j=0;j<MAX_NUMBER_OF_CONTROL_FLAGS_PER_STATE;j++) {
+             shm->controlFlags[i].outputControlFlag[j]=taskStateTmp.outputControlFlag[j];      
+             shm->controlFlags[i].inputControlFlag[j]=taskStateTmp.inputControlFlag[j];      
+            }
+
+//            shm->taskStateSysVar[i].flags|=TASK_EXIT;
+//            __sync_fetch_and_and(&(shm->taskStateSysVar[i].flags),TASK_EXIT);          
+            __sync_fetch_and_nand(&(shm->taskStateSysVar[i].exit),0);          
+//printf("aaaaaa->%d",__sync_fetch_and_add(&(shm->taskStateSysVar[i].exit),0));          
+            
+            numberOfSMIIterations=__sync_fetch_and_add(&(shm->numberOfSMIIterations),0);	    
+	    while (numberOfSMIIterations==__sync_fetch_and_add(&(shm->numberOfSMIIterations),0) && shm->run!=0) 	    
+	    {
+		usleep(STD_SLEEP);	   
+	    }	 
+            __sync_fetch_and_and(&(shm->taskStateSysVar[i].exit),0);          	    
+	   }
+
+if (0) {	  
 	   if ((taskStateSysVarTmp.flags&TASK_EXEC)!=0
 /*	    && ((shm->taskStateSysVar[i].oneShot==0
 	      || (shm->taskStateSysVar[i].flags&TASK_EXIT)==0
@@ -238,11 +267,13 @@ usleep(10000);
 //if (n==0 && shm->taskStateSysVar[i].taskID==27 && shm->taskState[i].stateID==72) printf("-----------------\n");
 //	    shm->taskStateSysVar[i].flags&=~(TASK_ACTIVE);
 //	    shm->taskStateSysVar[i].flags&=~(TASK_EXEC);	    
+/*
             for (j=0;j<MAX_NUMBER_OF_CONTROL_FLAGS_PER_STATE;j++) {
              shm->taskStateSysVar[i].outputControlFlagTmp[j]=
               taskStateTmp.outputControlFlag[j];      
             }
-            __sync_fetch_and_nand(&(shm->taskStateSysVar[i].copy),0);          
+*/
+//            __sync_fetch_and_nand(&(shm->taskStateSysVar[i].copy),0);          
 
 //	    shm->taskStateSysVar[i].flags|=TASK_EXIT;
 //	    shm->t3=shm->reftime;
@@ -257,6 +288,7 @@ usleep(10000);
 		usleep(STD_SLEEP);	   
 	    }	 
 	   }
+}	   
 	  }
 	 }
 	 if (shm->run==0) break; 
-- 
GitLab