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
|
/* $Id$
Part of SWI-Prolog
Author: Jan Wielemaker
E-mail: wielemak@science.uva.nl
WWW: http://www.swi-prolog.org
Copyright (C): 1985-2007, University of Amsterdam
This library 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; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef O_PLGMP_INCLUDED
#define O_PLGMP_INCLUDED
#define COMMON(type) SO_LOCAL type
#ifdef O_GMP
#include <gmp.h>
#define O_MY_GMP_ALLOC 1
#define O_GMP_PRECHECK_ALLOCATIONS 1 /* GMP 4.2.3 uses abort() sometimes */
COMMON(void) initGMP(void);
COMMON(void) cleanupGMP(void);
COMMON(void) get_integer(word w, number *n);
COMMON(void) promoteToMPZNumber(number *n);
COMMON(void) promoteToMPQNumber(number *n);
COMMON(void) ensureWritableNumber(Number n);
COMMON(void) clearGMPNumber(Number n);
COMMON(void) addMPZToBuffer(Buffer b, mpz_t mpz);
COMMON(char *) loadMPZFromCharp(const char *data, Word r, Word *store);
COMMON(char *) skipMPZOnCharp(const char *data);
COMMON(int) mpz_to_int64(mpz_t mpz, int64_t *i);
#define clearNumber(n) \
do { if ( (n)->type != V_INTEGER ) clearGMPNumber(n); } while(0)
#else /*O_GMP*/
#define get_integer(w, n) \
do \
{ (n)->type = V_INTEGER; \
(n)->value.i = valInteger(w); \
} while(0)
#define clearGMPNumber(n) (void)0
#define clearNumber(n) (void)0
#define ensureWritableNumber(n) (void)0
#define initGMP() (void)0
#endif /*O_GMP*/
/*******************************
* GMP ALLOCATION *
*******************************/
#if O_MY_GMP_ALLOC
typedef struct mp_mem_header
{ struct mp_mem_header *prev;
struct mp_mem_header *next;
struct ar_context *context;
} mp_mem_header;
typedef struct ar_context
{ struct ar_context *parent;
size_t allocated;
} ar_context;
#define O_GMP_LEAK_CHECK 0
#if O_GMP_LEAK_CHECK
#define GMP_LEAK_CHECK(g) g
#else
#define GMP_LEAK_CHECK(g)
#endif
#define AR_CTX ar_context __PL_ar_ctx = {0};
#define AR_BEGIN() \
do \
{ __PL_ar_ctx.parent = LD->gmp.context; \
LD->gmp.context = &__PL_ar_ctx; \
GMP_LEAK_CHECK(__PL_ar_ctx.allocated = LD->gmp.allocated); \
} while(0)
#define AR_END() \
do \
{ LD->gmp.context = __PL_ar_ctx.parent; \
GMP_LEAK_CHECK(if ( __PL_ar_ctx.allocated != LD->gmp.allocated ) \
{ Sdprintf("GMP: lost %ld bytes\n", \
LD->gmp.allocated-__PL_ar_ctx.allocated); \
}) \
} while(0)
#define AR_CLEANUP() \
mp_cleanup(&__PL_ar_ctx)
COMMON(void) mp_cleanup(ar_context *ctx);
#else /*O_MY_GMP_ALLOC*/
#define AR_CTX
#define AR_BEGIN() (void)0
#define AR_END() (void)0
#define AR_CLEANUP() (void)0
#endif /*O_MY_GMP_ALLOC*/
#endif /*O_PLGMP_INCLUDED*/
|