From 3f46377b24952a2f1842fadfc7e5ee5fc8bf7f35 Mon Sep 17 00:00:00 2001
From: Torsten Merz <mer114@moon-ph.nexus.csiro.au>
Date: Wed, 25 Sep 2019 21:02:27 +1000
Subject: [PATCH] removed one shot function for nrt tasks, added nrt multi core
 smi locking

---
 smi/src/rt_def.h       |  3 ++-
 smi/src/shm.c          | 11 +++++---
 smi/src/smi.c          | 40 +++++++++++++++++++++++------
 smi/src/smi_def.h      |  4 ++-
 smi/src/smi_nrt.c      |  3 ++-
 smi/src/taskdisp_nrt.c | 57 +++++++++++++++++++++++++++++++++---------
 6 files changed, 92 insertions(+), 26 deletions(-)

diff --git a/smi/src/rt_def.h b/smi/src/rt_def.h
index 028295d..d71f23c 100644
--- a/smi/src/rt_def.h
+++ b/smi/src/rt_def.h
@@ -95,7 +95,8 @@ typedef volatile struct {
 
         taskStateStruct taskState[MAX_NUMBER_OF_TASK_STATES];  
         taskStateSysVarStruct taskStateSysVar[MAX_NUMBER_OF_TASK_STATES];  
-        
+
+        unsigned int smiLock;        
         int intTest;
         RTIME t1,t2,t3;
         int run;
diff --git a/smi/src/shm.c b/smi/src/shm.c
index a6010ee..d0df68b 100644
--- a/smi/src/shm.c
+++ b/smi/src/shm.c
@@ -94,17 +94,19 @@ int smiLogRead(int iteration, unsigned char filter,
 // return=0 ok
 // numberOfLeafStates=0 no data
 
-    int i,index,n;
+    int i,index,n,numberOfEntries;
     unsigned int smiIterationTmp;    
     stateIDLogType state;
 
     *numberOfLeafStates=0;
     
-    index=smiLogBuf->index;    
+//    index=smiLogBuf->index;    
+     index=__sync_fetch_and_add(&(smiLogBuf->index),0);	        
+     numberOfEntries=__sync_fetch_and_add(&(smiLogBuf->numberOfEntries),0);	        
     
-    if (index==0 && smiLogBuf->numberOfEntries!=SMI_LOG_BUF_SIZE) return(0); // no log data
+    if (index==0 && numberOfEntries!=SMI_LOG_BUF_SIZE) return(0); // no log data
     
-    n=smiLogBuf->numberOfEntries;
+    n=numberOfEntries;
     smiIterationTmp=0;
     for (i=0;i<n;i++) {
        index--;
@@ -149,6 +151,7 @@ int smiLogRead(int iteration, unsigned char filter,
 }
 
 
+
 int getSMIEntry(int iteration, 
    unsigned int *smiIteration, unsigned int *time, unsigned int *numberOfLeafStates,
    stateIDType *leafStates, flagsIDType *taskStateFlags,
diff --git a/smi/src/smi.c b/smi/src/smi.c
index fd53aaa..e7867c9 100644
--- a/smi/src/smi.c
+++ b/smi/src/smi.c
@@ -245,6 +245,20 @@ indexGettimeBuf++;
 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));        
+
+	for (i=0;i<shm->numberOfTaskStates;i++) {
+	 if (__sync_fetch_and_add(&(shm->taskStateSysVar[i].copy),0)) {
+	  int j;
+          for (j=0;j<MAX_NUMBER_OF_CONTROL_FLAGS_PER_STATE;j++) {
+           shm->taskState[i].outputControlFlag[j]=
+            shm->taskStateSysVar[i].outputControlFlagTmp[j];
+          }
+          shm->taskStateSysVar[i].flags|=TASK_EXIT;          
+          __sync_fetch_and_and(&(shm->taskStateSysVar[i].copy),0);
+	 }
+        }
 
   shm->numberOfCurrentLeafStates=0;
 
@@ -309,7 +323,10 @@ if (t2-t1>maxGettime) maxGettime=t2-t1;
   }
     
 /* new log */
-  index=smiLogBuf->index;
+int numberOfEntries;
+     numberOfEntries=__sync_fetch_and_add(&(smiLogBuf->numberOfEntries),0);	        
+//  index=smiLogBuf->index;
+  index=__sync_fetch_and_add(&(smiLogBuf->index),0);	        
   if (SMI_LOG_BUF_SIZE>0) {
    smiLogBuf->smiLogEntry[index].smiIteration=shm->numberOfSMIIterations;  
    smiLogBuf->smiLogEntry[index].time=GETTIME_MS;
@@ -324,14 +341,18 @@ if (t2-t1>maxGettime) maxGettime=t2-t1;
     (unsigned char*)logFilter,
     shm->numberOfCurrentLeafStates*sizeof(unsigned char));    
   }
-  if (smiLogBuf->numberOfEntries<SMI_LOG_BUF_SIZE) {
-   smiLogBuf->numberOfEntries+=1;
+  if (numberOfEntries<SMI_LOG_BUF_SIZE) {
+//   smiLogBuf->numberOfEntries+=1;
+  __sync_fetch_and_add(&(smiLogBuf->numberOfEntries),1);
+   numberOfEntries++;
   }
   index++;
   if (index>=SMI_LOG_BUF_SIZE) {
     index=0;
   }	
-  smiLogBuf->index=index;
+//  smiLogBuf->index=index;
+     __sync_fetch_and_add(&(smiLogBuf->index),
+      index-__sync_fetch_and_add(&(smiLogBuf->index),0));	        
 /* end new log */
 
   eventVar.eventQueue[0]=PULSE_E;
@@ -395,7 +416,12 @@ if (atomicStateVariables[i].stateID==15) {
     } 
     
   if (shm->numberOfCurrentLeafStates>maxNumberOfConcurrentStates) maxNumberOfConcurrentStates=shm->numberOfCurrentLeafStates;
-  shm->numberOfSMIIterations=shm->numberOfSMIIterations+1;
+//  shm->numberOfSMIIterations=shm->numberOfSMIIterations+1;
+  __sync_fetch_and_add(&(shm->numberOfSMIIterations),1);
+  __sync_fetch_and_add(&(shm->smiLock),
+	 __sync_fetch_and_add(&(shm->numberOfSMIIterations),0)
+	 -__sync_fetch_and_add(&(shm->smiLock),0));
+//rt_printf("out=%d ",  __sync_fetch_and_add(&(shm->smiLock),0));
 }
 
 void visitStates(stateIDType superstate) {
@@ -498,8 +524,8 @@ printf("transition\n");
     shm->taskStateSysVar[atomicStateVariables[i].taskStateVar].flags&=~(TASK_EXIT);    
 //    shm->taskStateSysVar[atomicStateVariables[i].taskStateVar].exclusive=        
 //      taskData[atomicStateVariables[i].taskID].exclusive;  
-    shm->taskStateSysVar[atomicStateVariables[i].taskStateVar].oneShot=        
-      taskData[atomicStateVariables[i].taskID].oneShot;  
+//    shm->taskStateSysVar[atomicStateVariables[i].taskStateVar].oneShot=        
+//      taskData[atomicStateVariables[i].taskID].oneShot;  
     shm->taskState[atomicStateVariables[i].taskStateVar].duration=
      taskData[atomicStateVariables[i].taskID].duration;      
 //    shm->taskStateSysVar[atomicStateVariables[i].taskStateVar].oneShot=
diff --git a/smi/src/smi_def.h b/smi/src/smi_def.h
index da9d547..379830d 100644
--- a/smi/src/smi_def.h
+++ b/smi/src/smi_def.h
@@ -64,11 +64,13 @@ 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 flags;  
   taskIDType taskID;
   processType process;
   signed char nrt;
-  signed char oneShot; 
+//  signed char oneShot; 
   unsigned char numberOfDataPorts;
   dataPathIDType dataPort[MAX_NUMBER_OF_DATA_PORTS_PER_STATE];
 } taskStateSysVarStruct;
diff --git a/smi/src/smi_nrt.c b/smi/src/smi_nrt.c
index b3eb060..92820bf 100644
--- a/smi/src/smi_nrt.c
+++ b/smi/src/smi_nrt.c
@@ -364,7 +364,8 @@ printf("[parseESM] transitionID=%d ",shm->transitionID);
         }
         if (ret==1) {
           printf("[parseESM] line=%d tokens: ",lineNumber); 
-          for (i=0;i<numberBufferSize;i++) printf("%d ",numberBuffer[i]); printf("\n"); 
+          for (i=0;i<numberBufferSize;i++) printf("%d ",numberBuffer[i]); 
+          printf("\n"); 
           break;
         }
       }
diff --git a/smi/src/taskdisp_nrt.c b/smi/src/taskdisp_nrt.c
index c2f26db..9a2b2eb 100644
--- a/smi/src/taskdisp_nrt.c
+++ b/smi/src/taskdisp_nrt.c
@@ -1,4 +1,5 @@
 #include <stdlib.h>
+#include <string.h>
 #include <stdio.h>
 #include <unistd.h>
 #include <sys/resource.h>
@@ -175,9 +176,13 @@ void exitNrtTaskDispatcher(void) {
 }
 
 void nrtTaskDispatcher(int nrtProcessID) {
-	int i;
+	int i,j;
 	int n;
-	static unsigned int numberOfSMIIterations=0;
+//	static unsigned int numberOfSMIIterations=0;
+        unsigned int numberOfSMIIterations;
+        taskStateStruct taskStateTmp;
+        taskStateSysVarStruct taskStateSysVarTmp;
+        
 /*
 for (i=0;i<shm->numberOfTaskStates;i++) {
 printf("%d_%d_%d_%d_%d ",i,shm->taskStateSysVar[i].flags,shm->taskStateSysVar[i].taskID,shm->taskStateSysVar[i].process,shm->taskStateSysVar[i].nrt);fflush(stdout);
@@ -192,14 +197,34 @@ usleep(10000);
 //{printf("%d_%d ",shm->taskStateSysVar[i].flags,shm->taskStateSysVar[i].taskID);fflush(stdout);usleep(10000);}	
 	  n=shm->taskStateSysVar[i].process;
 	  if (n==nrtProcessID) {
-	   if ((shm->taskStateSysVar[i].flags&TASK_EXEC)!=0
-	    && ((shm->taskStateSysVar[i].oneShot==0
+
+           unsigned int smiLock;
+           
+           smiLock=0;
+           while (smiLock==0)
+           {
+            smiLock=__sync_fetch_and_add(&(shm->smiLock),0);          
+            if (smiLock!=0) { 
+	     memcpy((unsigned char*)&taskStateTmp,
+              (unsigned char*)&(shm->taskState[i]),
+              sizeof(taskStateStruct));	  
+	     memcpy((unsigned char*)&taskStateSysVarTmp,
+              (unsigned char*)&(shm->taskStateSysVar[i]),
+              sizeof(taskStateSysVarStruct));
+            }             
+            if (smiLock==0 || smiLock!=__sync_fetch_and_add(&(shm->smiLock),0)) {
+             usleep(STD_SLEEP);	                           
+            } else smiLock=1;
+           } 
+	  
+	   if ((taskStateSysVarTmp.flags&TASK_EXEC)!=0
+/*	    && ((shm->taskStateSysVar[i].oneShot==0
 	      || (shm->taskStateSysVar[i].flags&TASK_EXIT)==0
 	     )
-	    ) 
+	    ) */
 	   ) {
-	    shm->taskStateSysVar[i].flags|=TASK_ACTIVE;
-	    shm->taskStateSysVar[i].flags&=~(TASK_BUSY);        
+//	    shm->taskStateSysVar[i].flags|=TASK_ACTIVE;
+//	    shm->taskStateSysVar[i].flags&=~(TASK_BUSY);        
 //	    dataPathPointer[0]=NULL;
 /*printf("nrt: execTask stateID=%d taskID=%d nrtProcessID=%d dt=%d\n",
  shm->taskState[i].stateID,
@@ -209,16 +234,24 @@ usleep(10000);
 */
 //printf("%d\n",shm->taskStateSysVar[i].taskID);
 //if (nrtProcessID==1) {printf("!");fflush(stdout);usleep(100000);}
-	    execTask(&shm->taskState[i],&shm->taskStateSysVar[i],shm->taskStateSysVar[i].taskID);
+	    execTask(&taskStateTmp,&taskStateSysVarTmp,taskStateSysVarTmp.taskID);
 //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_ACTIVE);
 //	    shm->taskStateSysVar[i].flags&=~(TASK_EXEC);	    
-	    shm->taskStateSysVar[i].flags|=TASK_EXIT;
+            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);          
+
+//	    shm->taskStateSysVar[i].flags|=TASK_EXIT;
 //	    shm->t3=shm->reftime;
 //	    shm->taskStateSysVar[i].flags&=~(TASK_SMI);	    	   
-	    numberOfSMIIterations=shm->numberOfSMIIterations;
+//	    numberOfSMIIterations=shm->numberOfSMIIterations;
+            numberOfSMIIterations=__sync_fetch_and_add(&(shm->numberOfSMIIterations),0);	    
 //	    while ((shm->taskStateSysVar[i].flags&TASK_SMI)==0 && shm->run!=0) 
-	    while (numberOfSMIIterations==shm->numberOfSMIIterations && shm->run!=0) 
+//	    while (numberOfSMIIterations==shm->numberOfSMIIterations && shm->run!=0) 
+	    while (numberOfSMIIterations==__sync_fetch_and_add(&(shm->numberOfSMIIterations),0) && shm->run!=0) 	    
 	    {
 //if (nrtProcessID==0) {printf("%d ",shm->taskStateSysVar[i].flags);fflush(stdout);}
 		usleep(STD_SLEEP);	   
-- 
GitLab