diff options
-rw-r--r-- | linux/include/_GateMP.h | 3 | ||||
-rw-r--r-- | linux/include/_lad.h | 2 | ||||
-rw-r--r-- | linux/src/api/Ipc.c | 30 | ||||
-rw-r--r-- | linux/src/api/gates/GateMP.c | 80 | ||||
-rw-r--r-- | linux/src/daemon/GateMP_daemon.c | 139 | ||||
-rw-r--r-- | linux/src/daemon/lad.c | 27 |
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(¶ms); 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: |