Rev 39 | Rev 46 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 39 | Rev 45 | ||
---|---|---|---|
Line 268... | Line 268... | ||
268 | <imageobject role="fop"> |
268 | <imageobject role="fop"> |
269 | <imagedata fileref="images.vector/buddy_alloc.svg" format="SVG" /> |
269 | <imagedata fileref="images.vector/buddy_alloc.svg" format="SVG" /> |
270 | </imageobject> |
270 | </imageobject> |
271 | </mediaobject></para> |
271 | </mediaobject></para> |
272 | 272 | ||
273 | <para>In buddy allocator, memory is broken down into power-of-two |
273 | <para>In the buddy allocator, the memory is broken down into |
274 | sized naturally aligned blocks. These blocks are organized in an array |
274 | power-of-two sized naturally aligned blocks. These blocks are |
- | 275 | organized in an array of lists, in which the list with index i |
|
275 | of lists in which list with index i contains all unallocated blocks of |
276 | contains all unallocated blocks of size |
276 | the size <mathphrase>2<superscript>i</superscript></mathphrase>. The |
277 | <mathphrase>2<superscript>i</superscript></mathphrase>. The index i is |
277 | index i is called the order of block. Should there be two adjacent |
278 | called the order of block. Should there be two adjacent equally sized |
278 | equally sized blocks in list <mathphrase>i</mathphrase> (i.e. |
279 | blocks in the list i<mathphrase> </mathphrase>(i.e. buddies), the |
279 | buddies), the buddy allocator would coalesce them and put the |
280 | buddy allocator would coalesce them and put the resulting block in |
280 | resulting block in list <mathphrase>i + 1</mathphrase>, provided that |
281 | list <mathphrase>i + 1</mathphrase>, provided that the resulting block |
281 | the resulting block would be naturally aligned. Similarily, when the |
282 | would be naturally aligned. Similarily, when the allocator is asked to |
282 | allocator is asked to allocate a block of size |
283 | allocate a block of size |
283 | <mathphrase>2<superscript>i</superscript></mathphrase>, it first tries |
284 | <mathphrase>2<superscript>i</superscript></mathphrase>, it first tries |
284 | to satisfy the request from list with index i. If the request cannot |
285 | to satisfy the request from the list with index i. If the request |
285 | be satisfied (i.e. the list i is empty), the buddy allocator will try |
286 | cannot be satisfied (i.e. the list i is empty), the buddy allocator |
286 | to allocate and split larger block from list with index i + 1. Both of |
287 | will try to allocate and split a larger block from the list with index |
287 | these algorithms are recursive. The recursion ends either when there |
288 | i + 1. Both of these algorithms are recursive. The recursion ends |
288 | are no blocks to coalesce in the former case or when there are no |
289 | either when there are no blocks to coalesce in the former case or when |
289 | blocks that can be split in the latter case.</para> |
290 | there are no blocks that can be split in the latter case.</para> |
290 | 291 | ||
291 | <!--graphic fileref="images/mm1.png" format="EPS" /--> |
292 | <!--graphic fileref="images/mm1.png" format="EPS" /--> |
292 | 293 | ||
293 | <para>This approach greatly reduces external fragmentation of memory |
294 | <para>This approach greatly reduces external fragmentation of memory |
294 | and helps in allocating bigger continuous blocks of memory aligned to |
295 | and helps in allocating bigger continuous blocks of memory aligned to |
Line 303... | Line 304... | ||
303 | 304 | ||
304 | <para>The buddy allocator is, in fact, an abstract framework wich can |
305 | <para>The buddy allocator is, in fact, an abstract framework wich can |
305 | be easily specialized to serve one particular task. It knows nothing |
306 | be easily specialized to serve one particular task. It knows nothing |
306 | about the nature of memory it helps to allocate. In order to beat the |
307 | about the nature of memory it helps to allocate. In order to beat the |
307 | lack of this knowledge, the buddy allocator exports an interface that |
308 | lack of this knowledge, the buddy allocator exports an interface that |
308 | each of its clients is required to implement. When supplied an |
309 | each of its clients is required to implement. When supplied with an |
309 | implementation of this interface, the buddy allocator can use |
310 | implementation of this interface, the buddy allocator can use |
310 | specialized external functions to find buddy for a block, split and |
311 | specialized external functions to find a buddy for a block, split and |
311 | coalesce blocks, manipulate block order and mark blocks busy or |
312 | coalesce blocks, manipulate block order and mark blocks busy or |
312 | available. For precize documentation of this interface, refer to |
313 | available. For precise documentation of this interface, refer to |
313 | <emphasis>"HelenOS Generic Kernel Reference Manual"</emphasis>.</para> |
314 | <emphasis>"HelenOS Generic Kernel Reference Manual"</emphasis>.</para> |
314 | 315 | ||
315 | <formalpara> |
316 | <formalpara> |
316 | <title>Data organization</title> |
317 | <title>Data organization</title> |
317 | 318 | ||
Line 322... | Line 323... | ||
322 | <para>Whatever entities are allocated by the buddy allocator, the |
323 | <para>Whatever entities are allocated by the buddy allocator, the |
323 | first entity within a block is used to represent the entire block. |
324 | first entity within a block is used to represent the entire block. |
324 | The first entity keeps the order of the whole block. Other entities |
325 | The first entity keeps the order of the whole block. Other entities |
325 | within the block are assigned the magic value |
326 | within the block are assigned the magic value |
326 | <constant>BUDDY_INNER_BLOCK</constant>. This is especially important |
327 | <constant>BUDDY_INNER_BLOCK</constant>. This is especially important |
327 | for effective identification of buddies in one-dimensional array |
328 | for effective identification of buddies in a one-dimensional array |
328 | because the entity that represents a potential buddy cannot be |
329 | because the entity that represents a potential buddy cannot be |
329 | associated with <constant>BUDDY_INNER_BLOCK</constant> (i.e. if it |
330 | associated with <constant>BUDDY_INNER_BLOCK</constant> (i.e. if it |
330 | is associated with <constant>BUDDY_INNER_BLOCK</constant> then it is |
331 | is associated with <constant>BUDDY_INNER_BLOCK</constant> then it is |
331 | not a buddy).</para> |
332 | not a buddy).</para> |
332 | 333 | ||
333 | <para>Buddy allocator always uses first frame to represent frame |
334 | <para>The buddy allocator always uses the first frame to represent |
334 | block. This frame contains <varname>buddy_order</varname> variable |
335 | the frame block. This frame contains <varname>buddy_order</varname> |
335 | to provide information about the block size it actually represents ( |
336 | variable to provide information about the block size it actually |
- | 337 | represents ( |
|
336 | <mathphrase>2<superscript>buddy_order</superscript></mathphrase> |
338 | <mathphrase>2<superscript>buddy_order</superscript></mathphrase> |
337 | frames block). Other frames in block have this value set to magic |
339 | frames block). Other frames in block have this value set to magic |
338 | <constant>BUDDY_INNER_BLOCK</constant> that is much greater than |
340 | <constant>BUDDY_INNER_BLOCK</constant> that is much greater than |
339 | buddy <varname>max_order</varname> value.</para> |
341 | buddy <varname>max_order</varname> value.</para> |
340 | 342 |