]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - keystone-rtos/rm-lld.git/blobdiff - src/rm_allocator.c
Made requesting instance's allocation count for resource available via the service...
[keystone-rtos/rm-lld.git] / src / rm_allocator.c
index d3f700a3dbf76c61acde23de3f9efeb8c9c0f896..c18b64502b7888f432a9c2ebaba34bc7989ef140 100644 (file)
 static Rm_Allocator *allocatorAdd(Rm_Handle rmHandle, const char *resourceName)
 {
     Rm_Inst      *rmInst = (Rm_Inst *)rmHandle;
-    Rm_Allocator *allocators   = rmInst->u.server.allocators;
+    Rm_Allocator *allocators   = rmAllocatorGetAllocatorList(rmHandle);
     Rm_Allocator *newAllocator = NULL;
 
-    newAllocator = Rm_osalMalloc(sizeof(Rm_Allocator));
+    newAllocator = Rm_osalMalloc(sizeof(*allocators));
 
     if (newAllocator) {
-        memset((void *)newAllocator, 0, sizeof(Rm_Allocator));
+        memset((void *)newAllocator, 0, sizeof(*newAllocator));
         strncpy(newAllocator->resourceName, resourceName, RM_NAME_MAX_CHARS);
         newAllocator->allocatorRootEntry = NULL;
         newAllocator->nextAllocator = NULL;  
@@ -88,121 +88,171 @@ static Rm_Allocator *allocatorAdd(Rm_Handle rmHandle, const char *resourceName)
                 allocators = allocators->nextAllocator;
             }
             allocators->nextAllocator = newAllocator;
+            RM_SS_OBJ_WB(allocators, Rm_Allocator);
         }
         else {
-            rmInst->u.server.allocators = newAllocator;
+            if ((rmInst->instType == Rm_instType_SERVER) ||
+                (rmInst->instType == Rm_instType_SHARED_SERVER)) {
+                rmInst->u.server.allocators = newAllocator;
+            }
+            else if (rmInst->instType == Rm_instType_CLIENT_DELEGATE) {
+                rmInst->u.cd.allocators = newAllocator;
+            }            
         }
     }
     return (newAllocator);
 }
 
-/* FUNCTION PURPOSE: Deletes a resource allocator
+/* FUNCTION PURPOSE: Checks a resource node's ownership
  ***********************************************************************
- * DESCRIPTION: Deletes a resource allocator based on the given
- *              resource name.  The resource allocator will be
- *              removed from the RM instance allocator list.
+ * DESCRIPTION: Returns the owner reference count if the provided
+ *              instance node is in the list of resource node owners.  Otherwise,
+ *              returns 0.
  */
-static int32_t allocatorDelete(Rm_Handle rmHandle, char *resourceName)
+static int allocatorResNodeIsOwnedBy(Rm_Handle rmHandle, Rm_ResourceNode *node, Rm_PolicyValidInstNode *serviceInstNode)
 {
-    Rm_Inst      *rmInst = (Rm_Inst *)rmHandle;    
-    Rm_Allocator *allocator = rmInst->u.server.allocators;
-    Rm_Allocator *prevAllocator = NULL;
-    int32_t       retVal = RM_OK;
+    Rm_Inst  *rmInst = (Rm_Inst *)rmHandle;
+    Rm_Owner *owner = node->ownerList;
 
-    while (allocator) {
-        if (strncmp(allocator->resourceName, resourceName, RM_NAME_MAX_CHARS) == 0) {
-            break;             
+    while (owner) {
+        RM_SS_OBJ_INV(owner, Rm_Owner);
+        if (owner->instNameNode == serviceInstNode) {
+            return(owner->refCnt);           
         }
-        prevAllocator = allocator;
-        allocator = allocator->nextAllocator;
+        owner = owner->nextOwner;
     }
+    return(0);
+}
 
-    if (allocator) {
-        if (prevAllocator == NULL) {
-            rmInst->u.server.allocators = allocator->nextAllocator;
-        }
-        else {
-            prevAllocator->nextAllocator = allocator->nextAllocator;
+/* FUNCTION PURPOSE: Increments an owner's refCnt
+ ***********************************************************************
+ * DESCRIPTION: Increments a resource owner's reference count
+ */
+static void allocatorResNodeOwnerRefCntInc(Rm_Handle rmHandle, Rm_ResourceNode *node, Rm_PolicyValidInstNode *serviceInstNode)
+{
+    Rm_Inst  *rmInst = (Rm_Inst *)rmHandle;
+    Rm_Owner *owner = node->ownerList;
+
+    while (owner) {
+        RM_SS_OBJ_INV(owner, Rm_Owner);
+        if (owner->instNameNode == serviceInstNode) {
+            owner->refCnt++;
+            RM_SS_OBJ_WB(owner, Rm_Owner);
+            break;
         }
-        Rm_osalFree((void *)allocator, sizeof(Rm_Allocator));
-    }
-    else {
-        retVal = RM_ERROR_RES_ALLOCATOR_DOES_NOT_EXIST;
+        owner = owner->nextOwner;
     }
-    return (retVal);
 }
 
-/* FUNCTION PURPOSE: Creates a new resource tree
+/* FUNCTION PURPOSE: Decrements an owner's refCnt
  ***********************************************************************
- * DESCRIPTION: Creates and populates a new resource tree allocator
- *              using the provided resource name and value range.  The
- *              name and value originate from the GRL.
+ * DESCRIPTION: Decrements a resource owner's reference count
  */
-static int32_t allocatorCreate(Rm_Handle rmHandle, const char *resourceName, Rm_ResourceRange *range)
+static void allocatorResNodeOwnerRefCntDec(Rm_Handle rmHandle, Rm_ResourceNode *node, Rm_PolicyValidInstNode *serviceInstNode)
 {
-    Rm_Allocator    *allocator = NULL;
-    Rm_ResourceTree *treeRootEntry = NULL;
-    Rm_ResourceNode *treeNode = NULL;
-    Rm_ResourceNode *collidingNode = NULL;
+    Rm_Inst  *rmInst = (Rm_Inst *)rmHandle;
+    Rm_Owner *owner = node->ownerList;
 
-    allocator = allocatorAdd(rmHandle, resourceName);
-    treeRootEntry = Rm_osalMalloc(sizeof(Rm_ResourceTree));
-    RB_INIT(treeRootEntry);
+    while (owner) {
+        RM_SS_OBJ_INV(owner, Rm_Owner);
+        if (owner->instNameNode == serviceInstNode) {
+            owner->refCnt--;
+            RM_SS_OBJ_WB(owner, Rm_Owner);
+            break;
+        }
+        owner = owner->nextOwner;
+    }
+}
 
-    while (range != NULL) {
-        treeNode = rmResourceNodeNew(range->base, range->length);
-        collidingNode = RB_INSERT(_Rm_AllocatorResourceTree, treeRootEntry, treeNode);
+/* FUNCTION PURPOSE: Returns an owner's refCnt
+ ***********************************************************************
+ * DESCRIPTION: Returns a resource owner's reference count
+ */
+static uint16_t allocatorResNodeOwnerGetRefCnt(Rm_Handle rmHandle, Rm_ResourceNode *node, Rm_PolicyValidInstNode *serviceInstNode)
+{
+    Rm_Inst  *rmInst = (Rm_Inst *)rmHandle;
+    Rm_Owner *owner = node->ownerList;
 
-        if (collidingNode) {
-            Rm_ResourceNode *nextNode = NULL;
-            
-            /* Node that was inserted collides with existing node.  Destroy tree and return error */
-            for (treeNode = RB_MIN(_Rm_AllocatorResourceTree, treeRootEntry); treeNode != NULL; treeNode = nextNode) {
-                       nextNode = RB_NEXT(_Rm_AllocatorResourceTree, treeRootEntry, treeNode);
-                       RB_REMOVE(_Rm_AllocatorResourceTree, treeRootEntry, nextNode);
-                rmResourceNodeFree(treeNode);
-               }
-            Rm_osalFree((void *)treeRootEntry, sizeof(Rm_ResourceTree));
-            allocatorDelete(rmHandle, allocator->resourceName);
-            return (RM_ERROR_GRL_RES_SPECIFIED_MORE_THAN_ONCE);
+    while (owner) {
+        RM_SS_OBJ_INV(owner, Rm_Owner);
+        if (owner->instNameNode == serviceInstNode) {
+            return (owner->refCnt);
         }
-        range = range->nextRange;
+        owner = owner->nextOwner;
     }
-    
-    allocator->allocatorRootEntry = treeRootEntry;
-    return(RM_OK);
+
+    return(0);
 }
 
 /* FUNCTION PURPOSE: Adds an owner to an allocator resource
  ***********************************************************************
  * DESCRIPTION: Adds a RM instance node to a resource node's
- *              list of owners.
+ *              list of owners.  If the owner is already present that
+ *              owner's reference count is incremented
  */
-static void allocatorResNodeOwnerAdd(Rm_ResourceNode *node, void *serviceInstNode)
+static void allocatorResNodeOwnerAdd(Rm_Handle rmHandle, Rm_ResourceNode *node, Rm_PolicyValidInstNode *serviceInstNode)
 {
+    Rm_Inst  *rmInst = (Rm_Inst *)rmHandle;    
     Rm_Owner *ownerList = node->ownerList;
     Rm_Owner *newOwner = NULL;
 
-    newOwner = Rm_osalMalloc(sizeof(Rm_Owner));
+    if (allocatorResNodeIsOwnedBy(rmHandle, node, serviceInstNode)) {
+        allocatorResNodeOwnerRefCntInc(rmHandle, node, serviceInstNode);
+    }
+    else {
+        newOwner = Rm_osalMalloc(sizeof(*newOwner));
+
+        if (newOwner) {
+            newOwner->instNameNode = serviceInstNode;
+            newOwner->refCnt = 0;
+            newOwner->nextOwner = NULL;  
+
+            /* Add owner entry to end of list */
+            if (ownerList) {
+                RM_SS_OBJ_INV(ownerList, Rm_Owner);
+                while (ownerList->nextOwner) {
+                    ownerList = ownerList->nextOwner;
+                    RM_SS_OBJ_INV(ownerList, Rm_Owner);
+                }
+                ownerList->nextOwner = newOwner;
+                RM_SS_OBJ_WB(ownerList, Rm_Owner);
+            }
+            else {
+                node->ownerList = newOwner;
+            }
 
-    if (newOwner) {
-        newOwner->instNameNode = serviceInstNode;
-        newOwner->nextOwner = NULL;  
+            node->allocationCount++;
+            newOwner->refCnt++;
+            newOwner->instNameNode->allocRefCount++;
+            RM_SS_OBJ_WB(newOwner, Rm_Owner);
+            RM_SS_OBJ_WB(newOwner->instNameNode, Rm_PolicyValidInstNode);
+        }
+    }
+}
 
-        /* Add owner entry to end of list */
-        if (ownerList) {
-            while (ownerList->nextOwner) {
-                ownerList = ownerList->nextOwner;
+/* FUNCTION PURPOSE: Compares two resource node's boundaries
+ ***********************************************************************
+ * DESCRIPTION: Returns TRUE if the resource nodes are neighbors from
+ *              a base+length perspective.  Otherwise, returns FALSE.
+ */
+static int allocatorResNodeBoundaryCompare(Rm_ResourceNode *node1, Rm_ResourceNode *node2)
+{
+    uint32_t node1End = node1->base + node1->length - 1;
+    uint32_t node2End = node2->base + node2->length - 1;
+
+    if (node1 && node2) {
+        if (node1->base < node2->base) {
+            if (node1End == (node2->base - 1)) {
+                return(RM_TRUE);
             }
-            ownerList->nextOwner = newOwner;
         }
-        else {
-            node->ownerList = newOwner;
+        else if (node2->base < node1->base) {
+            if (node2End == (node1->base - 1)) {
+                return(RM_TRUE);
+            }     
         }
-
-        node->allocationCount++;
-        newOwner->instNameNode->allocRefCount++;
     }
+    return(RM_FALSE);
 }
 
 /* FUNCTION PURPOSE: Compares two resource node's owners
@@ -210,18 +260,29 @@ static void allocatorResNodeOwnerAdd(Rm_ResourceNode *node, void *serviceInstNod
  * DESCRIPTION: Returns TRUE if the owners of two resource nodes 
  *              are equivalent.  Otherwise, returns FALSE.
  */
-static bool allocatorResNodeOwnerCompare(Rm_ResourceNode *node1, Rm_ResourceNode *node2)
+static int allocatorResNodeOwnerCompare(Rm_Handle rmHandle, Rm_ResourceNode *node1, Rm_ResourceNode *node2)
 {
+    Rm_Inst  *rmInst = (Rm_Inst *)rmHandle;    
     Rm_Owner *node1Owners = node1->ownerList;
     Rm_Owner *node2Owners = node2->ownerList;
-    bool      matchedInst;
+    int       matchedInst;
+
+    if (rmInst->instType == Rm_instType_SHARED_SERVER) {
+        while(node2Owners) {
+            Rm_osalBeginMemAccess((void *)node2Owners, sizeof(*node2Owners));
+            node2Owners = node2Owners->nextOwner;
+        }
+        node2Owners = node2->ownerList;
+    }
 
     if (node1->allocationCount == node2->allocationCount) {
         while (node1Owners) {
-            matchedInst = false;
+            RM_SS_OBJ_INV(node1Owners, Rm_Owner);
+            matchedInst = RM_FALSE;
             while (node2Owners) {
-                if (node1Owners->instNameNode == node2Owners->instNameNode) {
-                    matchedInst = true;
+                if ((node1Owners->instNameNode == node2Owners->instNameNode) &&
+                    (node1Owners->refCnt == node2Owners->refCnt)) {
+                    matchedInst = RM_TRUE;
                     break;
                 }
                 node2Owners = node2Owners->nextOwner;
@@ -232,71 +293,94 @@ static bool allocatorResNodeOwnerCompare(Rm_ResourceNode *node1, Rm_ResourceNode
                 node1Owners = node1Owners->nextOwner;
             }
             else {
-                return(false);
+                return(RM_FALSE);
             }                
         }
     }
     else {
-        return(false);
+        return(RM_FALSE);
     }  
     
-    return(true);
+    return(RM_TRUE);
 }
 
 /* FUNCTION PURPOSE: Deletes an owner from an allocator resource
  ***********************************************************************
- * DESCRIPTION: Removes a RM instance node from a resource node's
- *              list of owners.
+ * DESCRIPTION: Removes a RM owner entry from a resource node's
+ *              list of owners.  If the refCnt for the specified
+ *              owner is greater than 1 only the refCnt is
+ *              decremented
  */
-static void allocatorResNodeOwnerDelete(Rm_ResourceNode *node, void *serviceInstNode)
+static void allocatorResNodeOwnerDelete(Rm_Handle rmHandle, Rm_ResourceNode *node, void *serviceInstNode)
 {
+    Rm_Inst  *rmInst = (Rm_Inst *)rmHandle;    
     Rm_Owner *owner = node->ownerList;
     Rm_Owner *prevOwner = NULL;
 
-    while (owner) {
-        if (owner->instNameNode == serviceInstNode) {
-            break;             
-        }
-        prevOwner = owner;
-        owner = owner->nextOwner;
-    }
-
-    if (prevOwner == NULL) {
-        node->ownerList = owner->nextOwner;
+    if (allocatorResNodeIsOwnedBy(rmHandle, node, serviceInstNode) > 1) {
+        allocatorResNodeOwnerRefCntDec(rmHandle, node, serviceInstNode);
     }
     else {
-        prevOwner->nextOwner = owner->nextOwner;
+        while (owner) {
+            RM_SS_OBJ_INV(owner, Rm_Owner);
+            if (owner->instNameNode == serviceInstNode) {
+                break;             
+            }
+            prevOwner = owner;
+            owner = owner->nextOwner;
+        }
+
+        if (owner) {
+            if (prevOwner == NULL) {
+                node->ownerList = owner->nextOwner;
+            }
+            else {
+                prevOwner->nextOwner = owner->nextOwner;
+                RM_SS_OBJ_WB(prevOwner, Rm_Owner);
+            }
+            
+            node->allocationCount--;
+            owner->instNameNode->allocRefCount--;
+            RM_SS_OBJ_WB(owner->instNameNode, Rm_PolicyValidInstNode);
+            Rm_osalFree((void *)owner, sizeof(*owner));
+        }
     }
-    
-    node->allocationCount--;
-    owner->instNameNode->allocRefCount--;
-    Rm_osalFree((void *)owner, sizeof(Rm_Owner));
 }
 
 /* FUNCTION PURPOSE: Copies the owners of a resource node
  ***********************************************************************
  * DESCRIPTION: Creates a list of resource owners for the destination
- *              resource node that is equivalent to the the 
- *              source resource node's owners
+ *              resource node that is equivalent to the source resource
+ *              node's owners
+ *
+ *              dstNode must be a newly created node without any owners.
  */
-static void allocatorResNodeOwnerCopy(Rm_ResourceNode *dstNode, Rm_ResourceNode *srcNode)
+static void allocatorResNodeOwnerCopy(Rm_Handle rmHandle, Rm_ResourceNode *dstNode, Rm_ResourceNode *srcNode)
 {
+    Rm_Inst  *rmInst = (Rm_Inst *)rmHandle;
     Rm_Owner *srcOwnerList = srcNode->ownerList;
     Rm_Owner *dstNewOwner;
     Rm_Owner *dstPrevOwner;
 
+    if (dstNode->ownerList != NULL) {
+        return;
+    }
     dstNode->allocationCount = srcNode->allocationCount;
 
     while (srcOwnerList) {
-        dstNewOwner = Rm_osalMalloc(sizeof(Rm_Owner));
+        RM_SS_OBJ_INV(srcOwnerList, Rm_Owner);
+        dstNewOwner = Rm_osalMalloc(sizeof(*dstNewOwner));
         dstNewOwner->instNameNode = srcOwnerList->instNameNode;
+        dstNewOwner->refCnt = srcOwnerList->refCnt;
         dstNewOwner->nextOwner = NULL;
+        RM_SS_OBJ_WB(dstNewOwner, Rm_Owner);
 
         if (dstNode->ownerList == NULL) {
             dstNode->ownerList = dstNewOwner;
         }
         else {
             dstPrevOwner->nextOwner = dstNewOwner;
+            RM_SS_OBJ_WB(dstPrevOwner, Rm_Owner);
         }
         dstPrevOwner = dstNewOwner;
         srcOwnerList = srcOwnerList->nextOwner;
@@ -308,37 +392,62 @@ static void allocatorResNodeOwnerCopy(Rm_ResourceNode *dstNode, Rm_ResourceNode
  * DESCRIPTION: Deletes all owners from the owners list of a 
  *              resource node.
  */
-static void allocatorResNodeOwnerClear(Rm_ResourceNode *node)
+static void allocatorResNodeOwnerClear(Rm_Handle rmHandle, Rm_ResourceNode *node)
 {
+    Rm_Inst  *rmInst = (Rm_Inst *)rmHandle;    
     Rm_Owner *owner = node->ownerList;
     Rm_Owner *nextOwner;
 
     while (owner) {
+        RM_SS_OBJ_INV(owner, Rm_Owner);
         nextOwner = owner->nextOwner;
         node->allocationCount--;
         owner->instNameNode->allocRefCount--;
-        Rm_osalFree((void *)owner, sizeof(Rm_Owner));
+        RM_SS_OBJ_WB(owner->instNameNode, Rm_PolicyValidInstNode);
+        Rm_osalFree((void *)owner, sizeof(*owner));
         owner = nextOwner;
     }
 }
 
-/* FUNCTION PURPOSE: Checks a resource node's ownership
+/* FUNCTION PURPOSE: Get the status for an allocator resource
  ***********************************************************************
- * DESCRIPTION: Returns TRUE if the provided instance node is
- *              in the list of resource node owners.  Otherwise,
- *              returns FALSE.
+ * DESCRIPTION: Called when a resource status request is made.  The
+ *              resource's allocator is searched for the resource base
+ *              and length specified in the transaction.  The 
+ *              resource's owner reference count is returned if the 
+ *              resource range is found.
  */
-static bool allocatorResNodeIsOwnedBy(Rm_ResourceNode *node, void *serviceInstNode)
+static int32_t allocatorStatus(Rm_Handle rmHandle, Rm_Allocator *allocator, Rm_AllocatorOpInfo *opInfo)
 {
-    Rm_Owner *owner = node->ownerList;
+    Rm_ResourceNode  findNode;
+    Rm_ResourceNode *matchingNode = NULL; 
+    uint32_t         matchingEnd;
+    uint32_t         findEnd;    
+    int32_t          retVal;
 
-    while (owner) {
-        if (owner->instNameNode == serviceInstNode) {
-            return(true);           
+    memset((void *)&findNode, 0, sizeof(findNode));
+    findNode.base = opInfo->resourceInfo->base;
+    findNode.length = opInfo->resourceInfo->length;
+    matchingNode = RB_FIND(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, &findNode);
+
+    if (matchingNode) {
+        matchingEnd = matchingNode->base + matchingNode->length - 1;
+        findEnd = findNode.base + findNode.length - 1;
+        if ((findNode.base >= matchingNode->base) && (findEnd <= matchingEnd)) {        
+            opInfo->resourceInfo->ownerCount = matchingNode->allocationCount;
+            opInfo->resourceInfo->instAllocCount = allocatorResNodeOwnerGetRefCnt(rmHandle, matchingNode,
+                                                                                  opInfo->serviceSrcInstNode);            
+            retVal = RM_SERVICE_APPROVED;
         }
-        owner = owner->nextOwner;
+        else {
+            retVal = RM_SERVICE_DENIED_PARTIAL_STATUS;
+        }
+    }
+    else {
+        retVal = RM_SERVICE_DENIED_RES_RANGE_DOES_NOT_EXIST;
     }
-    return(false);
+
+    return(retVal);  
 }
 
 /* FUNCTION PURPOSE: Preallocates an allocator resource
@@ -352,22 +461,43 @@ static bool allocatorResNodeIsOwnedBy(Rm_ResourceNode *node, void *serviceInstNo
  */
 static int32_t allocatorPreAllocate(Rm_Handle rmHandle, Rm_Allocator *allocator, int32_t resourcePolicy, 
                                     Rm_AllocatorOpInfo *opInfo)
-{
-    Rm_Inst           *rmInst = (Rm_Inst *)rmHandle;    
+{   
+    Rm_Inst           *rmInst = (Rm_Inst *)rmHandle;
     Rm_ResourceNode    findNode;
     Rm_ResourceNode   *matchingNode = NULL;
+    Rm_ResourceNode   *nextNode;
     uint32_t           matchingEnd;
+    uint32_t           findEnd;
     uint32_t           rangeIndex;
-    bool               resourceFound = false;
+    int                resourceFound = RM_FALSE;
     Rm_PolicyCheckType policyCheckType;
     Rm_PolicyCheckCfg  policyCheckCfg;
-    bool               nodePassesPolicy;
-    int32_t            retVal = RM_SERVICE_PROCESSING;    
+    int                nodePassesPolicy;
+    int32_t            retVal = RM_OK;
+
+    if (opInfo->operation == Rm_allocatorOp_PRE_ALLOCATE_INIT) {
+        policyCheckType = Rm_policyCheck_INIT;
+    }
+    else if (opInfo->operation == Rm_allocatorOp_PRE_ALLOCATE_USE) {
+        policyCheckType = Rm_policyCheck_USE;
+    }
+    else {
+        retVal = RM_ERROR_INVALID_SERVICE_TYPE;
+        return (retVal);
+    }
 
-    opInfo->resourceInfo->base = rmPolicyGetResourceBase(opInfo->policy, opInfo->serviceSrcInstNode, 
-                                                         resourcePolicy, opInfo->allocType, 
-                                                         &retVal);
-    if (retVal != RM_SERVICE_PROCESSING) {
+    if (rmInst->instType == Rm_instType_CLIENT_DELEGATE) {
+        /* Set base to first node's base since CD will not have all resources like Server */
+        matchingNode = RB_MIN(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry);
+        opInfo->resourceInfo->base = matchingNode->base;
+    }
+    else {
+        opInfo->resourceInfo->base = rmPolicyGetResourceBase(opInfo->policy, opInfo->serviceSrcInstNode, 
+                                                             resourcePolicy, policyCheckType, 
+                                                             &retVal);
+    }
+    
+    if (retVal != RM_OK) {
         return (retVal);
     }
 
@@ -380,18 +510,12 @@ static int32_t allocatorPreAllocate(Rm_Handle rmHandle, Rm_Allocator *allocator,
         opInfo->resourceInfo->alignment = 1;
     }    
 
-    memset((void *)&findNode, 0, sizeof(Rm_ResourceNode));
+    memset((void *)&findNode, 0, sizeof(findNode));
     findNode.base = opInfo->resourceInfo->base;
     findNode.length = opInfo->resourceInfo->length;
 
     /* Configure policy checking structure */
-    memset((void *)&policyCheckCfg, 0, sizeof(Rm_PolicyCheckCfg));
-    if (RM_policy_GET_PERM(opInfo->allocType, RM_POLICY_PERM_INIT_SHIFT)) {
-        policyCheckType = Rm_policyCheck_INIT;
-    }
-    else if (RM_policy_GET_PERM(opInfo->allocType, RM_POLICY_PERM_USE_SHIFT)) {
-        policyCheckType = Rm_policyCheck_USE;
-    }
+    memset((void *)&policyCheckCfg, 0, sizeof(policyCheckCfg));
     policyCheckCfg.policyDtb = opInfo->policy;
     policyCheckCfg.resourceOffset = resourcePolicy;
     
@@ -399,9 +523,13 @@ static int32_t allocatorPreAllocate(Rm_Handle rmHandle, Rm_Allocator *allocator,
         matchingNode = RB_FIND(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, &findNode);
         
         if (matchingNode) {
-            if (!allocatorResNodeIsOwnedBy(matchingNode, opInfo->serviceSrcInstNode)) {
-                /* Attempt to preallocate from node only if not owned by instance requesting the allocation */
-                nodePassesPolicy = false;
+            matchingEnd = matchingNode->base + matchingNode->length - 1;
+            findEnd = findNode.base + findNode.length - 1;
+            nodePassesPolicy = RM_BOOL_UNDEF;
+            if ((matchingNode->allocationCount == 0) &&
+                (findNode.base >= matchingNode->base) && (findEnd <= matchingEnd)) {
+                /* Attempt to preallocate from node only if not owned by anyone and sits
+                 * within a matching node. */
                 policyCheckCfg.type = policyCheckType;
                 policyCheckCfg.validInstNode = opInfo->serviceSrcInstNode;
                 policyCheckCfg.resourceBase = findNode.base;
@@ -411,7 +539,7 @@ static int32_t allocatorPreAllocate(Rm_Handle rmHandle, Rm_Allocator *allocator,
                 if (nodePassesPolicy && (matchingNode->allocationCount > 0)) {
                     policyCheckCfg.validInstNode = opInfo->serviceSrcInstNode;
                     
-                    if (allocatorResNodeIsOwnedBy(matchingNode, rmPolicyGetLinuxInstNode(rmInst->u.server.globalValidInstTree))) {
+                    if (allocatorResNodeIsOwnedBy(rmHandle, matchingNode, rmPolicyGetLinuxInstNode(rmHandle))) {
                         /* Check if instance requesting resource has privileges to share
                          * a resource already reserved by Linux */
                         policyCheckCfg.type = Rm_policyCheck_SHARED_LINUX;
@@ -433,13 +561,12 @@ static int32_t allocatorPreAllocate(Rm_Handle rmHandle, Rm_Allocator *allocator,
                     nodePassesPolicy = !rmPolicyCheckPrivilege(&policyCheckCfg, &retVal);
                 }
 
-                if (retVal != RM_SERVICE_PROCESSING) {
+                if (retVal != RM_OK) {
                     break;
                 }
 
                 if (nodePassesPolicy) {
-                    matchingEnd = matchingNode->base + matchingNode->length - 1;
-                    /* Initialize indexer to be first resource value that alignment */
+                    /* Initialize indexer to be first resource value that alignment satisfies */
                     rangeIndex = findNode.base;
                     if (rangeIndex % opInfo->resourceInfo->alignment) {
                         rangeIndex += (opInfo->resourceInfo->alignment -
@@ -450,14 +577,31 @@ static int32_t allocatorPreAllocate(Rm_Handle rmHandle, Rm_Allocator *allocator,
                         /* Block of unallocated resources within matchingNode that satisfies
                          * allocate requirements */
                         opInfo->resourceInfo->base = rangeIndex;
-                        resourceFound = true;
+                        resourceFound = RM_TRUE;
+                        retVal = RM_SERVICE_PROCESSING;
                     }     
                 }
             }
             
             if (!resourceFound) {
                 /* Check next resource node for available resources */
-                findNode.base = matchingNode->base + matchingNode->length;
+                if (findNode.base < matchingNode->base) {
+                    findNode.base = matchingNode->base;
+                }
+                else {
+                    if (!nodePassesPolicy) {
+                        findNode.base += findNode.length;
+                    }
+                    else {
+                        /* Matching node allocated, move to next node */
+                        if (nextNode = RB_NEXT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode)) {
+                            findNode.base = nextNode->base;
+                        }
+                        else {
+                            retVal = RM_SERVICE_DENIED_RES_ALLOC_REQS_NOT_MET;
+                        }
+                    }
+                }
             }
         }
         else {
@@ -483,42 +627,46 @@ static int32_t allocatorPreAllocate(Rm_Handle rmHandle, Rm_Allocator *allocator,
 static int32_t allocatorAllocate(Rm_Handle rmHandle, Rm_Allocator *allocator, int32_t resourcePolicy, 
                                  Rm_AllocatorOpInfo *opInfo)
 {
-    Rm_Inst            *rmInst = (Rm_Inst *)rmHandle;
     Rm_ResourceNode     findNode;
     Rm_ResourceNode    *matchingNode = NULL;
     Rm_ResourceNode    *leftNode = NULL;
     Rm_ResourceNode    *rightNode = NULL;
     Rm_PolicyCheckType  policyCheckType;    
     Rm_PolicyCheckCfg   policyCheckCfg;
-    bool                allocPassesPolicy;
-    bool                combineLeft = false;
-    bool                combineRight = false;    
+    int                 allocPassesPolicy;
+    int                 combineLeft = RM_FALSE;
+    int                 combineRight = RM_FALSE;    
     uint32_t            findEnd;
     uint32_t            matchingEnd;  
-    int32_t             retVal = RM_SERVICE_PROCESSING;
+    int32_t             retVal;
+
+    if (opInfo->operation == Rm_allocatorOp_ALLOCATE_INIT) {
+        policyCheckType = Rm_policyCheck_INIT;
+    }
+    else if (opInfo->operation == Rm_allocatorOp_ALLOCATE_USE) {
+        policyCheckType = Rm_policyCheck_USE;
+    }
+    else {
+        retVal = RM_ERROR_INVALID_SERVICE_TYPE;
+        return (retVal);
+    }   
 
-    memset((void *)&findNode, 0, sizeof(Rm_ResourceNode));
+    memset((void *)&findNode, 0, sizeof(findNode));
     findNode.base = opInfo->resourceInfo->base;
     findNode.length = opInfo->resourceInfo->length;
     matchingNode = RB_FIND(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, &findNode);
 
     /* Prepare privilege checks */
-    memset((void *)&policyCheckCfg, 0, sizeof(Rm_PolicyCheckCfg));
-    if (RM_policy_GET_PERM(opInfo->allocType, RM_POLICY_PERM_INIT_SHIFT)) {
-        policyCheckType = Rm_policyCheck_INIT;
-    }
-    else if (RM_policy_GET_PERM(opInfo->allocType, RM_POLICY_PERM_USE_SHIFT)) {
-        policyCheckType = Rm_policyCheck_USE;
-    }
+    memset((void *)&policyCheckCfg, 0, sizeof(policyCheckCfg)); 
 
     if (matchingNode) {
         findEnd = findNode.base + findNode.length - 1;
         matchingEnd = matchingNode->base + matchingNode->length - 1;
         
         if ((findNode.base >= matchingNode->base) && (findEnd <= matchingEnd)) {
-            if (opInfo->serviceSrcInstNode == rmPolicyGetLinuxInstNode(rmInst->u.server.globalValidInstTree)) {
+            if (opInfo->serviceSrcInstNode == rmPolicyGetLinuxInstNode(rmHandle)) {
                 /* Bypass policy checks since Linux Kernel has full privileges */
-                allocPassesPolicy = true;
+                allocPassesPolicy = RM_TRUE;
             }
             else {
                 policyCheckCfg.policyDtb = opInfo->policy;
@@ -537,9 +685,9 @@ static int32_t allocatorAllocate(Rm_Handle rmHandle, Rm_Allocator *allocator, in
                     }
                 }
 
-                if (!allocatorResNodeIsOwnedBy(matchingNode, opInfo->serviceSrcInstNode)) {
+                if (!allocatorResNodeIsOwnedBy(rmHandle, matchingNode, opInfo->serviceSrcInstNode)) {
                     if (allocPassesPolicy && (matchingNode->allocationCount > 0)) {
-                        if (allocatorResNodeIsOwnedBy(matchingNode, rmPolicyGetLinuxInstNode(rmInst->u.server.globalValidInstTree))) {
+                        if (allocatorResNodeIsOwnedBy(rmHandle, matchingNode, rmPolicyGetLinuxInstNode(rmHandle))) {
                             /* Check if instance requesting resource has privileges to share
                              * a resource already reserved by Linux */
                             policyCheckCfg.type = Rm_policyCheck_SHARED_LINUX;
@@ -573,149 +721,181 @@ static int32_t allocatorAllocate(Rm_Handle rmHandle, Rm_Allocator *allocator, in
             }
             
             if (allocPassesPolicy) {
-                if (!allocatorResNodeIsOwnedBy(matchingNode, opInfo->serviceSrcInstNode)) {
-                    /* Handle any possible node combinations if requesting instance is
-                     * not already in resource's owner list.  Automatic approval if requesting
-                     * instance is already in owner list. */
-                    if ((findNode.base == matchingNode->base) && (findEnd == matchingEnd)) {
-                        /* findNode range matches matchingNode range
-                         *
-                         *   |<--left node-->||<--matched  node-->||<--right node-->| => existing node
-                         *                    |<--alloc request-->|  => requested resources
-                         */                     
-                        leftNode = RB_PREV(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);
-                        rightNode = RB_NEXT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);
-                        RB_REMOVE(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);
-                        allocatorResNodeOwnerAdd(matchingNode, opInfo->serviceSrcInstNode);
-
-                        if (leftNode && allocatorResNodeOwnerCompare(leftNode, matchingNode)) {
-                            RB_REMOVE(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, leftNode);
-                            combineLeft = true;
-                        }
-                        if (rightNode && allocatorResNodeOwnerCompare(rightNode, matchingNode)) {
-                            RB_REMOVE(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, rightNode);
-                            combineRight = true;
-                        }
+                /* Handle any possible node combinations if requesting instance is
+                 * not already in resource's owner list.  Automatic approval if requesting
+                 * instance is already in owner list. */
+                if ((findNode.base == matchingNode->base) && (findEnd == matchingEnd)) {
+                    /* findNode range matches matchingNode range
+                     *
+                     *   |<--left node-->||<--matched  node-->||<--right node-->| => existing node
+                     *                    |<--alloc request-->|  => requested resources
+                     */                     
+                    leftNode = RB_PREV(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);
+                    rightNode = RB_NEXT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);
+                    RB_REMOVE(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);
+                    allocatorResNodeOwnerAdd(rmHandle, matchingNode, opInfo->serviceSrcInstNode);
+
+                    if (leftNode && allocatorResNodeOwnerCompare(rmHandle, leftNode, matchingNode) &&
+                        allocatorResNodeBoundaryCompare(leftNode, matchingNode)) {
+                        RB_REMOVE(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, leftNode);
+                        combineLeft = RM_TRUE;
+                    }
+                    if (rightNode && allocatorResNodeOwnerCompare(rmHandle, rightNode, matchingNode) &&
+                        allocatorResNodeBoundaryCompare(rightNode, matchingNode)) {
+                        RB_REMOVE(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, rightNode);
+                        combineRight = RM_TRUE;
+                    }
 
-                        if (combineLeft && combineRight) {
-                            /* Combine all three nodes into matchingNode */
-                            matchingNode->base = leftNode->base;
-                            matchingNode->length = leftNode->length + matchingNode->length + rightNode->length;
+                    if (combineLeft && combineRight) {
+                        /* Combine all three nodes into matchingNode */
+                        matchingNode->base = leftNode->base;
+                        matchingNode->length = leftNode->length + matchingNode->length + rightNode->length;
 
-                            allocatorResNodeOwnerClear(leftNode);
-                            rmResourceNodeFree(leftNode);
-                            allocatorResNodeOwnerClear(rightNode);
-                            rmResourceNodeFree(rightNode);                        
-                        }
-                        else if (combineLeft) {
-                            /* Combine left and matching nodes.  Reinsert right. */
-                            matchingNode->base = leftNode->base;
-                            matchingNode->length += leftNode->length;
-
-                            allocatorResNodeOwnerClear(leftNode);
-                            rmResourceNodeFree(leftNode);
-                            RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, rightNode);                        
+                        allocatorResNodeOwnerClear(rmHandle, leftNode);
+                        rmResourceNodeFree(leftNode);
+                        allocatorResNodeOwnerClear(rmHandle, rightNode);
+                        rmResourceNodeFree(rightNode);                        
+                    }
+                    else if (combineLeft) {
+                        /* Combine left and matching nodes.  Reinsert right. */
+                        matchingNode->base = leftNode->base;
+                        matchingNode->length += leftNode->length;
+
+                        allocatorResNodeOwnerClear(rmHandle, leftNode);
+                        rmResourceNodeFree(leftNode);
+                        if (rightNode) {
+                            RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, rightNode);  
                         }
-                        else if (combineRight) {
-                            /* Combine right and matching nodes.  Reinsert left. */
-                            matchingNode->length += rightNode->length;
+                    }
+                    else if (combineRight) {
+                        /* Combine right and matching nodes.  Reinsert left. */
+                        matchingNode->length += rightNode->length;
 
-                            allocatorResNodeOwnerClear(rightNode);
-                            rmResourceNodeFree(rightNode);
+                        allocatorResNodeOwnerClear(rmHandle, rightNode);
+                        rmResourceNodeFree(rightNode);
+                        if (leftNode) {
                             RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, leftNode);
                         }
-                        else {
-                            /* No combine. */
+                    }
+                    else {
+                        /* No combine. */
+                        if (leftNode) {
                             RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, leftNode);
+                        }
+                        if (rightNode) {
                             RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, rightNode);
                         }
+                    }
 
-                        /* Always reinsert matchingNode */                
-                        RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);   
-                    }   
-                    else if ((findNode.base > matchingNode->base) && (findEnd < matchingEnd)) {
-                        /* findNode range is subset of matchingNode range and neither boundary is
-                         * equivalent.
+                    /* Always reinsert matchingNode */                
+                    RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);
+                    
+                    /* Matching node contains new reference count after alloc.  Return new owner count
+                     * and originating instance allocation reference count. */
+                    opInfo->resourceInfo->ownerCount = matchingNode->allocationCount;
+                    opInfo->resourceInfo->instAllocCount = allocatorResNodeOwnerGetRefCnt(rmHandle, matchingNode,
+                                                                                          opInfo->serviceSrcInstNode);
+                }   
+                else if ((findNode.base > matchingNode->base) && (findEnd < matchingEnd)) {
+                    /* findNode range is subset of matchingNode range and neither boundary is
+                     * equivalent.
+                     *
+                     * |<----------matched node---------->|
+                     *        |<---alloc request--->|
+                     */ 
+                    RB_REMOVE(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);
+                    leftNode = rmResourceNodeNew(matchingNode->base, findNode.base - matchingNode->base);
+                    allocatorResNodeOwnerCopy(rmHandle, leftNode, matchingNode);
+                    rightNode = rmResourceNodeNew(findNode.base + findNode.length, matchingEnd - findEnd);
+                    allocatorResNodeOwnerCopy(rmHandle, rightNode, matchingNode);
+
+                    matchingNode->base = findNode.base;                                    
+                    matchingNode->length = findNode.length;
+                    allocatorResNodeOwnerAdd(rmHandle, matchingNode, opInfo->serviceSrcInstNode);
+
+                    /* Insert all the nodes */
+                    RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);
+                    RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, leftNode);
+                    RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, rightNode);
+                    
+                    /* Matching node contains new reference count after alloc.  Return new owner count
+                     * and originating instance allocation reference count. */
+                    opInfo->resourceInfo->ownerCount = matchingNode->allocationCount;
+                    opInfo->resourceInfo->instAllocCount = allocatorResNodeOwnerGetRefCnt(rmHandle, matchingNode, 
+                                                                                          opInfo->serviceSrcInstNode);
+                }  
+                else {    
+                    if (findNode.base == matchingNode->base) {
+                        /* findNode base and matchingNode base are equivalent.  May be combine
+                         * possibilities to the left
                          *
-                         * |<----------matched node---------->|
-                         *        |<---alloc request--->|
-                         */ 
+                         * |<---left node (alloc'd)--->||<----------matched node---------->|
+                         *                              |<---findNode (alloc req)--->|
+                         */                         
+                        leftNode = RB_PREV(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);
                         RB_REMOVE(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);
-                        leftNode = rmResourceNodeNew(matchingNode->base, findNode.base - matchingNode->base);
-                        allocatorResNodeOwnerCopy(leftNode, matchingNode);
-                        rightNode = rmResourceNodeNew(findNode.base + findNode.length, matchingEnd - findEnd);
-                        allocatorResNodeOwnerCopy(rightNode, matchingNode);
+                        /* Add allocating instance to owner list for compare with leftNode */
+                        allocatorResNodeOwnerAdd(rmHandle, matchingNode, opInfo->serviceSrcInstNode);
+                        
+                        if (leftNode && allocatorResNodeOwnerCompare(rmHandle, leftNode, matchingNode) &&
+                            allocatorResNodeBoundaryCompare(leftNode, matchingNode)) {
+                            RB_REMOVE(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, leftNode);
+                            /* Combine leftNode and findNode */
+                            leftNode->length += findNode.length;
+                        }
+                        else {
+                            leftNode = rmResourceNodeNew(findNode.base, findNode.length);
+                            allocatorResNodeOwnerCopy(rmHandle, leftNode, matchingNode);
+                        }
 
-                        matchingNode->base = findNode.base;                                    
-                        matchingNode->length = findNode.length;
-                        allocatorResNodeOwnerAdd(matchingNode, opInfo->serviceSrcInstNode);
+                        /* Account for leftNode in matchingNode */
+                        matchingNode->base = findNode.base + findNode.length;
+                        matchingNode->length = matchingEnd - findEnd;  
 
-                        /* Insert all the nodes */
-                        RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);
                         RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, leftNode);
-                        RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, rightNode);
-                    }  
-                    else {    
-                        if (findNode.base == matchingNode->base) {
-                            /* findNode base and matchingNode base are equivalent.  May be combine
-                             * possibilities to the left
-                             *
-                             * |<---left node (alloc'd)--->||<----------matched node---------->|
-                             *                              |<---findNode (alloc req)--->|
-                             */                         
-                            leftNode = RB_PREV(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);
-                            RB_REMOVE(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);
-                            /* Add allocating instance to owner list for compare with leftNode */
-                            allocatorResNodeOwnerAdd(matchingNode, opInfo->serviceSrcInstNode);
-                            
-                            if (leftNode && allocatorResNodeOwnerCompare(leftNode, matchingNode)) {
-                                RB_REMOVE(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, leftNode);
-                                /* Combine leftNode and findNode */
-                                leftNode->length += findNode.length;
-                            }
-                            else {
-                                leftNode = rmResourceNodeNew(findNode.base, findNode.length);
-                                allocatorResNodeOwnerCopy(leftNode, matchingNode);
-                            }
-
-                            /* Account for leftNode in matchingNode */
-                            matchingNode->base = findNode.base + findNode.length;
-                            matchingNode->length = matchingEnd - findEnd;  
-
-                            RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, leftNode);
+                        /* Left node contains new reference count after alloc.  Return new owner count
+                         * and originating instance allocation reference count. */
+                        opInfo->resourceInfo->ownerCount = leftNode->allocationCount;
+                        opInfo->resourceInfo->instAllocCount = allocatorResNodeOwnerGetRefCnt(rmHandle, leftNode, 
+                                                                                              opInfo->serviceSrcInstNode);
+                    }
+                    else if (findEnd == matchingEnd) {
+                        /* findNode end and matchingNode end are equivalent.  May be combine
+                         * possibilities to the right
+                         *
+                         * |<----------matched node---------->||<---right node (alloc'd)--->|
+                         *       |<---findNode (alloc req)--->| 
+                         */                        
+                        rightNode = RB_NEXT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);
+                        RB_REMOVE(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);
+                        /* Add allocating instance to owner list for compare with rightNode */
+                        allocatorResNodeOwnerAdd(rmHandle, matchingNode, opInfo->serviceSrcInstNode);
+                        
+                        if (rightNode && allocatorResNodeOwnerCompare(rmHandle, rightNode, matchingNode) &&
+                            allocatorResNodeBoundaryCompare(rightNode, matchingNode)) {
+                            RB_REMOVE(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, rightNode);
+                            /* Combine rightNode and findNode */
+                            rightNode->base = findNode.base;
+                            rightNode->length += findNode.length;
+                        }
+                        else {
+                            rightNode = rmResourceNodeNew(findNode.base, findNode.length);
+                            allocatorResNodeOwnerCopy(rmHandle, rightNode, matchingNode);
                         }
-                        else if (findEnd == matchingEnd) {
-                            /* findNode end and matchingNode end are equivalent.  May be combine
-                             * possibilities to the right
-                             *
-                             * |<----------matched node---------->||<---right node (alloc'd)--->|
-                             *       |<---findNode (alloc req)--->| 
-                             */                        
-                            rightNode = RB_NEXT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);
-                            RB_REMOVE(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);
-                            /* Add allocating instance to owner list for compare with rightNode */
-                            allocatorResNodeOwnerAdd(matchingNode, opInfo->serviceSrcInstNode);
-                            
-                            if (rightNode && allocatorResNodeOwnerCompare(rightNode, matchingNode)) {
-                                RB_REMOVE(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, rightNode);
-                                /* Combine rightNode and findNode */
-                                rightNode->base = findNode.base;
-                                rightNode->length += findNode.length;
-                            }
-                            else {
-                                rightNode = rmResourceNodeNew(findNode.base, findNode.length);
-                                allocatorResNodeOwnerCopy(rightNode, matchingNode);
-                            }
 
-                            /* Account for rightNode in matchingNode */
-                            matchingNode->length -= findNode.length;  
+                        /* Account for rightNode in matchingNode */
+                        matchingNode->length -= findNode.length;  
 
-                            RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, rightNode);
-                        }
-                        /* Remove allocating instance from leftover matchingNode */
-                        allocatorResNodeOwnerDelete(matchingNode, opInfo->serviceSrcInstNode);
-                        RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);
+                        RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, rightNode);
+                        /* Right node contains new reference count after alloc.  Return new owner count
+                         * and originating instance allocation reference count. */
+                        opInfo->resourceInfo->ownerCount = rightNode->allocationCount;
+                        opInfo->resourceInfo->instAllocCount = allocatorResNodeOwnerGetRefCnt(rmHandle, rightNode, 
+                                                                                              opInfo->serviceSrcInstNode);
                     }
+                    /* Remove allocating instance from leftover matchingNode */
+                    allocatorResNodeOwnerDelete(rmHandle, matchingNode, opInfo->serviceSrcInstNode);
+                    RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);
                 }
                 retVal = RM_SERVICE_APPROVED;
             }
@@ -743,19 +923,19 @@ static int32_t allocatorAllocate(Rm_Handle rmHandle, Rm_Allocator *allocator, in
  *              become equivalent (in terms of ownership) after the
  *              allocation.
  */
-static int32_t allocatorFree(Rm_Allocator *allocator, Rm_AllocatorOpInfo *opInfo)
+static int32_t allocatorFree(Rm_Handle rmHandle, Rm_Allocator *allocator, Rm_AllocatorOpInfo *opInfo)
 {
     Rm_ResourceNode  findNode;
     Rm_ResourceNode *matchingNode = NULL;
     Rm_ResourceNode *leftNode = NULL;
     Rm_ResourceNode *rightNode = NULL;
-    bool             combineLeft = false;
-    bool             combineRight = false;
+    int              combineLeft = RM_FALSE;
+    int              combineRight = RM_FALSE;
     uint32_t         findEnd;
     uint32_t         matchingEnd;
     int32_t          retVal;
 
-    memset((void *)&findNode, 0, sizeof(Rm_ResourceNode));
+    memset((void *)&findNode, 0, sizeof(findNode));
     findNode.base = opInfo->resourceInfo->base;
     findNode.length = opInfo->resourceInfo->length;
     matchingNode = RB_FIND(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, &findNode);
@@ -766,7 +946,7 @@ static int32_t allocatorFree(Rm_Allocator *allocator, Rm_AllocatorOpInfo *opInfo
         
         if ((findNode.base >= matchingNode->base) && (findEnd <= matchingEnd)) {  
             if (matchingNode->allocationCount) {
-                if (allocatorResNodeIsOwnedBy(matchingNode, opInfo->serviceSrcInstNode)) {
+                if (allocatorResNodeIsOwnedBy(rmHandle, matchingNode, opInfo->serviceSrcInstNode)) {
                     if ((findNode.base == matchingNode->base) && (findEnd == matchingEnd))
                     {
                         /* Case 1: Free range equals allocated matched node exactly. Attempt to combine 
@@ -778,15 +958,17 @@ static int32_t allocatorFree(Rm_Allocator *allocator, Rm_AllocatorOpInfo *opInfo
                         leftNode = RB_PREV(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);
                         rightNode = RB_NEXT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);
                         RB_REMOVE(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);
-                        allocatorResNodeOwnerDelete(matchingNode, opInfo->serviceSrcInstNode);
+                        allocatorResNodeOwnerDelete(rmHandle, matchingNode, opInfo->serviceSrcInstNode);
 
-                        if (leftNode && allocatorResNodeOwnerCompare(leftNode, matchingNode)) {
+                        if (leftNode && allocatorResNodeOwnerCompare(rmHandle, leftNode, matchingNode) &&
+                            allocatorResNodeBoundaryCompare(leftNode, matchingNode)) {
                             RB_REMOVE(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, leftNode);
-                            combineLeft = true;
+                            combineLeft = RM_TRUE;
                         }
-                        if (rightNode && allocatorResNodeOwnerCompare(rightNode, matchingNode)) {
+                        if (rightNode && allocatorResNodeOwnerCompare(rmHandle, rightNode, matchingNode) &&
+                            allocatorResNodeBoundaryCompare(rightNode, matchingNode)) {
                             RB_REMOVE(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, rightNode);
-                            combineRight = true;
+                            combineRight = RM_TRUE;
                         }
 
                         if (combineLeft && combineRight) {
@@ -794,9 +976,9 @@ static int32_t allocatorFree(Rm_Allocator *allocator, Rm_AllocatorOpInfo *opInfo
                             matchingNode->base = leftNode->base;
                             matchingNode->length = leftNode->length + matchingNode->length + rightNode->length;
 
-                            allocatorResNodeOwnerClear(leftNode);
+                            allocatorResNodeOwnerClear(rmHandle, leftNode);
                             rmResourceNodeFree(leftNode);
-                            allocatorResNodeOwnerClear(rightNode);
+                            allocatorResNodeOwnerClear(rmHandle, rightNode);
                             rmResourceNodeFree(rightNode);                        
                         }
                         else if (combineLeft) {
@@ -804,26 +986,40 @@ static int32_t allocatorFree(Rm_Allocator *allocator, Rm_AllocatorOpInfo *opInfo
                             matchingNode->base = leftNode->base;
                             matchingNode->length += leftNode->length;
 
-                            allocatorResNodeOwnerClear(leftNode);
+                            allocatorResNodeOwnerClear(rmHandle, leftNode);
                             rmResourceNodeFree(leftNode);
-                            RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, rightNode);                        
+                            if (rightNode) {
+                                RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, rightNode); 
+                            }
                         }
                         else if (combineRight) {
                             /* Combine right and matching nodes.  Reinsert left. */
                             matchingNode->length += rightNode->length;
 
-                            allocatorResNodeOwnerClear(rightNode);
+                            allocatorResNodeOwnerClear(rmHandle, rightNode);
                             rmResourceNodeFree(rightNode);
-                            RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, leftNode);
+                            if (leftNode) {
+                                RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, leftNode);
+                            }
                         }
                         else {
                             /* No combine. */
-                            RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, leftNode);
-                            RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, rightNode);
+                            if (leftNode) {
+                                RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, leftNode);
+                            }
+                            if (rightNode) {
+                                RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, rightNode);
+                            }
                         }
 
                         /* Always reinsert matchingNode */
-                        RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);                    
+                        RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);
+                        
+                        /* Matching node is what remains after free.  Return remaining owner count
+                         * and originating instance allocation reference count. */
+                        opInfo->resourceInfo->ownerCount = matchingNode->allocationCount;
+                        opInfo->resourceInfo->instAllocCount = allocatorResNodeOwnerGetRefCnt(rmHandle, matchingNode,
+                                                                                              opInfo->serviceSrcInstNode);
                     }
                     else if ((findNode.base > matchingNode->base) && (findEnd < matchingEnd)) {
                         /* Case 2: Free range is less than range in matched node. Split
@@ -832,25 +1028,31 @@ static int32_t allocatorFree(Rm_Allocator *allocator, Rm_AllocatorOpInfo *opInfo
                          * |<----------matched node---------->|
                          *        |<---free request--->|
                          *
-                         * Remove instance from AllocatedTo list then add it back in for side nodes for
+                         * Remove instance from owner list then add it back in for side nodes for
                          * proper accounting of allocations in validInstance list
                          */ 
                         RB_REMOVE(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);
-                        allocatorResNodeOwnerDelete(matchingNode, opInfo->serviceSrcInstNode);
+                        allocatorResNodeOwnerDelete(rmHandle, matchingNode, opInfo->serviceSrcInstNode);
                         
                         leftNode = rmResourceNodeNew(matchingNode->base, findNode.base - matchingNode->base);
-                        allocatorResNodeOwnerCopy(leftNode, matchingNode);
-                        allocatorResNodeOwnerAdd(leftNode, opInfo->serviceSrcInstNode);
+                        allocatorResNodeOwnerCopy(rmHandle, leftNode, matchingNode);
+                        allocatorResNodeOwnerAdd(rmHandle, leftNode, opInfo->serviceSrcInstNode);
                         RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, leftNode);
                         
                         rightNode = rmResourceNodeNew(findNode.base + findNode.length, matchingEnd - findEnd);
-                        allocatorResNodeOwnerCopy(rightNode, matchingNode);
-                        allocatorResNodeOwnerAdd(rightNode, opInfo->serviceSrcInstNode);
+                        allocatorResNodeOwnerCopy(rmHandle, rightNode, matchingNode);
+                        allocatorResNodeOwnerAdd(rmHandle, rightNode, opInfo->serviceSrcInstNode);
                         RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, rightNode);
 
                         matchingNode->base = findNode.base;                                    
                         matchingNode->length = findNode.length;
                         RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);
+                        
+                        /* Matching node is what remains after free.  Return remaining owner count
+                         * and originating instance allocation reference count. */
+                        opInfo->resourceInfo->ownerCount = matchingNode->allocationCount;
+                        opInfo->resourceInfo->instAllocCount = allocatorResNodeOwnerGetRefCnt(rmHandle, matchingNode,
+                                                                                              opInfo->serviceSrcInstNode);
                     }
                     else {                        
                         if (findNode.base == matchingNode->base) {
@@ -864,22 +1066,29 @@ static int32_t allocatorFree(Rm_Allocator *allocator, Rm_AllocatorOpInfo *opInfo
                             leftNode = RB_PREV(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);
                             RB_REMOVE(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);
                             /* Remove freeing instance from owner list for compare with leftNode */
-                            allocatorResNodeOwnerDelete(matchingNode, opInfo->serviceSrcInstNode);
+                            allocatorResNodeOwnerDelete(rmHandle, matchingNode, opInfo->serviceSrcInstNode);
                             
-                            if (leftNode && allocatorResNodeOwnerCompare(leftNode, matchingNode)) {
+                            if (leftNode && allocatorResNodeOwnerCompare(rmHandle, leftNode, matchingNode) &&
+                                allocatorResNodeBoundaryCompare(leftNode, matchingNode)) {
                                 RB_REMOVE(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, leftNode);
                                 /* Combine leftNode and findNode */
                                 leftNode->length += findNode.length;
                             }
                             else {
                                 leftNode = rmResourceNodeNew(findNode.base, findNode.length);
-                                allocatorResNodeOwnerCopy(leftNode, matchingNode);
+                                allocatorResNodeOwnerCopy(rmHandle, leftNode, matchingNode);
                             }
 
                             /* Remove leftNode range from matchingNode */
                             matchingNode->base = findNode.base + findNode.length;
                             matchingNode->length = matchingEnd - findEnd;  
                             RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, leftNode);
+                            
+                            /* Left node is what remains after free.  Return remaining owner count
+                             * and originating instance allocation reference count. */
+                            opInfo->resourceInfo->ownerCount = leftNode->allocationCount;
+                            opInfo->resourceInfo->instAllocCount = allocatorResNodeOwnerGetRefCnt(rmHandle, leftNode,
+                                                                                                  opInfo->serviceSrcInstNode);
                         }
                         else if (findEnd == matchingEnd) {
                             /* Case 4: Free range is on right boundary of matched node. Try to 
@@ -892,9 +1101,10 @@ static int32_t allocatorFree(Rm_Allocator *allocator, Rm_AllocatorOpInfo *opInfo
                             rightNode = RB_NEXT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);
                             RB_REMOVE(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode); 
                             /* Remove freeing instance from owner list for compare with rightNode */
-                            allocatorResNodeOwnerDelete(matchingNode, opInfo->serviceSrcInstNode);
+                            allocatorResNodeOwnerDelete(rmHandle, matchingNode, opInfo->serviceSrcInstNode);
                             
-                            if (rightNode && allocatorResNodeOwnerCompare(rightNode, matchingNode)) {
+                            if (rightNode && allocatorResNodeOwnerCompare(rmHandle, rightNode, matchingNode) &&
+                                allocatorResNodeBoundaryCompare(rightNode, matchingNode)) {
                                 RB_REMOVE(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, rightNode);
                                 /* Combine rightNode and findNode */
                                 rightNode->base = findNode.base;
@@ -902,26 +1112,41 @@ static int32_t allocatorFree(Rm_Allocator *allocator, Rm_AllocatorOpInfo *opInfo
                             }
                             else {
                                 rightNode = rmResourceNodeNew(findNode.base, findNode.length);
-                                allocatorResNodeOwnerCopy(rightNode, matchingNode);
+                                allocatorResNodeOwnerCopy(rmHandle, rightNode, matchingNode);
                             }
 
                             /* Remove rightNode range from matchingNode */
                             matchingNode->length -= findNode.length;  
                             RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, rightNode);
+                            
+                            /* Right node is what remains after free.  Return remaining owner count
+                             * and originating instance allocation reference count. */
+                            opInfo->resourceInfo->ownerCount = rightNode->allocationCount;
+                            opInfo->resourceInfo->instAllocCount = allocatorResNodeOwnerGetRefCnt(rmHandle, rightNode,
+                                                                                                  opInfo->serviceSrcInstNode);
                         }
 
                         /* Add freeing instance back into matchingNode allocations */
-                        allocatorResNodeOwnerAdd(matchingNode, opInfo->serviceSrcInstNode);
+                        allocatorResNodeOwnerAdd(rmHandle, matchingNode, opInfo->serviceSrcInstNode);
                         RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);
                     }
-
                     retVal = RM_SERVICE_APPROVED;
                 }
                 else {
+                    /* Return owner count and instance alloc count.  In case it's a reference count
+                     * check in application */
+                    opInfo->resourceInfo->ownerCount = matchingNode->allocationCount;
+                    opInfo->resourceInfo->instAllocCount = allocatorResNodeOwnerGetRefCnt(rmHandle, matchingNode,
+                                                                                          opInfo->serviceSrcInstNode);
                     retVal = RM_SERVICE_DENIED_RES_NOT_ALLOCD_TO_INST;
                 }
             }
             else {
+                /* Return owner count and instance alloc count.  In case it's a reference count
+                 * check in application */
+                opInfo->resourceInfo->ownerCount = matchingNode->allocationCount;
+                opInfo->resourceInfo->instAllocCount = allocatorResNodeOwnerGetRefCnt(rmHandle, matchingNode,
+                                                                                      opInfo->serviceSrcInstNode);
                 retVal = RM_SERVICE_DENIED_RES_ALREADY_FREE;
             }
         }
@@ -945,23 +1170,23 @@ static int32_t allocatorReserveLinuxResource(Rm_Handle rmHandle, Rm_LinuxAlias *
                                              Rm_LinuxValueRange *linuxValues, Rm_AllocatorOpInfo *opInfo)
 {
     int32_t   retVal = RM_OK;
-    bool      baseFound = false;
-    bool      lengthFound = false;
+    int       baseFound = RM_FALSE;
+    int       lengthFound = RM_FALSE;
     uint32_t  valueIndex = 0;
 
     while ((linuxValues) && (!baseFound || !lengthFound)) {
         if (linuxAlias->baseOffset == valueIndex) {
             opInfo->resourceInfo->base = linuxValues->value;
-            baseFound = true;
+            baseFound = RM_TRUE;
 
             if (linuxAlias->lengthOffset == RM_DTB_UTIL_LINUX_ALIAS_OFFSET_NOT_SET) {
                 opInfo->resourceInfo->length = 1;
-                lengthFound = true;
+                lengthFound = RM_TRUE;
             }
         }
         else if (linuxAlias->lengthOffset == valueIndex) {
             opInfo->resourceInfo->length = linuxValues->value;
-            lengthFound = true;
+            lengthFound = RM_TRUE;
         }
 
         linuxValues = (Rm_LinuxValueRange *)linuxValues->nextValue;
@@ -1000,20 +1225,20 @@ static int32_t allocatorFindLinuxResource(Rm_Handle rmHandle, const char *resour
     int32_t             propOffset;
     int32_t             nodeOffset = RM_DTB_UTIL_STARTING_NODE_OFFSET;
     int32_t             prevDepth = RM_DTB_UTIL_STARTING_DEPTH;
-    int32_t             depth;
+    int32_t             depth = RM_DTB_UTIL_STARTING_DEPTH;
     int32_t             propertyLen;
     const char         *propertyName;
     const void         *propertyData; 
     Rm_LinuxValueRange *linuxValueRange;
     int32_t             retVal = RM_OK; 
 
-    memset((void *) &opInfo, 0, sizeof(Rm_AllocatorOpInfo));
-    memset((void *) &resourceInfo, 0, sizeof(Rm_ResourceInfo));
+    memset((void *)&opInfo, 0, sizeof(opInfo));
+    memset((void *)&resourceInfo, 0, sizeof(resourceInfo));
 
     strncpy(resourceInfo.name, resourceName, RM_NAME_MAX_CHARS);
     opInfo.policy = rmInst->u.server.globalPolicy;
-    opInfo.serviceSrcInstNode = rmPolicyGetLinuxInstNode(rmInst->u.server.globalValidInstTree);
-    opInfo.operation = Rm_allocatorOp_ALLOCATE;
+    opInfo.serviceSrcInstNode = rmPolicyGetLinuxInstNode(rmHandle);
+    opInfo.operation = Rm_allocatorOp_ALLOCATE_INIT;
     opInfo.resourceInfo = &resourceInfo;    
 
     while(linuxAlias) {
@@ -1108,7 +1333,7 @@ static int32_t allocatorExtractGrlResProps(Rm_Handle rmHandle, const char *resou
         range = rangeBasePtr = rmDtbUtilResExtractRange(resourceProperties->rangeData, 
                                                         resourceProperties->rangeLen);
         
-        if ((retVal = allocatorCreate(rmHandle, resourceName, range)) >= RM_OK) {
+        if ((retVal = rmAllocatorCreate(rmHandle, resourceName, range)) >= RM_OK) {
             if (resourceProperties->linuxAliasData && resourceProperties->linuxAliasLen) {
                 if (linuxDtb) {
                     linuxAlias = rmDtbUtilResExtractLinuxAlias(resourceProperties->linuxAliasData,
@@ -1117,9 +1342,6 @@ static int32_t allocatorExtractGrlResProps(Rm_Handle rmHandle, const char *resou
                         retVal = allocatorFindLinuxResource(rmHandle, resourceName, linuxDtb, linuxAlias);            
                     }
                 }
-                else {
-                    retVal = RM_ERROR_GRL_LINUX_ALIAS_BUT_NO_DTB;
-                }
             }
         }
     }
@@ -1130,8 +1352,11 @@ static int32_t allocatorExtractGrlResProps(Rm_Handle rmHandle, const char *resou
                                                             resourceProperties->nsAssignLen, &retVal);
             if (nsAssignments) {
                 nsAssignmentBasePtr = nsAssignments;
+                if (rmInst->instType == Rm_instType_SHARED_SERVER) {
+                    rmNameServerTreeInv(rmInst->u.server.nameServer);
+                }                  
                 while (nsAssignments) {
-                    memset((void *)&nameServerObjCfg, 0, sizeof(Rm_NameServerObjCfg));
+                    memset((void *)&nameServerObjCfg, 0, sizeof(nameServerObjCfg));
                     nameServerObjCfg.nameServerTree = rmInst->u.server.nameServer;
                     nameServerObjCfg.nodeCfg.objName = nsAssignments->nsName;
                     nameServerObjCfg.nodeCfg.resourceName = (char *)resourceName;
@@ -1140,10 +1365,16 @@ static int32_t allocatorExtractGrlResProps(Rm_Handle rmHandle, const char *resou
                     rmNameServerAddObject(&nameServerObjCfg);
                     nsAssignments = nsAssignments->nextNsAssignment;
                 }
+                if (rmInst->instType == Rm_instType_SHARED_SERVER) {
+                    rmNameServerTreeWb(rmInst->u.server.nameServer);
+                }                
                 rmDtbUtilResFreeNsAssignmentList(nsAssignmentBasePtr);
             }
         }
     }
+    else {
+        rmAllocatorDelete(rmHandle, resourceName);
+    }
 
     rmDtbUtilResFreeRange(rangeBasePtr);
     if (linuxAlias) {
@@ -1156,14 +1387,69 @@ static int32_t allocatorExtractGrlResProps(Rm_Handle rmHandle, const char *resou
  ********************** Internal Functions ****************************
  **********************************************************************/
 
+/* FUNCTION PURPOSE: Creates a new resource tree
+ ***********************************************************************
+ * DESCRIPTION: Creates and populates a new resource tree allocator
+ *              using the provided resource name and value range.  The
+ *              name and value originate from the GRL.
+ */
+int32_t rmAllocatorCreate(Rm_Handle rmHandle, const char *resourceName, Rm_ResourceRange *range)
+{
+    Rm_Inst         *rmInst = (Rm_Inst *)rmHandle;
+    Rm_Allocator    *allocator = NULL;
+    Rm_ResourceTree *treeRoot = NULL;
+    Rm_ResourceNode *treeNode = NULL;
+
+    allocator = allocatorAdd(rmHandle, resourceName);
+    treeRoot = Rm_osalMalloc(sizeof(*treeRoot));
+    RB_INIT(treeRoot);
+
+    while (range != NULL) {
+        treeNode = rmResourceNodeNew(range->base, range->length);
+        RB_INSERT(_Rm_AllocatorResourceTree, treeRoot, treeNode);
+        range = range->nextRange;
+    }
+    if (rmInst->instType == Rm_instType_SHARED_SERVER) {
+        rmResourceTreeWb(treeRoot);
+    }
+    
+    allocator->allocatorRootEntry = treeRoot;
+    RM_SS_OBJ_WB(allocator, Rm_Allocator);
+    return(RM_OK);
+}
+
+/* FUNCTION PURPOSE: Returns a pointer to the allocator list
+ ***********************************************************************
+ * DESCRIPTION: Returns a pointer to the instance's allocator list
+ *              based on the instance type
+ */
+Rm_Allocator *rmAllocatorGetAllocatorList(Rm_Handle rmHandle)
+{
+    Rm_Inst      *rmInst = (Rm_Inst *)rmHandle;
+    Rm_Allocator *list = NULL;
+
+    if ((rmInst->instType == Rm_instType_SERVER) ||
+        (rmInst->instType == Rm_instType_SHARED_SERVER)) {
+        list = rmInst->u.server.allocators;
+    }
+    else if (rmInst->instType == Rm_instType_CLIENT_DELEGATE) {
+        list = rmInst->u.cd.allocators;
+    }
+    return(list);
+}
+
 /* FUNCTION PURPOSE: Finds an allocator
  ***********************************************************************
  * DESCRIPTION: Returns a pointer to an allocator that matches the 
  *              provided resource name.
  */
-Rm_Allocator *rmAllocatorFind(Rm_Allocator *allocatorList, char *resourceName)
+Rm_Allocator *rmAllocatorFind(Rm_Handle rmHandle, const char *resourceName)
 {
+    Rm_Inst      *rmInst = (Rm_Inst *)rmHandle;
+    Rm_Allocator *allocatorList = rmAllocatorGetAllocatorList(rmHandle);
+    
     while (allocatorList) {
+        RM_SS_OBJ_INV(allocatorList, Rm_Allocator);
         if (strncmp(allocatorList->resourceName, resourceName, RM_NAME_MAX_CHARS) == 0) {
             break;             
         }
@@ -1173,6 +1459,75 @@ Rm_Allocator *rmAllocatorFind(Rm_Allocator *allocatorList, char *resourceName)
     return (allocatorList);
 }
 
+/* FUNCTION PURPOSE: Checks if a resource node is localized
+ ***********************************************************************
+ * DESCRIPTION: Checks if a resource node is localized.  A localized
+ *              node is one that is free and has no neighboring nodes
+ *              or neighboring nodes that do not have resource values
+ *              contiguous with the node being checked.  The function
+ *              will return RM_TRUE is the node is localized.  
+ *              Otherwise, the function returns RM_FALSE
+ */
+int rmAllocatorGetNodeLocalization(Rm_Handle rmHandle, char *resourceName, 
+                                   int32_t *resBase, uint32_t *resLen)
+{
+    Rm_Inst         *rmInst = (Rm_Inst *)rmHandle;
+    void *           policy = rmPolicyGetPolicy((Rm_Handle)rmInst);
+    int32_t          resOffsetInPolicy = rmPolicyGetResourceOffset(policy, resourceName);
+    uint32_t         allocSize = rmPolicyGetResourceCdAllocSize(policy, resOffsetInPolicy);    
+    Rm_Allocator    *allocator = rmAllocatorFind(rmHandle, resourceName);
+    Rm_ResourceNode  findNode;
+    Rm_ResourceNode *matchingNode = NULL;
+    Rm_ResourceNode *neighborNode = NULL;   
+    int              nodeIsLocalized;
+
+    memset((void *)&findNode, 0, sizeof(findNode));
+    findNode.base = *resBase;
+    findNode.length = *resLen;
+    matchingNode = RB_FIND(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, &findNode);
+
+    if (matchingNode) {
+        /* Node can be freed back to Server from CD if:
+         * - allocationCount == 0
+         * - node's resource range is multiple of policy allocation size
+         * - node's resource range boundaries are not contiguous with surrounding nodes */
+        if (matchingNode->allocationCount) {
+            nodeIsLocalized = RM_FALSE;
+            goto exitLocalization;
+        }
+            
+        if (matchingNode->length % allocSize) {
+            nodeIsLocalized = RM_FALSE;
+            goto exitLocalization;        
+        }
+
+        /* Check left neighbor */
+        neighborNode = RB_PREV(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);
+        if (neighborNode && allocatorResNodeBoundaryCompare(neighborNode, matchingNode)) {
+            nodeIsLocalized = RM_FALSE;
+            goto exitLocalization; 
+        }
+
+        /* Check right neighbor */
+        neighborNode = RB_NEXT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);
+        if (neighborNode && allocatorResNodeBoundaryCompare(neighborNode, matchingNode)) {
+            nodeIsLocalized = RM_FALSE;
+            goto exitLocalization; 
+        }
+
+        /* All localization checks passed.  Return the base and length of localized node. */
+        nodeIsLocalized = RM_TRUE;
+        *resBase = matchingNode->base;
+        *resLen = matchingNode->length;
+    }
+    else {
+        nodeIsLocalized = RM_FALSE;
+    }
+
+exitLocalization:
+    return (nodeIsLocalized);
+}
+
 /* FUNCTION PURPOSE: Issues an allocator operation
  ***********************************************************************
  * DESCRIPTION: Issues an allocator preallocate, allocate, or free
@@ -1186,18 +1541,33 @@ int32_t rmAllocatorOperation(Rm_Handle rmHandle, Rm_AllocatorOpInfo *opInfo)
     int32_t       retVal;
     
     resourceOffsetInPolicy = rmPolicyGetResourceOffset(opInfo->policy, opInfo->resourceInfo->name);
-    allocator = rmAllocatorFind(rmInst->u.server.allocators, opInfo->resourceInfo->name);
+    allocator = rmAllocatorFind(rmHandle, opInfo->resourceInfo->name);
     
     if ((resourceOffsetInPolicy > 0) && allocator) {
-        if (opInfo->operation == Rm_allocatorOp_PRE_ALLOCATE) {
+        if (rmInst->instType == Rm_instType_SHARED_SERVER) {
+            rmResourceTreeInv(allocator->allocatorRootEntry);
+        }
+
+        if (opInfo->operation == Rm_allocatorOp_GET_STATUS) {
+            retVal = allocatorStatus(rmHandle, allocator, opInfo);
+        }
+        else if ((opInfo->operation == Rm_allocatorOp_PRE_ALLOCATE_INIT) ||
+                 (opInfo->operation == Rm_allocatorOp_PRE_ALLOCATE_USE)) {
             retVal = allocatorPreAllocate(rmHandle, allocator, resourceOffsetInPolicy, opInfo);
         }               
-        else if (opInfo->operation == Rm_allocatorOp_ALLOCATE) {
+        else if ((opInfo->operation == Rm_allocatorOp_ALLOCATE_INIT) ||
+                 (opInfo->operation == Rm_allocatorOp_ALLOCATE_USE)) {
             retVal = allocatorAllocate(rmHandle, allocator, resourceOffsetInPolicy, opInfo);
         }
         else if (opInfo->operation == Rm_allocatorOp_FREE) {
-            retVal = allocatorFree(allocator, opInfo);
-        }         
+            retVal = allocatorFree(rmHandle, allocator, opInfo);
+        } 
+
+        if ((rmInst->instType == Rm_instType_SHARED_SERVER) &&
+            (opInfo->operation != Rm_allocatorOp_GET_STATUS) &&
+            (retVal == RM_SERVICE_APPROVED)) {
+            rmResourceTreeWb(allocator->allocatorRootEntry);
+        }        
     }
     else {
         /* Resource could not be found in policy and/or allocator */
@@ -1226,7 +1596,7 @@ int32_t rmAllocatorInitializeResources(Rm_Handle rmHandle, void *globalResourceD
 
     /* Parse the Global Resource List, creating an allocator for each specified resource node */
     while ((nodeOffset >= RM_DTB_UTIL_STARTING_NODE_OFFSET) && (nodeDepth >= RM_DTB_UTIL_STARTING_DEPTH)) {
-        memset((void *)&resProperties, 0, sizeof(Rm_ResourceProperties));
+        memset((void *)&resProperties, 0, sizeof(resProperties));
         /* Get properties of resource node */
         propOffset = fdt_first_property_offset(globalResourceDtb, nodeOffset);
         while (propOffset >= RM_DTB_UTIL_STARTING_NODE_OFFSET) {
@@ -1281,6 +1651,83 @@ exitAllocInit:
     return(retVal);
 }
 
+/* FUNCTION PURPOSE: Deletes a resource allocator resource node
+ ***********************************************************************
+ * DESCRIPTION: Deletes a resource allocator's node based on the given
+ *              resource name, base and length.
+ */
+void rmAllocatorDeleteNode(Rm_Handle rmHandle, const char *resName, int32_t resBase, uint32_t resLen)
+{
+    Rm_Allocator    *allocator = rmAllocatorFind(rmHandle, resName);
+    Rm_ResourceNode  findNode;
+    Rm_ResourceNode *matchingNode;
+
+    memset((void *)&findNode, 0, sizeof(findNode));
+    findNode.base = resBase;
+    findNode.length = resLen;
+    matchingNode = RB_FIND(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, &findNode);
+    
+    if (matchingNode) {
+        RB_REMOVE(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);
+        rmResourceNodeFree(matchingNode);
+    }
+}
+
+/* FUNCTION PURPOSE: Deletes a resource allocator
+ ***********************************************************************
+ * DESCRIPTION: Deletes a resource allocator based on the given
+ *              resource name.  The resource allocator will be
+ *              removed from the RM instance allocator list.
+ */
+int32_t rmAllocatorDelete(Rm_Handle rmHandle, const char *resourceName)
+{
+    Rm_Inst         *rmInst = (Rm_Inst *)rmHandle;    
+    Rm_Allocator    *allocator = rmAllocatorGetAllocatorList(rmHandle);
+    Rm_Allocator    *prevAllocator = NULL;
+    Rm_ResourceTree *treeRoot;
+    Rm_ResourceNode *node = NULL;
+    Rm_ResourceNode *nextNode = NULL;
+    int32_t          retVal = RM_OK;
+
+    while (allocator) {
+        if (strncmp(allocator->resourceName, resourceName, RM_NAME_MAX_CHARS) == 0) {
+            break;             
+        }
+        prevAllocator = allocator;
+        allocator = allocator->nextAllocator;
+    }
+
+    if (allocator) {
+        if (prevAllocator == NULL) {
+            if ((rmInst->instType == Rm_instType_SERVER) ||
+                (rmInst->instType == Rm_instType_SHARED_SERVER)) {
+                rmInst->u.server.allocators = allocator->nextAllocator;
+            }
+            else if (rmInst->instType == Rm_instType_CLIENT_DELEGATE) {
+                rmInst->u.cd.allocators = allocator->nextAllocator;
+            }              
+        }
+        else {
+            prevAllocator->nextAllocator = allocator->nextAllocator;
+            RM_SS_OBJ_WB(prevAllocator, Rm_Allocator);
+        }
+            
+        /* Destroy tree and return error */
+        treeRoot = allocator->allocatorRootEntry;
+        for (node = RB_MIN(_Rm_AllocatorResourceTree, treeRoot); node != NULL; node = nextNode) {
+               nextNode = RB_NEXT(_Rm_AllocatorResourceTree, treeRoot, node);
+               RB_REMOVE(_Rm_AllocatorResourceTree, treeRoot, nextNode);
+            rmResourceNodeFree(node);
+        }
+        Rm_osalFree((void *)treeRoot, sizeof(*treeRoot));        
+        Rm_osalFree((void *)allocator, sizeof(*allocator));
+    }
+    else {
+        retVal = RM_ERROR_RES_ALLOCATOR_DOES_NOT_EXIST;
+    }
+    return (retVal);
+}
+
 /* FUNCTION PURPOSE: Deletes server allocators
  ***********************************************************************
  * DESCRIPTION: Removes all resource nodes for each
@@ -1288,32 +1735,36 @@ exitAllocInit:
  *              itself.  Used to free all memory consumed
  *              by the allocators.
  */
-void rmAllocatorDeleteResources(Rm_Allocator *allocatorList)
+void rmAllocatorDeleteResources(Rm_Handle rmHandle)
 {
+    Rm_Inst         *rmInst = (Rm_Inst *)rmHandle;
+    Rm_Allocator    *allocatorList = rmAllocatorGetAllocatorList(rmHandle);
     Rm_Allocator    *nextAllocator;
     Rm_ResourceTree *resTree;
     Rm_ResourceNode *resNode;
     Rm_ResourceNode *nextResNode;
 
     while (allocatorList) {
+        RM_SS_OBJ_INV(allocatorList, Rm_Allocator);
         nextAllocator = allocatorList->nextAllocator;
         resTree = allocatorList->allocatorRootEntry;
 
+        if (rmInst->instType == Rm_instType_SHARED_SERVER) {
+            rmResourceTreeInv(resTree);
+        }
         /* Delete each resource node in the allocator */
         for (resNode = RB_MIN(_Rm_AllocatorResourceTree, resTree); resNode != NULL; resNode = nextResNode) {
             nextResNode = RB_NEXT(_Rm_AllocatorResourceTree, resTree, resNode);
             RB_REMOVE(_Rm_AllocatorResourceTree, resTree, resNode);
             if (resNode->allocationCount) {
                 /* Delete all the owners in the resource's owner list */
-                allocatorResNodeOwnerClear(resNode);
+                allocatorResNodeOwnerClear(rmHandle, resNode);
             }
             rmResourceNodeFree(resNode);
         }        
-        if (RB_MIN(_Rm_AllocatorResourceTree, resTree) == NULL) {
-            /* No more resource nodes in allocator */
-            Rm_osalFree((void *)resTree, sizeof(Rm_ResourceTree));
-        }
-        Rm_osalFree((void *)allocatorList, sizeof(Rm_Allocator));
+
+        Rm_osalFree((void *)resTree, sizeof(*resTree));
+        Rm_osalFree((void *)allocatorList, sizeof(*allocatorList));
         allocatorList = nextAllocator;
     }
 }