summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--linux/include/_GateMP.h3
-rw-r--r--linux/include/_lad.h2
-rw-r--r--linux/src/api/Ipc.c30
-rw-r--r--linux/src/api/gates/GateMP.c80
-rw-r--r--linux/src/daemon/GateMP_daemon.c139
-rw-r--r--linux/src/daemon/lad.c27
6 files changed, 243 insertions, 38 deletions
diff --git a/linux/include/_GateMP.h b/linux/include/_GateMP.h
index 3c26db1..901a6a1 100644
--- a/linux/include/_GateMP.h
+++ b/linux/include/_GateMP.h
@@ -89,6 +89,9 @@ Int GateMP_start(Void);
/* Stop the GateMP module */
Int GateMP_stop(Void);
+Int GateMP_attach(UInt16 procId);
+Int GateMP_detach(UInt16 procId);
+
#if defined (__cplusplus)
}
#endif /* defined (__cplusplus) */
diff --git a/linux/include/_lad.h b/linux/include/_lad.h
index 3cffe83..b0a9c82 100644
--- a/linux/include/_lad.h
+++ b/linux/include/_lad.h
@@ -187,6 +187,8 @@ typedef enum {
LAD_MESSAGEQ_DELETE,
LAD_MESSAGEQ_MSGINIT,
LAD_MULTIPROC_GETCONFIG,
+ LAD_GATEMP_ATTACH,
+ LAD_GATEMP_DETACH,
LAD_GATEMP_START,
LAD_GATEMP_GETNUMRESOURCES,
LAD_GATEMP_GETFREERESOURCE,
diff --git a/linux/src/api/Ipc.c b/linux/src/api/Ipc.c
index 42ac0cb..e81700c 100644
--- a/linux/src/api/Ipc.c
+++ b/linux/src/api/Ipc.c
@@ -400,6 +400,9 @@ Int Ipc_attach(UInt16 procId)
{
Int status = Ipc_S_SUCCESS;
UInt16 clusterId;
+#if defined(GATEMP_SUPPORT)
+ Int ret;
+#endif
/* cannot attach to yourself */
if (MultiProc_self() == procId) {
@@ -443,6 +446,18 @@ Int Ipc_attach(UInt16 procId)
/* hack: bind all existing message queues to remote processor */
MessageQ_bind(procId);
+#if defined(GATEMP_SUPPORT)
+ if (GateMP_isSetup()) {
+ /* establish GateMP connection to remote processor */
+ ret = GateMP_attach(procId);
+
+ if (ret < 0) {
+ PRINTVERBOSE1("Ipc_attach: failed to GateMP_attach to procId %d\n",
+ procId);
+ }
+ }
+#endif
+
/* getting here means we have successfully attached */
Ipc_module.attached[clusterId]++;
@@ -459,6 +474,9 @@ Int Ipc_detach(UInt16 procId)
{
Int status = Ipc_S_SUCCESS;
UInt16 clusterId;
+#if defined(GATEMP_SUPPORT)
+ Int ret;
+#endif
/* cannot detach from yourself */
if (MultiProc_self() == procId) {
@@ -486,6 +504,18 @@ Int Ipc_detach(UInt16 procId)
goto done;
}
+#if defined(GATEMP_SUPPORT)
+ if (GateMP_isSetup()) {
+ /* establish GateMP connection to remote processor */
+ ret = GateMP_detach(procId);
+
+ if (ret < 0) {
+ PRINTVERBOSE1("Ipc_detach: failed to GateMP_detach from procId %d\n",
+ procId);
+ }
+ }
+#endif
+
/* hack: unbind all existing message queues from remote processor */
MessageQ_unbind(procId);
diff --git a/linux/src/api/gates/GateMP.c b/linux/src/api/gates/GateMP.c
index e9d17c2..e71629d 100644
--- a/linux/src/api/gates/GateMP.c
+++ b/linux/src/api/gates/GateMP.c
@@ -124,6 +124,86 @@ static GateMP_Params GateMP_defInstParams =
.remoteProtect = GateMP_RemoteProtect_SYSTEM
};
+/*
+ * ======== GateMP_attach ========
+ * Internal function.
+ */
+Int GateMP_attach(UInt16 procId)
+{
+ Int status;
+ LAD_ClientHandle clHandle;
+ struct LAD_CommandObj cmd;
+ union LAD_ResponseObj rsp;
+
+ clHandle = LAD_findHandle();
+
+ if (clHandle == LAD_MAXNUMCLIENTS) {
+ PRINTVERBOSE0("GateMP_attach: not connected to LAD\n");
+ return (GateMP_E_RESOURCE);
+ }
+
+ cmd.cmd = LAD_GATEMP_ATTACH;
+ cmd.clientId = clHandle;
+ cmd.args.attach.procId = procId;
+
+ if ((status = LAD_putCommand(&cmd)) != LAD_SUCCESS) {
+ PRINTVERBOSE1("GateMP_attach: sending LAD command failed, "
+ "status=%d\n", status);
+ return (GateMP_E_FAIL);
+ }
+
+ if ((status = LAD_getResponse(clHandle, &rsp)) != LAD_SUCCESS) {
+ PRINTVERBOSE1("GateMP_attach: no LAD response, status=%d\n",
+ status);
+ return (GateMP_E_FAIL);
+ }
+
+ status = rsp.status;
+ PRINTVERBOSE1("GateMP_attach: LAD response, status=%d\n", status)
+
+ return (status);
+}
+
+/*
+ * ======== GateMP_detach ========
+ * Internal function.
+ */
+Int GateMP_detach(UInt16 procId)
+{
+ Int status;
+ LAD_ClientHandle clHandle;
+ struct LAD_CommandObj cmd;
+ union LAD_ResponseObj rsp;
+
+ clHandle = LAD_findHandle();
+
+ if (clHandle == LAD_MAXNUMCLIENTS) {
+ PRINTVERBOSE0("GateMP_detach: not connected to LAD\n");
+ return (GateMP_E_RESOURCE);
+ }
+
+ cmd.cmd = LAD_GATEMP_DETACH;
+ cmd.clientId = clHandle;
+ cmd.args.detach.procId = procId;
+
+ if ((status = LAD_putCommand(&cmd)) != LAD_SUCCESS) {
+ PRINTVERBOSE1("GateMP_detach: sending LAD command failed, "
+ "status=%d\n", status);
+ return (GateMP_E_FAIL);
+ }
+
+ if ((status = LAD_getResponse(clHandle, &rsp)) != LAD_SUCCESS) {
+ PRINTVERBOSE1("GateMP_detach: no LAD response, status=%d\n",
+ status);
+ return (GateMP_E_FAIL);
+ }
+
+ status = rsp.status;
+ PRINTVERBOSE1("GateMP_detach: LAD response, status=%d\n", status)
+
+ return (status);
+}
+
Int GateMP_start(Void)
{
Int status;
diff --git a/linux/src/daemon/GateMP_daemon.c b/linux/src/daemon/GateMP_daemon.c
index d2db25d..7e689d1 100644
--- a/linux/src/daemon/GateMP_daemon.c
+++ b/linux/src/daemon/GateMP_daemon.c
@@ -92,10 +92,12 @@ typedef struct {
GateMP_Handle defaultGate;
NameServer_Handle nameServer;
Bool isSetup;
+ Int refCount[MultiProc_MAXPROCESSORS];
+ UInt16 attachedProcId;
} GateMP_ModuleObject;
/* Internal functions */
-static Int GateMP_openDefaultGate(GateMP_Handle *handlePtr);
+static Int GateMP_openDefaultGate(GateMP_Handle *handlePtr, UInt16 procId[]);
static Int GateMP_closeDefaultGate(GateMP_Handle *handlePtr);
/* =============================================================================
@@ -114,7 +116,9 @@ static GateMP_ModuleObject GateMP_state = {
.remoteCustom2InUse = NULL,
.defaultGate = NULL,
.nameServer = NULL,
- .isSetup = FALSE
+ .isSetup = FALSE,
+ .refCount = {0},
+ .attachedProcId = MultiProc_INVALIDID,
};
static GateMP_ModuleObject * GateMP_module = &GateMP_state;
@@ -124,17 +128,15 @@ static GateMP_ModuleObject * GateMP_module = &GateMP_state;
* =============================================================================
*/
-/* Function to setup the gatemp module. */
+/*
+ * Function to setup the gatemp module.
+ *
+ * No need to refCount this since it's not callable by user.
+ */
Int GateMP_setup(Void)
{
Int status = GateMP_S_SUCCESS;
NameServer_Params params;
- UInt32 nsValue[NUM_INFO_FIELDS];
- UInt32 len;
- UInt32 size;
- UInt32 alignDiff;
- UInt32 offset;
- Int32 fdMem;
NameServer_Params_init(&params);
params.maxRuntimeEntries = MAX_RUNTIME_ENTRIES;
@@ -150,38 +152,81 @@ Int GateMP_setup(Void)
status = GateMP_E_FAIL;
LOG0("GateMP_setup: NameServer_create failed\n");
}
+ else {
+ GateMP_module->isSetup = TRUE;
+ }
- if (status == GateMP_S_SUCCESS) {
- do {
- sleep(1); /* Give the slaves some time to get NameServer ready */
- status = GateMP_openDefaultGate(&GateMP_module->defaultGate);
- } while (status == GateMP_E_NOTFOUND);
+ return status;
+}
+Int GateMP_attach(UInt16 procId)
+{
+ GateMP_Handle deflateGate; /* that's right, Pats fan here */
+ Int status = GateMP_S_SUCCESS;
+ UInt32 nsValue[NUM_INFO_FIELDS];
+ UInt32 len;
+ UInt32 size;
+ UInt32 alignDiff;
+ UInt32 offset;
+ Int32 fdMem;
+ UInt16 procList[2];
+ UInt16 clId;
+
+ /* procId already validated in API layer */
+ clId = procId - MultiProc_getBaseIdOfCluster();
+ if (clId >= MultiProc_getNumProcsInCluster()) {
+ LOG1("GateMP_attach: procId %d not in range for local cluster\n",
+ procId);
+ return GateMP_E_INVALIDARG;
+ }
- if (status < 0) {
- LOG0("GateMP_setup: failed to open default gate\n");
- status = GateMP_E_FAIL;
- }
+ /* must reference count because we have multiple clients */
+ if (GateMP_module->refCount[clId] > 0) {
+ GateMP_module->refCount[clId]++;
+ goto done;
+ }
+
+ procList[0] = procId;
+ procList[1] = MultiProc_INVALIDID;
+ status = GateMP_openDefaultGate(&deflateGate, procList);
+
+ if (status < 0) {
+ LOG1("GateMP_attach: failed to open default gate on procId %d\n",
+ procId);
+ goto done;
}
if (status == GateMP_S_SUCCESS) {
+ if (GateMP_module->attachedProcId != MultiProc_INVALIDID) {
+ LOG1("GateMP_attach: can't attach to procId %d\n", procId);
+ LOG1(" already attached to %d\n",
+ GateMP_module->attachedProcId);
+ status = GateMP_E_ALREADYEXISTS;
+ goto done;
+ }
+
+ GateMP_module->attachedProcId = procId;
+ GateMP_module->defaultGate = deflateGate;
+
+ GateMP_module->refCount[clId]++;
+
/* Process global info NameServer entry */
len = sizeof(nsValue);
status = NameServer_get(GateMP_module->nameServer, "_GateMP_TI_info",
- &nsValue, &len, NULL);
+ &nsValue, &len, procList);
if (status < 0) {
- LOG0("GateMP_setup: failed to find info entry\n");
+ LOG0("GateMP_attach: failed to find info entry\n");
status = GateMP_E_NOTFOUND;
}
else {
fdMem = open ("/dev/mem", O_RDWR | O_SYNC);
if (fdMem < 0){
- LOG0("GateMP_setup: failed to open the /dev/mem!\n");
- status = GateMP_E_FAIL;
- goto cleanup;
+ LOG0("GateMP_attach: failed to open the /dev/mem!\n");
+ status = GateMP_E_OSFAILURE;
+ goto done;
}
GateMP_module->numRemoteSystem = nsValue[3];
@@ -272,19 +317,33 @@ Int GateMP_setup(Void)
/* TODO: setup the proxy map */
-cleanup:
- /* clean up if error */
- if (status < 0) {
- GateMP_destroy();
- }
-
- GateMP_module->isSetup = TRUE;
+done:
return (status);
}
-Void GateMP_destroy(Void)
+Int GateMP_detach(UInt16 procId)
{
+ UInt16 clId;
+
+ if (procId != GateMP_module->attachedProcId) {
+ return GateMP_E_NOTFOUND;
+ }
+
+ /* procId already validated in API layer */
+ clId = procId - MultiProc_getBaseIdOfCluster();
+ if (clId >= MultiProc_getNumProcsInCluster()) {
+ LOG1("GateMP_detach: procId %d not in range for local cluster\n",
+ procId);
+ return GateMP_E_INVALIDARG;
+ }
+
+
+ /* decrement reference count regardless of outcome below */
+ if (--GateMP_module->refCount[clId] > 0) {
+ goto done;
+ }
+
if (GateMP_module->remoteSystemInUse) {
munmap((unsigned int *)GateMP_module->remoteSystemInUse,
GateMP_module->numRemoteSystem * sizeof (UInt8));
@@ -305,8 +364,16 @@ Void GateMP_destroy(Void)
if (GateMP_module->defaultGate) {
GateMP_closeDefaultGate(&GateMP_module->defaultGate);
+ GateMP_module->attachedProcId = MultiProc_INVALIDID;
}
+done:
+
+ return GateMP_S_SUCCESS;
+}
+
+Void GateMP_destroy(Void)
+{
if (GateMP_module->nameServer) {
NameServer_delete(&GateMP_module->nameServer);
GateMP_module->nameServer = NULL;
@@ -317,8 +384,8 @@ Void GateMP_destroy(Void)
return;
}
-/* Open default gate during GateMP_setup. Should only be called once */
-static Int GateMP_openDefaultGate(GateMP_Handle *handlePtr)
+/* Open default gate during GateMP_attach. Should only be called once */
+static Int GateMP_openDefaultGate(GateMP_Handle *handlePtr, UInt16 procId[])
{
Int status = GateMP_S_SUCCESS;
UInt32 len;
@@ -326,13 +393,12 @@ static Int GateMP_openDefaultGate(GateMP_Handle *handlePtr)
GateMP_Object * obj = NULL;
UInt32 arg;
UInt32 mask;
- UInt32 creatorProcId;
GateMP_RemoteSystemProxy_Params systemParams;
/* assert that a valid pointer has been supplied */
if (handlePtr == NULL) {
- LOG0("GateMP_open: argument cannot be null\n");
+ LOG0("GateMP_openDefaultGate: argument cannot be null\n");
status = GateMP_E_INVALIDARG;
}
@@ -340,7 +406,7 @@ static Int GateMP_openDefaultGate(GateMP_Handle *handlePtr)
len = sizeof(nsValue);
status = NameServer_get(GateMP_module->nameServer, "_GateMP_TI_dGate",
- &nsValue, &len, NULL);
+ &nsValue, &len, procId);
if (status < 0) {
*handlePtr = NULL;
@@ -349,7 +415,6 @@ static Int GateMP_openDefaultGate(GateMP_Handle *handlePtr)
else {
arg = nsValue[2];
mask = nsValue[3];
- creatorProcId = nsValue[1] >> 16;
}
}
diff --git a/linux/src/daemon/lad.c b/linux/src/daemon/lad.c
index 170c3ec..b9c740e 100644
--- a/linux/src/daemon/lad.c
+++ b/linux/src/daemon/lad.c
@@ -127,6 +127,7 @@ int main(int argc, char * argv[])
Int c;
#if defined(GATEMP_SUPPORT)
Int status;
+ UInt16 procId;
#endif
String tmpString;
#if DAEMON
@@ -686,11 +687,33 @@ opencommandFIFO:
break;
#if defined(GATEMP_SUPPORT)
+ case LAD_GATEMP_ATTACH:
+ procId = cmd.args.attach.procId;
+ LOG1("LAD_GATEMP_ATTACH: calling GateMP_attach(%d)...\n", procId)
+
+ rsp.status = GateMP_attach(procId);
+
+ LOG1(" status = %d\n", rsp.status)
+ LOG0("DONE\n")
+
+ break;
+
+ case LAD_GATEMP_DETACH:
+ procId = cmd.args.detach.procId;
+ LOG1("LAD_GATEMP_DETACH: calling GateMP_detach(%d)...\n", procId)
+
+ rsp.status = GateMP_detach(procId);
+
+ LOG1(" status = %d\n", rsp.status)
+ LOG0("DONE\n")
+
+ break;
+
case LAD_GATEMP_START:
LOG0("LAD_GATEMP_START: calling GateMP_start()...\n")
rsp.gateMPStart.nameServerHandle = GateMP_getNameServer();
- rsp.gateMPStart.status = GateMP_S_SUCCESS;;
+ rsp.gateMPStart.status = GateMP_S_SUCCESS;
LOG1(" status = %d\n", rsp.gateMPStart.status)
LOG0("DONE\n")
@@ -797,6 +820,8 @@ opencommandFIFO:
case LAD_MESSAGEQ_MSGINIT:
case LAD_MULTIPROC_GETCONFIG:
#if defined(GATEMP_SUPPORT)
+ case LAD_GATEMP_ATTACH:
+ case LAD_GATEMP_DETACH:
case LAD_GATEMP_START:
case LAD_GATEMP_GETNUMRESOURCES:
case LAD_GATEMP_GETFREERESOURCE: