Back to index

libdrm  2.4.37
Functions
mm.c File Reference
#include <stdlib.h>
#include <assert.h>
#include "xf86drm.h"
#include "mm.h"

Go to the source code of this file.

Functions

void mmDumpMemInfo (const struct mem_block *heap)
 For debuging purpose.
struct mem_blockmmInit (int ofs, int size)
 input: total size in bytes return: a heap pointer if OK, NULL if error
static struct mem_blockSliceBlock (struct mem_block *p, int startofs, int size, int reserved, int alignment)
struct mem_blockmmAllocMem (struct mem_block *heap, int size, int align2, int startSearch)
 Allocate 'size' bytes with 2^align2 bytes alignment, restrict the search to free memory after 'startSearch' depth and back buffers should be in different 4mb banks to get better page hits if possible input: size = size of block align2 = 2^align2 bytes alignment startSearch = linear offset from start of heap to begin search return: pointer to the allocated block, 0 if error.
struct mem_blockmmFindBlock (struct mem_block *heap, int start)
 Free block starts at offset input: pointer to a heap, start offset return: pointer to a block.
static int Join2Blocks (struct mem_block *p)
int mmFreeMem (struct mem_block *b)
 Free block starts at offset input: pointer to a block return: 0 if OK, -1 if error.
void mmDestroy (struct mem_block *heap)
 destroy MM

Function Documentation

static int Join2Blocks ( struct mem_block p) [static]

Definition at line 206 of file mm.c.

{
       /* XXX there should be some assertions here */

       /* NOTE: heap->free == 0 */

       if (p->free && p->next->free) {
              struct mem_block *q = p->next;

              assert(p->ofs + p->size == q->ofs);
              p->size += q->size;

              p->next = q->next;
              q->next->prev = p;

              q->next_free->prev_free = q->prev_free;
              q->prev_free->next_free = q->next_free;

              free(q);
              return 1;
       }
       return 0;
}

Here is the caller graph for this function:

struct mem_block* mmAllocMem ( struct mem_block heap,
int  size,
int  align2,
int  startSearch 
) [read]

Allocate 'size' bytes with 2^align2 bytes alignment, restrict the search to free memory after 'startSearch' depth and back buffers should be in different 4mb banks to get better page hits if possible input: size = size of block align2 = 2^align2 bytes alignment startSearch = linear offset from start of heap to begin search return: pointer to the allocated block, 0 if error.

Definition at line 162 of file mm.c.

{
       struct mem_block *p;
       const int mask = (1 << align2) - 1;
       int startofs = 0;
       int endofs;

       if (!heap || align2 < 0 || size <= 0)
              return NULL;

       for (p = heap->next_free; p != heap; p = p->next_free) {
              assert(p->free);

              startofs = (p->ofs + mask) & ~mask;
              if (startofs < startSearch) {
                     startofs = startSearch;
              }
              endofs = startofs + size;
              if (endofs <= (p->ofs + p->size))
                     break;
       }

       if (p == heap)
              return NULL;

       assert(p->free);
       p = SliceBlock(p, startofs, size, 0, mask + 1);

       return p;
}

Here is the call graph for this function:

void mmDestroy ( struct mem_block heap)

destroy MM

Definition at line 257 of file mm.c.

{
       struct mem_block *p;

       if (!heap)
              return;

       for (p = heap->next; p != heap;) {
              struct mem_block *next = p->next;
              free(p);
              p = next;
       }

       free(heap);
}
void mmDumpMemInfo ( const struct mem_block heap)

For debuging purpose.

Definition at line 31 of file mm.c.

{
       drmMsg("Memory heap %p:\n", (void *)heap);
       if (heap == 0) {
              drmMsg("  heap == 0\n");
       } else {
              const struct mem_block *p;

              for (p = heap->next; p != heap; p = p->next) {
                     drmMsg("  Offset:%08x, Size:%08x, %c%c\n", p->ofs,
                            p->size, p->free ? 'F' : '.',
                            p->reserved ? 'R' : '.');
              }

              drmMsg("\nFree list:\n");

              for (p = heap->next_free; p != heap; p = p->next_free) {
                     drmMsg(" FREE Offset:%08x, Size:%08x, %c%c\n", p->ofs,
                            p->size, p->free ? 'F' : '.',
                            p->reserved ? 'R' : '.');
              }

       }
       drmMsg("End of memory blocks\n");
}

Here is the call graph for this function:

struct mem_block* mmFindBlock ( struct mem_block heap,
int  start 
) [read]

Free block starts at offset input: pointer to a heap, start offset return: pointer to a block.

Definition at line 194 of file mm.c.

{
       struct mem_block *p;

       for (p = heap->next; p != heap; p = p->next) {
              if (p->ofs == start)
                     return p;
       }

       return NULL;
}
int mmFreeMem ( struct mem_block b)

Free block starts at offset input: pointer to a block return: 0 if OK, -1 if error.

Definition at line 230 of file mm.c.

{
       if (!b)
              return 0;

       if (b->free) {
              drmMsg("block already free\n");
              return -1;
       }
       if (b->reserved) {
              drmMsg("block is reserved\n");
              return -1;
       }

       b->free = 1;
       b->next_free = b->heap->next_free;
       b->prev_free = b->heap;
       b->next_free->prev_free = b;
       b->prev_free->next_free = b;

       Join2Blocks(b);
       if (b->prev != b->heap)
              Join2Blocks(b->prev);

       return 0;
}

Here is the call graph for this function:

struct mem_block* mmInit ( int  ofs,
int  size 
) [read]

input: total size in bytes return: a heap pointer if OK, NULL if error

Definition at line 57 of file mm.c.

{
       struct mem_block *heap, *block;

       if (size <= 0)
              return NULL;

       heap = (struct mem_block *)calloc(1, sizeof(struct mem_block));
       if (!heap)
              return NULL;

       block = (struct mem_block *)calloc(1, sizeof(struct mem_block));
       if (!block) {
              free(heap);
              return NULL;
       }

       heap->next = block;
       heap->prev = block;
       heap->next_free = block;
       heap->prev_free = block;

       block->heap = heap;
       block->next = heap;
       block->prev = heap;
       block->next_free = heap;
       block->prev_free = heap;

       block->ofs = ofs;
       block->size = size;
       block->free = 1;

       return heap;
}
static struct mem_block* SliceBlock ( struct mem_block p,
int  startofs,
int  size,
int  reserved,
int  alignment 
) [static, read]

Definition at line 92 of file mm.c.

{
       struct mem_block *newblock;

       /* break left  [p, newblock, p->next], then p = newblock */
       if (startofs > p->ofs) {
              newblock =
                  (struct mem_block *)calloc(1, sizeof(struct mem_block));
              if (!newblock)
                     return NULL;
              newblock->ofs = startofs;
              newblock->size = p->size - (startofs - p->ofs);
              newblock->free = 1;
              newblock->heap = p->heap;

              newblock->next = p->next;
              newblock->prev = p;
              p->next->prev = newblock;
              p->next = newblock;

              newblock->next_free = p->next_free;
              newblock->prev_free = p;
              p->next_free->prev_free = newblock;
              p->next_free = newblock;

              p->size -= newblock->size;
              p = newblock;
       }

       /* break right, also [p, newblock, p->next] */
       if (size < p->size) {
              newblock =
                  (struct mem_block *)calloc(1, sizeof(struct mem_block));
              if (!newblock)
                     return NULL;
              newblock->ofs = startofs + size;
              newblock->size = p->size - size;
              newblock->free = 1;
              newblock->heap = p->heap;

              newblock->next = p->next;
              newblock->prev = p;
              p->next->prev = newblock;
              p->next = newblock;

              newblock->next_free = p->next_free;
              newblock->prev_free = p;
              p->next_free->prev_free = newblock;
              p->next_free = newblock;

              p->size = size;
       }

       /* p = middle block */
       p->free = 0;

       /* Remove p from the free list: 
        */
       p->next_free->prev_free = p->prev_free;
       p->prev_free->next_free = p->next_free;

       p->next_free = 0;
       p->prev_free = 0;

       p->reserved = reserved;
       return p;
}

Here is the caller graph for this function: