summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 5f7aec7)
raw | patch | inline | side by side (parent: 5f7aec7)
author | Justin Sobota <jsobota@ti.com> | |
Tue, 12 Feb 2013 19:37:49 +0000 (14:37 -0500) | ||
committer | Justin Sobota <jsobota@ti.com> | |
Tue, 12 Feb 2013 19:37:49 +0000 (14:37 -0500) |
rm.h | patch | blob | history | |
src/rm.c | patch | blob | history | |
test/rm_test.c | patch | blob | history |
index e41967289eb2bda043899d510cfcdbcc417ec365..03cdd3f6b0d90407b92e6c421ad45f25c5716947 100644 (file)
--- a/rm.h
+++ b/rm.h
#define RM_ERROR_ALREADY_REGD_SERVER_OR_CD RM_ERROR_BASE-37
/** Transport registration callout function pointers specified as valid but were NULL */
#define RM_ERROR_NULL_CALLOUTS_WHEN_VALID RM_ERROR_BASE-38
-/** Service both a NameServer name and a base, length, or alignment */
+/** Service has both a NameServer name and a base, length, or alignment specified */
#define RM_ERROR_NS_NAME_AND_RES_VAL_CONFLICT RM_ERROR_BASE-39
/** Instance type not recognized */
#define RM_ERROR_INVALID_INST_TYPE RM_ERROR_BASE-40
diff --git a/src/rm.c b/src/rm.c
index 8972186ad07b810f9139751f77649662233c14f7..96dbf83ab7345f0fa936397e95fc49cc298d7865 100644 (file)
--- a/src/rm.c
+++ b/src/rm.c
@@ -568,167 +568,176 @@ static int32_t treeAllocate(Rm_Inst *rmInst, Rm_Allocator *allocator, int32_t re
retVal = RM_SERVICE_DENIED_USE_PERM_NOT_GIVEN;\r
}\r
}\r
- \r
- if (allocPassesPolicy && (matchingNode->allocationCount > 0)) {\r
- /* Check exclusive privileges of instance requesting resource. Requesting\r
- * instance with exclusive privileges can't reserve resource if already owned*/\r
- policyCheckCfg.type = Rm_policyCheck_EXCLUSIVE;\r
- policyCheckCfg.validInstNode = opInfo->serviceSrcInstNode;\r
- allocPassesPolicy = !rmPolicyCheckPrivilege(&policyCheckCfg, &retVal);\r
- if (!allocPassesPolicy) {\r
- retVal = RM_SERVICE_DENIED_EXCLUSIVE_RES_ALLOCD;\r
+\r
+ if (!isOwnedBy(matchingNode, opInfo->serviceSrcInstNode)) {\r
+ /* Perform exclusive checks if requesting instance does not already an\r
+ * owner of the resource */\r
+ if (allocPassesPolicy && (matchingNode->allocationCount > 0)) {\r
+ /* Check exclusive privileges of instance requesting resource. Requesting\r
+ * instance with exclusive privileges can't reserve resource if already owned*/\r
+ policyCheckCfg.type = Rm_policyCheck_EXCLUSIVE;\r
+ policyCheckCfg.validInstNode = opInfo->serviceSrcInstNode;\r
+ allocPassesPolicy = !rmPolicyCheckPrivilege(&policyCheckCfg, &retVal);\r
+ if (!allocPassesPolicy) {\r
+ retVal = RM_SERVICE_DENIED_EXCLUSIVE_RES_ALLOCD;\r
+ }\r
}\r
+ if (allocPassesPolicy && (matchingNode->allocationCount == 1)) {\r
+ /* Check exclusive privileges of instance that currently owns resource */\r
+ policyCheckCfg.type = Rm_policyCheck_EXCLUSIVE;\r
+ policyCheckCfg.validInstNode = matchingNode->ownerList->instNameNode;\r
+ allocPassesPolicy = !rmPolicyCheckPrivilege(&policyCheckCfg, &retVal);\r
+ if (!allocPassesPolicy) {\r
+ retVal = RM_SERVICE_DENIED_ALLOCD_TO_EXCLUSIVE_INST;\r
+ } \r
+ } \r
}\r
- if (allocPassesPolicy && (matchingNode->allocationCount == 1)) {\r
- /* Check exclusive privileges of instance that currently owns resource */\r
- policyCheckCfg.type = Rm_policyCheck_EXCLUSIVE;\r
- policyCheckCfg.validInstNode = matchingNode->ownerList->instNameNode;\r
- allocPassesPolicy = !rmPolicyCheckPrivilege(&policyCheckCfg, &retVal);\r
- if (!allocPassesPolicy) {\r
- retVal = RM_SERVICE_DENIED_ALLOCD_TO_EXCLUSIVE_INST;\r
- } \r
- } \r
}\r
\r
- if (allocPassesPolicy) { \r
- if ((findNode.base == matchingNode->base) && (findEnd == matchingEnd)) {\r
- /* findNode range matches matchingNode range\r
- *\r
- * |<--left node-->||<--matched node-->||<--right node-->| => existing node\r
- * |<--alloc request-->| => requested resources\r
- */ \r
- leftNode = RB_PREV(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);\r
- rightNode = RB_NEXT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);\r
- RB_REMOVE(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);\r
- addOwner(matchingNode, opInfo->serviceSrcInstNode);\r
-\r
- if (leftNode && compareResourceNodeOwners(leftNode, matchingNode)) {\r
- RB_REMOVE(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, leftNode);\r
- combineLeft = true;\r
- }\r
- if (rightNode && compareResourceNodeOwners(rightNode, matchingNode)) {\r
- RB_REMOVE(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, rightNode);\r
- combineRight = true;\r
- }\r
-\r
- if (combineLeft && combineRight) {\r
- /* Combine all three nodes into matchingNode */\r
- matchingNode->base = leftNode->base;\r
- matchingNode->length = leftNode->length + matchingNode->length + rightNode->length;\r
-\r
- clearOwners(leftNode);\r
- rmResourceNodeFree(leftNode);\r
- clearOwners(rightNode);\r
- rmResourceNodeFree(rightNode); \r
- }\r
- else if (combineLeft) {\r
- /* Combine left and matching nodes. Reinsert right. */\r
- matchingNode->base = leftNode->base;\r
- matchingNode->length += leftNode->length;\r
-\r
- clearOwners(leftNode);\r
- rmResourceNodeFree(leftNode);\r
- RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, rightNode); \r
- }\r
- else if (combineRight) {\r
- /* Combine right and matching nodes. Reinsert left. */\r
- matchingNode->length += rightNode->length;\r
-\r
- clearOwners(rightNode);\r
- rmResourceNodeFree(rightNode);\r
- RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, leftNode);\r
- }\r
- else {\r
- /* No combine. */\r
- RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, leftNode);\r
- RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, rightNode);\r
- }\r
-\r
- /* Always reinsert matchingNode */ \r
- RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode); \r
- } \r
- else if ((findNode.base > matchingNode->base) && (findEnd < matchingEnd)) {\r
- /* findNode range is subset of matchingNode range and neither boundary is\r
- * equivalent.\r
- *\r
- * |<----------matched node---------->|\r
- * |<---alloc request--->|\r
- */ \r
- RB_REMOVE(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);\r
- leftNode = rmResourceNodeNew(matchingNode->base, findNode.base - matchingNode->base);\r
- copyOwners(leftNode, matchingNode);\r
- rightNode = rmResourceNodeNew(findNode.base + findNode.length, matchingEnd - findEnd);\r
- copyOwners(rightNode, matchingNode);\r
-\r
- matchingNode->base = findNode.base; \r
- matchingNode->length = findNode.length;\r
- addOwner(matchingNode, opInfo->serviceSrcInstNode);\r
-\r
- /* Insert all the nodes */\r
- RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);\r
- RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, leftNode);\r
- RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, rightNode);\r
- } \r
- else { \r
- if (findNode.base == matchingNode->base) {\r
- /* findNode base and matchingNode base are equivalent. May be combine\r
- * possibilities to the left\r
+ if (allocPassesPolicy) {\r
+ if (!isOwnedBy(matchingNode, opInfo->serviceSrcInstNode)) {\r
+ /* Handle any possible node combinations if requesting instance is\r
+ * not already in resource's owner list. Automatic approval if requesting\r
+ * instance is already in owner list. */\r
+ if ((findNode.base == matchingNode->base) && (findEnd == matchingEnd)) {\r
+ /* findNode range matches matchingNode range\r
*\r
- * |<---left node (alloc'd)--->||<----------matched node---------->|\r
- * |<---findNode (alloc req)--->|\r
- */ \r
+ * |<--left node-->||<--matched node-->||<--right node-->| => existing node\r
+ * |<--alloc request-->| => requested resources\r
+ */ \r
leftNode = RB_PREV(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);\r
+ rightNode = RB_NEXT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);\r
RB_REMOVE(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);\r
- /* Add allocating instance to owner list for compare with leftNode */\r
addOwner(matchingNode, opInfo->serviceSrcInstNode);\r
- \r
+\r
if (leftNode && compareResourceNodeOwners(leftNode, matchingNode)) {\r
RB_REMOVE(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, leftNode);\r
- /* Combine leftNode and findNode */\r
- leftNode->length += findNode.length;\r
+ combineLeft = true;\r
}\r
- else {\r
- leftNode = rmResourceNodeNew(findNode.base, findNode.length);\r
- copyOwners(leftNode, matchingNode);\r
+ if (rightNode && compareResourceNodeOwners(rightNode, matchingNode)) {\r
+ RB_REMOVE(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, rightNode);\r
+ combineRight = true;\r
}\r
\r
- /* Account for leftNode in matchingNode */\r
- matchingNode->base = findNode.base + findNode.length;\r
- matchingNode->length = matchingEnd - findEnd; \r
+ if (combineLeft && combineRight) {\r
+ /* Combine all three nodes into matchingNode */\r
+ matchingNode->base = leftNode->base;\r
+ matchingNode->length = leftNode->length + matchingNode->length + rightNode->length;\r
\r
- RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, leftNode);\r
- }\r
- else if (findEnd == matchingEnd) {\r
- /* findNode end and matchingNode end are equivalent. May be combine\r
- * possibilities to the right\r
- *\r
- * |<----------matched node---------->||<---right node (alloc'd)--->|\r
- * |<---findNode (alloc req)--->| \r
- */ \r
- rightNode = RB_NEXT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);\r
- RB_REMOVE(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);\r
- /* Add allocating instance to owner list for compare with rightNode */\r
- addOwner(matchingNode, opInfo->serviceSrcInstNode);\r
- \r
- if (rightNode && compareResourceNodeOwners(rightNode, matchingNode)) {\r
- RB_REMOVE(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, rightNode);\r
- /* Combine rightNode and findNode */\r
- rightNode->base = findNode.base;\r
- rightNode->length += findNode.length;\r
+ clearOwners(leftNode);\r
+ rmResourceNodeFree(leftNode);\r
+ clearOwners(rightNode);\r
+ rmResourceNodeFree(rightNode); \r
+ }\r
+ else if (combineLeft) {\r
+ /* Combine left and matching nodes. Reinsert right. */\r
+ matchingNode->base = leftNode->base;\r
+ matchingNode->length += leftNode->length;\r
+\r
+ clearOwners(leftNode);\r
+ rmResourceNodeFree(leftNode);\r
+ RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, rightNode); \r
+ }\r
+ else if (combineRight) {\r
+ /* Combine right and matching nodes. Reinsert left. */\r
+ matchingNode->length += rightNode->length;\r
+\r
+ clearOwners(rightNode);\r
+ rmResourceNodeFree(rightNode);\r
+ RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, leftNode);\r
}\r
else {\r
- rightNode = rmResourceNodeNew(findNode.base, findNode.length);\r
- copyOwners(rightNode, matchingNode);\r
+ /* No combine. */\r
+ RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, leftNode);\r
+ RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, rightNode);\r
}\r
\r
- /* Account for rightNode in matchingNode */\r
- matchingNode->length -= findNode.length; \r
+ /* Always reinsert matchingNode */ \r
+ RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode); \r
+ } \r
+ else if ((findNode.base > matchingNode->base) && (findEnd < matchingEnd)) {\r
+ /* findNode range is subset of matchingNode range and neither boundary is\r
+ * equivalent.\r
+ *\r
+ * |<----------matched node---------->|\r
+ * |<---alloc request--->|\r
+ */ \r
+ RB_REMOVE(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);\r
+ leftNode = rmResourceNodeNew(matchingNode->base, findNode.base - matchingNode->base);\r
+ copyOwners(leftNode, matchingNode);\r
+ rightNode = rmResourceNodeNew(findNode.base + findNode.length, matchingEnd - findEnd);\r
+ copyOwners(rightNode, matchingNode);\r
+\r
+ matchingNode->base = findNode.base; \r
+ matchingNode->length = findNode.length;\r
+ addOwner(matchingNode, opInfo->serviceSrcInstNode);\r
\r
+ /* Insert all the nodes */\r
+ RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);\r
+ RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, leftNode);\r
RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, rightNode);\r
+ } \r
+ else { \r
+ if (findNode.base == matchingNode->base) {\r
+ /* findNode base and matchingNode base are equivalent. May be combine\r
+ * possibilities to the left\r
+ *\r
+ * |<---left node (alloc'd)--->||<----------matched node---------->|\r
+ * |<---findNode (alloc req)--->|\r
+ */ \r
+ leftNode = RB_PREV(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);\r
+ RB_REMOVE(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);\r
+ /* Add allocating instance to owner list for compare with leftNode */\r
+ addOwner(matchingNode, opInfo->serviceSrcInstNode);\r
+ \r
+ if (leftNode && compareResourceNodeOwners(leftNode, matchingNode)) {\r
+ RB_REMOVE(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, leftNode);\r
+ /* Combine leftNode and findNode */\r
+ leftNode->length += findNode.length;\r
+ }\r
+ else {\r
+ leftNode = rmResourceNodeNew(findNode.base, findNode.length);\r
+ copyOwners(leftNode, matchingNode);\r
+ }\r
+\r
+ /* Account for leftNode in matchingNode */\r
+ matchingNode->base = findNode.base + findNode.length;\r
+ matchingNode->length = matchingEnd - findEnd; \r
+\r
+ RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, leftNode);\r
+ }\r
+ else if (findEnd == matchingEnd) {\r
+ /* findNode end and matchingNode end are equivalent. May be combine\r
+ * possibilities to the right\r
+ *\r
+ * |<----------matched node---------->||<---right node (alloc'd)--->|\r
+ * |<---findNode (alloc req)--->| \r
+ */ \r
+ rightNode = RB_NEXT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);\r
+ RB_REMOVE(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);\r
+ /* Add allocating instance to owner list for compare with rightNode */\r
+ addOwner(matchingNode, opInfo->serviceSrcInstNode);\r
+ \r
+ if (rightNode && compareResourceNodeOwners(rightNode, matchingNode)) {\r
+ RB_REMOVE(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, rightNode);\r
+ /* Combine rightNode and findNode */\r
+ rightNode->base = findNode.base;\r
+ rightNode->length += findNode.length;\r
+ }\r
+ else {\r
+ rightNode = rmResourceNodeNew(findNode.base, findNode.length);\r
+ copyOwners(rightNode, matchingNode);\r
+ }\r
+\r
+ /* Account for rightNode in matchingNode */\r
+ matchingNode->length -= findNode.length; \r
+\r
+ RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, rightNode);\r
+ }\r
+ /* Remove allocating instance from leftover matchingNode */\r
+ deleteOwner(matchingNode, opInfo->serviceSrcInstNode);\r
+ RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);\r
}\r
- /* Remove allocating instance from leftover matchingNode */\r
- deleteOwner(matchingNode, opInfo->serviceSrcInstNode);\r
- RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);\r
}\r
retVal = RM_SERVICE_APPROVED;\r
}\r
diff --git a/test/rm_test.c b/test/rm_test.c
index e0b4a641751846311795404d38945f1c6b6f4b3a..b852246d4c7fee4fd9087b07076a9a40fb1e879f 100644 (file)
--- a/test/rm_test.c
+++ b/test/rm_test.c
/* Wait for Client and Client Delegate to do their UNSPECIFIED allocates */
waitOnSyncObj();
- Rm_printResourceStatus(rmServerHandle);
+ Rm_printResourceStatus(rmServerHandle);
+
+ /* Test allocation of a resource twice from the same instance with init and use privileges. Both
+ * should be approved but the instance should only be mentioned once in the resource's owner list */
+ memset((void *) &requestInfo, 0, sizeof(Rm_ServiceReqInfo));
+ requestInfo.type = Rm_service_RESOURCE_ALLOCATE_INIT;
+ requestInfo.resourceName = resourceNameGpQ;
+ requestInfo.resourceBase = 6543;
+ requestInfo.resourceLength = 10;
+ requestInfo.callback.serviceCallback = testServiceCallback;
+ System_printf("Core %d: %s Allocating resource for init...\n", MultiProc_self(), rmServerName);
+ rmServerServiceHandle->Rm_serviceHandler(rmServerServiceHandle->rmHandle, &requestInfo, &responseInfo);
+ if ((responseInfo.serviceState == RM_SERVICE_APPROVED) ||
+ (responseInfo.serviceState == RM_SERVICE_PROCESSING)) {
+ if (blockForResponse(&responseInfo)) {
+ System_printf("Core %d: %s allocate resource: %s base: %d length: %d\n", MultiProc_self(),
+ rmServerName,
+ requestInfo.resourceName,
+ requestInfo.resourceBase,
+ requestInfo.resourceLength);
+ }
+ }
+ else {
+ System_printf("Core %d: Static allocation failed with error: %d\n", MultiProc_self(),
+ responseInfo.serviceState);
+ }
+ memset((void *) &requestInfo, 0, sizeof(Rm_ServiceReqInfo));
+ requestInfo.type = Rm_service_RESOURCE_ALLOCATE_USE;
+ requestInfo.resourceName = resourceNameGpQ;
+ requestInfo.resourceBase = 6543;
+ requestInfo.resourceLength = 10;
+ requestInfo.callback.serviceCallback = testServiceCallback;
+
+ System_printf("Core %d: %s Allocating same resource for use...\n", MultiProc_self(), rmServerName);
+ rmServerServiceHandle->Rm_serviceHandler(rmServerServiceHandle->rmHandle, &requestInfo, &responseInfo);
+ if ((responseInfo.serviceState == RM_SERVICE_APPROVED) ||
+ (responseInfo.serviceState == RM_SERVICE_PROCESSING)) {
+ if (blockForResponse(&responseInfo)) {
+ System_printf("Core %d: %s allocate resource: %s base: %d length: %d\n", MultiProc_self(),
+ rmServerName,
+ requestInfo.resourceName,
+ requestInfo.resourceBase,
+ requestInfo.resourceLength);
+ }
+ }
+ else {
+ System_printf("Core %d: Static allocation failed with error: %d\n", MultiProc_self(),
+ responseInfo.serviceState);
+ }
+
+ Rm_printResourceStatus(rmServerHandle);
}
else if (MultiProc_self() == 1) {
/* Issue the service request for the resources tied to the name via the service port */