blob: 27e95b010b3e6894c2818df4fce8728d2c545bd2 [file] [log] [blame]
/*BHEADER**********************************************************************
* (c) 1997 The Regents of the University of California
*
* See the file COPYRIGHT_and_DISCLAIMER for a complete copyright
* notice, contact person, and disclaimer.
*
* $Revision$
*********************************************************************EHEADER*/
/******************************************************************************
*
* Memory management utilities
*
*****************************************************************************/
#include <stdlib.h>
#include <stdio.h>
#include "utilities.h"
#ifdef HYPRE_USE_PTHREADS
#include "threading.h"
#ifdef HYPRE_USE_UMALLOC
#include "umalloc_local.h"
#define _umalloc_(size) (threadid == hypre_NumThreads) ? \
(char *) malloc(size) : \
(char *) _umalloc(_uparam[threadid].myheap, size)
#define _ucalloc_(count, size) (threadid == hypre_NumThreads) ? \
(char *) calloc(count, size) : \
(char *) _ucalloc(_uparam[threadid].myheap,\
count, size)
#define _urealloc_(ptr, size) (threadid == hypre_NumThreads) ? \
(char *) realloc(ptr, size) : \
(char *) _urealloc(ptr, size)
#define _ufree_(ptr) (threadid == hypre_NumThreads) ? \
free(ptr) : _ufree(ptr)
#endif
#else
#ifdef HYPRE_USE_UMALLOC
#undef HYPRE_USE_UMALLOC
#endif
#endif
/******************************************************************************
*
* Standard routines
*
*****************************************************************************/
/*--------------------------------------------------------------------------
* hypre_OutOfMemory
*--------------------------------------------------------------------------*/
int
hypre_OutOfMemory( int size )
{
printf("Out of memory trying to allocate %d bytes\n", size);
fflush(stdout);
return 0;
}
/*--------------------------------------------------------------------------
* hypre_MAlloc
*--------------------------------------------------------------------------*/
char *
hypre_MAlloc( int size )
{
char *ptr;
if (size > 0)
{
#ifdef HYPRE_USE_UMALLOC
int threadid = hypre_GetThreadID();
ptr = _umalloc_(size);
#else
ptr = malloc(size);
#endif
#if 1
if (ptr == NULL)
{
hypre_OutOfMemory(size);
}
#endif
}
else
{
ptr = NULL;
}
return ptr;
}
/*--------------------------------------------------------------------------
* hypre_CAlloc
*--------------------------------------------------------------------------*/
char *
hypre_CAlloc( int count,
int elt_size )
{
char *ptr;
int size = count*elt_size;
if (size > 0)
{
#ifdef HYPRE_USE_UMALLOC
int threadid = hypre_GetThreadID();
ptr = _ucalloc_(count, elt_size);
#else
ptr = calloc(count, elt_size);
#endif
#if 1
if (ptr == NULL)
{
hypre_OutOfMemory(size);
}
#endif
}
else
{
ptr = NULL;
}
return ptr;
}
/*--------------------------------------------------------------------------
* hypre_ReAlloc
*--------------------------------------------------------------------------*/
char *
hypre_ReAlloc( char *ptr,
int size )
{
#ifdef HYPRE_USE_UMALLOC
if (ptr == NULL)
{
ptr = hypre_MAlloc(size);
}
else if (size == 0)
{
hypre_Free(ptr);
}
else
{
int threadid = hypre_GetThreadID();
ptr = _urealloc_(ptr, size);
}
#else
ptr = realloc(ptr, size);
#endif
#if 1
if ((ptr == NULL) && (size > 0))
{
hypre_OutOfMemory(size);
}
#endif
return ptr;
}
/*--------------------------------------------------------------------------
* hypre_Free
*--------------------------------------------------------------------------*/
void
hypre_Free( char *ptr )
{
if (ptr)
{
#ifdef HYPRE_USE_UMALLOC
int threadid = hypre_GetThreadID();
_ufree_(ptr);
#else
free(ptr);
#endif
}
}
/*--------------------------------------------------------------------------
* These Shared routines are for one thread to allocate memory for data
* will be visible to all threads. The file-scope pointer
* global_alloc_ptr is used in these routines.
*--------------------------------------------------------------------------*/
#ifdef HYPRE_USE_PTHREADS
char *global_alloc_ptr;
double *global_data_ptr;
/*--------------------------------------------------------------------------
* hypre_SharedMAlloc
*--------------------------------------------------------------------------*/
char *
hypre_SharedMAlloc( int size )
{
char *ptr;
int unthreaded = pthread_equal(initial_thread, pthread_self());
int I_call_malloc = unthreaded ||
pthread_equal(hypre_thread[0],pthread_self());
if (I_call_malloc) {
global_alloc_ptr = hypre_MAlloc( size );
}
hypre_barrier(&talloc_mtx, unthreaded);
ptr = global_alloc_ptr;
hypre_barrier(&talloc_mtx, unthreaded);
return ptr;
}
/*--------------------------------------------------------------------------
* hypre_SharedCAlloc
*--------------------------------------------------------------------------*/
char *
hypre_SharedCAlloc( int count,
int elt_size )
{
char *ptr;
int unthreaded = pthread_equal(initial_thread, pthread_self());
int I_call_calloc = unthreaded ||
pthread_equal(hypre_thread[0],pthread_self());
if (I_call_calloc) {
global_alloc_ptr = hypre_CAlloc( count, elt_size );
}
hypre_barrier(&talloc_mtx, unthreaded);
ptr = global_alloc_ptr;
hypre_barrier(&talloc_mtx, unthreaded);
return ptr;
}
/*--------------------------------------------------------------------------
* hypre_SharedReAlloc
*--------------------------------------------------------------------------*/
char *
hypre_SharedReAlloc( char *ptr,
int size )
{
int unthreaded = pthread_equal(initial_thread, pthread_self());
int I_call_realloc = unthreaded ||
pthread_equal(hypre_thread[0],pthread_self());
if (I_call_realloc) {
global_alloc_ptr = hypre_ReAlloc( ptr, size );
}
hypre_barrier(&talloc_mtx, unthreaded);
ptr = global_alloc_ptr;
hypre_barrier(&talloc_mtx, unthreaded);
return ptr;
}
/*--------------------------------------------------------------------------
* hypre_SharedFree
*--------------------------------------------------------------------------*/
void
hypre_SharedFree( char *ptr )
{
int unthreaded = pthread_equal(initial_thread, pthread_self());
int I_call_free = unthreaded ||
pthread_equal(hypre_thread[0],pthread_self());
hypre_barrier(&talloc_mtx, unthreaded);
if (I_call_free) {
hypre_Free(ptr);
}
hypre_barrier(&talloc_mtx, unthreaded);
}
/*--------------------------------------------------------------------------
* hypre_IncrementSharedDataPtr
*--------------------------------------------------------------------------*/
double *
hypre_IncrementSharedDataPtr( double *ptr, int size )
{
int unthreaded = pthread_equal(initial_thread, pthread_self());
int I_increment = unthreaded ||
pthread_equal(hypre_thread[0],pthread_self());
if (I_increment) {
global_data_ptr = ptr + size;
}
hypre_barrier(&talloc_mtx, unthreaded);
ptr = global_data_ptr;
hypre_barrier(&talloc_mtx, unthreaded);
return ptr;
}
#endif