Initial look at memory management (iii) partner Algorithms

Source: Internet
Author: User
Tags random seed

Assuming that the system can use 2 m characters in memory space (from 0 to 2 m addresses), the entire memory zone is an idle block with a size of 2 m at the start of operation, after running for a period of time, it is divided into several occupied blocks and idle blocks. To facilitate searching during allocation, we create all idle blocks of the same size in a subtable. Each sub-table is a double linked list. Such a linked list may contain m + 1, which organizes the m + 1 header pointer into a table using a vector structure, this is the usable space table in the partner system ,:



Allocation Algorithm:

When a user initiates a memory request whose size is N, the user can first use the table to find the child table with the node size matching n. If the child table is not empty, allocate any node in the sub-table. If the sub-table is empty, search for it from a non-empty sub-table with a larger node until an idle block is found, then, some of them are allocated to the user, and the remaining parts are inserted into the corresponding sub-table.
If 2k-1 <n ≤ 2k-1 and the k + 1 sub-table is not empty, delete the first node in the linked list and assign it to the user. If 2k-2 <n ≤ 2k-1-1, at this time, because the child table with the node size of 2k-1 is empty, you need to retrieve one from the child table with the node size of 2 K and allocate half of them to the user, the remaining half is inserted as a new node in the child table with the node size of 2k-1. If 2k-i-1 <n
≤2k-i-1 (I is an integer smaller than yes), and all subtables with nodes less than 2 K are empty, you also need to retrieve one from the subtable with a node size of 2 K, A small part of 2k-i is allocated to the user, and the remaining part is divided into several nodes, which are inserted into the node sizes of 2k-1, 2k-2 ,... And 2k-i subtables.

Recycling algorithm:

When a user releases a block that is no longer used, the system needs to insert the new idle block to the available space table. Here, there is also a problem that the adjacent idle blocks of addresses are merged into large blocks. However, in the partner system, only two idle blocks of mutual "partners" are considered.
What is "partner "? As mentioned above, a large idle block is often split into two storage zones of equal size during allocation. The two chunks split from the same block are called "mutual partners ". For example, assume that p is the initial address of the idle block with the size of POW (2, K), and p mod POW (2, K + 1) = 0, then, the two idle blocks whose initial addresses are P and P + POW (2, K) are mutual partners. When idle blocks are recycled in the partner system, they are merged into large blocks only when their partners are idle blocks. That is to say, if there are two idle blocks, even if the size is the same and the address is adjacent, but they are not split from the same block, they are not merged.
Therefore, when recycling idle blocks, determine whether the partner is idle blocks. If not, simply insert the released idle blocks into the corresponding sub-tables. If yes, find and delete the partner in the corresponding subtable, and then identify whether the partner of the merged idle block is a idle block. Repeat this until the partner of the free block obtained by the merge operation is not the idle block, and then insert it into the corresponding sub-table.


The Code is as follows (only a single-chain table is used ):


# Include <stdio. h> # include <stdlib. h> # include <time. h> # define min_momory_size 536870912 // The minimum random memory size: 512 MB (1 GB at the maximum) # define index_size 30 // hash index table size # define worktime 1500 // system working time # define max_req_size 268435456 // apply for the maximum capacity for idle memory allocation: 256 m # define min_due 30 // minimum time for using memory blocks # define max_due 90 // maximum time for using memory blocks # define occupy_interval 60 // maximum interval of each allocation # define used 1 // memory block used # define unused 0 // memory block not used // node Structure of memory block linked list typedef Struct buddy_node {int flag; // indicates whether the space is using int base; // The base address of the memory in this block, int occupy; // the actual size of the space used, int fragment; // shard size int duetime; // use the time struct buddy_node * nextptr; // point to the next node} buddy, * buddyptr; // hash index table structure typedef struct hash_table {int nodesize; buddyptr headptr;} indextable; indextable table [index_size]; // use the hash table management partner system int ready = 0; // int availspace when memory needs to be allocated; // allocable space size int totalfragment = 0; // total Fragment Size // function: calculated based on the value of K Calculate the size of the memory block connected to the hash table necklace int get_size (int K) {int I, nodesize = 1; for (I = 0; I <K; I ++) nodesize * = 2; return nodesize;} // function: Initialize the hash index table void ini_index (void) {int I; for (I = 0; I <index_size; I ++) {table [I]. nodesize = get_size (I); table [I]. headptr = NULL ;}// function: Initialize the void int_system (INT memory_size) {int I, ADDR = 0; int left = memory_size; buddyptr newnodeptr = NULL; // initialize the allocable space and fragment size availspace = Memory_size; totalfragment = 0; // split the memory into idle blocks as many as 2 times as possible and insert them into the corresponding index table item for (I = INDEX_SIZE-1; left> 0; I --) {If (left/table [I]. nodesize = 1) {newnodeptr = (buddyptr) malloc (sizeof (Buddy); // distribution node newnodeptr-> flag = Unused; newnodeptr-> base = ADDR; newnodeptr-> occupy = 0; newnodeptr-> fragment = 0; newnodeptr-> duetime = 0; newnodeptr-> nextptr = NULL; Table [I]. headptr = newnodeptr; ADDR + = table [I]. Nodesize; left-= table [I]. nodesize ;}}// function: after the program runs, all nodes void free_system (void) {int I; buddyptr tempptr = NULL, tofreeptr = NULL; for (I = 0; I <index_size; I ++) {If (Table [I]. headptr) {tempptr = table [I]. headptr; Table [I]. headptr = NULL; // release all nodes while (tempptr) {tofreeptr = tempptr; tempptr = tempptr-> nextptr; free (tofreeptr) ;}}// function: add a node (the parameter is the information of the memory block node) void insert_node (int I, in T inbase, int F, int OCC, int frag, int d) {buddyptr newnodeptr = NULL, preptr = NULL, curptr = NULL; newnodeptr = (buddyptr) malloc (sizeof (Buddy); // distribution node newnodeptr-> base = inbase; newnodeptr-> flag = f; newnodeptr-> occupy = OCC; newnodeptr-> fragment = frag; newnodeptr-> duetime = D; newnodeptr-> nextptr = NULL; If (Table [I]. headptr = NULL) Table [I]. headptr = newnodeptr; else {curptr = table [I]. Headptr; preptr = NULL; // Insert the memory block in the address order while (curptr & curptr-> base <inbase) {preptr = curptr; curptr = curptr-> nextptr ;} if (preptr = NULL) {// insert newnodeptr-> nextptr = curptr; Table [I]. headptr = newnodeptr;} else if (curptr = NULL) {// Insert the last preptr-> nextptr = newnodeptr;} else {// Insert the intermediate preptr-> nextptr = newnodeptr; newnodeptr-> nextptr = curptr; }}// function: Delete the node int delete_node (int I, buddypt R delptr) {buddyptr preptr = NULL, curptr = NULL; int basehold = delptr-> base; curptr = table [I]. headptr; while (curptr! = Delptr) {// locate the node to be deleted. preptr = curptr; curptr = curptr-> nextptr;} If (preptr = NULL) // The node to be deleted is in the top table [I]. headptr = curptr-> nextptr; else // The node to be deleted is not in the preptr-> nextptr = curptr-> nextptr; free (curptr ); // release the node return basehold; // return the base address of the deleted memory block node} // function: the allocation algorithm void buddy_allocate (INT time_slice) of the partner system {int I, j, size, due; int state = 0; // allocation status: 0 is not allocated, 1 is allocated int inbase, basehold; buddyptr curptr = NULL; If (ready = time_slice) {// printf ("time % d:", time_slice); size = 1 + rand () % max_req_size; // apply for the memory size due = min_due + rand () % (max_due-min_due); // apply for the memory usage time if (availspace> size) {// allocate when the allocable space is greater than the requested space // search for the allocable memory block in sequence (I = 0; (I <index_size) & (State = 0); I ++) {// locate a block index not smaller than the applied size if (Table [I]. nodesize> = size & table [I]. headptr) {curptr = table [I]. headptr; // traverses the corresponding loop chain Table while (curptr & (State = 0) {// find the idle block if (curptr-> flag = Unused) {// If (Table [I]. nodesize/size = 1) {// set the information curptr-> flag = used; curptr-> occupy = size on the allocated memory block; curptr-> fragment = table [I]. nodesize-size; curptr-> duetime = due + ready; // modify the allocated space and fragment size of the system. availspace-= table [I]. nodesize; totalfragment + = curptr-> fragment; State = 1; // mark the allocated break;} // the size of the idle block is just twice the size of the applied el Se {basehold = delete_node (I, curptr); // Delete large idle blocks and keep their base address inbase = basehold + Table [I]. nodesize; j = I; // split the idle block do {J --; inbase-= table [J]. nodesize; // set the base address insert_node (J, inbase, unused, 0, 0, 0) for the memory block node to be added ); // Add a smaller idle block printf ("A block cut takes place \ n");} while (Table [J]. nodesize/size> 1); // allocate insert_node (J, basehold, used, size, table [J]. nodesize-size, due + ready); // modify the size of the allocated space and fragments. Vailspace-= table [J]. nodesize; totalfragment + = table [J]. nodesize-size; State = 1; // mark allocated} // The block is occupied. Check else curptr = curptr-> nextptr;} at the next node ;}}} printf ("allocated % d, fragment % d, due % d \ n", size, totalfragment, ready + due);} else if (availspace <size) & (availspace + totalfragment)> = size) printf ("Allocation failed because of fragment! \ N "); else printf (" Allocation failed because of no enough unused space! \ N "); ready + = (1 + rand () % occupy_interval); // time when memory needs to be allocated next time} // function: void buddy_retrieve (INT time_slice) {int I, basehold, DIF; int f = 0; int modnext = 0; buddyptr curptr = NULL, todelptr = NULL; // search for and reclaim the block to be recycled (I = 0; I <index_size; I ++) {If (Table [I]. headptr) {curptr = table [I]. headptr; while (curptr) {If (curptr-> flag = used) & (curptr-> duetime = time_slice) {// you need to recycle it. // you can modify the file system. Total allocated space and shard size availspace + = table [I]. nodesize; totalfragment-= curptr-> fragment; // recycle the idle block curptr-> flag = Unused; curptr-> occupy = 0; curptr-> fragment = 0; curptr-> duetime = 0; printf ("time % d: retrieve % d, fragment % d \ n", time_slice, table [I]. nodesize, totalfragment) ;}curptr = curptr-> nextptr ;}}// merge idle blocks for (I = 0; I <index_size; I ++) {If (Table [I]. headptr) {curptr = table [I]. headptr; while (Curptr & curptr-> nextptr) {// combine the contiguous idle blocks and add them to the list at the next level if (curptr-> flag = Unused & (curptr-> nextptr) -> flag = Unused) {DIF = (curptr-> nextptr)-> base-curptr-> base; modnext = (INT) (curptr-> nextptr-> base) % (2 * Table [I]. nodesize); If (DIF = table [I]. nodesize) & (modnext = 0) {// Delete two nodes todelptr = curptr; curptr = curptr-> nextptr; basehold = delete_node (I, todelptr ); todelptr = curptr; curptr = Curptr-> nextptr; delete_node (I, todelptr); insert_node (I + 1, basehold, unused, 0, 0, 0 ); // Add the merged node printf ("two blocks merge \ n");} else curptr = curptr-> nextptr ;}}}} // function: void buddy_system (void) {int time_slice = 0; // use the allocation algorithm and retrieval algorithm for (; time_slice <worktime; time_slice ++) {buddy_allocate (time_slice); // The allocation algorithm buddy_retrieve (time_slice );/ /Reclaim Algorithm} int main (INT argc, char * argv []) {int memory_size; ini_index (); // initialize the hash index table srand (Time (null )); // set the Random Seed // The memory size to be managed for random generation: 512 MB ~ 1g memory_size = min_momory_size + rand () % min_momory_size; printf ("the size of memory is: % d \ n", memory_size); int_system (memory_size ); // initialize the partner system buddy_system (); // The process printf ("time % d: system execution stops and the spaces are all freed. \ n ", worktime); free_system (); // release all nodes return 0 ;}


Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.