diff --git a/src/rm.c b/src/rm.c
index b846210264c2c99ccabafa688029c94f3ed0374e..cfa937e2e484e7d095aa58c78b8470d51bc550bd 100644 (file)
--- a/src/rm.c
+++ b/src/rm.c
/* Standard includes */
#include <stdint.h>
#include <string.h>
-#include <stdbool.h>
/* RM external includes */
#include <ti/drv/rm/rm.h>
#include <ti/drv/rm/rm_transport.h>
/* RM internal includes */
+#include <ti/drv/rm/include/rm_internal.h>
#include <ti/drv/rm/include/rm_loc.h>
#include <ti/drv/rm/include/rm_allocatorloc.h>
#include <ti/drv/rm/include/rm_transportloc.h>
#include <ti/drv/rm/include/rm_nameserverloc.h>
+#include <ti/drv/rm/include/rm_servicesloc.h>
/* RM LIBFDT includes */
#include <ti/drv/rm/util/libfdt/libfdt.h>
************************** Globals ***********************************
**********************************************************************/
-/** @brief Global Variable which describes the RM Version Information */
+/* Global Variable which describes the RM Version Information */
const char rmVersionStr[] = RM_VERSION_STR ":" __DATE__ ":" __TIME__;
/**********************************************************************
@@ -121,7 +122,10 @@ void createResourceReqPkt(Rm_Packet *rmPkt, char *localInstName, Rm_Transaction
}
else if (transaction->type == Rm_service_RESOURCE_ALLOCATE_USE) {
resourceReqPkt->resourceReqType = Rm_resReqPktType_ALLOCATE_USE;
- }
+ }
+ else if (transaction->type == Rm_service_RESOURCE_STATUS) {
+ resourceReqPkt->resourceReqType = Rm_resReqPktType_GET_STATUS;
+ }
else if (transaction->type == Rm_service_RESOURCE_FREE) {
resourceReqPkt->resourceReqType = Rm_resReqPktType_FREE;
}
{
Rm_ServiceRespInfo serviceResponse;
+ serviceResponse.rmHandle = (Rm_Handle)rmInst;
/* The responseTransaction will contain the resultant state details of
* the requestTransaction's service request */
serviceResponse.serviceState = transaction->state;
/* Pass back the ID that was provided to the component when it requested
* the service */
serviceResponse.serviceId = transaction->localId;
+ /* Owner count will only be set within RM under certain circumstances. Most of time
+ * it will be RM_RESOURCE_NUM_OWNERS_INVALID */
+ serviceResponse.resourceNumOwners = transaction->resourceInfo.ownerCount;
/* Service was approved and service was an allocate request. The resource
* data is passed back to the component */
if ((serviceResponse.serviceState == RM_SERVICE_APPROVED) &&
((transaction->type == Rm_service_RESOURCE_ALLOCATE_INIT) ||
(transaction->type == Rm_service_RESOURCE_ALLOCATE_USE) ||
+ (transaction->type == Rm_service_RESOURCE_FREE) ||
+ (transaction->type == Rm_service_RESOURCE_STATUS) ||
(transaction->type == Rm_service_RESOURCE_GET_BY_NAME)))
{
strncpy(serviceResponse.resourceName, transaction->resourceInfo.name, RM_NAME_MAX_CHARS);
serviceResponse.resourceLength = transaction->resourceInfo.length;
}
- /* Issue the callback to the requesting component with the response information */
- transaction->callback.serviceCallback(&serviceResponse);
-
- /* Delete the transaction from the transaction queue */
- rmTransactionQueueDelete(rmInst, transaction->localId);
+ if (transaction->u.callback.serviceCallback) {
+ /* Issue the callback to the requesting component with the response information */
+ transaction->u.callback.serviceCallback(&serviceResponse);
+ /* Delete the transaction from the transaction queue */
+ rmTransactionQueueDelete(rmInst, transaction->localId);
+ }
+ else {
+ rmServiceInternalCallback((Rm_Handle)rmInst);
+ }
+
return;
}
*/
static void transactionResponder (Rm_Inst *rmInst, Rm_Transaction *transaction)
{
- Rm_Transport *dstTransport = NULL;
+ Rm_Transport *dstTransport = transaction->u.respTrans;
Rm_Packet *rmPkt = NULL;
Rm_PacketHandle pktHandle = NULL;
- if (dstTransport = rmTransportFindRemoteName(rmInst->transports, transaction->pktSrcInstName)) {
- rmPkt = dstTransport->callouts.rmAllocPkt(dstTransport->appTransportHandle,
- sizeof(Rm_Packet), &pktHandle);
- if (!rmPkt || !pktHandle) {
- transaction->state = RM_ERROR_TRANSPORT_ALLOC_PKT_ERROR;
- goto errorExit;
- }
+ rmPkt = dstTransport->callouts.rmAllocPkt(dstTransport->appTransportHandle,
+ sizeof(Rm_Packet), &pktHandle);
+ if (!rmPkt || !pktHandle) {
+ transaction->state = RM_ERROR_TRANSPORT_ALLOC_PKT_ERROR;
+ goto errorExit;
+ }
- switch (transaction->type) {
- case Rm_service_RESOURCE_ALLOCATE_INIT:
- case Rm_service_RESOURCE_ALLOCATE_USE:
- case Rm_service_RESOURCE_FREE:
- case Rm_service_RESOURCE_GET_BY_NAME:
- createResourceResponsePkt(rmPkt, transaction);
- break;
- case Rm_service_RESOURCE_MAP_TO_NAME:
- case Rm_service_RESOURCE_UNMAP_NAME:
- createNsResponsePkt(rmPkt, transaction);
- break;
- }
- if (dstTransport->callouts.rmSendPkt(dstTransport->appTransportHandle, pktHandle) < RM_OK) {
- transaction->state = RM_ERROR_TRANSPORT_SEND_ERROR;
- goto errorExit;
- }
-
- /* Response packet sent: Delete transaction from queue */
- rmTransactionQueueDelete(rmInst, transaction->localId);
+ switch (transaction->type) {
+ case Rm_service_RESOURCE_ALLOCATE_INIT:
+ case Rm_service_RESOURCE_ALLOCATE_USE:
+ case Rm_service_RESOURCE_STATUS:
+ case Rm_service_RESOURCE_FREE:
+ case Rm_service_RESOURCE_GET_BY_NAME:
+ createResourceResponsePkt(rmPkt, transaction);
+ break;
+ case Rm_service_RESOURCE_MAP_TO_NAME:
+ case Rm_service_RESOURCE_UNMAP_NAME:
+ createNsResponsePkt(rmPkt, transaction);
+ break;
}
- else {
- transaction->state = RM_ERROR_TRANSPORT_REMOTE_HNDL_NOT_REGD;
+ if (dstTransport->callouts.rmSendPkt(dstTransport->appTransportHandle, pktHandle) < RM_OK) {
+ transaction->state = RM_ERROR_TRANSPORT_SEND_ERROR;
+ goto errorExit;
}
+
+ /* Response packet sent: Delete transaction from queue */
+ rmTransactionQueueDelete(rmInst, transaction->localId);
+
errorExit:
- /* Do not delete transaction on error. Error transactions should be visible from
+ /* Do not delete transaction on transport error. Transport error transactions should be visible
* from Rm_printInstanceStatus() */
return;
}
switch (transaction->type) {
case Rm_service_RESOURCE_ALLOCATE_INIT:
case Rm_service_RESOURCE_ALLOCATE_USE:
+ case Rm_service_RESOURCE_STATUS:
case Rm_service_RESOURCE_FREE:
case Rm_service_RESOURCE_GET_BY_NAME:
createResourceReqPkt(rmPkt, rmInst->instName, transaction);
@@ -336,13 +349,160 @@ static void transactionForwarder (Rm_Inst *rmInst, Rm_Transaction *transaction)
transaction->state = RM_ERROR_TRANSPORT_SEND_ERROR;
goto errorExit;
}
- transaction->hasBeenForwarded = true;
+ transaction->hasBeenForwarded = RM_TRUE;
/* Transaction not deleted. Waiting for response from RM CD or Server */
}
errorExit:
+ /* Do not delete transaction on transport error. Transport error transactions should be visible
+ * from Rm_printInstanceStatus() */
return;
}
+/* FUNCTION PURPOSE: Handles static allocation requests
+ ***********************************************************************
+ * DESCRIPTION: Validates allocation requests received on CDs and
+ * Clients prior to the instance's registering
+ * with a Server. The allocation request is validated
+ * against a static policy.
+ */
+static void staticAllocationHandler (Rm_Handle rmHandle, Rm_Transaction *transaction)
+{
+ Rm_Inst *rmInst = (Rm_Inst *)rmHandle;
+ void *staticPolicy = rmPolicyGetPolicy(rmHandle);
+ Rm_PolicyCheckCfg privCheckCfg;
+ int32_t result;
+
+ if (staticPolicy) {
+ if ((transaction->type == Rm_service_RESOURCE_ALLOCATE_INIT) ||
+ (transaction->type == Rm_service_RESOURCE_ALLOCATE_USE)) {
+ /* Check request against static policy */
+ memset((void *)&privCheckCfg, 0, sizeof(Rm_PolicyCheckCfg));
+
+ if (transaction->type == Rm_service_RESOURCE_ALLOCATE_INIT) {
+ privCheckCfg.type = Rm_policyCheck_INIT;
+ }
+ else {
+ privCheckCfg.type = Rm_policyCheck_USE;
+ }
+ privCheckCfg.policyDtb = staticPolicy;
+ privCheckCfg.validInstNode = rmPolicyGetValidInstNode(rmHandle, rmInst->instName);
+ privCheckCfg.resourceOffset = rmPolicyGetResourceOffset(staticPolicy,
+ transaction->resourceInfo.name);
+ privCheckCfg.resourceBase = transaction->resourceInfo.base;
+ privCheckCfg.resourceLength = transaction->resourceInfo.length;
+
+ if (rmPolicyCheckPrivilege(&privCheckCfg, &result)) {
+ transaction->state = RM_SERVICE_APPROVED_STATIC;
+ }
+ else if (result == RM_OK) {
+ /* Privilege check returned false without error */
+ transaction->state = RM_SERVICE_DENIED_BY_STATIC_POLICY;
+ }
+ else {
+ /* Privilege check returned false with error */
+ transaction->state = result;
+ }
+ }
+ else {
+ transaction->state = RM_SERVICE_DENIED_INVALID_STATIC_REQUEST;
+ }
+ }
+ else {
+ transaction->state = RM_ERROR_REQ_FAILED_NO_STATIC_POLICY;
+ }
+}
+
+/* FUNCTION PURPOSE: Requests resources from Server for CD
+ ***********************************************************************
+ * DESCRIPTION: Function creates a service request to allocate resources
+ * from the Server for local management by the CD. The
+ * transaction which causes this request is put in the
+ * pending state in order to wait for the response from the
+ * Server
+ */
+static int32_t cdRequestServerResources(Rm_Inst *rmInst, Rm_Transaction *transaction)
+{
+ Rm_Transaction *newTrans = NULL;
+ void * policy = rmPolicyGetPolicy((Rm_Handle)rmInst);
+ int32_t resourceOffsetInPolicy;
+ uint32_t allocSize = 0;
+ int32_t retVal;
+
+ resourceOffsetInPolicy = rmPolicyGetResourceOffset(policy, transaction->resourceInfo.name);
+ if (resourceOffsetInPolicy > 0) {
+ if (allocSize = rmPolicyGetResourceAllocSize(policy, resourceOffsetInPolicy)) {
+ if (newTrans = rmTransactionQueueAdd(rmInst)) {
+ newTrans->type = transaction->type;
+ strncpy(newTrans->serviceSrcInstName, rmInst->instName, RM_NAME_MAX_CHARS);
+ newTrans->state = RM_SERVICE_PROCESSING;
+ strncpy(newTrans->resourceInfo.name, transaction->resourceInfo.name, RM_NAME_MAX_CHARS);
+ newTrans->resourceInfo.base = RM_RESOURCE_BASE_UNSPECIFIED;
+ /* Make sure request length will satisfy transaction length */
+ newTrans->resourceInfo.length = allocSize;
+ while (newTrans->resourceInfo.length < transaction->resourceInfo.length) {
+ newTrans->resourceInfo.length += allocSize;
+ }
+ newTrans->resourceInfo.alignment = transaction->resourceInfo.alignment;
+ newTrans->pendingTransactionId = transaction->localId;
+ transactionForwarder(rmInst, newTrans);
+
+ retVal = RM_SERVICE_PENDING_SERVER_RESPONSE;
+ }
+ else {
+ retVal = RM_ERROR_TRANS_REQ_TO_SERVER_NOT_CREATED;
+ }
+ }
+ else {
+ /* Forward request to Server for completion if policy has
+ * no allocation size for resource */
+ retVal = RM_SERVICE_PROCESSING;
+ }
+ }
+ else {
+ /* Resource could not be found in policy */
+ retVal = RM_SERVICE_DENIED_RES_DOES_NOT_EXIST;
+ }
+ return (retVal);
+}
+
+/* FUNCTION PURPOSE: Frees local resources to Server from CD
+ ***********************************************************************
+ * DESCRIPTION: Function creates a service request to free locally
+ * managed resources that are now localized back to
+ * the Server.
+ */
+static int32_t cdFreeResourcesToServer(Rm_Inst *rmInst, Rm_Transaction *transaction)
+{
+ int32_t baseToFree = transaction->resourceInfo.base;
+ uint32_t lenToFree = transaction->resourceInfo.length;
+ Rm_Transaction *newTrans = NULL;
+ /* This function should only be called after a free was approved */
+ int32_t retVal = RM_SERVICE_APPROVED;
+
+ /* Did free result in a localized free node that can be given back to Server? If
+ * so create transaction to Server to free localized resource node */
+ if (rmAllocatorGetNodeLocalization((Rm_Handle)rmInst, transaction->resourceInfo.name,
+ &baseToFree, &lenToFree)) {
+ if (newTrans = rmTransactionQueueAdd(rmInst)) {
+ newTrans->type = transaction->type;
+ strncpy(newTrans->serviceSrcInstName, rmInst->instName, RM_NAME_MAX_CHARS);
+ newTrans->state = RM_SERVICE_PROCESSING;
+ strncpy(newTrans->resourceInfo.name, transaction->resourceInfo.name, RM_NAME_MAX_CHARS);
+ newTrans->resourceInfo.base = baseToFree;
+ newTrans->resourceInfo.length = lenToFree;
+ newTrans->pendingTransactionId = transaction->localId;
+ transactionForwarder(rmInst, newTrans);
+
+ retVal = RM_SERVICE_PENDING_SERVER_RESPONSE;
+ }
+ else {
+ /* Error: Need to re-allocate what was freed */
+ retVal = RM_ERROR_TRANS_REQ_TO_SERVER_NOT_CREATED;
+ }
+ }
+ return (retVal);
+}
+
/* FUNCTION PURPOSE: Arbitrates allocation service requests
***********************************************************************
* DESCRIPTION: Issues a set of allocator operations in order to
* retrieved from the NameServer prior to the allocation
* attempt.
*/
-static void allocationHandler (Rm_Inst *rmInst, Rm_Transaction *transaction, void *validInstNode,
- uint32_t allocType)
+static void allocationHandler (Rm_Inst *rmInst, Rm_Transaction *transaction)
{
- Rm_AllocatorOpInfo opInfo;
- Rm_NameServerObjCfg nameServerObjCfg;
- int32_t retVal = transaction->state;
+ Rm_AllocatorOpInfo opInfo;
+ Rm_NameServerObjCfg nameServerObjCfg;
+ int32_t retVal = transaction->state;
memset((void *)&opInfo, 0, sizeof(Rm_AllocatorOpInfo));
-
+ opInfo.policy = rmPolicyGetPolicy((Rm_Handle)rmInst);
+ opInfo.resourceInfo = &transaction->resourceInfo;
+ opInfo.serviceSrcInstNode = rmPolicyGetValidInstNode((Rm_Handle)rmInst, transaction->serviceSrcInstName);
+ if (opInfo.serviceSrcInstNode == NULL) {
+ retVal = RM_SERVICE_DENIED_INST_NAME_NOT_VALID;
+ goto errorExit;
+ }
+
if (rmInst->instType == Rm_instType_CLIENT_DELEGATE) {
- /* Forward all allocation requests to Server if transport is up. Otherwise, just queue. */
- if (rmInst->registeredWithDelegateOrServer) {
- transactionForwarder(rmInst, transaction);
- }
- }
- else if (rmInst->instType == Rm_instType_SERVER) {
- opInfo.policy = rmInst->policy;
- opInfo.resourceInfo = &transaction->resourceInfo;
- opInfo.serviceSrcInstNode = validInstNode;
- opInfo.allocType = allocType;
+ if (transaction->resourceInfo.base != RM_RESOURCE_BASE_UNSPECIFIED) {
+ if (rmAllocatorFind((Rm_Handle)rmInst, transaction->resourceInfo.name)) {
+ /* Attempt to allocate from local resources that were provided by Server */
+ if (transaction->type == Rm_service_RESOURCE_ALLOCATE_INIT) {
+ opInfo.operation = Rm_allocatorOp_ALLOCATE_INIT;
+ }
+ else if (transaction->type == Rm_service_RESOURCE_ALLOCATE_USE) {
+ opInfo.operation = Rm_allocatorOp_ALLOCATE_USE;
+ }
+ else {
+ retVal = RM_ERROR_INVALID_SERVICE_TYPE;
+ goto errorExit;
+ }
+ retVal = rmAllocatorOperation((Rm_Handle)rmInst, &opInfo);
+ if (retVal == RM_SERVICE_DENIED_RES_RANGE_DOES_NOT_EXIST) {
+ /* Request resource range was not found within local resources
+ * provided by Server. Set back to PROCESSING so request is forwarded to
+ * Server */
+ retVal = RM_SERVICE_PROCESSING;
+ }
+ }
+ }
+ else {
+ if (rmAllocatorFind((Rm_Handle)rmInst, transaction->resourceInfo.name)) {
+ int32_t oldAlign = transaction->resourceInfo.alignment;
+
+ /* Attempt to allocate from local resources that were provided by Server */
+ if (transaction->type == Rm_service_RESOURCE_ALLOCATE_INIT) {
+ opInfo.operation = Rm_allocatorOp_PRE_ALLOCATE_INIT;
+ }
+ else if (transaction->type == Rm_service_RESOURCE_ALLOCATE_USE) {
+ opInfo.operation = Rm_allocatorOp_PRE_ALLOCATE_USE;
+ }
+ else {
+ retVal = RM_ERROR_INVALID_SERVICE_TYPE;
+ goto errorExit;
+ }
+ retVal = rmAllocatorOperation((Rm_Handle)rmInst, &opInfo);
+
+ if (retVal == RM_SERVICE_PROCESSING) {
+ if (transaction->type == Rm_service_RESOURCE_ALLOCATE_INIT) {
+ opInfo.operation = Rm_allocatorOp_ALLOCATE_INIT;
+ }
+ else if (transaction->type == Rm_service_RESOURCE_ALLOCATE_USE) {
+ opInfo.operation = Rm_allocatorOp_ALLOCATE_USE;
+ }
+ else {
+ retVal = RM_ERROR_INVALID_SERVICE_TYPE;
+ goto errorExit;
+ }
+ retVal = rmAllocatorOperation((Rm_Handle)rmInst, &opInfo);
+
+ if (retVal == RM_SERVICE_DENIED_RES_RANGE_DOES_NOT_EXIST) {
+ /* Request resource range was not found within local resources
+ * provided by Server. Set back to PROCESSING so request is forwarded to
+ * Server */
+ retVal = RM_SERVICE_PROCESSING;
+ }
+ }
+ else if (retVal == RM_SERVICE_DENIED_RES_ALLOC_REQS_NOT_MET) {
+ if (transaction->pendingTransactionId) {
+ /* Request to Server for resources to complete transaction locally
+ * performed once already. Forward transaction to Server for completion */
+ retVal = RM_SERVICE_PROCESSING;
+ }
+ else {
+ /* Restore base and alignment since they were replaced in pre-allocate routine */
+ transaction->resourceInfo.base = RM_RESOURCE_BASE_UNSPECIFIED;
+ transaction->resourceInfo.alignment = oldAlign;
+
+ retVal = cdRequestServerResources(rmInst, transaction);
+ }
+ }
+ }
+ else {
+ retVal = cdRequestServerResources(rmInst, transaction);
+ }
+ }
+ }
+ else if ((rmInst->instType == Rm_instType_SERVER)||
+ (rmInst->instType == Rm_instType_SHARED_SERVER)) {
/* Populated NameServer name has precedence over base */
if (strlen(transaction->resourceInfo.nameServerName) > 0) {
- if ((transaction->resourceInfo.base == 0) &&
- (transaction->resourceInfo.length == 0) &&
- (transaction->resourceInfo.alignment == 0)) {
- memset((void *)&nameServerObjCfg, 0, sizeof(Rm_NameServerObjCfg));
- nameServerObjCfg.nameServerTree = rmInst->nameServer;
- nameServerObjCfg.nodeCfg.objName = transaction->resourceInfo.nameServerName;
- if ((retVal = rmNameServerFindObject(&nameServerObjCfg)) == RM_SERVICE_PROCESSING) {
- strncpy(transaction->resourceInfo.name, nameServerObjCfg.nodeCfg.resourceName, RM_NAME_MAX_CHARS);
- transaction->resourceInfo.base = nameServerObjCfg.nodeCfg.resourceBase;
- transaction->resourceInfo.length = nameServerObjCfg.nodeCfg.resourceLength;
- }
+ if (rmInst->instType == Rm_instType_SHARED_SERVER) {
+ rmNameServerTreeInv(rmInst->u.server.nameServer);
+ }
+ memset((void *)&nameServerObjCfg, 0, sizeof(Rm_NameServerObjCfg));
+ nameServerObjCfg.nameServerTree = rmInst->u.server.nameServer;
+ nameServerObjCfg.nodeCfg.objName = transaction->resourceInfo.nameServerName;
+ if ((retVal = rmNameServerFindObject(&nameServerObjCfg)) == RM_SERVICE_PROCESSING) {
+ strncpy(transaction->resourceInfo.name, nameServerObjCfg.nodeCfg.resourceName, RM_NAME_MAX_CHARS);
+ transaction->resourceInfo.base = nameServerObjCfg.nodeCfg.resourceBase;
+ transaction->resourceInfo.length = nameServerObjCfg.nodeCfg.resourceLength;
}
else {
- retVal = RM_ERROR_NS_NAME_AND_RES_VAL_CONFLICT;
+ goto errorExit;
}
}
- if (retVal == RM_SERVICE_PROCESSING) {
- if (transaction->resourceInfo.base == RM_RESOURCE_BASE_UNSPECIFIED) {
- opInfo.operation = Rm_allocatorOp_PRE_ALLOCATE;
- retVal = rmAllocatorOperation((Rm_Handle)rmInst, &opInfo);
+ if (transaction->resourceInfo.base == RM_RESOURCE_BASE_UNSPECIFIED) {
+ if (transaction->type == Rm_service_RESOURCE_ALLOCATE_INIT) {
+ opInfo.operation = Rm_allocatorOp_PRE_ALLOCATE_INIT;
}
-
- if (retVal == RM_SERVICE_PROCESSING) {
- opInfo.operation = Rm_allocatorOp_ALLOCATE;
- retVal = rmAllocatorOperation((Rm_Handle)rmInst, &opInfo);
- }
+ else if (transaction->type == Rm_service_RESOURCE_ALLOCATE_USE) {
+ opInfo.operation = Rm_allocatorOp_PRE_ALLOCATE_USE;
+ }
+ else {
+ retVal = RM_ERROR_INVALID_SERVICE_TYPE;
+ goto errorExit;
+ }
+ retVal = rmAllocatorOperation((Rm_Handle)rmInst, &opInfo);
}
-
- transaction->state = retVal;
+
+ if (retVal == RM_SERVICE_PROCESSING) {
+ if (transaction->type == Rm_service_RESOURCE_ALLOCATE_INIT) {
+ opInfo.operation = Rm_allocatorOp_ALLOCATE_INIT;
+ }
+ else if (transaction->type == Rm_service_RESOURCE_ALLOCATE_USE) {
+ opInfo.operation = Rm_allocatorOp_ALLOCATE_USE;
+ }
+ else {
+ retVal = RM_ERROR_INVALID_SERVICE_TYPE;
+ goto errorExit;
+ }
+ retVal = rmAllocatorOperation((Rm_Handle)rmInst, &opInfo);
+ }
+ }
+errorExit:
+ transaction->state = retVal;
+}
- if (strncmp(transaction->serviceSrcInstName, rmInst->instName, RM_NAME_MAX_CHARS)) {
- /* Source of allocation was not the server instance, provide the transaction
- * to the transaction responder */
- transactionResponder(rmInst, transaction);
+/* FUNCTION PURPOSE: Handles resource status service requests
+ ***********************************************************************
+ * DESCRIPTION: Issues a set of allocator operations to retrieve the
+ * current status (currently just owner reference count)
+ * for the resource specified in the transaction
+ */
+static void statusHandler (Rm_Inst *rmInst, Rm_Transaction *transaction)
+{
+ Rm_AllocatorOpInfo opInfo;
+ Rm_NameServerObjCfg nameServerObjCfg;
+ int32_t retVal = transaction->state;
+
+ memset((void *)&opInfo, 0, sizeof(Rm_AllocatorOpInfo));
+ opInfo.operation = Rm_allocatorOp_GET_STATUS;
+ opInfo.policy = rmPolicyGetPolicy((Rm_Handle)rmInst);
+ opInfo.resourceInfo = &transaction->resourceInfo;
+ opInfo.serviceSrcInstNode = rmPolicyGetValidInstNode((Rm_Handle)rmInst, transaction->serviceSrcInstName);
+ if (opInfo.serviceSrcInstNode == NULL) {
+ retVal = RM_SERVICE_DENIED_INST_NAME_NOT_VALID;
+ goto errorExit;
+ }
+
+ if ((strlen(transaction->resourceInfo.nameServerName) == 0) &&
+ ((transaction->resourceInfo.base == RM_RESOURCE_BASE_UNSPECIFIED) ||
+ (transaction->resourceInfo.length == 0))) {
+ retVal = RM_SERVICE_DENIED_RES_DOES_NOT_EXIST;
+ goto errorExit;
+ }
+
+ if (rmInst->instType == Rm_instType_CLIENT_DELEGATE) {
+ if (rmAllocatorFind((Rm_Handle)rmInst, transaction->resourceInfo.name)) {
+ /* Attempt to get status from local resources that were provided by Server */
+ retVal = rmAllocatorOperation((Rm_Handle)rmInst, &opInfo);
+
+ if (retVal == RM_SERVICE_DENIED_RES_RANGE_DOES_NOT_EXIST) {
+ /* Request resource range was not found within local allocator resources
+ * provided by Server. Set back to PROCESSING so request is forwarded to
+ * Server */
+ retVal = RM_SERVICE_PROCESSING;
+ }
}
- /* Otherwise let the return stack return the transaction to the serviceHandler */
- }
+ }
+ else if ((rmInst->instType == Rm_instType_SERVER)||
+ (rmInst->instType == Rm_instType_SHARED_SERVER)) {
+ /* Populated NameServer name has precedence over base and length values */
+ if (strlen(transaction->resourceInfo.nameServerName) > 0) {
+ if (rmInst->instType == Rm_instType_SHARED_SERVER) {
+ rmNameServerTreeInv(rmInst->u.server.nameServer);
+ }
+ memset((void *)&nameServerObjCfg, 0, sizeof(Rm_NameServerObjCfg));
+ nameServerObjCfg.nameServerTree = rmInst->u.server.nameServer;
+ nameServerObjCfg.nodeCfg.objName = transaction->resourceInfo.nameServerName;
+ if ((retVal = rmNameServerFindObject(&nameServerObjCfg)) == RM_SERVICE_PROCESSING) {
+ strncpy(transaction->resourceInfo.name, nameServerObjCfg.nodeCfg.resourceName, RM_NAME_MAX_CHARS);
+ transaction->resourceInfo.base = nameServerObjCfg.nodeCfg.resourceBase;
+ transaction->resourceInfo.length = nameServerObjCfg.nodeCfg.resourceLength;
+ }
+ else {
+ goto errorExit;
+ }
+ }
+ retVal = rmAllocatorOperation((Rm_Handle)rmInst, &opInfo);
+ }
+errorExit:
+ transaction->state = retVal;
}
/* FUNCTION PURPOSE: Arbitrates free service requests
@@ -426,58 +738,364 @@ static void allocationHandler (Rm_Inst *rmInst, Rm_Transaction *transaction, voi
* retrieved from the NameServer prior to the free
* attempt.
*/
-static void freeHandler (Rm_Inst *rmInst, Rm_Transaction *transaction, void *validInstNode)
+static void freeHandler (Rm_Inst *rmInst, Rm_Transaction *transaction)
{
Rm_AllocatorOpInfo opInfo;
Rm_NameServerObjCfg nameServerObjCfg;
int32_t retVal = transaction->state;
memset((void *)&opInfo, 0, sizeof(Rm_AllocatorOpInfo));
-
- if (rmInst->instType == Rm_instType_CLIENT_DELEGATE) {
- /* Forward all free requests to Server if transport is up. Otherwise, just queue. */
- if (rmInst->registeredWithDelegateOrServer) {
- transactionForwarder(rmInst, transaction);
- }
+ opInfo.operation = Rm_allocatorOp_FREE;
+ opInfo.policy = rmPolicyGetPolicy((Rm_Handle)rmInst);
+ opInfo.resourceInfo = &transaction->resourceInfo;
+ opInfo.serviceSrcInstNode = rmPolicyGetValidInstNode((Rm_Handle)rmInst, transaction->serviceSrcInstName);
+ if (opInfo.serviceSrcInstNode == NULL) {
+ retVal = RM_SERVICE_DENIED_INST_NAME_NOT_VALID;
+ goto errorExit;
+ }
+
+ if ((strlen(transaction->resourceInfo.nameServerName) == 0) &&
+ ((transaction->resourceInfo.base == RM_RESOURCE_BASE_UNSPECIFIED) ||
+ (transaction->resourceInfo.length == 0))) {
+ retVal = RM_SERVICE_DENIED_RES_DOES_NOT_EXIST;
+ goto errorExit;
}
- else if (rmInst->instType == Rm_instType_SERVER) {
- opInfo.policy = rmInst->policy;
- opInfo.resourceInfo = &transaction->resourceInfo;
- opInfo.serviceSrcInstNode = validInstNode;
+ if (rmInst->instType == Rm_instType_CLIENT_DELEGATE) {
+ if (rmAllocatorFind((Rm_Handle)rmInst, transaction->resourceInfo.name)) {
+ /* Attempt to free from local resources that were provided by Server */
+ retVal = rmAllocatorOperation((Rm_Handle)rmInst, &opInfo);
+
+ if (retVal == RM_SERVICE_APPROVED) {
+ /* Check if free allows local resources to be freed back to Server */
+ retVal = cdFreeResourcesToServer(rmInst, transaction);
+ }
+ else if (retVal == RM_SERVICE_DENIED_RES_RANGE_DOES_NOT_EXIST) {
+ /* Request resource range was not found within local allocator resources
+ * provided by Server. Set back to PROCESSING so request is forwarded to
+ * Server */
+ retVal = RM_SERVICE_PROCESSING;
+ }
+ }
+ }
+ else if ((rmInst->instType == Rm_instType_SERVER) ||
+ (rmInst->instType == Rm_instType_SHARED_SERVER)) {
/* Populated NameServer name has precedence over base */
if (strlen(transaction->resourceInfo.nameServerName) > 0) {
- if ((transaction->resourceInfo.base == 0) &&
- (transaction->resourceInfo.length == 0) &&
- (transaction->resourceInfo.alignment == 0)) {
- memset((void *)&nameServerObjCfg, 0, sizeof(Rm_NameServerObjCfg));
- nameServerObjCfg.nameServerTree = rmInst->nameServer;
- nameServerObjCfg.nodeCfg.objName = transaction->resourceInfo.nameServerName;
- if ((retVal = rmNameServerFindObject(&nameServerObjCfg)) == RM_SERVICE_PROCESSING) {
- strncpy(transaction->resourceInfo.name, nameServerObjCfg.nodeCfg.resourceName, RM_NAME_MAX_CHARS);
- transaction->resourceInfo.base = nameServerObjCfg.nodeCfg.resourceBase;
- transaction->resourceInfo.length = nameServerObjCfg.nodeCfg.resourceLength;
- }
+ if (rmInst->instType == Rm_instType_SHARED_SERVER) {
+ rmNameServerTreeInv(rmInst->u.server.nameServer);
+ }
+ memset((void *)&nameServerObjCfg, 0, sizeof(Rm_NameServerObjCfg));
+ nameServerObjCfg.nameServerTree = rmInst->u.server.nameServer;
+ nameServerObjCfg.nodeCfg.objName = transaction->resourceInfo.nameServerName;
+ if ((retVal = rmNameServerFindObject(&nameServerObjCfg)) == RM_SERVICE_PROCESSING) {
+ strncpy(transaction->resourceInfo.name, nameServerObjCfg.nodeCfg.resourceName, RM_NAME_MAX_CHARS);
+ transaction->resourceInfo.base = nameServerObjCfg.nodeCfg.resourceBase;
+ transaction->resourceInfo.length = nameServerObjCfg.nodeCfg.resourceLength;
}
else {
- retVal = RM_ERROR_NS_NAME_AND_RES_VAL_CONFLICT;
- }
+ goto errorExit;
+ }
+ }
+
+ retVal = rmAllocatorOperation((Rm_Handle)rmInst, &opInfo);
+ }
+errorExit:
+ transaction->state = retVal;
+}
+
+/* FUNCTION PURPOSE: Client transaction handling process
+ ***********************************************************************
+ * DESCRIPTION: Client process for handling transactions created
+ * from services received via the service handle or the
+ * transport. The Client process:
+ * - Performs static allocations if no transport
+ * to CD or Server has been registered
+ * - Forwards all service requests to CD or Server
+ * once transport has been registered
+ */
+static void clientProcess (Rm_Inst *rmInst, Rm_Transaction *transaction)
+{
+ Rm_Transaction *transQ = rmInst->transactionQueue;
+
+ if (!rmInst->registeredWithDelegateOrServer) {
+ staticAllocationHandler((Rm_Handle)rmInst, transaction);
+ }
+ else {
+ if (transaction->state == RM_SERVICE_PROCESSING) {
+ /* Forward all new transactions to CD or Server */
+ transactionForwarder(rmInst, transaction);
+ }
+ else {
+ /* Transaction validated. Return result. */
+ serviceResponder(rmInst, transaction);
+ }
+
+ /* Forward any queued static requests that weren't forwarded */
+ while(transQ) {
+ if ((transQ->state == RM_SERVICE_APPROVED_STATIC) &&
+ (!transQ->hasBeenForwarded)) {
+ transactionForwarder(rmInst, transQ);
+ }
+ transQ = transQ->nextTransaction;
+ }
+ }
+ /* Let call stack return transaction result app via Rm_serviceHandler */
+}
+
+/* FUNCTION PURPOSE: Client Delegate transaction handling process
+ ***********************************************************************
+ * DESCRIPTION: Client Delegate process for handling transactions created
+ * from services received via the service handle or the
+ * transport. The Client Delegate process:
+ * - Performs static allocations if no transport
+ * to Server has been registered
+ * - Forwards all NameServer related service requests
+ * to Server once transport has been registered
+ * - Attempts to complete resource service requests
+ * received from registered Clients
+ */
+static void cdProcess (Rm_Inst *rmInst, Rm_Transaction *transaction)
+{
+ Rm_Transaction *newTrans = NULL;
+ Rm_Allocator *allocator = NULL;
+ Rm_Transaction *transQ = rmInst->transactionQueue;
+
+ if (!rmInst->registeredWithDelegateOrServer) {
+ if ((transaction->state == RM_SERVICE_PROCESSING) &&
+ (strncmp(transaction->serviceSrcInstName, rmInst->instName, RM_NAME_MAX_CHARS) == 0)) {
+ /* Attempt static allocation of requests originating from CD inst */
+ staticAllocationHandler((Rm_Handle)rmInst, transaction);
+ }
+ /* Everything else left in transaction queue for forwarding once transport to
+ * Server is registered */
+ }
+ else {
+ if (transaction->pendingTransactionId) {
+ Rm_Transaction *pendingTrans = rmTransactionQueueFind(rmInst, transaction->pendingTransactionId);
+
+ /* Transaction is response from Server for transaction sent to get
+ * information in order to complete pending transaction */
+ if (transaction->state == RM_SERVICE_APPROVED) {
+ if (transaction->type == Rm_service_RESOURCE_GET_BY_NAME) {
+ /* Transfer resource data tied to name to pending transaction */
+ strncpy(pendingTrans->resourceInfo.name, transaction->resourceInfo.name, RM_NAME_MAX_CHARS);
+ pendingTrans->resourceInfo.base = transaction->resourceInfo.base;
+ pendingTrans->resourceInfo.length = transaction->resourceInfo.length;
+ /* Delete NS name from pending transaction so Server isn't queried again */
+ memset(pendingTrans->resourceInfo.nameServerName, 0, RM_NAME_MAX_CHARS);
+ /* Now that resource values have been retrieved clear pending transaction ID so
+ * CD doesn't think a resource request was sent to Server already for more local resources */
+ pendingTrans->pendingTransactionId = 0;
+
+ /* Return original transaction to processing state to attempt completion. */
+ pendingTrans->state = RM_SERVICE_PROCESSING;
+ }
+ else if ((transaction->type == Rm_service_RESOURCE_ALLOCATE_INIT) ||
+ (transaction->type == Rm_service_RESOURCE_ALLOCATE_USE)) {
+ /* Add resources provided by Server to those managed by CD */
+ if (allocator = rmAllocatorFind((Rm_Handle)rmInst, transaction->resourceInfo.name)) {
+ Rm_ResourceNode *treeNode = NULL;
+
+ treeNode = rmResourceNodeNew(transaction->resourceInfo.base, transaction->resourceInfo.length);
+ RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, treeNode);
+ }
+ else {
+ Rm_ResourceRange resRange;
+
+ memset((void *)&resRange, 0, sizeof(resRange));
+ resRange.base = transaction->resourceInfo.base;
+ resRange.length = transaction->resourceInfo.length;
+
+ rmAllocatorCreate((Rm_Handle)rmInst, transaction->resourceInfo.name, &resRange);
+ }
+
+ /* Return original transaction to processing state to attempt completion */
+ pendingTrans->state = RM_SERVICE_PROCESSING;
+ }
+ else if (transaction->type == Rm_service_RESOURCE_FREE) {
+ /* Local resource freed on Server. Need to remove from local allocator. */
+ rmAllocatorDeleteNode((Rm_Handle)rmInst, transaction->resourceInfo.name,
+ transaction->resourceInfo.base, transaction->resourceInfo.length);
+
+ /* Delete the allocator if there are no nodes left in the tree */
+ allocator = rmAllocatorFind((Rm_Handle)rmInst, transaction->resourceInfo.name);
+ if (RB_MIN(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry) == NULL) {
+ rmAllocatorDelete((Rm_Handle)rmInst, transaction->resourceInfo.name);
+ }
+
+ /* Allow original free to complete */
+ pendingTrans->state = RM_SERVICE_APPROVED;
+ }
+ }
+ else {
+ if (transaction->type == Rm_service_RESOURCE_FREE) {
+ /* Error occurred when trying to free local resource on Server. Reinsert local
+ * resources freed by original request */
+ Rm_AllocatorOpInfo opInfo;
+
+ memset((void *)&opInfo, 0, sizeof(Rm_AllocatorOpInfo));
+ opInfo.policy = rmPolicyGetPolicy((Rm_Handle)rmInst);
+ opInfo.resourceInfo = &pendingTrans->resourceInfo;
+ opInfo.serviceSrcInstNode = rmPolicyGetValidInstNode((Rm_Handle)rmInst, pendingTrans->serviceSrcInstName);
+ /* Can't regain the original type of allocate. Default to init */
+ opInfo.operation = Rm_allocatorOp_ALLOCATE_INIT;
+ if (rmAllocatorOperation((Rm_Handle)rmInst, &opInfo) != RM_SERVICE_APPROVED) {
+ transaction->state = RM_ERROR_LOST_RESOURCES_ON_CD;
+ }
+ }
+ /* Transfer error or denial to pending transaction */
+ pendingTrans->state = transaction->state;
+ }
+ rmTransactionQueueDelete(rmInst, transaction->localId);
+ /* Switch to pending transaction */
+ transaction = pendingTrans;
}
- if(retVal == RM_SERVICE_PROCESSING) {
- opInfo.operation = Rm_allocatorOp_FREE;
- retVal = rmAllocatorOperation((Rm_Handle)rmInst, &opInfo);
- }
+ if ((transaction->type == Rm_service_RESOURCE_ALLOCATE_INIT) ||
+ (transaction->type == Rm_service_RESOURCE_ALLOCATE_USE) ||
+ (transaction->type == Rm_service_RESOURCE_STATUS) ||
+ (transaction->type == Rm_service_RESOURCE_FREE)) {
+ if ((transaction->state == RM_SERVICE_PROCESSING) &&
+ (strlen(transaction->resourceInfo.nameServerName) > 0)) {
+ /* Create and forward new transaction to Server to
+ * retrieve resource data mapped to name */
+ if (newTrans = rmTransactionQueueAdd(rmInst)) {
+ newTrans->type = Rm_service_RESOURCE_GET_BY_NAME;
+ strncpy(newTrans->serviceSrcInstName, rmInst->instName, RM_NAME_MAX_CHARS);
+ newTrans->state = RM_SERVICE_PROCESSING;
+ strncpy(newTrans->resourceInfo.nameServerName, transaction->resourceInfo.nameServerName,
+ RM_NAME_MAX_CHARS);
+ newTrans->pendingTransactionId = transaction->localId;
+ transactionForwarder(rmInst, newTrans);
+
+ transaction->state = RM_SERVICE_PENDING_SERVER_RESPONSE;
+ }
+ else {
+ transaction->state = RM_ERROR_TRANS_REQ_TO_SERVER_NOT_CREATED;
+ }
+ }
+ }
- transaction->state = retVal;
+ if ((transaction->type == Rm_service_RESOURCE_ALLOCATE_INIT) ||
+ (transaction->type == Rm_service_RESOURCE_ALLOCATE_USE)) {
+ if (transaction->state == RM_SERVICE_PROCESSING) {
+ allocationHandler(rmInst, transaction);
+ }
+ }
+ else if (transaction->type == Rm_service_RESOURCE_STATUS) {
+ if (transaction->state == RM_SERVICE_PROCESSING) {
+ statusHandler(rmInst, transaction);
+ }
+ }
+ else if (transaction->type == Rm_service_RESOURCE_FREE) {
+ if (transaction->state == RM_SERVICE_PROCESSING) {
+ freeHandler(rmInst, transaction);
+ }
+ }
+ /* Forward all NameServer-based transactions */
+ if (transaction->state == RM_SERVICE_PROCESSING) {
+ /* CD could not complete transaction. Forward to Server */
+ transactionForwarder(rmInst, transaction);
+ }
+ else if (transaction->state != RM_SERVICE_PENDING_SERVER_RESPONSE) {
+ /* Transaction completed by CD or completed response received from Server. Return result */
+ if (strncmp(transaction->serviceSrcInstName, rmInst->instName, RM_NAME_MAX_CHARS)) {
+ /* Transaction did not originate on this instance */
+ transactionResponder(rmInst, transaction);
+ }
+ else {
+ /* Transaction originated on this instance */
+ serviceResponder(rmInst, transaction);
+ }
+ }
+
+ /* Attempt allocation of any queued static requests:
+ * RM_SERVICE_APPROVED_STATIC - Originated locally
+ * RM_SERVICE_PROCESSING - Received from any registered Clients */
+ while(transQ) {
+ if (((transQ->state == RM_SERVICE_PROCESSING) ||
+ (transQ->state == RM_SERVICE_APPROVED_STATIC)) &&
+ (!transQ->hasBeenForwarded)) {
+ transactionForwarder(rmInst, transQ);
+ }
+ transQ = transQ->nextTransaction;
+ }
+ }
+}
+
+/* FUNCTION PURPOSE: Server transaction handling process
+ ***********************************************************************
+ * DESCRIPTION: Server process for handling transactions created
+ * from services received via the service handle or the
+ * transport. The Server process:
+ * - Validates all service requests received from
+ * the service handle and registered CDs and
+ * Clients
+ */
+static void serverProcess (Rm_Inst *rmInst, Rm_Transaction *transaction)
+{
+ Rm_NameServerObjCfg nameServerObjCfg;
+
+ switch (transaction->type) {
+ case Rm_service_RESOURCE_STATUS:
+ statusHandler(rmInst, transaction);
+ break;
+ case Rm_service_RESOURCE_ALLOCATE_INIT:
+ case Rm_service_RESOURCE_ALLOCATE_USE:
+ allocationHandler(rmInst, transaction);
+ break;
+ case Rm_service_RESOURCE_FREE:
+ freeHandler(rmInst, transaction);
+ break;
+ case Rm_service_RESOURCE_MAP_TO_NAME:
+ case Rm_service_RESOURCE_GET_BY_NAME:
+ case Rm_service_RESOURCE_UNMAP_NAME:
+ if (rmInst->u.server.nameServer) {
+ if (rmInst->instType == Rm_instType_SHARED_SERVER) {
+ rmNameServerTreeInv(rmInst->u.server.nameServer);
+ }
+ memset((void *)&nameServerObjCfg, 0, sizeof(Rm_NameServerObjCfg));
+ nameServerObjCfg.nameServerTree = rmInst->u.server.nameServer;
+ nameServerObjCfg.nodeCfg.objName = transaction->resourceInfo.nameServerName;
+ if (transaction->type == Rm_service_RESOURCE_MAP_TO_NAME) {
+ nameServerObjCfg.nodeCfg.resourceName = transaction->resourceInfo.name;
+ nameServerObjCfg.nodeCfg.resourceBase= transaction->resourceInfo.base;
+ nameServerObjCfg.nodeCfg.resourceLength = transaction->resourceInfo.length;
+ transaction->state = rmNameServerAddObject(&nameServerObjCfg);
+ }
+ else if (transaction->type == Rm_service_RESOURCE_GET_BY_NAME) {
+ if ((transaction->state = rmNameServerFindObject(&nameServerObjCfg)) ==
+ RM_SERVICE_PROCESSING) {
+ strncpy(transaction->resourceInfo.name, nameServerObjCfg.nodeCfg.resourceName, RM_NAME_MAX_CHARS);
+ transaction->resourceInfo.base = nameServerObjCfg.nodeCfg.resourceBase;
+ transaction->resourceInfo.length = nameServerObjCfg.nodeCfg.resourceLength;
+ transaction->state = RM_SERVICE_APPROVED;
+ }
+ }
+ else if (transaction->type == Rm_service_RESOURCE_UNMAP_NAME) {
+ transaction->state = rmNameServerDeleteObject(&nameServerObjCfg);
+ }
+
+ if (rmInst->instType == Rm_instType_SHARED_SERVER) {
+ rmNameServerTreeWb(rmInst->u.server.nameServer);
+ }
+ }
+ else {
+ transaction->state = RM_ERROR_NAMESERVER_DOES_NOT_EXIST;
+ }
+ break;
+ }
+
+ /* Source of shared server transaction will always be local. */
+ if (rmInst->instType != Rm_instType_SHARED_SERVER) {
if (strncmp(transaction->serviceSrcInstName, rmInst->instName, RM_NAME_MAX_CHARS)) {
- /* Source of allocation was not the server instance, provide the transaction
- * to the transaction responder */
+ /* Source of transaction was not Server, return transaction via responder */
transactionResponder(rmInst, transaction);
}
- /* Otherwise let the return stack return the transaction to the serviceHandler */
- }
+ }
+ /* Otherwise let call stack return transaction result app via Rm_serviceHandler */
}
/**********************************************************************
return (retVal);
}
-/* FUNCTION PURPOSE: Processes a transaction
+/* FUNCTION PURPOSE: Routes a transaction for processing
***********************************************************************
- * DESCRIPTION: Processes transactions created from services
- * received via the service handle or the transport.
- * Transactions will be routed within the RM system
- * based on the RM instance type and the type of
- * the transaction.
+ * DESCRIPTION: Routes a received transaction to the appropriate
+ * instance processing routine
*/
-void rmTransactionProcessor (Rm_Inst *rmInst, Rm_Transaction *transaction)
+void rmProcessRouter (Rm_Inst *rmInst, Rm_Transaction *transaction)
{
- void *validInstNode;
- Rm_PolicyCheckCfg privCheckCfg;
- Rm_NameServerObjCfg nameServerObjCfg;
- uint32_t allocType = 0;
-
- /* Handle static transactions originating on this instance. Any other static transactions will be
- * stored in transaction queue until all transports are up. */
- if (((rmInst->instType == Rm_instType_CLIENT) || (rmInst->instType == Rm_instType_CLIENT_DELEGATE)) &&
- (!rmInst->registeredWithDelegateOrServer) &&
- (strncmp(transaction->serviceSrcInstName, rmInst->instName, RM_NAME_MAX_CHARS) == 0)) {
- if (rmInst->staticInfo.staticPolicy) {
- if ((transaction->type == Rm_service_RESOURCE_ALLOCATE_INIT) ||
- (transaction->type == Rm_service_RESOURCE_ALLOCATE_USE)) {
- /* Check request against startup policy */
- memset((void *)&privCheckCfg, 0, sizeof(Rm_PolicyCheckCfg));
-
- if (transaction->type == Rm_service_RESOURCE_ALLOCATE_INIT) {
- privCheckCfg.type = Rm_policyCheck_INIT;
- }
- else {
- privCheckCfg.type = Rm_policyCheck_USE;
- }
- privCheckCfg.policyDtb = rmInst->staticInfo.staticPolicy;
- privCheckCfg.validInstNode = rmPolicyGetValidInstNode(rmInst->staticInfo.staticValidInstTree,
- rmInst->instName);
- privCheckCfg.resourceOffset = rmPolicyGetResourceOffset(rmInst->staticInfo.staticPolicy,
- transaction->resourceInfo.name);
- privCheckCfg.resourceBase = transaction->resourceInfo.base;
- privCheckCfg.resourceLength = transaction->resourceInfo.length;
-
- if (rmPolicyCheckPrivilege(&privCheckCfg, &transaction->state)) {
- transaction->state = RM_SERVICE_APPROVED_STATIC;
- }
- else if (transaction->state == RM_SERVICE_PROCESSING) {
- /* Privilege check returned false without error */
- transaction->state = RM_SERVICE_DENIED_BY_STATIC_POLICY;
- }
- }
- else {
- transaction->state = RM_SERVICE_DENIED_INVALID_STATIC_REQUEST;
- }
- }
- else {
- transaction->state = RM_ERROR_REQ_FAILED_NO_STATIC_POLICY;
- }
- }
- else {
- /* Handle auto-forwarded transactions. These transactions include:
- * - All request transactions received on Clients are forwarded to the Client Delegate
- * - NameServer requests received on the Client Delegate are forwarded to the Server */
- if ((rmInst->instType == Rm_instType_CLIENT) ||
- ((rmInst->instType == Rm_instType_CLIENT_DELEGATE) &&
- ((transaction->type == Rm_service_RESOURCE_MAP_TO_NAME) ||
- (transaction->type == Rm_service_RESOURCE_GET_BY_NAME) ||
- (transaction->type == Rm_service_RESOURCE_UNMAP_NAME)))) {
-
- if ((transaction->state != RM_SERVICE_PROCESSING) &&
- (transaction->state != RM_SERVICE_APPROVED_STATIC)) {
- if (strncmp(transaction->serviceSrcInstName, rmInst->instName, RM_NAME_MAX_CHARS)) {
- /* Transaction did not originate on this instance */
- transactionResponder(rmInst, transaction);
- }
- else {
- /* Transaction originated on this instance */
- serviceResponder(rmInst, transaction);
- }
- }
- else {
- /* Forward request if transport is up. Otherwise, just queue. */
- if (rmInst->registeredWithDelegateOrServer) {
- transactionForwarder(rmInst, transaction);
- }
- }
- }
- else {
- /* Validate service's originating instance name */
- if (rmInst->instType == Rm_instType_SERVER) {
- validInstNode = rmPolicyGetValidInstNode(rmInst->validInstances, transaction->serviceSrcInstName);
- if (validInstNode == NULL) {
- transaction->state = RM_SERVICE_DENIED_INST_NAME_NOT_VALID;
-
- /* Send result via responder if transaction did not originate from this instance */
- if (strncmp(transaction->serviceSrcInstName, rmInst->instName, RM_NAME_MAX_CHARS)) {
- transactionResponder(rmInst, transaction);
- }
- }
- }
-
- switch (transaction->type) {
- case Rm_service_RESOURCE_ALLOCATE_INIT:
- case Rm_service_RESOURCE_ALLOCATE_USE:
- case Rm_service_RESOURCE_FREE:
- if ((transaction->state != RM_SERVICE_PROCESSING) &&
- (transaction->state != RM_SERVICE_APPROVED_STATIC)) {
- /* Transaction complete */
- if (strncmp(transaction->serviceSrcInstName, rmInst->instName, RM_NAME_MAX_CHARS)) {
- /* Transaction result not destined for this instance */
- transactionResponder(rmInst, transaction);
- }
- else {
- /* Transaction result destined for this instance */
- serviceResponder(rmInst, transaction);
- }
- }
- else {
- /* Complete allocation/free request */
- if (transaction->type == Rm_service_RESOURCE_FREE) {
- freeHandler(rmInst, transaction, validInstNode);
- }
- else {
- switch (transaction->type) {
- case Rm_service_RESOURCE_ALLOCATE_INIT:
- RM_policy_SET_PERM(allocType, RM_POLICY_PERM_INIT_SHIFT, 1);
- break;
- case Rm_service_RESOURCE_ALLOCATE_USE:
- RM_policy_SET_PERM(allocType, RM_POLICY_PERM_USE_SHIFT, 1);
- break;
- }
- allocationHandler(rmInst, transaction, validInstNode, allocType);
- }
- }
- break;
- case Rm_service_RESOURCE_MAP_TO_NAME:
- case Rm_service_RESOURCE_GET_BY_NAME:
- case Rm_service_RESOURCE_UNMAP_NAME:
- /* NameServer resides on server */
- memset((void *)&nameServerObjCfg, 0, sizeof(Rm_NameServerObjCfg));
- if (rmInst->nameServer) {
- nameServerObjCfg.nameServerTree = rmInst->nameServer;
- nameServerObjCfg.nodeCfg.objName = transaction->resourceInfo.nameServerName;
- if (transaction->type == Rm_service_RESOURCE_MAP_TO_NAME) {
- nameServerObjCfg.nodeCfg.resourceName = transaction->resourceInfo.name;
- nameServerObjCfg.nodeCfg.resourceBase= transaction->resourceInfo.base;
- nameServerObjCfg.nodeCfg.resourceLength = transaction->resourceInfo.length;
- transaction->state = rmNameServerAddObject(&nameServerObjCfg);
- }
- else if (transaction->type == Rm_service_RESOURCE_GET_BY_NAME) {
- if ((transaction->state = rmNameServerFindObject(&nameServerObjCfg)) ==
- RM_SERVICE_PROCESSING) {
- strncpy(transaction->resourceInfo.name, nameServerObjCfg.nodeCfg.resourceName, RM_NAME_MAX_CHARS);
- transaction->resourceInfo.base = nameServerObjCfg.nodeCfg.resourceBase;
- transaction->resourceInfo.length = nameServerObjCfg.nodeCfg.resourceLength;
- transaction->state = RM_SERVICE_APPROVED;
- }
- }
- else if (transaction->type == Rm_service_RESOURCE_UNMAP_NAME) {
- transaction->state = rmNameServerDeleteObject(&nameServerObjCfg);
- }
- }
- else {
- transaction->state = RM_ERROR_NAMESERVER_DOES_NOT_EXIST;
- }
-
- /* Send result via responder if transaction did not originate from this instance */
- if (strncmp(transaction->serviceSrcInstName, rmInst->instName, RM_NAME_MAX_CHARS)) {
- transactionResponder(rmInst, transaction);
- }
- break;
- }
- }
+ if (rmInst->instType == Rm_instType_CLIENT) {
+ clientProcess(rmInst, transaction);
}
-
- /* Forward any queued requests that weren't forwarded yet */
- if (rmInst->registeredWithDelegateOrServer) {
- transaction = rmInst->transactionQueue;
- while(transaction) {
- if (((transaction->state == RM_SERVICE_PROCESSING) ||
- (transaction->state == RM_SERVICE_APPROVED_STATIC)) &&
- !transaction->hasBeenForwarded) {
- transactionForwarder(rmInst, transaction);
- }
- transaction = transaction->nextTransaction;
- }
+ else if (rmInst->instType == Rm_instType_CLIENT_DELEGATE) {
+ cdProcess(rmInst, transaction);
}
+ else if ((rmInst->instType == Rm_instType_SERVER) ||
+ (rmInst->instType == Rm_instType_SHARED_SERVER)) {
+ serverProcess(rmInst, transaction);
+ }
}
/**********************************************************************
* DESCRIPTION: Prints the status (allocate/free status, as well as
* owners) for all resources managed by the RM
* instance network. Also, prints the NameServer name
- * entries. This function is only available on server
- * instances.
+ * entries. The number of resource range owners is
+ * returned as well. This function is only available on
+ * Server and CD instances.
*/
-void Rm_printResourceStatus(Rm_Handle rmServerHandle)
+int32_t Rm_resourceStatus(Rm_Handle rmHandle, int printResources)
{
- Rm_Inst *rmInst = (Rm_Inst *)rmServerHandle;
- Rm_Allocator *allocator = rmInst->allocators;
+ Rm_Inst *rmInst = (Rm_Inst *)rmHandle;
+ Rm_Allocator *allocator = NULL;
Rm_Owner *owners;
Rm_ResourceTree *treeRoot;
Rm_ResourceNode *treeNode;
+ int32_t totalResOwners = 0;
+ void *key;
- if (rmInst->instType == Rm_instType_SERVER) {
- while (allocator != NULL) {
- Rm_osalLog("Resource: %s\n", allocator->resourceName);
+ RM_SS_INST_INV_ENTER_CS(key);
+ RM_SC_INST_INV_ENTER_CS(key);
- treeRoot = allocator->allocatorRootEntry;
+ if (rmInst->instType != Rm_instType_CLIENT) {
+ Rm_osalLog("Instance name: %s\n", rmInst->instName);
+ Rm_osalLog("Handle: 0x%08x\n", rmHandle);
+ if (rmInst->instType == Rm_instType_SERVER) {
+ Rm_osalLog("Type: Server\n");
+ }
+ else if (rmInst->instType == Rm_instType_CLIENT_DELEGATE) {
+ Rm_osalLog("Type: Client Delegate\n");
+ }
+ else if (rmInst->instType == Rm_instType_SHARED_SERVER) {
+ Rm_osalLog("Type: Shared Server\n");
+ }
+ else if (rmInst->instType == Rm_instType_SHARED_CLIENT) {
+ Rm_osalLog("Type: Shared Client\n");
+ }
+
+ Rm_osalLog("\nResource Status:\n\n");
+ }
+
+ if (rmInst->instType == Rm_instType_SHARED_CLIENT) {
+ /* Transfer control to shared server instance */
+ rmInst = rmInst->u.sharedClient.sharedServerHandle;
+ }
- RB_FOREACH(treeNode, _Rm_AllocatorResourceTree, treeRoot) {
- Rm_osalLog(" %10d - %10d ", treeNode->base,
- treeNode->base + treeNode->length -1);
+ if ((rmInst->instType == Rm_instType_SERVER) ||
+ (rmInst->instType == Rm_instType_SHARED_SERVER) ||
+ (rmInst->instType == Rm_instType_CLIENT_DELEGATE)) {
+ allocator = rmAllocatorGetAllocatorList(rmHandle);
+
+ if (!allocator) {
+ Rm_osalLog("No resources managed by instance at the moment\n\n");
+ }
+
+ while (allocator) {
+ RM_SS_OBJ_INV(allocator, Rm_Allocator);
+ if (printResources) {
+ Rm_osalLog("Resource: %s\n", allocator->resourceName);
+ }
+
+ treeRoot = allocator->allocatorRootEntry;
+ if (rmInst->instType == Rm_instType_SHARED_SERVER) {
+ rmResourceTreeInv(treeRoot);
+ }
+ RB_FOREACH(treeNode, _Rm_AllocatorResourceTree, treeRoot) {
+ if (printResources) {
+ if ((treeNode->base >= 65536) ||
+ ((treeNode->base + treeNode->length - 1) >= 65536)) {
+ /* Print in hex if number is very large */
+ Rm_osalLog(" 0x%08x - 0x%08x ", treeNode->base,
+ treeNode->base + treeNode->length - 1);
+ }
+ else {
+ Rm_osalLog(" %10d - %10d ", treeNode->base,
+ treeNode->base + treeNode->length - 1);
+ }
+ }
if (treeNode->allocationCount == 0) {
- Rm_osalLog("FREE\n");
+ if (printResources) {
+ Rm_osalLog("FREE\n");
+ }
}
else {
owners = treeNode->ownerList;
while (owners) {
- Rm_osalLog("%s ", owners->instNameNode->name);
+ RM_SS_OBJ_INV(owners, Rm_Owner);
+ if (printResources) {
+ Rm_osalLog("%s ", owners->instNameNode->name);
+ }
+ totalResOwners++;
owners = owners->nextOwner;
}
- Rm_osalLog("\n");
+ if (printResources) {
+ Rm_osalLog("\n");
+ }
}
}
- allocator = allocator->nextAllocator;
+ allocator = allocator->nextAllocator;
+ }
+
+ if ((rmInst->instType == Rm_instType_SERVER) ||
+ (rmInst->instType == Rm_instType_SHARED_SERVER)) {
+ if (printResources) {
+ rmNameServerPrintObjects((Rm_Handle)rmInst);
+ }
}
- rmNameServerPrintObjects(rmInst->nameServer);
}
+ else {
+ totalResOwners = RM_ERROR_INVALID_RES_STATUS_INSTANCE;
+ }
+
+ RM_SS_INST_WB_EXIT_CS(key);
+ return(totalResOwners);
}
/* FUNCTION PURPOSE: Display status of a RM instance
* properties such as the state of all transactions
* in the transaction queue and registered transports
*/
-void Rm_printInstanceStatus(Rm_Handle rmHandle)
+void Rm_instanceStatus(Rm_Handle rmHandle)
{
Rm_Inst *rmInst = (Rm_Inst *)rmHandle;
- Rm_Transport *transportList = rmInst->transports;
- Rm_Transaction *transactionQ = rmInst->transactionQueue;
+ Rm_Transport *transportList = NULL;
+ Rm_Transaction *transactionQ = NULL;
+ void *key;
+
+ RM_SS_INST_INV_ENTER_CS(key);
+ RM_SC_INST_INV_ENTER_CS(key);
Rm_osalLog("Instance name: %s\n", rmInst->instName);
+ Rm_osalLog("Handle: 0x%08x\n", rmHandle);
if (rmInst->instType == Rm_instType_SERVER) {
- Rm_osalLog("Type: Server\n");
+ Rm_osalLog("Type: Server\n");
}
else if (rmInst->instType == Rm_instType_CLIENT_DELEGATE) {
- Rm_osalLog("Type: Client Delegate\n");
+ Rm_osalLog("Type: Client Delegate\n");
}
- else {
- Rm_osalLog("Type: Client\n");
+ else if (rmInst->instType == Rm_instType_CLIENT) {
+ Rm_osalLog("Type: Client\n");
}
-
+ else if (rmInst->instType == Rm_instType_SHARED_SERVER) {
+ Rm_osalLog("Type: Shared Server\n");
+ }
+ else if (rmInst->instType == Rm_instType_SHARED_CLIENT) {
+ Rm_osalLog("Type: Shared Client\n");
+
+ Rm_osalLog("\nShared Server Properties:\n");
+ /* Transfer to Shared Server instance to print out transport and
+ * transaction status */
+ rmInst = rmInst->u.sharedClient.sharedServerHandle;
+ Rm_osalLog("Instance name: %s\n", rmInst->instName);
+ Rm_osalLog("Handle: 0x%08x\n", rmHandle);
+ }
+
+ transportList = rmInst->transports;
if (transportList) {
Rm_osalLog("\nRegistered Transports:\n");
while (transportList) {
- Rm_osalLog(" Remote instName: %s\n", transportList->remoteInstName);
+ RM_SS_OBJ_INV(transportList, Rm_Transport);
if (transportList->remoteInstType == Rm_instType_SERVER) {
Rm_osalLog(" Remote instType: Server\n");
}
}
}
+ transactionQ = rmInst->transactionQueue;
if (transactionQ) {
Rm_osalLog("\nQueued Service Transactions:\n");
while (transactionQ) {
+ RM_SS_OBJ_INV(transactionQ, Rm_Transaction);
Rm_osalLog(" Service type: %d\n", transactionQ->type);
Rm_osalLog(" Service ID: %d\n", transactionQ->localId);
Rm_osalLog(" Service srcInstName %s\n", transactionQ->serviceSrcInstName);
transactionQ = transactionQ->nextTransaction;
}
}
+ RM_SS_INST_WB_EXIT_CS(key);
}
/* FUNCTION PURPOSE: RM instance creation and initialization
*/
Rm_Handle Rm_init(const Rm_InitCfg *initCfg, int32_t *result)
{
- Rm_Inst *rmInst;
- void *globalResourceDtb = NULL;
- void *linuxResourceDtb = NULL;
- bool addLinux = false;
+ Rm_Inst *rmInst = NULL;
+ Rm_Inst *sharedServerInst = NULL;
+ uint32_t policySize;
+ void *globalResourceDtb = NULL;
+ void *linuxResourceDtb = NULL;
+ int addLinux = RM_FALSE;
+ void *key;
*result = RM_OK;
if ((initCfg->instName == NULL) ||
((strlen(initCfg->instName) + 1) > RM_NAME_MAX_CHARS)) {
*result = RM_ERROR_INVALID_INST_NAME;
- return (NULL);
+ goto errorExit;
}
if (initCfg->instType >= Rm_instType_LAST) {
*result = RM_ERROR_INVALID_INST_TYPE;
+ goto errorExit;
}
/* Create and initialize instance */
- rmInst = Rm_osalMalloc (sizeof(Rm_Inst));
- memset ((void *) rmInst, 0, sizeof(Rm_Inst));
- rmInst->isLocked = false;
- rmInst->registeredWithDelegateOrServer = false;
+ rmInst = Rm_osalMalloc(sizeof(*rmInst));
+ memset ((void *)rmInst, 0, sizeof(*rmInst));
+ rmInst->isLocked = RM_FALSE;
+ rmInst->registeredWithDelegateOrServer = RM_FALSE;
rmInst->transactionSeqNum = transactionInitSequenceNum();
rmInst->instType = initCfg->instType;
strncpy (rmInst->instName, initCfg->instName, RM_NAME_MAX_CHARS);
- if (rmInst->instType == Rm_instType_SERVER) {
+ if ((rmInst->instType == Rm_instType_SERVER) ||
+ (rmInst->instType == Rm_instType_SHARED_SERVER)) {
if (!initCfg->instCfg.serverCfg.globalResourceList ||
!initCfg->instCfg.serverCfg.globalPolicy) {
*result = RM_ERROR_INVALID_SERVER_CONFIGURATION;
- Rm_osalFree((void *)rmInst, sizeof(Rm_Inst));
- return(NULL);
+ goto errorExit;
}
- rmInst->policy = initCfg->instCfg.serverCfg.globalPolicy;
- fdt_open_into(rmInst->policy, rmInst->policy, fdt_totalsize(rmInst->policy));
+ if (rmInst->instType == Rm_instType_SHARED_SERVER) {
+ /* Shared Server makes copy of policy in shared memory for Shared Clients
+ * on other cores */
+ policySize = fdt_totalsize(initCfg->instCfg.serverCfg.globalPolicy);
+ /* Align policy size to cache boundary */
+ if (policySize % RM_MAX_CACHE_ALIGN) {
+ policySize += (RM_MAX_CACHE_ALIGN - (policySize % RM_MAX_CACHE_ALIGN));
+ }
+ rmInst->u.server.policySize = policySize;
+ rmInst->u.server.globalPolicy = Rm_osalMalloc(rmInst->u.server.policySize);
+ memcpy(rmInst->u.server.globalPolicy, initCfg->instCfg.serverCfg.globalPolicy, rmInst->u.server.policySize);
+ }
+ else {
+ rmInst->u.server.globalPolicy = initCfg->instCfg.serverCfg.globalPolicy;
+ }
if (initCfg->instCfg.serverCfg.linuxDtb) {
linuxResourceDtb = initCfg->instCfg.serverCfg.linuxDtb;
- fdt_open_into(linuxResourceDtb, linuxResourceDtb, fdt_totalsize(linuxResourceDtb));
- addLinux = true;
+ addLinux = RM_TRUE;
}
/* Create valid instance list from policy. Must be done prior to parsing
* GRL so that Linux resources can be reserved correctly */
- rmInst->validInstances = rmPolicyCreateValidInstTree(rmInst->policy, addLinux, result);
- /* Validate policy assignment strings */
- *result = rmPolicyValidatePolicy(rmInst->policy, rmInst->validInstances);
+ rmInst->u.server.globalValidInstTree = rmPolicyCreateValidInstTree((Rm_Handle)rmInst, addLinux, result);
+ if (*result == RM_OK) {
+ *result = rmPolicyValidatePolicy((Rm_Handle)rmInst);
+ }
+
+ if (*result != RM_OK) {
+ if (rmInst->u.server.globalValidInstTree) {
+ rmPolicyFreeValidInstTree((Rm_Handle)rmInst);
+ }
+ goto errorExit;
+ }
+ else {
+ rmNameServerInit((Rm_Handle)rmInst);
- rmInst->nameServer = rmNameServerInit();
+ globalResourceDtb = initCfg->instCfg.serverCfg.globalResourceList;
- globalResourceDtb = initCfg->instCfg.serverCfg.globalResourceList;
- fdt_open_into(globalResourceDtb, globalResourceDtb, fdt_totalsize(globalResourceDtb));
+ if ((*result = rmAllocatorInitializeResources((Rm_Handle) rmInst, globalResourceDtb, linuxResourceDtb)) == RM_OK) {
+ *result = rmPolicyValidatePolicyResourceNames((Rm_Handle)rmInst);
+ }
- if ((*result = rmAllocatorInitializeResources((Rm_Handle) rmInst, globalResourceDtb, linuxResourceDtb)) == RM_OK) {
- *result = rmPolicyValidatePolicyResourceNames(rmInst->policy, (void *)rmInst->allocators);
- }
- if (*result < RM_OK) {
- Rm_osalFree((void *)rmInst, sizeof(Rm_Inst));
- return(NULL);
+ if (*result != RM_OK) {
+ rmAllocatorDeleteResources((Rm_Handle)rmInst);
+ rmNameServerDelete((Rm_Handle)rmInst);
+ goto errorExit;
+ }
}
}
+ else if (rmInst->instType == Rm_instType_CLIENT_DELEGATE) {
+ if (!initCfg->instCfg.cdCfg.cdPolicy) {
+ *result = RM_ERROR_INVALID_CD_CONFIGURATION;
+ goto errorExit;
+ }
- if ((rmInst->instType == Rm_instType_CLIENT) &&
- (initCfg->instCfg.clientCfg.staticPolicy)) {
- rmInst->staticInfo.staticPolicy = initCfg->instCfg.clientCfg.staticPolicy;
- }
- else if ((rmInst->instType == Rm_instType_CLIENT_DELEGATE) &&
- (initCfg->instCfg.cdCfg.staticPolicy)) {
- rmInst->staticInfo.staticPolicy = initCfg->instCfg.cdCfg.staticPolicy;
- }
- if (rmInst->staticInfo.staticPolicy) {
- fdt_open_into(rmInst->staticInfo.staticPolicy, rmInst->staticInfo.staticPolicy,
- fdt_totalsize(rmInst->staticInfo.staticPolicy));
- rmInst->staticInfo.staticValidInstTree = rmPolicyCreateValidInstTree(rmInst->staticInfo.staticPolicy,
- addLinux, result);
+ rmInst->u.cd.cdPolicy = initCfg->instCfg.cdCfg.cdPolicy;
+ rmInst->u.cd.cdValidInstTree = rmPolicyCreateValidInstTree((Rm_Handle)rmInst, addLinux, result);
if (*result == RM_OK) {
- /* Validate policy assignment strings */
- *result = rmPolicyValidatePolicy(rmInst->staticInfo.staticPolicy, rmInst->staticInfo.staticValidInstTree);
+ *result = rmPolicyValidatePolicy((Rm_Handle)rmInst);
}
+
if (*result != RM_OK) {
- if (rmInst->staticInfo.staticValidInstTree) {
- rmPolicyFreeValidInstTree(rmInst->staticInfo.staticValidInstTree);
+ if (rmInst->u.cd.cdValidInstTree) {
+ rmPolicyFreeValidInstTree((Rm_Handle)rmInst);
+ }
+ goto errorExit;
+ }
+
+ rmInst->u.cd.allocators = NULL;
+ }
+ else if (rmInst->instType == Rm_instType_CLIENT) {
+ if (initCfg->instCfg.clientCfg.staticPolicy) {
+ rmInst->u.client.staticPolicy = initCfg->instCfg.clientCfg.staticPolicy;
+ rmInst->u.client.staticValidInstTree = rmPolicyCreateValidInstTree((Rm_Handle)rmInst, addLinux, result);
+ if (*result == RM_OK) {
+ *result = rmPolicyValidatePolicy((Rm_Handle)rmInst);
+ }
+
+ if (*result != RM_OK) {
+ if (rmInst->u.client.staticValidInstTree) {
+ rmPolicyFreeValidInstTree((Rm_Handle)rmInst);
+ }
+ goto errorExit;
+ }
+ }
+ }
+ else if (rmInst->instType == Rm_instType_SHARED_CLIENT) {
+ if (initCfg->instCfg.sharedClientCfg.sharedServerHandle) {
+ rmInst->u.sharedClient.sharedServerHandle = initCfg->instCfg.sharedClientCfg.sharedServerHandle;
+ /* Invalidate the Shared server instance structure on this core to get the latest
+ * instance data. */
+ key = Rm_osalCsEnter();
+ Rm_osalBeginMemAccess((void *)rmInst->u.sharedClient.sharedServerHandle, sizeof(Rm_Inst));
+ sharedServerInst = rmInst->u.sharedClient.sharedServerHandle;
+ if (sharedServerInst->instType != Rm_instType_SHARED_SERVER) {
+ *result = RM_ERROR_INVALID_SHARED_SERVER_HANDLE;
+ Rm_osalCsExit(key);
+ goto errorExit;
+ }
+ else {
+ /* Invalidate the policy */
+ Rm_osalBeginMemAccess((void *)sharedServerInst->u.server.globalPolicy,
+ sharedServerInst->u.server.policySize);
}
- Rm_osalFree((void *)rmInst, sizeof(Rm_Inst));
- rmInst = NULL;
+ Rm_osalCsExit(key);
+ }
+ else {
+ *result = RM_ERROR_INVALID_SHARED_SERVER_HANDLE;
+ goto errorExit;
}
}
+
+ if (initCfg->instType == Rm_instType_SHARED_SERVER) {
+ /* Writeback the instance and policy for other cores */
+ Rm_osalEndMemAccess ((void *)rmInst, sizeof(Rm_Inst));
+ Rm_osalEndMemAccess ((void *)rmInst->u.server.globalPolicy, rmInst->u.server.policySize);
+ }
+ else if (rmInst->instType != Rm_instType_SHARED_CLIENT) {
+ /* Create the instance's task blocking mechanism */
+ rmInst->blockHandle = Rm_osalTaskBlockCreate();
+ }
+
return ((Rm_Handle) rmInst);
+errorExit:
+ if (rmInst) {
+ Rm_osalFree((void *)rmInst, sizeof(Rm_Inst));
+ }
+ return (NULL);
+}
+
+/* FUNCTION PURPOSE: Deletes an RM instance
+ ***********************************************************************
+ * DESCRIPTION: Frees all memory associated with an RM instance
+ * as long as all transports have been unregistered
+ * and the service handle has been closed
+ */
+int32_t Rm_delete(Rm_Handle rmHandle, int ignorePendingServices)
+{
+ Rm_Inst *rmInst = (Rm_Inst *)rmHandle;
+ void *key;
+
+ key = Rm_osalCsEnter();
+ if (rmInst->instType == Rm_instType_SHARED_SERVER) {
+ Rm_osalBeginMemAccess((void *)rmInst, sizeof(Rm_Inst));
+ }
+
+ if (rmInst->serviceHandle) {
+ return (RM_ERROR_CANT_DELETE_WITH_OPEN_SERV_HNDL);
+ }
+ else if (rmInst->transports) {
+ return (RM_ERROR_CANT_DELETE_WITH_REGD_TRANSPORT);
+ }
+ else if (rmInst->transactionQueue && !ignorePendingServices) {
+ return (RM_ERROR_CANT_DELETE_PENDING_TRANSACTIONS);
+ }
+
+ if ((rmInst->instType == Rm_instType_SERVER) ||
+ (rmInst->instType == Rm_instType_SHARED_SERVER)) {
+ rmAllocatorDeleteResources(rmHandle);
+ rmNameServerDelete(rmHandle);
+ rmInst->u.server.allocators = NULL;
+
+ if (rmInst->instType == Rm_instType_SHARED_SERVER) {
+ Rm_osalFree((void *)rmInst->u.server.globalPolicy, rmInst->u.server.policySize);
+ }
+ }
+ else if (rmInst->instType == Rm_instType_CLIENT_DELEGATE) {
+ rmAllocatorDeleteResources(rmHandle);
+ rmInst->u.cd.allocators = NULL;
+ }
+
+ if (rmInst->instType != Rm_instType_SHARED_CLIENT) {
+ /* Delete valid instance tree */
+ rmPolicyFreeValidInstTree(rmHandle);
+
+ /* Delete any transactions */
+ while(rmInst->transactionQueue) {
+ rmTransactionQueueDelete(rmInst, rmInst->transactionQueue->localId);
+ }
+
+ if (rmInst->instType != Rm_instType_SHARED_SERVER) {
+ /* Delete the instance's task blocking mechanism */
+ Rm_osalTaskBlockDelete(rmInst->blockHandle);
+ }
+ else {
+ Rm_osalEndMemAccess((void *)rmInst, sizeof(Rm_Inst));
+ }
+ }
+
+ Rm_osalFree((void *)rmInst, sizeof(Rm_Inst));
+
+ Rm_osalCsExit(key);
+ return (RM_OK);
}
/* FUNCTION PURPOSE: Returns RM version information
***********************************************************************
*/
-uint32_t Rm_getVersion (void)
+uint32_t Rm_getVersion(void)
{
return RM_VERSION_ID;
}
/* FUNCTION PURPOSE: Returns RM version string
***********************************************************************
*/
-const char* Rm_getVersionStr (void)
+const char* Rm_getVersionStr(void)
{
return rmVersionStr;
}