144 lines
4.0 KiB
C
144 lines
4.0 KiB
C
/*BHEADER**********************************************************************
|
|
* Copyright (c) 2008, Lawrence Livermore National Security, LLC.
|
|
* Produced at the Lawrence Livermore National Laboratory.
|
|
* This file is part of HYPRE. See file COPYRIGHT for details.
|
|
*
|
|
* HYPRE is free software; you can redistribute it and/or modify it under the
|
|
* terms of the GNU Lesser General Public License (as published by the Free
|
|
* Software Foundation) version 2.1 dated February 1999.
|
|
*
|
|
* $Revision$
|
|
***********************************************************************EHEADER*/
|
|
|
|
/******************************************************************************
|
|
*
|
|
* Box allocation routines. These hopefully increase efficiency
|
|
* and reduce memory fragmentation.
|
|
*
|
|
*****************************************************************************/
|
|
|
|
#include "_hypre_struct_mv.h"
|
|
|
|
/*--------------------------------------------------------------------------
|
|
* Box memory data structure and static variables used to manage free
|
|
* list and blocks to be freed by the finalization routine.
|
|
*--------------------------------------------------------------------------*/
|
|
|
|
union box_memory
|
|
{
|
|
union box_memory *d_next;
|
|
hypre_Box d_box;
|
|
};
|
|
|
|
static union box_memory *s_free = NULL;
|
|
static union box_memory *s_finalize = NULL;
|
|
static HYPRE_Int s_at_a_time = 1000;
|
|
static HYPRE_Int s_count = 0;
|
|
|
|
/*--------------------------------------------------------------------------
|
|
* Allocate a new block of memory and thread it into the free list. The
|
|
* first block will always be put on the finalize list to be freed by
|
|
* the hypre_BoxFinalizeMemory() routine to remove memory leaks.
|
|
*--------------------------------------------------------------------------*/
|
|
|
|
static HYPRE_Int
|
|
hypre_AllocateBoxBlock()
|
|
{
|
|
union box_memory *ptr;
|
|
HYPRE_Int i;
|
|
|
|
ptr = hypre_TAlloc(union box_memory, s_at_a_time);
|
|
ptr[0].d_next = s_finalize;
|
|
s_finalize = &ptr[0];
|
|
|
|
for (i = (s_at_a_time - 1); i > 0; i--)
|
|
{
|
|
ptr[i].d_next = s_free;
|
|
s_free = &ptr[i];
|
|
}
|
|
|
|
return hypre_error_flag;
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------
|
|
* Set up the allocation block size and allocate the first memory block.
|
|
*--------------------------------------------------------------------------*/
|
|
|
|
HYPRE_Int
|
|
hypre_BoxInitializeMemory( const HYPRE_Int at_a_time )
|
|
{
|
|
if (at_a_time > 0)
|
|
{
|
|
s_at_a_time = at_a_time;
|
|
}
|
|
|
|
return hypre_error_flag;
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------
|
|
* Free all of the memory used to manage boxes. This should only be
|
|
* called at the end of the program to collect free memory. The blocks
|
|
* in the finalize list are freed.
|
|
*--------------------------------------------------------------------------*/
|
|
|
|
HYPRE_Int
|
|
hypre_BoxFinalizeMemory()
|
|
{
|
|
union box_memory *byebye;
|
|
|
|
while (s_finalize)
|
|
{
|
|
byebye = s_finalize;
|
|
s_finalize = (s_finalize -> d_next);
|
|
hypre_TFree(byebye);
|
|
}
|
|
s_finalize = NULL;
|
|
s_free = NULL;
|
|
|
|
return hypre_error_flag;
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------
|
|
* Allocate a box from the free list. If no boxes exist on the free
|
|
* list, then allocate a block of memory to repopulate the free list.
|
|
*--------------------------------------------------------------------------*/
|
|
|
|
hypre_Box *
|
|
hypre_BoxAlloc()
|
|
{
|
|
union box_memory *ptr = NULL;
|
|
|
|
if (!s_free)
|
|
{
|
|
hypre_AllocateBoxBlock();
|
|
}
|
|
|
|
ptr = s_free;
|
|
s_free = (s_free -> d_next);
|
|
s_count++;
|
|
|
|
return( &(ptr -> d_box) );
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------
|
|
* Put a box back on the free list.
|
|
*--------------------------------------------------------------------------*/
|
|
|
|
HYPRE_Int
|
|
hypre_BoxFree( hypre_Box *box )
|
|
{
|
|
union box_memory *ptr = (union box_memory *) box;
|
|
|
|
(ptr -> d_next) = s_free;
|
|
s_free = ptr;
|
|
s_count--;
|
|
|
|
if (!s_count)
|
|
{
|
|
hypre_BoxFinalizeMemory();
|
|
}
|
|
|
|
return hypre_error_flag;
|
|
}
|
|
|