/*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: 2.4 $ ***********************************************************************EHEADER*/ /****************************************************************************** * * Box allocation routines. These hopefully increase efficiency * and reduce memory fragmentation. * *****************************************************************************/ #include "headers.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 int s_at_a_time = 1000; static 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 int hypre_AllocateBoxBlock() { int ierr = 0; union box_memory *ptr; 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 ierr; } /*-------------------------------------------------------------------------- * Set up the allocation block size and allocate the first memory block. *--------------------------------------------------------------------------*/ int hypre_BoxInitializeMemory( const int at_a_time ) { int ierr = 0; if (at_a_time > 0) { s_at_a_time = at_a_time; } return ierr; } /*-------------------------------------------------------------------------- * 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. *--------------------------------------------------------------------------*/ int hypre_BoxFinalizeMemory() { int ierr = 0; 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 ierr; } /*-------------------------------------------------------------------------- * 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. *--------------------------------------------------------------------------*/ int hypre_BoxFree( hypre_Box *box ) { int ierr = 0; union box_memory *ptr = (union box_memory *) box; (ptr -> d_next) = s_free; s_free = ptr; s_count--; if (!s_count) { hypre_BoxFinalizeMemory(); } return ierr; }