/*
 * Mesa 3-D graphics library
 * Version:  6.5.3
 *
 * Copyright (C) 2005-2007  Brian Paul   All Rights Reserved.
 *
 * 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
 * BRIAN PAUL 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 slang_mem.c
 *
 * Memory manager for GLSL compiler.  The general idea is to do all
 * allocations out of a large pool then just free the pool when done
 * compiling to avoid intricate malloc/free tracking and memory leaks.
 *
 * \author Brian Paul
 */

#include "main/context.h"
#include "main/macros.h"
#include "slang_mem.h"


#define GRANULARITY 8
#define ROUND_UP(B)  ( ((B) + (GRANULARITY - 1)) & ~(GRANULARITY - 1) )


/** If 1, use conventional malloc/free.  Helpful for debugging */
#define USE_MALLOC_FREE 0


struct slang_mempool_
{
   GLuint Size, Used, Count, Largest;
   char *Data;
   struct slang_mempool_ *Next;
};


slang_mempool *
_slang_new_mempool(GLuint initialSize)
{
   slang_mempool *pool = (slang_mempool *) _mesa_calloc(sizeof(slang_mempool));
   if (pool) {
      pool->Data = (char *) _mesa_calloc(initialSize);
      /*printf("ALLOC MEMPOOL %d at %p\n", initialSize, pool->Data);*/
      if (!pool->Data) {
         _mesa_free(pool);
         return NULL;
      }
      pool->Size = initialSize;
      pool->Used = 0;
   }
   return pool;
}


void
_slang_delete_mempool(slang_mempool *pool)
{
   GLuint total = 0;
   while (pool) {
      slang_mempool *next = pool->Next;
      /*
      printf("DELETE MEMPOOL %u / %u  count=%u largest=%u\n",
             pool->Used, pool->Size, pool->Count, pool->Largest);
      */
      total += pool->Used;
      _mesa_free(pool->Data);
      _mesa_free(pool);
      pool = next;
   }
   /*printf("TOTAL ALLOCATED: %u\n", total);*/
}


#ifdef DEBUG
static void
check_zero(const char *addr, GLuint n)
{
   GLuint i;
   for (i = 0; i < n; i++) {
      assert(addr[i]==0);
   }
}
#endif


#ifdef DEBUG
static GLboolean
is_valid_address(const slang_mempool *pool, void *addr)
{
   while (pool) {
      if ((char *) addr >= pool->Data &&
          (char *) addr < pool->Data + pool->Used)
         return GL_TRUE;

      pool = pool->Next;
   }
   return GL_FALSE;
}
#endif


/**
 * Alloc 'bytes' from shader mempool.
 */
void *
_slang_alloc(GLuint bytes)
{
#if USE_MALLOC_FREE
   return _mesa_calloc(bytes);
#else
   slang_mempool *pool;
   GET_CURRENT_CONTEXT(ctx);
   pool = (slang_mempool *) ctx->Shader.MemPool;

   if (bytes == 0)
      bytes = 1;

   while (pool) {
      if (pool->Used + bytes <= pool->Size) {
         /* found room */
         void *addr = (void *) (pool->Data + pool->Used);
#ifdef DEBUG
         check_zero((char*) addr, bytes);
#endif
         pool->Used += ROUND_UP(bytes);
         pool->Largest = MAX2(pool->Largest, bytes);
         pool->Count++;
         /*printf("alloc %u  Used %u\n", bytes, pool->Used);*/
         return addr;
      }
      else if (pool->Next) {
         /* try next block */
         pool = pool->Next;
      }
      else {
         /* alloc new pool */
         const GLuint sz = MAX2(bytes, pool->Size);
         pool->Next = _slang_new_mempool(sz);
         if (!pool->Next) {
            /* we're _really_ out of memory */
            return NULL;
         }
         else {
            pool = pool->Next;
            pool->Largest = bytes;
            pool->Count++;
            pool->Used = ROUND_UP(bytes);
#ifdef DEBUG
            check_zero((char*) pool->Data, bytes);
#endif
            return (void *) pool->Data;
         }
      }
   }
   return NULL;
#endif
}


void *
_slang_realloc(void *oldBuffer, GLuint oldSize, GLuint newSize)
{
#if USE_MALLOC_FREE
   return _mesa_realloc(oldBuffer, oldSize, newSize);
#else
   GET_CURRENT_CONTEXT(ctx);
   slang_mempool *pool = (slang_mempool *) ctx->Shader.MemPool;

   if (newSize < oldSize) {
      return oldBuffer;
   }
   else {
      const GLuint copySize = (oldSize < newSize) ? oldSize : newSize;
      void *newBuffer = _slang_alloc(newSize);

      if (oldBuffer)
         ASSERT(is_valid_address(pool, oldBuffer));

      if (newBuffer && oldBuffer && copySize > 0)
         _mesa_memcpy(newBuffer, oldBuffer, copySize);

      return newBuffer;
   }
#endif
}


/**
 * Clone string, storing in current mempool.
 */
char *
_slang_strdup(const char *s)
{
   if (s) {
      size_t l = _mesa_strlen(s);
      char *s2 = (char *) _slang_alloc(l + 1);
      if (s2)
         _mesa_strcpy(s2, s);
      return s2;
   }
   else {
      return NULL;
   }
}


/**
 * Don't actually free memory, but mark it (for debugging).
 */
void
_slang_free(void *addr)
{
#if USE_MALLOC_FREE
   _mesa_free(addr);
#else
   if (addr) {
      GET_CURRENT_CONTEXT(ctx);
      slang_mempool *pool = (slang_mempool *) ctx->Shader.MemPool;
      ASSERT(is_valid_address(pool, addr));
   }
#endif
}
