Added owner reference count to account for multiple allocates/frees of the same resou...
authorJustin Sobota <jsobota@ti.com>
Tue, 14 May 2013 20:47:59 +0000 (16:47 -0400)
committerJustin Sobota <jsobota@ti.com>
Tue, 14 May 2013 20:47:59 +0000 (16:47 -0400)
include/rm_treeloc.h
src/rm.c
src/rm_allocator.c
src/rm_policy.c
test/src/rm_test.c

index bc743703fb7a9445a74c481139a45f37cd5d07c8..e37ea2b556806fc7f01792b313920f4e32055503 100644 (file)
@@ -111,6 +111,9 @@ typedef struct Rm_Owner_s {
     /* Pointer to the valid instance node that currently
      * owns or partially owns the resource */
     Rm_PolicyValidInstNode *instNameNode;
+    /* Number of times this owner has allocated the resource it is
+     * linked to. */
+    uint16_t                refCnt;
     /* Link to the next owner of the resoruce if the resource is shared */
     struct Rm_Owner_s      *nextOwner;
 } Rm_Owner;
index 372e4d60807e45ae62268d5ff3a45294a3e102bc..f82d62b48e6d6ea6c3d08a5446066da10ad733f2 100644 (file)
--- a/src/rm.c
+++ b/src/rm.c
@@ -1303,7 +1303,7 @@ int32_t Rm_resourceStatus(Rm_Handle rmHandle, int printResources)
                     while (owners) {
                         RM_SS_OBJ_INV(owners, Rm_Owner);
                         if (printResources) {
-                            Rm_osalLog("%s ", owners->instNameNode->name);
+                            Rm_osalLog("%s (%d) ", owners->instNameNode->name, owners->refCnt);
                         }
                         totalResOwners++;
                         owners = owners->nextOwner;
index a178f8b17da5fba2d4dcecc6f5c7bf30e1908b99..241df5dce2d5d8f92fa366dc46e9b7b126e2918d 100644 (file)
@@ -103,10 +103,72 @@ static Rm_Allocator *allocatorAdd(Rm_Handle rmHandle, const char *resourceName)
     return (newAllocator);
 }
 
+/* FUNCTION PURPOSE: Checks a resource node's ownership
+ ***********************************************************************
+ * DESCRIPTION: Returns the owner reference count if the provided
+ *              instance node is in the list of resource node owners.  Otherwise,
+ *              returns 0.
+ */
+static int allocatorResNodeIsOwnedBy(Rm_Handle rmHandle, Rm_ResourceNode *node, void *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) {
+            return(owner->refCnt);           
+        }
+        owner = owner->nextOwner;
+    }
+    return(0);
+}
+
+/* FUNCTION PURPOSE: Increments an owner's refCnt
+ ***********************************************************************
+ * DESCRIPTION: Increments a resource owner's reference count
+ */
+static void allocatorResNodeOwnerRefCntInc(Rm_Handle rmHandle, Rm_ResourceNode *node, void *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;
+        }
+        owner = owner->nextOwner;
+    }
+}
+
+/* FUNCTION PURPOSE: Decrements an owner's refCnt
+ ***********************************************************************
+ * DESCRIPTION: Decrements a resource owner's reference count
+ */
+static void allocatorResNodeOwnerRefCntDec(Rm_Handle rmHandle, Rm_ResourceNode *node, void *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;
+        }
+        owner = owner->nextOwner;
+    }
+}
+
 /* 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_Handle rmHandle, Rm_ResourceNode *node, void *serviceInstNode)
 {
@@ -114,30 +176,37 @@ static void allocatorResNodeOwnerAdd(Rm_Handle rmHandle, Rm_ResourceNode *node,
     Rm_Owner *ownerList = node->ownerList;
     Rm_Owner *newOwner = NULL;
 
-    newOwner = Rm_osalMalloc(sizeof(*newOwner));
+    if (allocatorResNodeIsOwnedBy(rmHandle, node, serviceInstNode)) {
+        allocatorResNodeOwnerRefCntInc(rmHandle, node, serviceInstNode);
+    }
+    else {
+        newOwner = Rm_osalMalloc(sizeof(*newOwner));
 
-    if (newOwner) {
-        newOwner->instNameNode = serviceInstNode;
-        newOwner->nextOwner = NULL;  
+        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;
+            /* 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;
             }
-            ownerList->nextOwner = newOwner;
-            RM_SS_OBJ_WB(ownerList, Rm_Owner);
-        }
-        else {
-            node->ownerList = newOwner;
-        }
 
-        node->allocationCount++;
-        newOwner->instNameNode->allocRefCount++;
-        RM_SS_OBJ_WB(newOwner, Rm_Owner);
-        RM_SS_OBJ_WB(newOwner->instNameNode, Rm_PolicyValidInstNode);
+            node->allocationCount++;
+            newOwner->refCnt++;
+            newOwner->instNameNode->allocRefCount++;
+            RM_SS_OBJ_WB(newOwner, Rm_Owner);
+            RM_SS_OBJ_WB(newOwner->instNameNode, Rm_PolicyValidInstNode);
+        }
     }
 }
 
@@ -191,7 +260,8 @@ static int allocatorResNodeOwnerCompare(Rm_Handle rmHandle, Rm_ResourceNode *nod
             RM_SS_OBJ_INV(node1Owners, Rm_Owner);
             matchedInst = RM_FALSE;
             while (node2Owners) {
-                if (node1Owners->instNameNode == node2Owners->instNameNode) {
+                if ((node1Owners->instNameNode == node2Owners->instNameNode) &&
+                    (node1Owners->refCnt == node2Owners->refCnt)) {
                     matchedInst = RM_TRUE;
                     break;
                 }
@@ -216,8 +286,10 @@ static int allocatorResNodeOwnerCompare(Rm_Handle rmHandle, Rm_ResourceNode *nod
 
 /* 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_Handle rmHandle, Rm_ResourceNode *node, void *serviceInstNode)
 {
@@ -225,28 +297,33 @@ static void allocatorResNodeOwnerDelete(Rm_Handle rmHandle, Rm_ResourceNode *nod
     Rm_Owner *owner = node->ownerList;
     Rm_Owner *prevOwner = NULL;
 
-    while (owner) {
-        RM_SS_OBJ_INV(owner, Rm_Owner);
-        if (owner->instNameNode == serviceInstNode) {
-            break;             
-        }
-        prevOwner = owner;
-        owner = owner->nextOwner;
+    if (allocatorResNodeIsOwnedBy(rmHandle, node, serviceInstNode) > 1) {
+        allocatorResNodeOwnerRefCntDec(rmHandle, node, serviceInstNode);
     }
-
-    if (owner) {
-        if (prevOwner == NULL) {
-            node->ownerList = owner->nextOwner;
+    else {
+        while (owner) {
+            RM_SS_OBJ_INV(owner, Rm_Owner);
+            if (owner->instNameNode == serviceInstNode) {
+                break;             
+            }
+            prevOwner = owner;
+            owner = owner->nextOwner;
         }
-        else {
-            prevOwner->nextOwner = owner->nextOwner;
-            RM_SS_OBJ_WB(prevOwner, Rm_Owner);
+
+        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_SS_OBJ_WB(owner->instNameNode, Rm_PolicyValidInstNode);
-        Rm_osalFree((void *)owner, sizeof(*owner));
     }
 }
 
@@ -274,6 +351,7 @@ static void allocatorResNodeOwnerCopy(Rm_Handle rmHandle, Rm_ResourceNode *dstNo
         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);
 
@@ -311,27 +389,6 @@ static void allocatorResNodeOwnerClear(Rm_Handle rmHandle, Rm_ResourceNode *node
     }
 }
 
-/* FUNCTION PURPOSE: Checks a resource node's ownership
- ***********************************************************************
- * DESCRIPTION: Returns TRUE if the provided instance node is
- *              in the list of resource node owners.  Otherwise,
- *              returns FALSE.
- */
-static int allocatorResNodeIsOwnedBy(Rm_Handle rmHandle, Rm_ResourceNode *node, void *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) {
-            return(RM_TRUE);           
-        }
-        owner = owner->nextOwner;
-    }
-    return(RM_FALSE);
-}
-
 /* FUNCTION PURPOSE: Get the status for an allocator resource
  ***********************************************************************
  * DESCRIPTION: Called when a resource status request is made.  The
@@ -636,175 +693,169 @@ static int32_t allocatorAllocate(Rm_Handle rmHandle, Rm_Allocator *allocator, in
             }
             
             if (allocPassesPolicy) {
-                if (!allocatorResNodeIsOwnedBy(rmHandle, 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
+                /* 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;
+
+                        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;
+
+                        allocatorResNodeOwnerClear(rmHandle, rightNode);
+                        rmResourceNodeFree(rightNode);
+                        if (leftNode) {
+                            RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, leftNode);
+                        }
+                    }
+                    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);
+                    
+                    /* Matching node contains new reference count after alloc.  Return new owner count. */
+                    opInfo->resourceInfo->ownerCount = matchingNode->allocationCount;
+                }   
+                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. */
+                    opInfo->resourceInfo->ownerCount = matchingNode->allocationCount;
+                }  
+                else {    
+                    if (findNode.base == matchingNode->base) {
+                        /* findNode base and matchingNode base are equivalent.  May be combine
+                         * possibilities to the left
                          *
-                         *   |<--left node-->||<--matched  node-->||<--right node-->| => existing node
-                         *                    |<--alloc request-->|  => requested resources
-                         */                     
+                         * |<---left node (alloc'd)--->||<----------matched node---------->|
+                         *                              |<---findNode (alloc req)--->|
+                         */                         
                         leftNode = RB_PREV(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);
-                        rightNode = RB_NEXT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);
                         RB_REMOVE(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, 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);
-                            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;
-
-                            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;
-
-                            allocatorResNodeOwnerClear(rmHandle, rightNode);
-                            rmResourceNodeFree(rightNode);
-                            if (leftNode) {
-                                RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, leftNode);
-                            }
+                            /* Combine leftNode and findNode */
+                            leftNode->length += findNode.length;
                         }
                         else {
-                            /* No combine. */
-                            if (leftNode) {
-                                RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, leftNode);
-                            }
-                            if (rightNode) {
-                                RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, rightNode);
-                            }
+                            leftNode = rmResourceNodeNew(findNode.base, findNode.length);
+                            allocatorResNodeOwnerCopy(rmHandle, leftNode, matchingNode);
                         }
 
-                        /* Always reinsert matchingNode */                
-                        RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);
-                        
-                        /* Matching node contains new reference count after alloc.  Return new owner count. */
-                        opInfo->resourceInfo->ownerCount = matchingNode->allocationCount;
-                    }   
-                    else if ((findNode.base > matchingNode->base) && (findEnd < matchingEnd)) {
-                        /* findNode range is subset of matchingNode range and neither boundary is
-                         * equivalent.
+                        /* 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. */
+                        opInfo->resourceInfo->ownerCount = leftNode->allocationCount;
+                    }
+                    else if (findEnd == matchingEnd) {
+                        /* findNode end and matchingNode end are equivalent.  May be combine
+                         * possibilities to the right
                          *
-                         * |<----------matched node---------->|
-                         *        |<---alloc request--->|
-                         */ 
+                         * |<----------matched node---------->||<---right node (alloc'd)--->|
+                         *       |<---findNode (alloc req)--->| 
+                         */                        
+                        rightNode = RB_NEXT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);
                         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;
+                        /* Add allocating instance to owner list for compare with rightNode */
                         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. */
-                        opInfo->resourceInfo->ownerCount = matchingNode->allocationCount;
-                    }  
-                    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(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);
-                            }
-
-                            /* 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. */
-                            opInfo->resourceInfo->ownerCount = leftNode->allocationCount;
+                        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(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);
-                            }
 
-                            /* 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);
-                            /* Right node contains new reference count after alloc.  Return new owner count. */
-                            opInfo->resourceInfo->ownerCount = rightNode->allocationCount;
-                        }
-                        /* Remove allocating instance from leftover matchingNode */
-                        allocatorResNodeOwnerDelete(rmHandle, 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. */
+                        opInfo->resourceInfo->ownerCount = rightNode->allocationCount;
                     }
-                }
-                else {
-                    /* Already owned by requesting instance.  Just return owner count */
-                    opInfo->resourceInfo->ownerCount = matchingNode->allocationCount;
+                    /* Remove allocating instance from leftover matchingNode */
+                    allocatorResNodeOwnerDelete(rmHandle, matchingNode, opInfo->serviceSrcInstNode);
+                    RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);
                 }
                 retVal = RM_SERVICE_APPROVED;
             }
@@ -934,7 +985,7 @@ static int32_t allocatorFree(Rm_Handle rmHandle, Rm_Allocator *allocator, Rm_All
                          * |<----------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);
index 68d63931b1e4e7553f54c6d87695a48deaaffa89..418a19737df32c4326b3f1c8be887360066a2ece 100644 (file)
@@ -676,7 +676,7 @@ uint32_t rmPolicyGetResourceBase(void *policyDtb, Rm_PolicyValidInstNode *validI
     Rm_PolicyAssignment *assignmentStart = NULL;
     Rm_PolicyPermission *permission = NULL;
     Rm_PolicyPermission *permissionStart = NULL;
-    uint32_t             resourceBase = 0;
+    int32_t              resourceBase = 0;
 
     *result = RM_OK;
 
index cf7de3a5b1db77f07aca8c9704b959908b16ab51..4e7b7a9539c04d2e7efc09eaa052aebcb95e8fe3 100644 (file)
@@ -784,6 +784,23 @@ void rmServerTsk(UArg arg0, UArg arg1)
                  6543, 10, 0, NULL, RM_TEST_TRUE, &responseInfo);      
     rmServerServiceHandle->Rm_serviceHandler(rmServerServiceHandle->rmHandle, &requestInfo, &responseInfo);
     POSITIVE_PASS_CHECK("--- Init/Use Allocate of Resource from Same Inst (Use) --", 
+                        coreNum, rmServerName, resourceNameGpQ,
+                        requestInfo.resourceBase, requestInfo.resourceLength, 
+                        requestInfo.resourceAlignment, responseInfo.serviceState, RM_SERVICE_APPROVED);
+    
+    /* Should take two frees to free both references */
+    setRmRequest(&requestInfo, Rm_service_RESOURCE_FREE, resourceNameGpQ, 
+                 6543, 5, 0, NULL, RM_TEST_TRUE, &responseInfo);      
+    rmServerServiceHandle->Rm_serviceHandler(rmServerServiceHandle->rmHandle, &requestInfo, &responseInfo);
+    POSITIVE_PASS_CHECK("------- Free of Resource from Same Inst (1st Ref) -------", 
+                        coreNum, rmServerName, resourceNameGpQ,
+                        requestInfo.resourceBase, requestInfo.resourceLength, 
+                        requestInfo.resourceAlignment, responseInfo.serviceState, RM_SERVICE_APPROVED);
+
+    setRmRequest(&requestInfo, Rm_service_RESOURCE_FREE, resourceNameGpQ, 
+                 6543, 2, 0, NULL, RM_TEST_TRUE, &responseInfo);      
+    rmServerServiceHandle->Rm_serviceHandler(rmServerServiceHandle->rmHandle, &requestInfo, &responseInfo);
+    POSITIVE_PASS_CHECK("------- Free of Resource from Same Inst (2nd Ref) -------", 
                         coreNum, rmServerName, resourceNameGpQ,
                         requestInfo.resourceBase, requestInfo.resourceLength, 
                         requestInfo.resourceAlignment, responseInfo.serviceState, RM_SERVICE_APPROVED);