📄 ixethdbmem.c
字号:
macDescriptor->refCount++; UNLOCK_MAC_POOL; return macDescriptor;}/** * @brief allocates a mac tree node from the pool * * Allocates and initializes a mac tree node from the pool. * * @return the allocated mac tree node or NULL if the pool is empty * * @internal */IX_ETH_DB_PUBLICMacTreeNode* ixEthDBAllocMacTreeNode(void){ MacTreeNode *allocatedNode = NULL; if (treePool != NULL) { LOCK_TREE_POOL; allocatedNode = treePool; treePool = treePool->nextFree; UNLOCK_TREE_POOL; memset(allocatedNode, 0, sizeof(MacTreeNode)); } return allocatedNode;}/** * @brief frees a mac tree node back into the pool * * @param macNode mac tree node to be freed * * @warning not to be used except from ixEthDBFreeMacTreeNode(). * * @see ixEthDBFreeMacTreeNode() * * @internal */void ixEthDBPoolFreeMacTreeNode(MacTreeNode *macNode){ if (macNode != NULL) { LOCK_TREE_POOL; macNode->nextFree = treePool; treePool = macNode; UNLOCK_TREE_POOL; }}/** * @brief frees or reduces the usage count of a mac tree node smart pointer * * @param macNode mac tree node to free * * Reduces the usage count of the given mac node. If the usage count * reaches 0 the node is freed back into the pool using ixEthDBPoolFreeMacTreeNode() * * @internal */IX_ETH_DB_PUBLICvoid ixEthDBFreeMacTreeNode(MacTreeNode *macNode){ if (macNode->descriptor != NULL) { ixEthDBFreeMacDescriptor(macNode->descriptor); } if (macNode->left != NULL) { ixEthDBFreeMacTreeNode(macNode->left); } if (macNode->right != NULL) { ixEthDBFreeMacTreeNode(macNode->right); } ixEthDBPoolFreeMacTreeNode(macNode);}/** * @brief clones a mac tree node * * @param macNode mac tree node to be cloned * * Increments the usage count of the node, <i>its associated descriptor * and <b>recursively</b> of all its child nodes</i>. * * @warning this function is recursive and clones whole trees/subtrees, use only for * root nodes * * @internal */IX_ETH_DB_PUBLICMacTreeNode* ixEthDBCloneMacTreeNode(MacTreeNode *macNode){ if (macNode != NULL) { MacTreeNode *clonedMacNode = ixEthDBAllocMacTreeNode(); if (clonedMacNode != NULL) { if (macNode->right != NULL) { clonedMacNode->right = ixEthDBCloneMacTreeNode(macNode->right); } if (macNode->left != NULL) { clonedMacNode->left = ixEthDBCloneMacTreeNode(macNode->left); } if (macNode->descriptor != NULL) { clonedMacNode->descriptor = ixEthDBCloneMacDescriptor(macNode->descriptor); } } return clonedMacNode; } else { return NULL; }}#ifndef NDEBUG/* Debug statistical functions for memory usage */extern HashTable dbHashtable;int ixEthDBNumHashElements(void);int ixEthDBNumHashElements(void){ UINT32 bucketIndex; int numElements = 0; HashTable *hashTable = &dbHashtable; for (bucketIndex = 0 ; bucketIndex < hashTable->numBuckets ; bucketIndex++) { if (hashTable->hashBuckets[bucketIndex] != NULL) { HashNode *node = hashTable->hashBuckets[bucketIndex]; while (node != NULL) { numElements++; node = node->next; } } } return numElements;}UINT32 ixEthDBSearchTreeUsageGet(MacTreeNode *tree){ if (tree == NULL) { return 0; } else { return 1 /* this node */ + ixEthDBSearchTreeUsageGet(tree->left) + ixEthDBSearchTreeUsageGet(tree->right); }}int ixEthDBShowMemoryStatus(void){ MacDescriptor *mac; MacTreeNode *tree; HashNode *node; int macCounter = 0; int treeCounter = 0; int nodeCounter = 0; int totalTreeUsage = 0; int totalDescriptorUsage = 0; int totalCloneDescriptorUsage = 0; int totalNodeUsage = 0; UINT32 portIndex; LOCK_NODE_POOL; LOCK_MAC_POOL; LOCK_TREE_POOL; mac = macPool; tree = treePool; node = nodePool; while (mac != NULL) { macCounter++; mac = mac->nextFree; if (macCounter > MAC_POOL_SIZE) { break; } } while (tree != NULL) { treeCounter++; tree = tree->nextFree; if (treeCounter > TREE_POOL_SIZE) { break; } } while (node != NULL) { nodeCounter++; node = node->nextFree; if (nodeCounter > NODE_POOL_SIZE) { break; } } for (portIndex = 0 ; portIndex < IX_ETH_DB_NUMBER_OF_PORTS ; portIndex++) { int treeUsage = ixEthDBSearchTreeUsageGet(ixEthDBPortInfo[portIndex].updateMethod.searchTree); totalTreeUsage += treeUsage; totalCloneDescriptorUsage += treeUsage; /* each tree node contains a descriptor */ } totalNodeUsage = ixEthDBNumHashElements(); totalDescriptorUsage += totalNodeUsage; /* each hash table entry contains a descriptor */ UNLOCK_NODE_POOL; UNLOCK_MAC_POOL; UNLOCK_TREE_POOL; printf("Ethernet database memory usage stats:\n\n"); if (macCounter <= MAC_POOL_SIZE) { printf("\tMAC descriptor pool : %d free out of %d entries (%d%%)\n", macCounter, MAC_POOL_SIZE, macCounter * 100 / MAC_POOL_SIZE); } else { printf("\tMAC descriptor pool : invalid state (ring within the pool), normally %d entries\n", MAC_POOL_SIZE); } if (treeCounter <= TREE_POOL_SIZE) { printf("\tTree node pool : %d free out of %d entries (%d%%)\n", treeCounter, TREE_POOL_SIZE, treeCounter * 100 / TREE_POOL_SIZE); } else { printf("\tTREE descriptor pool : invalid state (ring within the pool), normally %d entries\n", TREE_POOL_SIZE); } if (nodeCounter <= NODE_POOL_SIZE) { printf("\tHash node pool : %d free out of %d entries (%d%%)\n", nodeCounter, NODE_POOL_SIZE, nodeCounter * 100 / NODE_POOL_SIZE); } else { printf("\tNODE descriptor pool : invalid state (ring within the pool), normally %d entries\n", NODE_POOL_SIZE); } printf("\n"); printf("\tMAC descriptor usage : %d entries, %d cloned\n", totalDescriptorUsage, totalCloneDescriptorUsage); printf("\tTree node usage : %d entries\n", totalTreeUsage); printf("\tHash node usage : %d entries\n", totalNodeUsage); printf("\n"); /* search for duplicate nodes in the mac pool */ { MacDescriptor *reference = macPool; while (reference != NULL) { MacDescriptor *comparison = reference->nextFree; while (comparison != NULL) { if (reference == comparison) { printf("Warning: reached a duplicate (%p), invalid MAC pool state\n", reference); return 1; } comparison = comparison->nextFree; } reference = reference->nextFree; } } printf("No duplicates found in the MAC pool (sanity check ok)\n"); return 0;}#endif /* NDEBUG *//** * @} EthMemoryManagement */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -