diff options
author | Kevin Ryde <user42@zip.com.au> | 2001-06-19 22:20:04 +0200 |
---|---|---|
committer | Kevin Ryde <user42@zip.com.au> | 2001-06-19 22:20:04 +0200 |
commit | ae675951b023f967cc6ba98103dc894e2da1c3ee (patch) | |
tree | 2682c6586df5cce2cd7b665616f9d0a6c319915f /gmp-impl.h | |
parent | 6fcd1c15ac70c145f337c9eea8af41476d0c1e2f (diff) | |
download | gmp-ae675951b023f967cc6ba98103dc894e2da1c3ee.tar.gz |
* acinclude.m4, configure.in (GMP_C_ATTRIBUTE_MALLOC): New macro.
* gmp-impl.h: Use it for all the malloc based TMP_ALLOCs.
* gmp-impl.h (__TMP_ALIGN): Moved from stack-alloc.c, use a union to
determine the value, and demand only 4 bytes align on 32-bit systems.
* gmp-impl.h (WANT_TMP_NOTREENTRANT): Move global parts of
stack-alloc.h to here, allow non power-of-2 __TMP_ALIGN in TMP_ALLOC.
* gmp-impl.h: Extend extern "C" to TMP_ALLOC declarations.
* gmp-impl.h (TMP_ALLOC_LIMBS_2): New macro.
Diffstat (limited to 'gmp-impl.h')
-rw-r--r-- | gmp-impl.h | 143 |
1 files changed, 107 insertions, 36 deletions
diff --git a/gmp-impl.h b/gmp-impl.h index b1440077f..fd75ad375 100644 --- a/gmp-impl.h +++ b/gmp-impl.h @@ -27,6 +27,13 @@ MA 02111-1307, USA. */ #ifndef __GMP_IMPL_H__ #define __GMP_IMPL_H__ +/* On Cray vector systems "short" and "unsigned short" might not be the same + number of bits, making the SHRT_MAX defaults below fail. (This depends + on compiler options.) Instead use limits.h. */ +#if defined _CRAY +#include <limits.h> +#endif + #if ! __GMP_WITHIN_CONFIGURE #include "config.h" #include "gmp-mparam.h" @@ -82,6 +89,50 @@ MA 02111-1307, USA. */ #endif +/* "const" basically means a function does nothing but examine its arguments + and give a return value, it doesn't read or write any memory (neither + global nor pointed to by arguments), and has no other side-effects. This + is more restrictive than "pure". See info node "(gcc)Function + Attributes". */ +#if HAVE_ATTRIBUTE_CONST +#define ATTRIBUTE_CONST __attribute__ ((const)) +#else +#define ATTRIBUTE_CONST +#endif + +#if HAVE_ATTRIBUTE_NORETURN +#define ATTRIBUTE_NORETURN __attribute__ ((noreturn)) +#else +#define ATTRIBUTE_NORETURN +#endif + +/* "malloc" means a function behaves like malloc in that the pointer it + returns doesn't alias anything. */ +#if HAVE_ATTRIBUTE_MALLOC +#define ATTRIBUTE_MALLOC __attribute__ ((malloc)) +#else +#define ATTRIBUTE_MALLOC +#endif + + +#if defined (__cplusplus) +extern "C" { +#endif + + +/* The alignment in bytes, used for TMP_ALLOCed blocks, when alloca or + __gmp_allocate_func doesn't already determine it. Currently TMP_ALLOC + isn't used for "double"s, so that's not in the union. */ +union tmp_align_t { + mp_limb_t l; + char *p; +}; +#define __TMP_ALIGN sizeof (union tmp_align_t) + +/* Return "a" rounded upwards to a multiple of "m", if it isn't already. + "a" must be an unsigned type. */ +#define ROUND_UP_MULTIPLE(a,m) ((a) + (-(a))%(m)) + #if WANT_TMP_ALLOCA /* Each TMP_ALLOC is simply an alloca(), and nothing else is needed. This is the preferred method. */ @@ -91,8 +142,40 @@ MA 02111-1307, USA. */ #define TMP_FREE(m) #endif -#if WANT_TMP_MALLOC -#include "stack-alloc.h" +#if WANT_TMP_REENTRANT +/* See tal-reent.c for some comments. */ +struct tmp_reentrant_t { + struct tmp_reentrant_t *next; + size_t size; /* bytes, including header */ +}; +void *__gmp_tmp_reentrant_alloc _PROTO ((struct tmp_reentrant_t **, size_t)) ATTRIBUTE_MALLOC; +void __gmp_tmp_reentrant_free _PROTO ((struct tmp_reentrant_t *)); +#define TMP_DECL(marker) struct tmp_reentrant_t *__tmp_marker +/* don't demand NULL, just cast a zero */ +#define TMP_MARK(marker) \ + do { __tmp_marker = (struct tmp_reentrant_t *) 0; } while (0) +#define TMP_ALLOC(size) __gmp_tmp_reentrant_alloc (&__tmp_marker, size) +#define TMP_FREE(marker) __gmp_tmp_reentrant_free (__tmp_marker) +#endif + +#if WANT_TMP_NOTREENTRANT +/* See stack-alloc.c for some comments. */ +struct tmp_marker +{ + struct tmp_stack *which_chunk; + void *alloc_point; +}; +typedef struct tmp_marker tmp_marker; +void *__gmp_tmp_alloc _PROTO ((unsigned long)) ATTRIBUTE_MALLOC; +void __gmp_tmp_mark _PROTO ((tmp_marker *)); +void __gmp_tmp_free _PROTO ((tmp_marker *)); +#define TMP_DECL(marker) tmp_marker marker +/* gcc recognises "(-(8*n))%8" or the like is always zero, which means the + rounding up is a noop for allocs of whole limbs. */ +#define TMP_ALLOC(size) \ + __gmp_tmp_alloc (ROUND_UP_MULTIPLE ((unsigned long) (size))) +#define TMP_MARK(marker) __gmp_tmp_mark (&marker) +#define TMP_FREE(marker) __gmp_tmp_free (&marker) #endif #if WANT_TMP_DEBUG @@ -107,12 +190,9 @@ struct tmp_debug_entry_t { char *block; size_t size; }; -void __gmp_tmp_debug_mark _PROTO ((const char *, int, - struct tmp_debug_t **)); -void *__gmp_tmp_debug_alloc _PROTO ((const char *, int, - struct tmp_debug_t **, size_t)); -void __gmp_tmp_debug_free _PROTO ((const char *, int, - struct tmp_debug_t **)); +void __gmp_tmp_debug_mark _PROTO ((const char *, int, struct tmp_debug_t **)); +void *__gmp_tmp_debug_alloc _PROTO ((const char *, int, struct tmp_debug_t **, size_t)) ATTRIBUTE_MALLOC; +void __gmp_tmp_debug_free _PROTO ((const char *, int, struct tmp_debug_t **)); /* don't demand NULL, just cast a zero */ #define TMP_DECL(marker) \ struct tmp_debug_t *__tmp_marker = (struct tmp_debug_t *) 0 @@ -130,6 +210,24 @@ void __gmp_tmp_debug_free _PROTO ((const char *, int, #define TMP_ALLOC_LIMBS(n) TMP_ALLOC_TYPE(n,mp_limb_t) #define TMP_ALLOC_MP_PTRS(n) TMP_ALLOC_TYPE(n,mp_ptr) +/* It's more efficient to allocate one block than two, but when debugging + continue to do separate TMP_ALLOC's to let each get protected with its + own redzone. */ +#if WANT_TMP_DEBUG +#define TMP_ALLOC_LIMBS_2(xp,xsize, yp,ysize) \ + do { \ + (xp) = TMP_ALLOC_LIMBS (xsize); \ + (yp) = TMP_ALLOC_LIMBS (ysize); \ + } while (0) +#else +#define TMP_ALLOC_LIMBS_2(xp,xsize, yp,ysize) \ + do { \ + (xp) = TMP_ALLOC_LIMBS ((xsize) + (ysize)); \ + (yp) = (xp) + (xsize); \ + } while (0) +#endif + + /* From gmp.h, nicer names for internal use. */ #define MPN_CMP(result, xp, yp, size) __GMPN_CMP(result, xp, yp, size) @@ -148,16 +246,11 @@ void __gmp_tmp_debug_free _PROTO ((const char *, int, #define ALLOC(x) ((x)->_mp_alloc) +/* Might be already defined by gmp-mparam.h, otherwise use what's in gmp.h. */ #ifndef BITS_PER_MP_LIMB #define BITS_PER_MP_LIMB __GMP_BITS_PER_MP_LIMB #endif -/* On Cray vector systems "short" and "unsigned short" might not be the same - number of bits, making the SHRT_MAX defaults below fail. (This depends - on compiler options.) Instead use limits.h. */ -#if defined _CRAY -#include <limits.h> -#endif /* The "short" defines are a bit different because shorts are promoted to ints by ~ or >> etc. */ @@ -281,10 +374,6 @@ void __gmp_tmp_debug_free _PROTO ((const char *, int, #define ASM_L(name) LSYM_PREFIX "asm_%=_" #name -#if defined (__cplusplus) -extern "C" { -#endif - void *__gmp_default_allocate _PROTO ((size_t)); void *__gmp_default_reallocate _PROTO ((void *, size_t, size_t)); void __gmp_default_free _PROTO ((void *, size_t)); @@ -311,24 +400,6 @@ void __gmp_default_free _PROTO ((void *, size_t)); #endif -/* See "(gcc)Function Attributes". Basically "const" means a function does - nothing but examine its arguments and give a return value, it doesn't - read or write any memory (neither global nor pointed to by arguments), - and has no other side-effects. */ - -#if HAVE_ATTRIBUTE_CONST -#define ATTRIBUTE_CONST __attribute__ ((const)) -#else -#define ATTRIBUTE_CONST -#endif - -#if HAVE_ATTRIBUTE_NORETURN -#define ATTRIBUTE_NORETURN __attribute__ ((noreturn)) -#else -#define ATTRIBUTE_NORETURN -#endif - - /* Dummy for non-gcc, code involving it will go dead. */ #ifndef __GNUC__ #define __builtin_constant_p(x) 0 |