Integrated red-black tree algorithm for tree allocators
[keystone-rtos/rm-lld.git] / src / rm.c
index 64a9dafa2025076d5dcf36341d9835d33e25be30..16b3dd72ebab462338aba2d5934295e6f44de774 100644 (file)
--- a/src/rm.c
+++ b/src/rm.c
 /* RM LIBFDT includes */\r
 #include <ti/drv/rm/src/libfdt/libfdt.h>\r
 \r
+/* AVL BBST includes */\r
+#include <ti/drv/rm/include/tree.h>\r
+\r
 /* RM OSAL layer */\r
 #include <rm_osal.h>\r
 \r
 /**********************************************************************\r
  ************************** Globals ***********************************\r
  **********************************************************************/\r
-#if 0\r
-/* Place QMSS PDSP permissions array */\r
-#pragma DATA_SECTION (rmQmssPdspFirmwarePerms, ".rm");\r
-#pragma DATA_ALIGN (rmQmssPdspFirmwarePerms, 128)\r
-Rm_Perms rmQmssPdspFirmwarePerms[RM_ALIGN_PERMISSIONS_ARRAY(RM_QMSS_FIRMWARE_PDSPS, Rm_Perms)];\r
-#endif\r
-\r
 char rmIntegerAllocator[] = "integer";\r
 char rmTreeAllocator[] = "tree";\r
 \r
@@ -79,6 +75,64 @@ extern char rmDtbStartingNode[];
 /** @brief Global Variable which describes the RM Version Information */\r
 const char   rmVersionStr[] = RM_VERSION_STR ":" __DATE__  ":" __TIME__;\r
 \r
+/**********************************************************************\r
+ ************** Red-Black BBST Tree Allocator Functions ***************\r
+ **********************************************************************/\r
+\r
+/* TODO: This needed? */\r
+/* Prototype for function that allocates new tree nodes */\r
+Rm_ResourceTreeNode *Rm_newResourceTreeNode(uint32_t resourceBase, uint32_t resourceLength)\r
+{\r
+    Rm_ResourceTreeNode *newNode = NULL;\r
+\r
+    newNode = Rm_osalMalloc(sizeof(Rm_ResourceTreeNode));\r
+\r
+    /* Populate the RM relevant fields */\r
+    newNode->base = resourceBase;\r
+    newNode->length = resourceLength;\r
+\r
+    return(newNode);\r
+}\r
+\r
+/* TODO: This needed? */\r
+/* Prototype for function that frees new tree nodes */\r
+void Rm_freeResourceTreeNode(Rm_ResourceTreeNode *treeNode)\r
+{\r
+    /* Free the memory associated with the tree node. */\r
+    Rm_osalFree((void *)treeNode, sizeof(Rm_ResourceTreeNode));\r
+}\r
+\r
+/* Prototype for tree node comparison function\r
+ * element1 < element2 --> return < 0\r
+ * element1 = element2 --> return 0\r
+ * element1 > element2 --> return > 0 */\r
+int Rm_ResourceTreeNodeCompare(Rm_ResourceTreeNode *element1, Rm_ResourceTreeNode *element2)\r
+{\r
+    uint32_t element1End = element1->base + element1->length - 1;\r
+    uint32_t element2End = element2->base + element2->length - 1;\r
+\r
+    if (element1End < element2->base)\r
+    {\r
+        /* End of element1 range is less than the start of element2's range.  Return a negative\r
+         * value */\r
+        return (-1);\r
+    }\r
+    else if (element1->base > element2End)\r
+    {\r
+        /* Start of element1 range is after end of element2's range.  Return a positive value */\r
+        return (1);\r
+    }\r
+    else\r
+    {\r
+        /* If neither of the latter conditions were satisfied there is some overlap between\r
+         * element1 and element2.  Return 0 since the application must handle this overlap. */\r
+        return (0);\r
+    }\r
+}\r
+\r
+/* Generate the red-black tree manipulation functions */\r
+RB_GENERATE(_Rm_ResourceTree, _Rm_ResourceTreeNode, linkage, Rm_ResourceTreeNodeCompare);\r
+\r
 /**********************************************************************\r
  ********************** Internal Functions ****************************\r
  **********************************************************************/\r
@@ -356,6 +410,30 @@ Rm_Allocator *Rm_allocatorAdd(Rm_Inst *rmInst, const char *resourceName, Rm_Allo
     return (newAllocator);\r
 }\r
 \r
+Rm_Allocator *Rm_allocatorFind(Rm_Inst *rmInst, char *resourceName)\r
+{\r
+    Rm_Allocator *allocator = (Rm_Allocator *)rmInst->allocators;\r
+\r
+    /* Make sure there is at least one allocator in the allocator list */\r
+    if (allocator != NULL)\r
+    {\r
+        /* Find the resource name within the allocator list.  If the end of the\r
+         * allocator list is reached without finding the resource name the \r
+         * allocator pointer will be NULL */\r
+        while (allocator != NULL)\r
+        {\r
+            if (strcmp(allocator->resourceName, resourceName) == 0)\r
+            {\r
+                /* Match: break out of loop and return the allocator */\r
+                break;             \r
+            }\r
+            allocator = allocator->nextAllocator;\r
+        }\r
+    }\r
+\r
+    return (allocator);\r
+}\r
+\r
 int32_t Rm_allocatorDelete(Rm_Inst *rmInst, char *resourceName)\r
 {\r
     Rm_Allocator *allocator = (Rm_Allocator *) rmInst->allocators;\r
@@ -447,6 +525,8 @@ int32_t Rm_createIntegerAllocator(Rm_Inst *rmInst, const char *resourceName, Rm_
             for (i = range->base; i < (range->base + range->length); i++, entryIndex++)\r
             {\r
                 intRootEntry->resourceArrayBase[entryIndex].value = i;\r
+                /* Initialize the allocatedTo field to the NOT_ALLOCATED string */\r
+                strcpy(intRootEntry->resourceArrayBase[entryIndex].allocatedTo, RM_NOT_ALLOCATED_STRING);\r
             }\r
             \r
             range = range->nextRange;\r
@@ -465,6 +545,66 @@ int32_t Rm_createIntegerAllocator(Rm_Inst *rmInst, const char *resourceName, Rm_
     return(0);  /* TODO: FIX THIS RETURN */\r
 }\r
 \r
+int32_t Rm_createTreeAllocator(Rm_Inst *rmInst, const char *resourceName, Rm_ResourceRange *range)\r
+{\r
+    Rm_Allocator *allocator = NULL;\r
+    Rm_ResourceTree *treeRootEntry = NULL;\r
+    Rm_ResourceTreeNode *treeNode = NULL;\r
+    Rm_ResourceTreeNode *collidingNode = NULL;\r
+\r
+    /* Create the new base integer allocator */\r
+    allocator = Rm_allocatorAdd(rmInst, resourceName, Rm_allocatorType_TREE);\r
+\r
+    /* Create the tree root entry and initialize it */\r
+    treeRootEntry = Rm_osalMalloc(sizeof(Rm_ResourceTree));\r
+    RB_INIT(treeRootEntry);\r
+\r
+    /* Create a node in the tree for resource range and insert them into the tree. */\r
+    while (range != NULL)\r
+    {\r
+        treeNode = Rm_osalMalloc(sizeof(Rm_ResourceTreeNode));\r
+        treeNode->base = range->base;\r
+        treeNode->length = range->length;\r
+        /* Initialize the allocatedTo field to the NOT_ALLOCATED string */\r
+        strcpy(treeNode->allocatedTo, RM_NOT_ALLOCATED_STRING);\r
+\r
+        /* Insert the node into the tree */\r
+        collidingNode = RB_INSERT(_Rm_ResourceTree, treeRootEntry, treeNode);\r
+\r
+        if (collidingNode)\r
+        {\r
+            Rm_ResourceTreeNode *nextNode = NULL;\r
+            \r
+            /* Node that was inserted colliding with an existing node.  Clean up the tree\r
+             * that's been allocated thus far and return an error since there should be no\r
+             * collisions */\r
+            for (treeNode = RB_MIN(_Rm_ResourceTree, treeRootEntry); treeNode != NULL; treeNode = nextNode)\r
+            {\r
+                       nextNode = RB_NEXT(_Rm_ResourceTree, treeRootEntry, treeNode);\r
+                       RB_REMOVE(_Rm_ResourceTree, treeRootEntry, nextNode);\r
+                       Rm_osalFree((void *)treeNode, sizeof(Rm_ResourceTreeNode));\r
+               }\r
+            /* Delete the tree root entry and the allocator */\r
+            Rm_osalFree((void *)treeRootEntry, sizeof(Rm_ResourceTree));\r
+            Rm_allocatorDelete(rmInst, allocator->resourceName);\r
+            return (-24); /* TODO FIX RETURN */\r
+        }\r
+\r
+        range = range->nextRange;\r
+    }\r
+\r
+    /* Assign the tree's root to the allocator */\r
+    allocator->allocatorRootEntry = treeRootEntry;\r
+\r
+    /* Print the base values as a test */\r
+    RB_FOREACH(treeNode, _Rm_ResourceTree, (Rm_ResourceTree *) allocator->allocatorRootEntry)\r
+    {\r
+        Rm_osalLog("Tree node base: %d length: %d and allocated to: %s\n", treeNode->base, treeNode->length, treeNode->allocatedTo);\r
+    }\r
+\r
+    return(0);   /* TODO: FIX THIS RETURN */\r
+}\r
+\r
 int32_t Rm_createAndInitAllocator(Rm_Inst *rmInst, const char *resourceName, \r
                                   Rm_ResourceProperties *resourceProperties)\r
 {\r
@@ -492,6 +632,7 @@ int32_t Rm_createAndInitAllocator(Rm_Inst *rmInst, const char *resourceName,
     else if (strcmp(allocatorType, &rmTreeAllocator[0]) == 0)\r
     {\r
         /* Create a tree allocator using the resource properties */\r
+        retVal = Rm_createTreeAllocator(rmInst, resourceName, range); \r
     }\r
     else\r
     {\r
@@ -670,92 +811,313 @@ int32_t Rm_parseResourceNode(Rm_Inst *rmInst, void *globalResourceDtb, int32_t n
     return (RM_DTB_UTIL_RESULT_OKAY);\r
 }\r
 \r
-int32_t Rm_initializeAllocators(Rm_Inst *rmInst, void *globalResourceDtb)\r
+/* Called when an allocate request is made but the base is unspecified.  RM must preallocate\r
+ * resources which then must be checked against the RM policy for the instance.  If the\r
+ * policy does not agree another resource(s) must be preallocated and tested against the \r
+ * policy.  Policy will provide initialize the preallocate with the base that it allows\r
+ * for the rm instance for the specified resource. */\r
+int32_t Rm_integerPreAllocate(Rm_Allocator *allocator, Rm_AllocatorOpInfo *opInfo)\r
 {\r
-    int32_t nodeOffset = RM_DTB_UTIL_STARTING_NODE_OFFSET;\r
-    int32_t startDepth = RM_DTB_UTIL_STARTING_DEPTH;\r
-    int32_t result = RM_DTB_UTIL_RESULT_OKAY;\r
-\r
-    /* Recursively parse the Global Resource List, creating an allocator for\r
-     * each resource as specified in the node */\r
-    result = Rm_parseResourceNode(rmInst, globalResourceDtb, nodeOffset, startDepth);\r
-\r
-    return(result);\r
+    \r
 }\r
-         \r
-int32_t Rm_reserveLinuxResources(void *linuxResourceDtb)\r
+\r
+int32_t Rm_integerAllocate(Rm_Allocator *allocator, Rm_AllocatorOpInfo *opInfo)\r
 {\r
-    return(0);\r
+    Rm_IntegerAllocatorRootEntry *root = allocator->allocatorRootEntry;\r
+    uint16_t resourceIndex, i, j;\r
+    bool resourcesValidated = TRUE;\r
+    int32_t retVal;\r
+\r
+    /* Find the specified resource base within the allocator */\r
+    for (resourceIndex = 0; resourceIndex < root->numResourceElements; resourceIndex++)\r
+    {\r
+        if (root->resourceArrayBase[resourceIndex].value == opInfo->resourceInfo->base)\r
+        {\r
+            /* Found the resource base in the allocator.  Break from the loop */\r
+            break;\r
+        }\r
+    }\r
+\r
+    /* Only execute the allocate operation if the resource base was found in the allocator\r
+     * and the base+range does not exceed the number of entries in the allocator */\r
+    if (resourceIndex + opInfo->resourceInfo->range <= root->numResourceElements)\r
+    {\r
+        /* Verify all resource values from base to base+range exist in the allocator and\r
+         * are not allocated to another instance. */\r
+        for (i = resourceIndex, j = opInfo->resourceInfo->base; \r
+             i < (resourceIndex + opInfo->resourceInfo->range);\r
+             i++, j++)\r
+        {\r
+            if (root->resourceArrayBase[i].value != j)\r
+            {\r
+                /* A value in the range did not match. */\r
+                retVal = RM_SERVICE_DENIED_RESOURCE_VALUE_IN_RANGE_DOES_NOT_EXIST;\r
+                resourcesValidated = FALSE;\r
+                break;\r
+            }\r
+            else if (strcmp(root->resourceArrayBase[i].allocatedTo, RM_NOT_ALLOCATED_STRING) != 0)\r
+            {\r
+                /* A value in the range is already allocated. */\r
+                retVal = RM_SERVICE_DENIED_RESOURCE_ALREADY_ALLOCATED;\r
+                resourcesValidated = FALSE;\r
+                break;            \r
+            }\r
+        }\r
 \r
+        if (resourcesValidated)\r
+        {\r
+            /* Allocate all resources from base to base+range */\r
+            for (i = resourceIndex; i < (resourceIndex + opInfo->resourceInfo->range); i++)\r
+            {\r
+                strcpy(root->resourceArrayBase[i].allocatedTo, opInfo->srcInstName);\r
+            }\r
+            retVal = RM_SERVICE_APPROVED_AND_COMPLETED;\r
+        }\r
+    }\r
+    else\r
+    {\r
+        retVal = RM_SERVICE_DENIED_RESOURCE_VALUE_IN_RANGE_DOES_NOT_EXIST;\r
+    }\r
+\r
+    return(retVal); \r
 }\r
 \r
-void Rm_allocationHandler (Rm_Inst *rmInst, Rm_Transaction *transaction)\r
+int32_t Rm_integerFree(Rm_Allocator *allocator, Rm_AllocatorOpInfo *opInfo)\r
 {\r
-    if (rmInst->instType == Rm_instType_CLIENT_DELEGATE)\r
+    Rm_IntegerAllocatorRootEntry *root = allocator->allocatorRootEntry;\r
+    uint16_t resourceIndex, i, j;\r
+    bool resourcesValidated = TRUE;\r
+    int32_t retVal;\r
+\r
+    /* Find the specified resource base within the allocator */\r
+    for (resourceIndex = 0; resourceIndex < root->numResourceElements; resourceIndex++)\r
     {\r
-#if 0        \r
-        /* Check local policy to see if the request can be satisfied with the\r
-         * resources stored locally */\r
-        Rm_policy...API()\r
+        if (root->resourceArrayBase[resourceIndex].value == opInfo->resourceInfo->base)\r
+        {\r
+            /* Found the resource base in the allocator.  Break from the loop */\r
+            break;\r
+        }\r
+    }\r
 \r
-        if (policy check approves the resource)\r
+    /* Only execute the free operation if the resource base was found in the allocator\r
+     * and the base+range does not exceed the number of entries in the allocator */\r
+    if (resourceIndex + opInfo->resourceInfo->range <= root->numResourceElements)\r
+    {\r
+        /* Verify all resource values from base to base+range exist in the allocator,\r
+         * were not already free and were allocated to the instance that is the source\r
+         * of the free request. */\r
+        for (i = resourceIndex, j = opInfo->resourceInfo->base; \r
+             i < (resourceIndex + opInfo->resourceInfo->range);\r
+             i++, j++)\r
         {\r
-            /* call the allocator to allocate the resource */\r
-            if (allocator returns resource)\r
+            if (root->resourceArrayBase[i].value != j)\r
             {\r
-                /* Populate the transaction with the allocated resources and the result */\r
-                transaction->state = approve reason;\r
-                return ...\r
+                /* A value in the range did not match. */\r
+                retVal = RM_SERVICE_DENIED_RESOURCE_VALUE_IN_RANGE_DOES_NOT_EXIST;\r
+                resourcesValidated = FALSE;\r
+                break;\r
             }\r
-            else\r
+            else if (strcmp(root->resourceArrayBase[i].allocatedTo, RM_NOT_ALLOCATED_STRING) == 0)\r
             {\r
-                /* allocator ran out of resources, need to contact Server for more\r
-                 * resources */\r
-                Rm_resourcePoolModRequest(...);\r
+                /* A value in the range is already free. */\r
+                retVal = RM_SERVICE_DENIED_RESOURCE_ALREADY_FREE;\r
+                resourcesValidated = FALSE;\r
+                break;            \r
+            }            \r
+            else if (strcmp(root->resourceArrayBase[i].allocatedTo, opInfo->srcInstName) != 0)\r
+            {\r
+                /* A value in the range was not allocated to the source of\r
+                 * the free request */\r
+                retVal = RM_SERVICE_DENIED_RESOURCE_NOT_ALLOCATED_TO_INSTANCE_REQUESTING_THE_SERVICE;\r
+                resourcesValidated = FALSE;\r
+                break;\r
             }\r
         }\r
-        else if (policy check denies resource)\r
+\r
+        if (resourcesValidated)\r
         {\r
-            /* Policy check denied resource. */\r
-            transaction->state= deny reason;\r
-            return ...\r
+            /* Free all resources from base to base+range */\r
+            for (i = resourceIndex; i < (resourceIndex + opInfo->resourceInfo->range); i++)\r
+            {\r
+                strcpy(root->resourceArrayBase[i].allocatedTo, RM_NOT_ALLOCATED_STRING);\r
+            }\r
+            retVal = RM_SERVICE_APPROVED_AND_COMPLETED;\r
         }\r
-        else if (policy check says forward to Server for validation)\r
+    }\r
+    else\r
+    {\r
+        retVal = RM_SERVICE_DENIED_RESOURCE_VALUE_IN_RANGE_DOES_NOT_EXIST;\r
+    }\r
+\r
+    return(retVal);\r
+}\r
+\r
+/* Called when an allocate request is made but the base is unspecified.  RM must preallocate\r
+ * resources which then must be checked against the RM policy for the instance.  If the\r
+ * policy does not agree another resource(s) must be preallocated and tested against the \r
+ * policy */\r
+int32_t Rm_treePreAllocate(Rm_Allocator *allocator, Rm_AllocatorOpInfo *opInfo)\r
+{\r
+\r
+}\r
+\r
+int32_t Rm_treeAllocate(Rm_Allocator *allocator, Rm_AllocatorOpInfo *opInfo)\r
+{\r
+    \r
+}\r
+\r
+int32_t Rm_treeFree(Rm_Allocator *allocator, Rm_AllocatorOpInfo *opInfo)\r
+{\r
+\r
+}\r
+\r
+int32_t Rm_allocatorOperation(Rm_Inst *rmInst, Rm_AllocatorOpInfo *opInfo)\r
+{\r
+    Rm_Allocator *allocator = NULL;\r
+    int32_t retVal;\r
+    void *key;\r
+\r
+    /* Lock access to the RM instance's transaction queue */\r
+    key = Rm_osalMtCsEnter();\r
+\r
+    /* Get the specified resource's allocator */\r
+    allocator = Rm_allocatorFind(rmInst, opInfo->resourceInfo->name);\r
+\r
+    if (allocator)\r
+    {\r
+        /* Call the allocator's type-based allocation function */\r
+        if(allocator->type == Rm_allocatorType_INTEGER)\r
         {\r
-            /* Forward the transaction to the Server */\r
-            Rm_transactionForwarder(rmInst, transaction);\r
+            if (opInfo->operation == Rm_allocatorOp_PRE_ALLOCATE)\r
+            {\r
+                retVal = Rm_integerPreAllocateUnspecified(allocator, opInfo);\r
+            }            \r
+            else if (opInfo->operation == Rm_allocatorOp_ALLOCATE)\r
+            {\r
+                retVal = Rm_integerAllocate(allocator, opInfo);\r
+            }\r
+            else if (opInfo->operation == Rm_allocatorOp_FREE)\r
+            {\r
+                retVal = Rm_integerFree(allocator, opInfo);\r
+            }\r
         }\r
-#endif         \r
+        else if (allocator->type == Rm_allocatorType_TREE)\r
+        {\r
+            if (opInfo->operation == Rm_allocatorOp_PRE_ALLOCATE)\r
+            {\r
+                retVal = Rm_treePreAllocateUnspecified(allocator, opInfo);\r
+            }               \r
+            else if (opInfo->operation == Rm_allocatorOp_ALLOCATE)\r
+            {\r
+                retVal = Rm_treeAllocate(allocator, opInfo);\r
+            }\r
+            else if (opInfo->operation == Rm_allocatorOp_FREE)\r
+            {\r
+                retVal = Rm_treeFree(allocator, opInfo);\r
+            }  \r
+        }        \r
     }\r
-    else if (rmInst->instType == Rm_instType_SERVER)\r
+    else\r
     {\r
-#if 0        \r
-        /* Check global policy to see if resource can be allocated. return result\r
-         * no matter what */\r
-        Rm_policy...API()\r
+        /* Allocator could not be found for resource */\r
+        retVal = RM_SERVICE_DENIED_RESOURCE_DOES_NOT_EXIST;\r
+    }\r
 \r
-        if (policy approves)\r
+    Rm_osalMtCsExit(key);\r
+    return(retVal);\r
+}\r
+\r
+void Rm_allocationHandler (Rm_Inst *rmInst, Rm_Transaction *transaction)\r
+{\r
+    if (rmInst->instType == Rm_instType_CLIENT_DELEGATE)\r
+    {\r
+#if 0        \r
+        if (resourceBase is unspecified)\r
         {\r
-            /* call allocator to allocate resource */\r
+           while (policy does not approve)\r
+           {\r
+               Rm_policy check get allowed base as starting point for prealloc\r
+               preallocate resource based on the range and alignment\r
+               Rm_policy...check\r
+           }\r
         }\r
+        else\r
+        {\r
+            /* Check local policy to see if the request can be satisfied with the\r
+             * resources stored locally */\r
+            Rm_policy...API()\r
 \r
-        transaction->state = approve or deny reason;\r
-        transaction->resourceInfo.base = ...;\r
-        transaction->resourceInfo.range = ...;\r
-\r
-        /* If source instance name does not match the current instance\r
-         * name the allocation request came from a Client.  The result\r
-         * must be sent back to the Client */\r
-        if (strcmp(transaction->sourceInstName, rmInst->name))\r
+            if (policy check approves the resource)\r
+            {\r
+                /* call the allocator to allocate the resource */\r
+                if (allocator returns resource)\r
+                {\r
+                    /* Populate the transaction with the allocated resources and the result */\r
+                    transaction->state = approve reason;\r
+                    return ...\r
+                }\r
+                else\r
+                {\r
+                    /* allocator ran out of resources, need to contact Server for more\r
+                     * resources */\r
+                    Rm_resourcePoolModRequest(...);\r
+                }\r
+            }\r
+            else if (policy check denies resource)\r
+            {\r
+                /* Policy check denied resource. */\r
+                transaction->state= deny reason;\r
+                return ...\r
+            }\r
+            else if (policy check says forward to Server for validation)\r
+            {\r
+                /* Forward the transaction to the Server */\r
+                Rm_transactionForwarder(rmInst, transaction);\r
+            }\r
+        }\r
+#endif         \r
+    }\r
+    else if (rmInst->instType == Rm_instType_SERVER)\r
+    {\r
+#if 0       \r
+        if (resourceBase is unspecified)\r
         {\r
-            /* Names don't match.  Send the transaction back to the Client */\r
-            Rm_transactionResponder(rmInst, transaction);\r
+           while (policy does not approve)\r
+           {\r
+               Rm_policy check get allowed base as starting point for prealloc\r
+               preallocate resource based on the range and alignment\r
+               Rm_policy...check\r
+           }\r
         }\r
         else\r
         {\r
-            /* Resource allocation request originated locally on the active\r
-             * instance. Send the response via the service responder. */          \r
-            Rm_serviceResponder(rmInst, transaction);                            \r
+            /* Check global policy to see if resource can be allocated. return result\r
+             * no matter what */\r
+            Rm_policy...API()\r
+\r
+            if (policy approves)\r
+            {\r
+                /* call allocator to allocate resource */\r
+            }\r
+\r
+            transaction->state = approve or deny reason;\r
+            transaction->resourceInfo.base = ...;\r
+            transaction->resourceInfo.range = ...;\r
+\r
+            /* If source instance name does not match the current instance\r
+             * name the allocation request came from a Client.  The result\r
+             * must be sent back to the Client */\r
+            if (strcmp(transaction->sourceInstName, rmInst->name))\r
+            {\r
+                /* Names don't match.  Send the transaction back to the Client */\r
+                Rm_transactionResponder(rmInst, transaction);\r
+            }\r
+            else\r
+            {\r
+                /* Resource allocation request originated locally on the active\r
+                 * instance. Send the response via the service responder. */          \r
+                Rm_serviceResponder(rmInst, transaction);                            \r
+            }\r
         }\r
 #endif        \r
     }   \r
@@ -1003,7 +1365,7 @@ void Rm_transactionProcessor (Rm_Inst *rmInst, Rm_Transaction *transaction)
                         if (Rm_nsAddObject(rmInst, transaction->resourceInfo.nsName,\r
                                            transaction->resourceInfo.base) == RM_NS_ACTION_APPROVED)\r
                         {\r
-                            transaction->state = RM_SERVICE_APPROVED;\r
+                            transaction->state = RM_SERVICE_APPROVED_AND_COMPLETED;\r
                         }\r
                         else\r
                         {\r
@@ -1018,7 +1380,7 @@ void Rm_transactionProcessor (Rm_Inst *rmInst, Rm_Transaction *transaction)
                         if (Rm_nsDeleteObject(rmInst, transaction->resourceInfo.nsName) == \r
                             RM_NS_ACTION_APPROVED)\r
                         {\r
-                            transaction->state = RM_SERVICE_APPROVED;\r
+                            transaction->state = RM_SERVICE_APPROVED_AND_COMPLETED;\r
                         }\r
                         else\r
                         {\r
@@ -1046,6 +1408,25 @@ void Rm_transactionProcessor (Rm_Inst *rmInst, Rm_Transaction *transaction)
     }\r
 }\r
 \r
+int32_t Rm_initializeAllocators(Rm_Inst *rmInst, void *globalResourceDtb)\r
+{\r
+    int32_t nodeOffset = RM_DTB_UTIL_STARTING_NODE_OFFSET;\r
+    int32_t startDepth = RM_DTB_UTIL_STARTING_DEPTH;\r
+    int32_t result = RM_DTB_UTIL_RESULT_OKAY;\r
+\r
+    /* Recursively parse the Global Resource List, creating an allocator for\r
+     * each resource as specified in the node */\r
+    result = Rm_parseResourceNode(rmInst, globalResourceDtb, nodeOffset, startDepth);\r
+\r
+    return(result);\r
+}\r
+         \r
+int32_t Rm_reserveLinuxResources(Rm_Inst *rmInst, void *linuxResourceDtb)\r
+{\r
+    return(0);\r
+\r
+}\r
+\r
 /**********************************************************************\r
  ********************** Application visible APIs **********************\r
  **********************************************************************/\r
@@ -1102,7 +1483,7 @@ Rm_Handle Rm_init(Rm_InitCfg *initCfg)
         {\r
             linuxResourceDtb = initCfg->linuxDtb;\r
             fdt_open_into(linuxResourceDtb, linuxResourceDtb, fdt_totalsize(linuxResourceDtb));            \r
-            Rm_reserveLinuxResources(linuxResourceDtb);\r
+            Rm_reserveLinuxResources(rmInst, linuxResourceDtb);\r
         }\r
     }\r
 \r