/** * @file rm_tree.c * * @brief * Resource Manager Tree Manipulation Source. * * \par * ============================================================================ * @n (C) Copyright 2012-2013, Texas Instruments, Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the * distribution. * * Neither the name of Texas Instruments Incorporated nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * \par */ /* Standard includes */ #include #include /* RM external API includes */ #include /* RM internal API includes */ #include /* RM OSAL layer */ #include /********************************************************************** ********************* NameServer Tree Functions ********************** **********************************************************************/ /* FUNCTION PURPOSE: Creates a new NameServer tree node *********************************************************************** * DESCRIPTION: Creates a new NameServer tree node with the * specified name and the resource values it is * tied to. */ Rm_NameServerNode *rmNameServerNodeNew(Rm_NameServerNodeCfg *nodeCfg) { Rm_NameServerNode *newNode = NULL; newNode = Rm_osalMalloc(sizeof(Rm_NameServerNode)); if (newNode) { strncpy(newNode->objName, nodeCfg->objName, RM_NAME_MAX_CHARS); strncpy(newNode->resourceName, nodeCfg->resourceName, RM_NAME_MAX_CHARS); newNode->resourceBase = nodeCfg->resourceBase; newNode->resourceLength = nodeCfg->resourceLength; } return(newNode); } /* FUNCTION PURPOSE: Deletes a NameServer tree node *********************************************************************** * DESCRIPTION: Deletes the specified NameServer tree node. */ void rmNameServerNodeFree(Rm_NameServerNode *node) { if (node) { Rm_osalFree((void *)node, sizeof(Rm_NameServerNode)); } } /* FUNCTION PURPOSE: Compares two NameServer tree nodes *********************************************************************** * DESCRIPTION: Returns the result of a comparison of two * NameServer tree node names. * node1 name < node2 name --> return < 0 * node1 name = node2 name --> return 0 * node1 name > node2 name --> return > 0 */ int rmNameServerNodeCompare(Rm_NameServerNode *node1, Rm_NameServerNode *node2) { return(strncmp(node1->objName, node2->objName, RM_NAME_MAX_CHARS)); } /* Generate the NameServer tree manipulation functions */ RB_GENERATE(_Rm_NameServerTree, _Rm_NameServerNode, linkage, rmNameServerNodeCompare); /********************************************************************** *************** Policy Valid Instance Tree Functions ***************** **********************************************************************/ /* FUNCTION PURPOSE: Creates a new valid instance tree node *********************************************************************** * DESCRIPTION: Creates a new valid instance tree node with the * specified name. */ Rm_PolicyValidInstNode *rmPolicyValidInstNodeNew(char *instName) { Rm_PolicyValidInstNode *newNode = NULL; newNode = Rm_osalMalloc(sizeof(Rm_PolicyValidInstNode)); strncpy(newNode->name, instName, RM_NAME_MAX_CHARS); newNode->allocRefCount = 0; newNode->deletePending = false; return(newNode); } /* FUNCTION PURPOSE: Deletes a valid instance tree node *********************************************************************** * DESCRIPTION: Deletes the specified valind instance tree node * if it has zero allocation references. */ void rmPolicyValidInstNodeFree(Rm_PolicyValidInstNode *node) { if (node->allocRefCount == 0) { Rm_osalFree((void *)node, sizeof(Rm_PolicyValidInstNode)); } } /* FUNCTION PURPOSE: Compares two valid instance tree nodes *********************************************************************** * DESCRIPTION: Returns the result of a comparison of two * valid instance tree node names. * node1 name < node2 name --> return < 0 * node1 name = node2 name --> return 0 * node1 name > node2 name --> return > 0 */ int rmPolicyValidInstNodeCompare(Rm_PolicyValidInstNode *node1, Rm_PolicyValidInstNode *node2) { return(strncmp(node1->name, node2->name, RM_NAME_MAX_CHARS)); } /* Generate the valid instance tree manipulation functions */ RB_GENERATE(_Rm_PolicyValidInstTree, _Rm_PolicyValidInstNode, linkage, rmPolicyValidInstNodeCompare); /********************************************************************** ***************** Allocator Resource Tree Functions ****************** **********************************************************************/ /* FUNCTION PURPOSE: Creates a new resource tree node *********************************************************************** * DESCRIPTION: Creates a new resource tree node with the * specified name resource values. */ Rm_ResourceNode *rmResourceNodeNew(uint32_t resourceBase, uint32_t resourceLength) { Rm_ResourceNode *newNode = NULL; newNode = Rm_osalMalloc(sizeof(Rm_ResourceNode)); memset((void *)newNode, 0, sizeof(Rm_ResourceNode)); newNode->base = resourceBase; newNode->length = resourceLength; newNode->allocationCount = 0; newNode->ownerList = NULL; return(newNode); } /* FUNCTION PURPOSE: Deletes a resource tree node *********************************************************************** * DESCRIPTION: Deletes the specified resource tree node * if its allocation count is zero. */ void rmResourceNodeFree(Rm_ResourceNode *node) { if (node->allocationCount == 0) { Rm_osalFree((void *)node, sizeof(Rm_ResourceNode)); } } /* FUNCTION PURPOSE: Compares two resource tree nodes *********************************************************************** * DESCRIPTION: Returns the result of a comparison of two * resource tree node value ranges. * |node1 range||node2 range| --> return < 0 * |node1 range| * |node2 range| --> return 0 (any overlap in ranges) * |node2 range||node1 range| --> return > 0 */ int rmResourceNodeCompare(Rm_ResourceNode *node1, Rm_ResourceNode *node2) { uint32_t node1End = node1->base + node1->length - 1; uint32_t node2End = node2->base + node2->length - 1; if (node1End < node2->base) { /* End of node1 range is less than the start of node2's range. Return a negative * value */ return (-1); } else if (node1->base > node2End) { /* Start of node1 range is after end of node2's range. Return a positive value */ return (1); } else { /* If neither of the latter conditions were satisfied there is some overlap between * node1 and node2. Return 0 since the application must handle this overlap. */ return (0); } } /* Generate the resource tree manipulation functions */ RB_GENERATE(_Rm_AllocatorResourceTree, _Rm_ResourceNode, linkage, rmResourceNodeCompare)