Esempio n. 1
0
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;
}
Esempio n. 2
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;
}
Esempio n. 3
0
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);
}