mesa/main/util: moving gallium u_mm to util, remove main/mm
authorAlejandro Piñeiro <apinheiro@igalia.com>
Thu, 28 Nov 2019 20:49:02 +0000 (21:49 +0100)
committerAlejandro Piñeiro <apinheiro@igalia.com>
Mon, 2 Dec 2019 12:59:28 +0000 (13:59 +0100)
Right now there are two copies of mm:
   * mesa/main/mm.[ch]
   * gallium/auxiliary/util/u_mm.[ch]

At some point they splitted, and from the commit message it was not
clear why it was not possible to have only one copy at a common place.

Taking into account that was several years ago, Im assuming that it
was not possible then.

This change would allow to have one copy of the same code, and also
being able to use that code out of mesa/main or gallium, if needed.

This commit moves u_mm and removes mm, as u_mm has slightly more
changes.

Reviewed-by: Jose Fonseca <jfonseca@vmware.com>
13 files changed:
src/gallium/auxiliary/Makefile.sources
src/gallium/auxiliary/meson.build
src/gallium/auxiliary/util/u_mm.c [deleted file]
src/gallium/auxiliary/util/u_mm.h [deleted file]
src/mesa/Makefile.sources
src/mesa/main/execmem.c
src/mesa/main/mm.c [deleted file]
src/mesa/main/mm.h [deleted file]
src/mesa/meson.build
src/util/Makefile.sources
src/util/meson.build
src/util/u_mm.c [new file with mode: 0644]
src/util/u_mm.h [new file with mode: 0644]

index 438cb6009537f80c6a8eac3756e961bd6af96f66..46c443b574703ac23dffa5f87379bb5ab8f4bca0 100644 (file)
@@ -264,8 +264,6 @@ C_SOURCES := \
        util/u_linear.h \
        util/u_log.c \
        util/u_log.h \
-       util/u_mm.c \
-       util/u_mm.h \
        util/u_network.c \
        util/u_network.h \
        util/u_pack_color.h \
index f96b32e9d752cc6bb69e77838efcecfec975c473..65e4eda87ef5fd376df228086bbb09dc92833a34 100644 (file)
@@ -284,8 +284,6 @@ files_libgallium = files(
   'util/u_linear.h',
   'util/u_log.c',
   'util/u_log.h',
-  'util/u_mm.c',
-  'util/u_mm.h',
   'util/u_network.c',
   'util/u_network.h',
   'util/u_pack_color.h',
diff --git a/src/gallium/auxiliary/util/u_mm.c b/src/gallium/auxiliary/util/u_mm.c
deleted file mode 100644 (file)
index c15f62d..0000000
+++ /dev/null
@@ -1,299 +0,0 @@
-/**************************************************************************
- *
- * Copyright (C) 1999 Wittawat Yamwong
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * WITTAWAT YAMWONG, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM, 
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 
- * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE 
- * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- **************************************************************************/
-
-
-#include "pipe/p_compiler.h"
-#include "util/u_debug.h"
-
-#include "util/u_memory.h"
-#include "util/u_mm.h"
-
-
-void
-u_mmDumpMemInfo(const struct mem_block *heap)
-{
-   debug_printf("Memory heap %p:\n", (void *) heap);
-   if (heap == NULL) {
-      debug_printf("  heap == 0\n");
-   }
-   else {
-      const struct mem_block *p;
-      int total_used = 0, total_free = 0;
-
-      for (p = heap->next; p != heap; p = p->next) {
-        debug_printf("  Offset:%08x, Size:%08x, %c%c\n", p->ofs, p->size,
-                      p->free ? 'F':'.',
-                      p->reserved ? 'R':'.');
-         if (p->free)
-            total_free += p->size;
-         else
-            total_used += p->size;
-      }
-
-      debug_printf("'\nMemory stats: total = %d, used = %d, free = %d\n",
-                   total_used + total_free, total_used, total_free);
-      debug_printf("\nFree list:\n");
-
-      for (p = heap->next_free; p != heap; p = p->next_free) {
-        debug_printf(" FREE Offset:%08x, Size:%08x, %c%c\n", p->ofs, p->size,
-                      p->free ? 'F':'.',
-                      p->reserved ? 'R':'.');
-      }
-
-   }
-   debug_printf("End of memory blocks\n");
-}
-
-
-struct mem_block *
-u_mmInit(int ofs, int size)
-{
-   struct mem_block *heap, *block;
-  
-   if (size <= 0) 
-      return NULL;
-
-   heap = CALLOC_STRUCT(mem_block);
-   if (!heap) 
-      return NULL;
-   
-   block = CALLOC_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, UNUSED int alignment)
-{
-   struct mem_block *newblock;
-
-   /* break left  [p, newblock, p->next], then p = newblock */
-   if (startofs > p->ofs) {
-      newblock = CALLOC_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 = CALLOC_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;
-}
-
-
-struct mem_block *
-u_mmAllocMem(struct mem_block *heap, int size, int align2, int startSearch)
-{
-   struct mem_block *p;
-   const int mask = (1 << align2)-1;
-   int startofs = 0;
-   int endofs;
-
-   assert(size >= 0);
-   assert(align2 >= 0);
-   /* Make sure that a byte alignment isn't getting passed for our
-    * power-of-two alignment arg.
-    */
-   assert(align2 < 32);
-
-   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;
-}
-
-
-struct mem_block *
-u_mmFindBlock(struct mem_block *heap, int start)
-{
-   struct mem_block *p;
-
-   for (p = heap->next; p != heap; p = p->next) {
-      if (p->ofs == start) 
-        return p;
-   }
-
-   return NULL;
-}
-
-
-static inline int
-Join2Blocks(struct mem_block *p)
-{
-   /* 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;
-}
-
-int
-u_mmFreeMem(struct mem_block *b)
-{
-   if (!b)
-      return 0;
-
-   if (b->free) {
-      debug_printf("block already free\n");
-      return -1;
-   }
-   if (b->reserved) {
-      debug_printf("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;
-}
-
-
-void
-u_mmDestroy(struct mem_block *heap)
-{
-   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);
-}
diff --git a/src/gallium/auxiliary/util/u_mm.h b/src/gallium/auxiliary/util/u_mm.h
deleted file mode 100644 (file)
index 6b158aa..0000000
+++ /dev/null
@@ -1,91 +0,0 @@
-/**************************************************************************
- *
- * Copyright (C) 1999 Wittawat Yamwong
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * KEITH WHITWELL, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM, 
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 
- * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE 
- * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- **************************************************************************/
-
-
-/**
- * @file
- * Memory manager code.  Primarily used by device drivers to manage texture
- * heaps, etc.
- */
-
-
-#ifndef _U_MM_H_
-#define _U_MM_H_
-
-
-struct mem_block {
-   struct mem_block *next, *prev;
-   struct mem_block *next_free, *prev_free;
-   struct mem_block *heap;
-   int ofs,size;
-   unsigned int free:1;
-   unsigned int reserved:1;
-};
-
-
-
-/** 
- * input: total size in bytes
- * return: a heap pointer if OK, NULL if error
- */
-extern struct mem_block *u_mmInit(int ofs, int size);
-
-/**
- * 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
- */
-extern struct mem_block *u_mmAllocMem(struct mem_block *heap, int size, int align2, 
-                            int startSearch);
-
-/**
- * Free block starts at offset
- * input: pointer to a block
- * return: 0 if OK, -1 if error
- */
-extern int u_mmFreeMem(struct mem_block *b);
-
-/**
- * Free block starts at offset
- * input: pointer to a heap, start offset
- * return: pointer to a block
- */
-extern struct mem_block *u_mmFindBlock(struct mem_block *heap, int start);
-
-/**
- * destroy MM
- */
-extern void u_mmDestroy(struct mem_block *mmInit);
-
-/**
- * For debugging purposes.
- */
-extern void u_mmDumpMemInfo(const struct mem_block *mmInit);
-
-#endif
index acb0c2b53cf32bb3e9e7d3d786e41e69bcf35501..dfdff434c4dde2cd2e35ef936471195513d13b68 100644 (file)
@@ -149,8 +149,6 @@ MAIN_FILES = \
        main/matrix.h \
        main/mipmap.c \
        main/mipmap.h \
-       main/mm.c \
-       main/mm.h \
        main/menums.h \
        main/mtypes.h \
        main/multisample.c \
index 2142b50a6e93e5a7c6a516a28a5fcec3aaea1840..8c7325bebf33b60878ea25ed05aef251a3392c4c 100644 (file)
@@ -46,7 +46,7 @@
 
 #include <unistd.h>
 #include <sys/mman.h>
-#include "mm.h"
+#include "util/u_mm.h"
 
 #ifdef MESA_SELINUX
 #include <selinux/selinux.h>
@@ -78,11 +78,11 @@ init_heap(void)
 #endif
 
    if (!exec_heap)
-      exec_heap = mmInit( 0, EXEC_HEAP_SIZE );
+      exec_heap = u_mmInit( 0, EXEC_HEAP_SIZE );
    
    if (!exec_mem)
       exec_mem = mmap(NULL, EXEC_HEAP_SIZE, PROT_EXEC | PROT_READ | PROT_WRITE,
-                     MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+                      MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
 
    return (exec_mem != MAP_FAILED);
 }
@@ -101,7 +101,7 @@ _mesa_exec_malloc(GLuint size)
 
    if (exec_heap) {
       size = (size + 31) & ~31;
-      block = mmAllocMem( exec_heap, size, 32, 0 );
+      block = u_mmAllocMem( exec_heap, size, 32, 0 );
    }
 
    if (block)
@@ -122,10 +122,10 @@ _mesa_exec_free(void *addr)
    mtx_lock(&exec_mutex);
 
    if (exec_heap) {
-      struct mem_block *block = mmFindBlock(exec_heap, (unsigned char *)addr - exec_mem);
+      struct mem_block *block = u_mmFindBlock(exec_heap, (unsigned char *)addr - exec_mem);
    
       if (block)
-        mmFreeMem(block);
+        u_mmFreeMem(block);
    }
 
    mtx_unlock(&exec_mutex);
diff --git a/src/mesa/main/mm.c b/src/mesa/main/mm.c
deleted file mode 100644 (file)
index 5f0bfe9..0000000
+++ /dev/null
@@ -1,282 +0,0 @@
-/*
- * GLX Hardware Device Driver common code
- * Copyright (C) 1999 Wittawat Yamwong
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * WITTAWAT YAMWONG, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM, 
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 
- * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE 
- * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- */
-
-#include <assert.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-#include "mm.h"
-
-
-void
-mmDumpMemInfo(const struct mem_block *heap)
-{
-   fprintf(stderr, "Memory heap %p:\n", (void *)heap);
-   if (heap == 0) {
-      fprintf(stderr, "  heap == 0\n");
-   } else {
-      const struct mem_block *p;
-
-      for(p = heap->next; p != heap; p = p->next) {
-        fprintf(stderr, "  Offset:%08x, Size:%08x, %c%c\n",p->ofs,p->size,
-                p->free ? 'F':'.',
-                p->reserved ? 'R':'.');
-      }
-
-      fprintf(stderr, "\nFree list:\n");
-
-      for(p = heap->next_free; p != heap; p = p->next_free) {
-        fprintf(stderr, " FREE Offset:%08x, Size:%08x, %c%c\n",p->ofs,p->size,
-                p->free ? 'F':'.',
-                p->reserved ? 'R':'.');
-      }
-
-   }
-   fprintf(stderr, "End of memory blocks\n");
-}
-
-struct mem_block *
-mmInit(unsigned ofs, unsigned size)
-{
-   struct mem_block *heap, *block;
-  
-   if (!size) 
-      return NULL;
-
-   heap = calloc(1, sizeof(struct mem_block));
-   if (!heap) 
-      return NULL;
-   
-   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, 
-           unsigned startofs, unsigned size, 
-           unsigned reserved, unsigned alignment)
-{
-   struct mem_block *newblock;
-
-   /* break left  [p, newblock, p->next], then p = newblock */
-   if (startofs > p->ofs) {
-      newblock = 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 = 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;
-}
-
-
-struct mem_block *
-mmAllocMem(struct mem_block *heap, unsigned size, unsigned align2, unsigned startSearch)
-{
-   struct mem_block *p;
-   const unsigned mask = (1 << align2)-1;
-   unsigned startofs = 0;
-   unsigned endofs;
-
-   if (!heap || !size)
-      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;
-}
-
-
-struct mem_block *
-mmFindBlock(struct mem_block *heap, unsigned start)
-{
-   struct mem_block *p;
-
-   for (p = heap->next; p != heap; p = p->next) {
-      if (p->ofs == start) 
-        return p;
-   }
-
-   return NULL;
-}
-
-
-static inline int
-Join2Blocks(struct mem_block *p)
-{
-   /* 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;
-}
-
-int
-mmFreeMem(struct mem_block *b)
-{
-   if (!b)
-      return 0;
-
-   if (b->free) {
-      fprintf(stderr, "block already free\n");
-      return -1;
-   }
-   if (b->reserved) {
-      fprintf(stderr, "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;
-}
-
-
-void
-mmDestroy(struct mem_block *heap)
-{
-   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);
-}
diff --git a/src/mesa/main/mm.h b/src/mesa/main/mm.h
deleted file mode 100644 (file)
index 228721c..0000000
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * GLX Hardware Device Driver common code
- * Copyright (C) 1999 Wittawat Yamwong
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * KEITH WHITWELL, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM, 
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 
- * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE 
- * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-
-/**
- * Memory manager code.  Primarily used by device drivers to manage texture
- * heaps, etc.
- */
-
-
-#ifndef MM_H
-#define MM_H
-
-
-struct mem_block {
-   struct mem_block *next, *prev;
-   struct mem_block *next_free, *prev_free;
-   struct mem_block *heap;
-   unsigned ofs;
-   unsigned size;
-   unsigned free:1;
-   unsigned reserved:1;
-};
-
-
-
-/** 
- * input: total size in bytes
- * return: a heap pointer if OK, NULL if error
- */
-extern struct mem_block *mmInit(unsigned ofs, unsigned size);
-
-/**
- * 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
- */
-extern struct mem_block *mmAllocMem(struct mem_block *heap, unsigned size, 
-                                    unsigned align2, unsigned startSearch);
-
-/**
- * Free block starts at offset
- * input: pointer to a block
- * return: 0 if OK, -1 if error
- */
-extern int mmFreeMem(struct mem_block *b);
-
-/**
- * Free block starts at offset
- * input: pointer to a heap, start offset
- * return: pointer to a block
- */
-extern struct mem_block *mmFindBlock(struct mem_block *heap, unsigned start);
-
-/**
- * destroy MM
- */
-extern void mmDestroy(struct mem_block *mmInit);
-
-/**
- * For debuging purpose.
- */
-extern void mmDumpMemInfo(const struct mem_block *mmInit);
-
-#endif
index 27e8058766a10ac4ea57cc6e69c9d3ce494cef6f..1254ccc619ea2449e21914545d1f9b64f091b823 100644 (file)
@@ -189,8 +189,6 @@ files_libmesa_common = files(
   'main/matrix.h',
   'main/mipmap.c',
   'main/mipmap.h',
-  'main/mm.c',
-  'main/mm.h',
   'main/menums.h',
   'main/mtypes.h',
   'main/multisample.c',
index dbdcbede6275c71349d44fece3ee3169e9e2d89f..cce28db005effc15a317c639c97644459a24cd1f 100644 (file)
@@ -112,6 +112,8 @@ MESA_UTIL_FILES := \
        os_memory_stdc.h \
        os_memory.h \
        u_memory.h \
+       u_mm.h \
+       u_mm.c \
        vma.c \
        vma.h
 
index 9300cb6e34ab3bf3845c3fc47cc7414776b12d93..540e4e9ce43b04f5d4da0ea8bd0428e7d054f441 100644 (file)
@@ -106,6 +106,8 @@ files_mesa_util = files(
   'u_vector.h',
   'u_math.c',
   'u_math.h',
+  'u_mm.c',
+  'u_mm.h',
   'u_debug.c',
   'u_debug.h',
   'u_cpu_detect.c',
diff --git a/src/util/u_mm.c b/src/util/u_mm.c
new file mode 100644 (file)
index 0000000..0d27597
--- /dev/null
@@ -0,0 +1,298 @@
+/**************************************************************************
+ *
+ * Copyright (C) 1999 Wittawat Yamwong
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * WITTAWAT YAMWONG, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM, 
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE 
+ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+
+#include "util/u_debug.h"
+
+#include "util/u_memory.h"
+#include "util/u_mm.h"
+
+
+void
+u_mmDumpMemInfo(const struct mem_block *heap)
+{
+   debug_printf("Memory heap %p:\n", (void *) heap);
+   if (heap == NULL) {
+      debug_printf("  heap == 0\n");
+   }
+   else {
+      const struct mem_block *p;
+      int total_used = 0, total_free = 0;
+
+      for (p = heap->next; p != heap; p = p->next) {
+        debug_printf("  Offset:%08x, Size:%08x, %c%c\n", p->ofs, p->size,
+                      p->free ? 'F':'.',
+                      p->reserved ? 'R':'.');
+         if (p->free)
+            total_free += p->size;
+         else
+            total_used += p->size;
+      }
+
+      debug_printf("'\nMemory stats: total = %d, used = %d, free = %d\n",
+                   total_used + total_free, total_used, total_free);
+      debug_printf("\nFree list:\n");
+
+      for (p = heap->next_free; p != heap; p = p->next_free) {
+        debug_printf(" FREE Offset:%08x, Size:%08x, %c%c\n", p->ofs, p->size,
+                      p->free ? 'F':'.',
+                      p->reserved ? 'R':'.');
+      }
+
+   }
+   debug_printf("End of memory blocks\n");
+}
+
+
+struct mem_block *
+u_mmInit(int ofs, int size)
+{
+   struct mem_block *heap, *block;
+  
+   if (size <= 0) 
+      return NULL;
+
+   heap = CALLOC_STRUCT(mem_block);
+   if (!heap) 
+      return NULL;
+   
+   block = CALLOC_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, UNUSED int alignment)
+{
+   struct mem_block *newblock;
+
+   /* break left  [p, newblock, p->next], then p = newblock */
+   if (startofs > p->ofs) {
+      newblock = CALLOC_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 = CALLOC_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;
+}
+
+
+struct mem_block *
+u_mmAllocMem(struct mem_block *heap, int size, int align2, int startSearch)
+{
+   struct mem_block *p;
+   const int mask = (1 << align2)-1;
+   int startofs = 0;
+   int endofs;
+
+   assert(size >= 0);
+   assert(align2 >= 0);
+   /* Make sure that a byte alignment isn't getting passed for our
+    * power-of-two alignment arg.
+    */
+   assert(align2 < 32);
+
+   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;
+}
+
+
+struct mem_block *
+u_mmFindBlock(struct mem_block *heap, int start)
+{
+   struct mem_block *p;
+
+   for (p = heap->next; p != heap; p = p->next) {
+      if (p->ofs == start) 
+        return p;
+   }
+
+   return NULL;
+}
+
+
+static inline int
+Join2Blocks(struct mem_block *p)
+{
+   /* 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;
+}
+
+int
+u_mmFreeMem(struct mem_block *b)
+{
+   if (!b)
+      return 0;
+
+   if (b->free) {
+      debug_printf("block already free\n");
+      return -1;
+   }
+   if (b->reserved) {
+      debug_printf("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;
+}
+
+
+void
+u_mmDestroy(struct mem_block *heap)
+{
+   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);
+}
diff --git a/src/util/u_mm.h b/src/util/u_mm.h
new file mode 100644 (file)
index 0000000..6b158aa
--- /dev/null
@@ -0,0 +1,91 @@
+/**************************************************************************
+ *
+ * Copyright (C) 1999 Wittawat Yamwong
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * KEITH WHITWELL, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM, 
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE 
+ * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+
+/**
+ * @file
+ * Memory manager code.  Primarily used by device drivers to manage texture
+ * heaps, etc.
+ */
+
+
+#ifndef _U_MM_H_
+#define _U_MM_H_
+
+
+struct mem_block {
+   struct mem_block *next, *prev;
+   struct mem_block *next_free, *prev_free;
+   struct mem_block *heap;
+   int ofs,size;
+   unsigned int free:1;
+   unsigned int reserved:1;
+};
+
+
+
+/** 
+ * input: total size in bytes
+ * return: a heap pointer if OK, NULL if error
+ */
+extern struct mem_block *u_mmInit(int ofs, int size);
+
+/**
+ * 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
+ */
+extern struct mem_block *u_mmAllocMem(struct mem_block *heap, int size, int align2, 
+                            int startSearch);
+
+/**
+ * Free block starts at offset
+ * input: pointer to a block
+ * return: 0 if OK, -1 if error
+ */
+extern int u_mmFreeMem(struct mem_block *b);
+
+/**
+ * Free block starts at offset
+ * input: pointer to a heap, start offset
+ * return: pointer to a block
+ */
+extern struct mem_block *u_mmFindBlock(struct mem_block *heap, int start);
+
+/**
+ * destroy MM
+ */
+extern void u_mmDestroy(struct mem_block *mmInit);
+
+/**
+ * For debugging purposes.
+ */
+extern void u_mmDumpMemInfo(const struct mem_block *mmInit);
+
+#endif