int main() { struct Node * tempNode1, *tempNode2, *tempNode3; int size = 10; struct HeadNode * tempHead = buddy_new(size); if (tempHead!=NULL) { //注意申请的空间最大不是2^k, 而是2^k - 1 tempNode1 = buddy_alloc(tempHead,size,511); buddy_print(tempHead, size); tempNode2 = buddy_alloc(tempHead,size,10); buddy_print(tempHead, size); tempNode3 = buddy_alloc(tempHead,size,10); buddy_print(tempHead, size); buddy_combine(tempHead, size, tempNode3); buddy_print(tempHead, size); buddy_combine(tempHead, size, tempNode2); buddy_print(tempHead, size); buddy_combine(tempHead, size, tempNode1); buddy_print(tempHead, size); } buddy_free(tempHead); getchar(); return 0; }
int pfree(ulong pfn) { // Obtain the node struct palloc_node *node = get_node_by_pfn(pfn); // Get tag and order int tag = node->tag; int order = node->order; int order_count = 0x1 << order; // Setup the node node->alloc = 0; // Lock the bucket spin_lock_int(&buckets[tag].lock); // Insert the node back to the list if (buckets[tag].buddies[order].value) { node->next = buckets[tag].buddies[order].next; node->has_next = 1; } else { node->next = 0; node->has_next = 0; } buckets[tag].buddies[order].has_next = 1; buckets[tag].buddies[order].next = pfn; // Setup the bucket buckets[tag].avail_pages += order_count; // Combine the buddy system buddy_combine(pfn); // Unlock the bucket spin_unlock_int(&buckets[tag].lock); return order_count; }
static void buddy_combine(ulong pfn) { // Obtain the node struct palloc_node *node = get_node_by_pfn(pfn); int tag = node->tag; int order = node->order; int order_count = 0x1 << order; // If we already have the highest order, then we are done if (order == PALLOC_MAX_ORDER) { return; } // Get some info of the higher order int higher = order + 1; ulong higher_size = ((ulong)0x1 << higher) * PAGE_SIZE; ulong higher_pfn = 0; ulong other_pfn = 0; ulong cur_addr = PFN_TO_ADDR(pfn); // Check the other node to see if they can form a buddy if (0 == cur_addr % higher_size) { higher_pfn = pfn; other_pfn = pfn + order_count; } else { higher_pfn = pfn - order_count; other_pfn = pfn - order_count; } struct palloc_node *other_node = get_node_by_pfn(other_pfn); // If the other node doesn't belong to the same bucket as current node, // or the other node is in use, then we are done, there's no way to combine if ( !other_node || !other_node->avail || other_node->tag != tag || other_node->alloc || order != other_node->order ) { return; } // Remove both nodes from the list remove_node(pfn, tag, order); remove_node(other_pfn, tag, order); // Setup the two nodes node->has_next = 0; node->next = 0; node->order = higher; node->tag = tag; node->avail = 1; other_node->has_next = 0; other_node->next = 0; other_node->order = higher; other_node->tag = tag; other_node->avail = 1; // Insert them into the higher order list insert_node(higher_pfn, tag, higher); // Combine the higiher order buddy_combine(higher_pfn); }