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 | ||