/*
 * 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 <stdlib.h>
#include <assert.h>

#include "xf86drm.h"
#include "mm.h"

void
mmDumpMemInfo(const struct mem_block *heap)
{
   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");
}

struct mem_block *
mmInit(int ofs, int size)
{
   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)
{
   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;
}


struct mem_block *
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;

   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 *
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 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) {
      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;
}


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);
}
