📄 nsalloc.c
字号:
* Increment the reference count(s) of all parents up to * the root! */ while ((node = acpi_ns_get_parent_node (node)) != NULL) { node->reference_count++; } return_VOID;}/******************************************************************************* * * FUNCTION: acpi_ns_delete_children * * PARAMETERS: parent_node - Delete this objects children * * RETURN: None. * * DESCRIPTION: Delete all children of the parent object. In other words, * deletes a "scope". * ******************************************************************************/voidacpi_ns_delete_children ( struct acpi_namespace_node *parent_node){ struct acpi_namespace_node *child_node; struct acpi_namespace_node *next_node; struct acpi_namespace_node *node; u8 flags; ACPI_FUNCTION_TRACE_PTR ("ns_delete_children", parent_node); if (!parent_node) { return_VOID; } /* If no children, all done! */ child_node = parent_node->child; if (!child_node) { return_VOID; } /* * Deallocate all children at this level */ do { /* Get the things we need */ next_node = child_node->peer; flags = child_node->flags; /* Grandchildren should have all been deleted already */ if (child_node->child) { ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Found a grandchild! P=%p C=%p\n", parent_node, child_node)); } /* Now we can free this child object */ ACPI_MEM_TRACKING (acpi_gbl_memory_lists[ACPI_MEM_LIST_NSNODE].total_freed++); ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Object %p, Remaining %X\n", child_node, acpi_gbl_current_node_count)); /* * Detach an object if there is one, then free the child node */ acpi_ns_detach_object (child_node); /* * Decrement the reference count(s) of all parents up to * the root! (counts were incremented when the node was created) */ node = child_node; while ((node = acpi_ns_get_parent_node (node)) != NULL) { node->reference_count--; } /* There should be only one reference remaining on this node */ if (child_node->reference_count != 1) { ACPI_REPORT_WARNING (("Existing references (%d) on node being deleted (%p)\n", child_node->reference_count, child_node)); } /* Now we can delete the node */ ACPI_MEM_FREE (child_node); /* And move on to the next child in the list */ child_node = next_node; } while (!(flags & ANOBJ_END_OF_PEER_LIST)); /* Clear the parent's child pointer */ parent_node->child = NULL; return_VOID;}/******************************************************************************* * * FUNCTION: acpi_ns_delete_namespace_subtree * * PARAMETERS: parent_node - Root of the subtree to be deleted * * RETURN: None. * * DESCRIPTION: Delete a subtree of the namespace. This includes all objects * stored within the subtree. * ******************************************************************************/voidacpi_ns_delete_namespace_subtree ( struct acpi_namespace_node *parent_node){ struct acpi_namespace_node *child_node = NULL; u32 level = 1; ACPI_FUNCTION_TRACE ("ns_delete_namespace_subtree"); if (!parent_node) { return_VOID; } /* * Traverse the tree of objects until we bubble back up * to where we started. */ while (level > 0) { /* Get the next node in this scope (NULL if none) */ child_node = acpi_ns_get_next_node (ACPI_TYPE_ANY, parent_node, child_node); if (child_node) { /* Found a child node - detach any attached object */ acpi_ns_detach_object (child_node); /* Check if this node has any children */ if (acpi_ns_get_next_node (ACPI_TYPE_ANY, child_node, NULL)) { /* * There is at least one child of this node, * visit the node */ level++; parent_node = child_node; child_node = NULL; } } else { /* * No more children of this parent node. * Move up to the grandparent. */ level--; /* * Now delete all of the children of this parent * all at the same time. */ acpi_ns_delete_children (parent_node); /* New "last child" is this parent node */ child_node = parent_node; /* Move up the tree to the grandparent */ parent_node = acpi_ns_get_parent_node (parent_node); } } return_VOID;}/******************************************************************************* * * FUNCTION: acpi_ns_remove_reference * * PARAMETERS: Node - Named node whose reference count is to be * decremented * * RETURN: None. * * DESCRIPTION: Remove a Node reference. Decrements the reference count * of all parent Nodes up to the root. Any node along * the way that reaches zero references is freed. * ******************************************************************************/voidacpi_ns_remove_reference ( struct acpi_namespace_node *node){ struct acpi_namespace_node *parent_node; struct acpi_namespace_node *this_node; ACPI_FUNCTION_ENTRY (); /* * Decrement the reference count(s) of this node and all * nodes up to the root, Delete anything with zero remaining references. */ this_node = node; while (this_node) { /* Prepare to move up to parent */ parent_node = acpi_ns_get_parent_node (this_node); /* Decrement the reference count on this node */ this_node->reference_count--; /* Delete the node if no more references */ if (!this_node->reference_count) { /* Delete all children and delete the node */ acpi_ns_delete_children (this_node); acpi_ns_delete_node (this_node); } this_node = parent_node; }}/******************************************************************************* * * FUNCTION: acpi_ns_delete_namespace_by_owner * * PARAMETERS: owner_id - All nodes with this owner will be deleted * * RETURN: Status * * DESCRIPTION: Delete entries within the namespace that are owned by a * specific ID. Used to delete entire ACPI tables. All * reference counts are updated. * ******************************************************************************/voidacpi_ns_delete_namespace_by_owner ( u16 owner_id){ struct acpi_namespace_node *child_node; struct acpi_namespace_node *deletion_node; u32 level; struct acpi_namespace_node *parent_node; ACPI_FUNCTION_TRACE_U32 ("ns_delete_namespace_by_owner", owner_id); parent_node = acpi_gbl_root_node; child_node = NULL; deletion_node = NULL; level = 1; /* * Traverse the tree of nodes until we bubble back up * to where we started. */ while (level > 0) { /* * Get the next child of this parent node. When child_node is NULL, * the first child of the parent is returned */ child_node = acpi_ns_get_next_node (ACPI_TYPE_ANY, parent_node, child_node); if (deletion_node) { acpi_ns_remove_reference (deletion_node); deletion_node = NULL; } if (child_node) { if (child_node->owner_id == owner_id) { /* Found a matching child node - detach any attached object */ acpi_ns_detach_object (child_node); } /* Check if this node has any children */ if (acpi_ns_get_next_node (ACPI_TYPE_ANY, child_node, NULL)) { /* * There is at least one child of this node, * visit the node */ level++; parent_node = child_node; child_node = NULL; } else if (child_node->owner_id == owner_id) { deletion_node = child_node; } } else { /* * No more children of this parent node. * Move up to the grandparent. */ level--; if (level != 0) { if (parent_node->owner_id == owner_id) { deletion_node = parent_node; } } /* New "last child" is this parent node */ child_node = parent_node; /* Move up the tree to the grandparent */ parent_node = acpi_ns_get_parent_node (parent_node); } } return_VOID;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -