1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159
|
/*=============================================================================
This file is part of FLINT.
FLINT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
FLINT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FLINT; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
=============================================================================*/
/******************************************************************************
Copyright (C) 2011 Fredrik Johansson
******************************************************************************/
#include <stdlib.h>
#include <stdio.h>
#include "flint.h"
#if HAVE_GC
#include "gc.h"
#endif
#if FLINT_REENTRANT && !HAVE_TLS
#include <pthread.h>
static pthread_once_t register_initialised = PTHREAD_ONCE_INIT;
pthread_mutex_t register_lock;
#endif
static void flint_memory_error()
{
flint_printf("Exception (FLINT memory_manager). Unable to allocate memory.\n");
abort();
}
void * flint_malloc(size_t size)
{
void * ptr;
#if HAVE_GC
ptr = GC_malloc(size);
#else
ptr = malloc(size);
#endif
if (ptr == NULL)
flint_memory_error();
return ptr;
}
void * flint_realloc(void * ptr, size_t size)
{
void * ptr2;
#if HAVE_GC
ptr2 = GC_realloc(ptr, size);
#else
ptr2 = realloc(ptr, size);
#endif
if (ptr2 == NULL)
flint_memory_error();
return ptr2;
}
void * flint_calloc(size_t num, size_t size)
{
void * ptr;
#if HAVE_GC
ptr = GC_malloc(num*size);
#else
ptr = calloc(num, size);
#endif
if (ptr == NULL)
flint_memory_error();
return ptr;
}
void flint_free(void * ptr)
{
#if !HAVE_GC
free(ptr);
#endif
}
FLINT_TLS_PREFIX size_t flint_num_cleanup_functions = 0;
FLINT_TLS_PREFIX flint_cleanup_function_t * flint_cleanup_functions = NULL;
#if FLINT_REENTRANT && !HAVE_TLS
void register_init()
{
pthread_mutex_init(®ister_lock, NULL);
}
#endif
void flint_register_cleanup_function(flint_cleanup_function_t cleanup_function)
{
#if FLINT_REENTRANT && !HAVE_TLS
pthread_once(®ister_initialised, register_init);
pthread_mutex_lock(®ister_lock);
#endif
flint_cleanup_functions = flint_realloc(flint_cleanup_functions,
(flint_num_cleanup_functions + 1) * sizeof(flint_cleanup_function_t));
flint_cleanup_functions[flint_num_cleanup_functions] = cleanup_function;
flint_num_cleanup_functions++;
#if FLINT_REENTRANT && !HAVE_TLS
pthread_mutex_unlock(®ister_lock);
#endif
}
void _fmpz_cleanup();
void flint_cleanup()
{
size_t i;
#if FLINT_REENTRANT && !HAVE_TLS
pthread_mutex_lock(®ister_lock);
#endif
for (i = 0; i < flint_num_cleanup_functions; i++)
flint_cleanup_functions[i]();
flint_free(flint_cleanup_functions);
flint_cleanup_functions = NULL;
flint_num_cleanup_functions = 0;
mpfr_free_cache();
_fmpz_cleanup();
#if FLINT_REENTRANT && !HAVE_TLS
pthread_mutex_unlock(®ister_lock);
#endif
}
|