Hello everyone, let's look at the process mfree, I said last time, this process algorithm is a bit complicated, and it should be said that the code is not very clear. Let's take a look at it:
/ *
* Free the Previously Allocated Space AA
* of size units INTO The Specified Map.
* Sort aa Into Both Map and Combine ON
* One or Both Ends if Possible.
* /
Mfree (MP, SIZE, AA)
Struct Map * MP;
{
Register struct map * bp;
Register Int T;
Register int A;
a = aa;
/ * An empty cycle ... (1) * /
For (bp = mp; bp-> m_addr <= a && bp-> m_size! = 0; bp );
/ * Judgment, recycling start * /
IF (BP> MP && (BP-1) -> M_ADDR (BP-1) -> m_size == a) {/ * What is it? (2)*/
(bp-1) -> m_size = size;
IF (a size == bp-> m_addr) {/ * here? (3) * /
(bp-1) -> m_size = bp-> m_size;
While (bp-> m_size) {
BP ;
(bp-1) -> m_addr = bp-> m_addr;
(bp-1) -> m_size = bp-> m_size;
}
}
} Else {/ * What is the situation here? (4) * /
IF (a size == bp-> m_addr && bp-> m_size) {
BP-> m_addr = - size;
BP-> m_size = size;
} Else if (size) do {/ * below the process? (5) * /
T = bp-> m_addr;
BP-> m_addr = a;
A = T;
T = bp-> m_size;
BP-> M_SIZE = SIZE;
BP ;
} while (size = t);
}
}
/ * ----------------------------------- * /
In the last time to say the Malloc process, you can see that the flag of the End of the MP table (unallocated area) is:
BP-> M_SIZE == 0 is true,
This time, let's talk about the recycling mechanism of UNIX storage management. When the address and size to be recovered are passed to MFREE as a parameter, UNIX will return a storage area that should be ordered to MP to MP to MP.
However, it is important to note that if the area has a valid storage area before and after, pay attention to combining them, and there is a reorganization of the MP table, but also the problem.
Let's take a look, such as a possibility:
If there is a valid storage area before A, it can be merged:
(BP-1) -> m_addr (bp-1) -> m_size == a true, this is our (2) role. Then the operation is:
(bp-1) -> m_size = size;
But at the same time, we have to pay attention to the merge of the latter effective storage area, ie
A size == bp-> m_addr is true,
This is (3) role. If you should merge, the operation is:
(bp-1) -> m_size = bp-> m_size;
While (bp-> m_size) {
BP ;
(bp-1) -> m_addr = bp-> m_addr;
(bp-1) -> m_size = bp-> m_size;
}
However, if you can not merge with the frontal effective storage area, it may be this as follows:
The same is available:
A size == bp-> m_addr && bp-> m_size,
To determine, this is (4) role. If so, the operation is:
BP-> m_addr = - size;
BP-> m_size = size;
Then there is a situation, that is, it can't merge with the front, it may be like this:
This requires some complex processes. But I want to explain to you first, not only this kind of situation can be, you can't merge it, let's take a look at this possible situation:
That is to say, until the end of the effective storage area, has not arrived at A. At this time, it is determined as:
BP-> M_SIZE == 0 is true,
You will see this action in detail:
IF (size) do {
T = bp-> m_addr;
BP-> m_addr = a;
A = T;
T = bp-> m_size;
BP-> M_SIZE = SIZE;
BP ;
} while (size = t);
In particular, pay attention to the use of T, which first makes the intermediate variable of the address, then do the intermediate variables of the space size. This is the process of (5). I asked you, and finally after the adjustment is over, if the end is pointing, bp-> m_size == 0 is really satisfied?
Now let's look back, you will understand the role of the empty cycle (1), only when
BP-> m_addr <= a && bp-> m_size! = 0 is true,
When we don't satisfy, we arrive at the time of recycling operation. However, if you don't understand the code behind, how do you understand it?
So this algorithm is a bit unclear, but the benefit is that the efficiency is high, it is almost impossible to improve!