SDOCM00104043 MessageQ_open() returns not found 3.00.03.27_eng 3.00.03.28
authorRamsey Harris <ramsey@ti.com>
Tue, 1 Oct 2013 00:09:50 +0000 (17:09 -0700)
committerChris Ring <cring@ti.com>
Tue, 1 Oct 2013 01:02:24 +0000 (18:02 -0700)
Concurrency issues in NameServerRemoteNotify caused message corruption
which resulted in keys not being found. Fixed by moving state variables
from message to object state and by splitting existing swi into two
separate ones, one for request and one for response. Updated ROV.

packages/ti/sdo/ipc/nsremote/NameServerRemoteNotify.c
packages/ti/sdo/ipc/nsremote/NameServerRemoteNotify.xdc
packages/ti/sdo/ipc/nsremote/NameServerRemoteNotify.xs

index 609c824737296ba8e765a5721b09a6fbc7b7a8db..92e45621df3e833d0301c25399291cf6909b8923 100644 (file)
         ti_sdo_ipc_nsremote_NameServerRemoteNotify_notifyEventId + \
                     (UInt32)((UInt32)Notify_SYSTEMKEY << 16)
 
+/* private constant values */
+#define NameServerRemoteNotify_RequestMsg       1
+#define NameServerRemoteNotify_ResponseMsg      2
+
 /*
  *************************************************************************
  *                       Instance functions
  *************************************************************************
  */
 Int NameServerRemoteNotify_Instance_init(NameServerRemoteNotify_Object *obj,
-        UInt16 remoteProcId,
-        const NameServerRemoteNotify_Params *params,
+        UInt16 remoteProcId, const NameServerRemoteNotify_Params *params,
         Error_Block *eb)
 {
     Int               offset = 0;
     Int               status;
     Semaphore_Params  semParams;
-    Semaphore_Handle  semRemoteWait;
-    Semaphore_Handle  semMultiBlock;
-    Swi_Handle        swiHandle;
+    Semaphore_Handle  semHandle;
     Swi_Params        swiParams;
+    Swi_Handle        swiHandle;
 
     /* Assert that a NameServerRemoteNotify_Params has been supplied */
     Assert_isTrue(params != NULL, Ipc_A_nullArgument);
@@ -96,15 +98,18 @@ Int NameServerRemoteNotify_Instance_init(NameServerRemoteNotify_Object *obj,
     }
 
     obj->regionId = SharedRegion_getId(params->sharedAddr);
+    obj->localState = NameServerRemoteNotify_IDLE;
+    obj->remoteState = NameServerRemoteNotify_IDLE;
 
-    /* Assert that sharedAddr is cache aligned */
+    /* assert that sharedAddr is cache aligned */
     Assert_isTrue(((UInt32)params->sharedAddr %
-                  SharedRegion_getCacheLineSize(obj->regionId) == 0),
-                  Ipc_A_addrNotCacheAligned);
+            SharedRegion_getCacheLineSize(obj->regionId) == 0),
+            Ipc_A_addrNotCacheAligned);
 
-    semRemoteWait = NameServerRemoteNotify_Instance_State_semRemoteWait(obj);
-    semMultiBlock = NameServerRemoteNotify_Instance_State_semMultiBlock(obj);
-    swiHandle = NameServerRemoteNotify_Instance_State_swiObj(obj);
+    /* asset message structure size is cache aligned */
+    Assert_isTrue((sizeof(NameServerRemoteNotify_Message) %
+            SharedRegion_getCacheLineSize(obj->regionId)) == 0,
+            NameServerRemoteNotify_A_messageSize);
 
     obj->msg[0] = (NameServerRemoteNotify_Message *)(params->sharedAddr);
     obj->msg[1] = (NameServerRemoteNotify_Message *)((UInt32)obj->msg[0] +
@@ -112,24 +117,35 @@ Int NameServerRemoteNotify_Instance_init(NameServerRemoteNotify_Object *obj,
     obj->gate = params->gate;
     obj->remoteProcId = remoteProcId;
 
-    /* construct the semaphore */
+    /* construct the remoteWait semaphore */
+    semHandle = NameServerRemoteNotify_Instance_State_semRemoteWait(obj);
     Semaphore_Params_init(&semParams);
-    Semaphore_construct(Semaphore_struct(semRemoteWait), 0, &semParams);
+    Semaphore_construct(Semaphore_struct(semHandle), 0, &semParams);
 
-    /* construct the semaphore */
-    Semaphore_construct(Semaphore_struct(semMultiBlock), 1, &semParams);
+    /* construct the multiBlock semaphore */
+    semHandle = NameServerRemoteNotify_Instance_State_semMultiBlock(obj);
+    Semaphore_Params_init(&semParams);
+    Semaphore_construct(Semaphore_struct(semHandle), 1, &semParams);
 
-    /* swi created with lowest priority and fxn = swiFxn */
+    /* construct swi which handles the request message */
+    swiHandle = NameServerRemoteNotify_Instance_State_swiRequest(obj);
     Swi_Params_init(&swiParams);
     swiParams.arg0 = (UArg)obj;
-    swiParams.priority = 0;
+    swiParams.priority = 0; /* lowest priority */
     Swi_construct(Swi_struct(swiHandle),
-                 (ti_sysbios_knl_Swi_FuncPtr)NameServerRemoteNotify_swiFxn,
-                 &swiParams, eb);
+             (ti_sysbios_knl_Swi_FuncPtr)NameServerRemoteNotify_swiFxnRequest,
+             &swiParams, eb);
+
+    /* construct swi which handles the response message */
+    swiHandle = NameServerRemoteNotify_Instance_State_swiResponse(obj);
+    Swi_Params_init(&swiParams);
+    swiParams.arg0 = (UArg)obj;
+    swiParams.priority = 0; /* lowest priority */
+    Swi_construct(Swi_struct(swiHandle),
+             (ti_sysbios_knl_Swi_FuncPtr)NameServerRemoteNotify_swiFxnResponse,
+             &swiParams, eb);
 
     /* initialize own side of message struct only */
-    obj->msg[offset]->request = 0;
-    obj->msg[offset]->response = 0;
     obj->msg[offset]->requestStatus = 0;
     obj->msg[offset]->value = 0;
     obj->msg[offset]->valueLen = 0;
@@ -147,13 +163,10 @@ Int NameServerRemoteNotify_Instance_init(NameServerRemoteNotify_Object *obj,
                     Cache_Type_ALL, TRUE);
     }
 
-    /* register the call back function and event Id with notify */
-    status = Notify_registerEventSingle(
-                remoteProcId,
-                0,
-                NameServerRemoteNotify_notifyEventId,
-                (Notify_FnNotifyCbck)NameServerRemoteNotify_cbFxn,
-                (UArg)swiHandle);
+    /* register notify callback function to handle message notifications */
+    status = Notify_registerEventSingle(remoteProcId, 0,
+            NameServerRemoteNotify_notifyEventId,
+            (Notify_FnNotifyCbck)NameServerRemoteNotify_cbFxn, (UArg)obj);
 
     /* if not successful return */
     if (status < 0) {
@@ -171,11 +184,10 @@ Int NameServerRemoteNotify_Instance_init(NameServerRemoteNotify_Object *obj,
 /*
  *  ======== NameServerRemoteNotify_Instance_finalize ========
  */
-Void NameServerRemoteNotify_Instance_finalize(NameServerRemoteNotify_Object *obj,
-    Int status)
+Void NameServerRemoteNotify_Instance_finalize(
+        NameServerRemoteNotify_Object *obj, Int status)
 {
-    Semaphore_Handle  semRemoteWait;
-    Semaphore_Handle  semMultiBlock;
+    Semaphore_Handle  semHandle;
     Swi_Handle        swiHandle;
 
     if (status == 0) {
@@ -183,23 +195,26 @@ Void NameServerRemoteNotify_Instance_finalize(NameServerRemoteNotify_Object *obj
         ti_sdo_utils_NameServer_unregisterRemoteDriver(obj->remoteProcId);
 
         /* unregister event from Notify module */
-        Notify_unregisterEventSingle(
-                       obj->remoteProcId,
-                       0,
-                       NameServerRemoteNotify_notifyEventId);
+        Notify_unregisterEventSingle(obj->remoteProcId, 0,
+                NameServerRemoteNotify_notifyEventId);
     }
 
-    semRemoteWait = NameServerRemoteNotify_Instance_State_semRemoteWait(obj);
-    if (semRemoteWait != NULL) {
-        Semaphore_destruct(Semaphore_struct(semRemoteWait));
+    semHandle = NameServerRemoteNotify_Instance_State_semRemoteWait(obj);
+    if (semHandle != NULL) {
+        Semaphore_destruct(Semaphore_struct(semHandle));
     }
 
-    semMultiBlock = NameServerRemoteNotify_Instance_State_semMultiBlock(obj);
-    if (semMultiBlock != NULL) {
-        Semaphore_destruct(Semaphore_struct(semMultiBlock));
+    semHandle = NameServerRemoteNotify_Instance_State_semMultiBlock(obj);
+    if (semHandle != NULL) {
+        Semaphore_destruct(Semaphore_struct(semHandle));
+    }
+
+    swiHandle = NameServerRemoteNotify_Instance_State_swiRequest(obj);
+    if (swiHandle != NULL) {
+        Swi_destruct(Swi_struct(swiHandle));
     }
 
-    swiHandle = NameServerRemoteNotify_Instance_State_swiObj(obj);
+    swiHandle = NameServerRemoteNotify_Instance_State_swiResponse(obj);
     if (swiHandle != NULL) {
         Swi_destruct(Swi_struct(swiHandle));
     }
@@ -249,18 +264,32 @@ Int NameServerRemoteNotify_attach(UInt16 remoteProcId, Ptr sharedAddr)
 /*
  *  ======== NameServerRemoteNotify_cbFxn ========
  */
-Void NameServerRemoteNotify_cbFxn(UInt16 procId,
-                                  UInt16 lineId,
-                                  UInt32 eventId,
-                                  UArg arg,
-                                  UInt32 payload)
+Void NameServerRemoteNotify_cbFxn(UInt16 procId, UInt16 lineId, UInt32 eventId,
+        UArg arg, UInt32 payload)
 {
+    NameServerRemoteNotify_Object *obj;
     Swi_Handle swiHandle;
 
-    /* Swi_Handle was passed as arg in register */
-    swiHandle = (Swi_Handle)arg;
+    obj = (NameServerRemoteNotify_Object *)arg;
+
+
+    switch (payload)
+    {
+        case NameServerRemoteNotify_RequestMsg:
+            swiHandle = NameServerRemoteNotify_Instance_State_swiRequest(obj);
+
+            /* set object state (used by ROV) */
+            obj->remoteState = NameServerRemoteNotify_RECEIVE_REQUEST;
+            break;
+
+        case NameServerRemoteNotify_ResponseMsg:
+            swiHandle = NameServerRemoteNotify_Instance_State_swiResponse(obj);
+
+            /* set object state (used by ROV) */
+            obj->localState = NameServerRemoteNotify_RECEIVE_RESPONSE;
+            break;
+    }
 
-    /* post the Swi */
     Swi_post(swiHandle);
 }
 
@@ -293,24 +322,18 @@ Int NameServerRemoteNotify_detach(UInt16 remoteProcId)
  *  ======== NameServerRemoteNotify_get ========
  */
 Int NameServerRemoteNotify_get(NameServerRemoteNotify_Object *obj,
-                               String instanceName,
-                               String name,
-                               Ptr value,
-                               UInt32 *valueLen,
-                               ISync_Handle syncHandle,
-                               Error_Block *eb)
+        String instanceName, String name, Ptr value, UInt32 *valueLen,
+        ISync_Handle syncHandle, Error_Block *eb)
 {
     Int len;
     Int retval = NameServer_E_NOTFOUND;
     Int offset = 0;
     Int status;
     Int notifyStatus;
-    IArg key;
     Semaphore_Handle semRemoteWait;
     Semaphore_Handle semMultiBlock;
 
-    Assert_isTrue(*valueLen <= 300,
-                      NameServerRemoteNotify_A_invalidValueLen);
+    Assert_isTrue(*valueLen <= 300, NameServerRemoteNotify_A_invalidValueLen);
 
     semRemoteWait = NameServerRemoteNotify_Instance_State_semRemoteWait(obj);
     semMultiBlock = NameServerRemoteNotify_Instance_State_semMultiBlock(obj);
@@ -319,7 +342,7 @@ Int NameServerRemoteNotify_get(NameServerRemoteNotify_Object *obj,
     Semaphore_pend(semMultiBlock, BIOS_WAIT_FOREVER);
 
     if (MultiProc_self() > obj->remoteProcId) {
-            offset = 1;
+        offset = 1;
     }
 
     if (obj->cacheEnable) {
@@ -328,12 +351,7 @@ Int NameServerRemoteNotify_get(NameServerRemoteNotify_Object *obj,
                   Cache_Type_ALL, TRUE);
     }
 
-    /* enter gate so nobody can be modifying message in shared memory */
-    key = GateMP_enter((GateMP_Handle)obj->gate);
-
     /* this is a request message */
-    obj->msg[offset]->request = 1;
-    obj->msg[offset]->response = 0;
     obj->msg[offset]->requestStatus = 0;
     obj->msg[offset]->valueLen = *valueLen;
 
@@ -345,6 +363,9 @@ Int NameServerRemoteNotify_get(NameServerRemoteNotify_Object *obj,
     len = strlen(name);
     strncpy((Char *)obj->msg[offset]->name, name, len + 1);
 
+    /* set object state (used by ROV) */
+    obj->localState = NameServerRemoteNotify_SEND_REQUEST;
+
     if (obj->cacheEnable) {
         Cache_wbInv(obj->msg[offset], sizeof(NameServerRemoteNotify_Message),
                     Cache_Type_ALL, TRUE);
@@ -354,19 +375,12 @@ Int NameServerRemoteNotify_get(NameServerRemoteNotify_Object *obj,
      *  Send the notification to remote processor. Do not wait here since
      *  we hold the GateMP.
      */
-    notifyStatus = Notify_sendEvent(
-                       obj->remoteProcId,
-                       0,
-                       NameServerRemoteNotify_notifyEventId,
-                       0,
-                       FALSE);
-
-    /* now we can leave the gate after we send the notification */
-    GateMP_leave((GateMP_Handle)obj->gate, key);
+    notifyStatus = Notify_sendEvent(obj->remoteProcId, 0,
+            NameServerRemoteNotify_notifyEventId,
+            NameServerRemoteNotify_RequestMsg, TRUE);
 
     if (notifyStatus < 0) {
         /* undo previous options */
-        obj->msg[offset]->request = 0;
         obj->msg[offset]->valueLen = 0;
 
         /* post the semaphore to make sure it doesn't block */
@@ -383,18 +397,14 @@ Int NameServerRemoteNotify_get(NameServerRemoteNotify_Object *obj,
     }
     else {
         /* getting here means we got the notification back */
-        /* enter gate so nobody can be modifying message in shared memory */
-        key = GateMP_enter((GateMP_Handle)obj->gate);
 
         if (obj->cacheEnable) {
             Cache_inv(obj->msg[offset], sizeof(NameServerRemoteNotify_Message),
-                      Cache_Type_ALL, TRUE);
+                    Cache_Type_ALL, TRUE);
         }
 
         /* if successful request then copy to value */
         if (obj->msg[offset]->requestStatus == TRUE) {
-            /* clear out requestStatus */
-            obj->msg[offset]->requestStatus = FALSE;
 
             /* copy to value */
             if (obj->msg[offset]->valueLen == sizeof(UInt32)) {
@@ -412,18 +422,8 @@ Int NameServerRemoteNotify_get(NameServerRemoteNotify_Object *obj,
             retval = NameServer_S_SUCCESS;
         }
 
-        /* clear out the request and response flags */
-        obj->msg[offset]->request  = 0;
-        obj->msg[offset]->response = 0;
-
-        if (obj->cacheEnable) {
-            Cache_wbInv(obj->msg[offset],
-                        sizeof(NameServerRemoteNotify_Message),
-                        Cache_Type_ALL, TRUE);
-        }
-
-        /*  Now we can leave the gate after we send the notification */
-        GateMP_leave((GateMP_Handle)obj->gate, key);
+        /* set object state (used by ROV) */
+        obj->localState = NameServerRemoteNotify_IDLE;
     }
 
     Semaphore_post(semMultiBlock);
@@ -448,14 +448,13 @@ SizeT NameServerRemoteNotify_sharedMemReq(Ptr sharedAddr)
 }
 
 /*
- *  ======== NameServerRemoteNotify_swiFxn ========
+ *  ======== NameServerRemoteNotify_swiFxnRequest ========
  */
-Void NameServerRemoteNotify_swiFxn(UArg arg)
+Void NameServerRemoteNotify_swiFxnRequest(UArg arg)
 {
     Int count = NameServer_E_FAIL;
-    Int offset = 0;
+    Int remoteId;
     UInt32 valueLen;
-    IArg key;
     NameServer_Handle handle;
     NameServerRemoteNotify_Object *obj;
 #ifndef xdc_runtime_Assert_DISABLE_ALL
@@ -464,83 +463,76 @@ Void NameServerRemoteNotify_swiFxn(UArg arg)
 
     obj = (NameServerRemoteNotify_Object *)arg;
 
-    if (MultiProc_self() > obj->remoteProcId) {
-        offset = 1;
-    }
+    /* compute index to remote message */
+    remoteId = (MultiProc_self() > obj->remoteProcId) ? 0 : 1;
 
     if (obj->cacheEnable) {
-        /* invalidate both request and response messages */
-        Cache_inv(obj->msg[0],
-                  sizeof(NameServerRemoteNotify_Message) << 1,
-                  Cache_Type_ALL, TRUE);
+        Cache_inv(obj->msg[remoteId], sizeof(NameServerRemoteNotify_Message),
+                Cache_Type_ALL, TRUE);
     }
 
-    /* in case of request */
-    if (obj->msg[1 - offset]->request == TRUE) {
-        /* get the NameServer handle */
-        handle = NameServer_getHandle(
-                     (String)obj->msg[1 - offset]->instanceName);
-        valueLen = obj->msg[1 - offset]->valueLen;
+    /* get the NameServer handle */
+    handle = NameServer_getHandle((String)obj->msg[remoteId]->instanceName);
+    valueLen = obj->msg[remoteId]->valueLen;
 
-        if (handle != NULL) {
-            /* Search for the NameServer entry */
-            if (valueLen == sizeof(UInt32)) {
-                count = NameServer_getLocalUInt32(handle,
-                    (String)obj->msg[1 - offset]->name,
-                    &obj->msg[1 - offset]->value);
-            }
-            else {
-                count = NameServer_getLocal(handle,
-                    (String)obj->msg[1 - offset]->name,
-                    &obj->msg[1 - offset]->valueBuf, &valueLen);
-            }
+    if (handle != NULL) {
+        /* Search for the NameServer entry */
+        if (valueLen == sizeof(UInt32)) {
+            count = NameServer_getLocalUInt32(handle,
+                (String)obj->msg[remoteId]->name, &obj->msg[remoteId]->value);
         }
-
-        /* enter gate so nobody can be modifying message in shared memory */
-        key = GateMP_enter((GateMP_Handle)obj->gate);
-
-        /*
-         *  If an entry was found, set requestStatus to TRUE
-         *  and valueLen to the size of data that was copied.
-         */
-        if (count == NameServer_S_SUCCESS) {
-            obj->msg[1 - offset]->requestStatus = TRUE;
-            obj->msg[1 - offset]->valueLen = valueLen;
+        else {
+            count = NameServer_getLocal(handle,
+                (String)obj->msg[remoteId]->name,
+                &obj->msg[remoteId]->valueBuf, &valueLen);
         }
+    }
 
-        /* Send a response back */
-        obj->msg[1 - offset]->response = TRUE;
-        obj->msg[1 - offset]->request = FALSE;
+    /*
+     *  If an entry was found, set requestStatus to TRUE
+     *  and valueLen to the size of data that was copied.
+     */
+    if (count == NameServer_S_SUCCESS) {
+        obj->msg[remoteId]->requestStatus = TRUE;
+        obj->msg[remoteId]->valueLen = valueLen;
+    }
 
-        if (obj->cacheEnable) {
-            Cache_wbInv(obj->msg[1 - offset],
-                        sizeof(NameServerRemoteNotify_Message),
-                        Cache_Type_ALL, TRUE);
-        }
+    /* set object state (used by ROV) */
+    obj->remoteState = NameServerRemoteNotify_SEND_RESPONSE;
 
-        /* now we can leave the gate */
-        GateMP_leave((GateMP_Handle)obj->gate, key);
+    if (obj->cacheEnable) {
+        Cache_wbInv(obj->msg[remoteId], sizeof(NameServerRemoteNotify_Message),
+                Cache_Type_ALL, TRUE);
+    }
 
-        /*
-         *  The Notify line must be active at this point for this processor to
-         *  have received a request.  Do not wait here since we are in a Swi.
-         */
+    /* must wait to prevent dropped events, even though this is a swi */
 #ifndef xdc_runtime_Assert_DISABLE_ALL
-        status =
+    status =
 #endif
-        Notify_sendEvent(obj->remoteProcId,
-                0, NameServerRemoteNotify_notifyEventId, 0, FALSE);
-        /* The NS query could fail, but the reply should never fail */
-        Assert_isTrue(status >= 0, Ipc_A_internal);
+    Notify_sendEvent(obj->remoteProcId, 0,
+            NameServerRemoteNotify_notifyEventId,
+            NameServerRemoteNotify_ResponseMsg, TRUE);
 
-    }
+    /* The NS query could fail, but the reply should never fail */
+    Assert_isTrue(status >= 0, Ipc_A_internal);
 
-    /* in case of response */
-    if (obj->msg[offset]->response == TRUE) {
-        /* post the Semaphore */
-        Semaphore_post(
-            NameServerRemoteNotify_Instance_State_semRemoteWait(obj));
-    }
+    /* set object state (used by ROV) */
+    obj->remoteState = NameServerRemoteNotify_IDLE;
+}
+
+/*
+ *  ======== NameServerRemoteNotify_swiFxnResponse ========
+ */
+Void NameServerRemoteNotify_swiFxnResponse(UArg arg)
+{
+    NameServerRemoteNotify_Object *obj;
+    Semaphore_Handle  sem;
+
+    obj = (NameServerRemoteNotify_Object *)arg;
+
+    /* post the semaphore to unblock waiting task */
+    sem = NameServerRemoteNotify_Instance_State_semRemoteWait(obj);
+    Semaphore_post(sem);
 }
 
 /*
index 5e44939a1dba011e4bdd1e44e2c58f8c2aec00f8..1822f9140b84d835c6bfecfd3103da291bfd736d 100644 (file)
@@ -92,14 +92,12 @@ module NameServerRemoteNotify inherits INameServerRemote
 
     /* structure in shared memory for retrieving value */
     struct Message {
-        Bits32  request;            /* if this is a request set to 1    */
-        Bits32  response;           /* if this is a response set to 1   */
         Bits32  requestStatus;      /* if request sucessful set to 1    */
         Bits32  value;              /* holds value if len <= 4          */
         Bits32  valueLen;           /* len of value                     */
         Bits32  instanceName[8];    /* name of NameServer instance      */
         Bits32  name[8];            /* name of NameServer entry         */
-        Bits32  valueBuf[75];       /* supports up to 300-byte value    */
+        Bits32  valueBuf[77];       /* padded to fill 128-B cache line  */
     };
 
     /*!
@@ -108,6 +106,15 @@ module NameServerRemoteNotify inherits INameServerRemote
     config xdc.runtime.Assert.Id A_invalidValueLen =
         {msg: "A_invalidValueLen: Invalid valueLen (too large)"};
 
+    /*!
+     *  Message structure size is not aligned on cache line size.
+     *
+     *  The message structure size must be an exact multiple of the
+     *  cache line size.
+     */
+    config xdc.runtime.Assert.Id A_messageSize =
+        {msg: "A_messageSize: message size not aligned with cache line size."};
+
     /*!
      *  ======== notifyEventId ========
      *  The Notify event ID.
@@ -174,22 +181,48 @@ internal:
                UInt32 payload);
 
     /*!
-     *  ======== swiFxn ========
-     *  The swi function that will be executed during the call back.
+     *  ======== swiFxnRequest ========
+     *  The swi function which handles a request message
      *
-     *  @param(arg)     argument to swi function
+     *  @param(arg)     pointer to the instance object
      */
-    Void swiFxn(UArg arg);
+    Void swiFxnRequest(UArg arg);
+
+    /*!
+     *  ======== swiFxnResponse ========
+     *  The swi function that which handles a response message
+     *
+     *  @param(arg)     pointer to the instance object
+     */
+    Void swiFxnResponse(UArg arg);
+
+    /*! no pending messages */
+    const UInt8 IDLE = 0;
+
+    /*! sending a request message to another processor */
+    const UInt8 SEND_REQUEST = 1;
+
+    /*! receiving a response message (in reply to a sent request) */
+    const UInt8 RECEIVE_RESPONSE = 2;
+
+    /*! receiving a request from a remote processor (unsolicited message) */
+    const UInt8 RECEIVE_REQUEST = 1;
+
+    /*! sending a response message (in reply to a received request) */
+    const UInt8 SEND_RESPONSE = 2;
 
     /* instance state */
     struct Instance_State {
         Message             *msg[2];        /* Ptrs to messages in shared mem */
         UInt16              regionId;       /* SharedRegion ID                */
+        UInt8               localState;     /* state of local message         */
+        UInt8               remoteState;    /* state of remote message        */
         GateMP.Handle       gate;           /* remote and local gate protect  */
-        Semaphore.Object    semRemoteWait;  /* sem to wait on remote proc     */
-        Semaphore.Object    semMultiBlock;  /* sem to block multiple threads  */
-        Swi.Object          swiObj;         /* instance swi object            */
         UInt16              remoteProcId;   /* remote MultiProc id            */
         Bool                cacheEnable;    /* cacheability                   */
+        Semaphore.Object    semRemoteWait;  /* sem to wait on remote proc     */
+        Semaphore.Object    semMultiBlock;  /* sem to block multiple threads  */
+        Swi.Object          swiRequest;     /* handle a request message       */
+        Swi.Object          swiResponse;    /* handle a response message      */
     };
 }
index fdf7f9bce71c45e5c58100ac8ad0faa180b5da06..985b5b3960751b4becb8ae94df97a7953c36391f 100644 (file)
@@ -130,102 +130,113 @@ function viewInitBasic(view, obj)
     }
     catch(e) {
         Program.displayError(view, 'remoteProcName',
-                             "Problem retrieving proc name: " + e);
+                "Problem retrieving proc name: " + e);
     }
 
     if (MultiProc.self$view() > obj.remoteProcId) {
-        var offset = 1;
+        var localId = 1;
+        var remoteId = 0;
     }
     else {
-        var offset = 0;
+        var localId = 0;
+        var remoteId = 1;
     }
-    var localId = offset;
-    var remoteId = 1 - offset;
 
+    /*
+     *  process local message state
+     */
     try {
-        var localMsg = Program.fetchStruct(
-                NSRN.Message$fetchDesc,
-                $addr(obj.msg[localId])); /* msg[0] belongs to local core */
+        var localMsg = Program.fetchStruct(NSRN.Message$fetchDesc,
+                $addr(obj.msg[localId]));
     }
     catch(e) {
-        Program.displayError(view, "localRequestStatus", "Problem " +
-            "retrieving local request status ");
+        Program.displayError(view, "localRequestStatus",
+                "Problem retrieving local request status");
         return;
     }
 
-    if (localMsg.request == 1 || localMsg.response == 1) {
-        if (localMsg.request == 1) {
-            /* Request */
-            view.localRequestStatus = "Receiving a request";
-        }
-        else {
-            /* Response */
-            view.localRequestStatus = "Sending a response ";
-            if (localMsg.requestStatus == 1) {
-                view.localRequestStatus += "(found)";
-                if (localMsg.valueLen <= 4) {
-                    view.localValue = "0x" +
-                        Number(localMsg.value).toString(16);
-                }
-                else {
-                    view.localValue = "Value at 0x" +
-                        Number(Number(obj.msg[localId]) +
-                        NSRN.Message.$offsetof("valueBuf")).toString(16);
-                }
-            }
-            else {
-                view.localRequestStatus += "(not found)";
-            }
-        }
+    view.localValue = "";
 
+    if (obj.localState == NSRN.IDLE) {
+        view.localRequestStatus = "Idle";
+        view.localInstanceName = "";
+        view.localName = "";
+    }
+    else {
         view.localInstanceName = fetchString(obj.msg[localId], "instanceName");
         view.localName = fetchString(obj.msg[localId], "name");
     }
-    else {
-        view.localRequestStatus = "Idle";
+
+    if (obj.localState == NSRN.SEND_REQUEST) {
+        view.localRequestStatus = "Sending a request";
+    }
+
+    if (obj.localState == NSRN.RECEIVE_RESPONSE) {
+        view.localRequestStatus = "Receiving a response";
+
+        if (localMsg.requestStatus == 1) {
+            view.localRequestStatus += " (found)";
+
+            if (localMsg.valueLen <= 4) {
+                view.localValue = "0x"+Number(localMsg.value).toString(16);
+            }
+            else {
+                view.localValue = "Value at 0x" +
+                    Number(Number(obj.msg[localId]) +
+                    NSRN.Message.$offsetof("valueBuf")).toString(16);
+            }
+        }
+        else {
+            view.localRequestStatus += " (not found)";
+        }
     }
 
+    /*
+     *  process remote message state
+     */
     try {
-        var remoteMsg = Program.fetchStruct(
-                NSRN.Message$fetchDesc,
+        var remoteMsg = Program.fetchStruct(NSRN.Message$fetchDesc,
                 $addr(obj.msg[remoteId]));
     }
     catch(e) {
-        Program.displayError(view, "localRequestStatus", "Problem " +
-            "retrieving remote request status ");
+        Program.displayError(view, "localRequestStatus",
+                "Problem retrieving remote request status");
         return;
     }
 
-    if (remoteMsg.request == 1 || remoteMsg.response == 1) {
-        if (remoteMsg.request == 1) {
-            /* Request */
-            view.remoteRequestStatus = "Receiving a request";
-        }
-        else {
-            /* Response */
-            view.remoteRequestStatus = "Sending a response ";
-            if (remoteMsg.requestStatus == 1) {
-                view.remoteRequestStatus += "(found)";
-
-                if (remoteMsg.valueLen <= 4) {
-                    view.remoteValue = "0x" +
-                        Number(remoteMsg.value).toString(16);
-                }
-                else {
-                    view.remoteValue = "Value at 0x" +
-                        Number(Number(obj.msg[remoteId]) +
-                        NSRN.Message.$offsetof("valueBuf")).toString(16);
-                }
+    view.remoteValue = "";
+
+    if (obj.remoteState == NSRN.IDLE) {
+        view.remoteRequestStatus = "Idle";
+        view.remoteInstanceName = "";
+        view.remoteName = "";
+    }
+    else {
+        view.remoteInstanceName = fetchString(obj.msg[remoteId],"instanceName");
+        view.remoteName = fetchString(obj.msg[remoteId], "name");
+    }
+
+    if (obj.remoteState == NSRN.RECEIVE_REQUEST) {
+        view.remoteRequestStatus = "Receiving a request";
+    }
+
+    if (obj.remoteState == NSRN.SEND_RESPONSE) {
+        view.remoteRequestStatus = "Sending a response";
+
+        if (remoteMsg.requestStatus == 1) {
+            view.remoteRequestStatus += " (found)";
+
+            if (remoteMsg.valueLen <= 4) {
+                view.remoteValue = "0x"+Number(remoteMsg.value).toString(16);
             }
             else {
-                view.remoteRequestStatus += "(not found)";
+                view.remoteValue = "Value at 0x" +
+                    Number(Number(obj.msg[remoteId]) +
+                    NSRN.Message.$offsetof("valueBuf")).toString(16);
             }
         }
-
-        view.remoteInstanceName = fetchString(obj.msg[remoteId], "instanceName");
-        view.remoteName = fetchString(obj.msg[remoteId], "name");
-    }
-    else {
-        view.remoteRequestStatus = "Idle";
+        else {
+            view.remoteRequestStatus += " (not found)";
+        }
     }
 }