diff options
Diffstat (limited to 'generic/tclInt.h')
| -rw-r--r-- | generic/tclInt.h | 69 |
1 files changed, 69 insertions, 0 deletions
diff --git a/generic/tclInt.h b/generic/tclInt.h index 28ec508..bf42f6a 100644 --- a/generic/tclInt.h +++ b/generic/tclInt.h @@ -2873,6 +2873,75 @@ typedef struct ProcessGlobalValue { } while (0) /* + *---------------------------------------------------------------------- + * Common functions for calculating overallocation. Trivial but allows for + * experimenting with growth factors without having to change code in + * multiple places. See TclAttemptAllocElemsEx and similar for usage + * examples. Best to use those functions. Direct use of TclUpsizeAlloc / + * TclResizeAlloc is needed in special cases such as when total size of + * memory block is limited to less than TCL_SIZE_MAX. + * + *---------------------------------------------------------------------- + */ +static inline Tcl_Size +TclUpsizeAlloc(TCL_UNUSED(Tcl_Size) /* oldSize. For future experiments with + * some growth algorithms that use this + * information. */, + Tcl_Size needed, + Tcl_Size limit) +{ + /* assert (oldCapacity < needed <= limit) */ + if (needed < (limit - needed/2)) { + return needed + needed / 2; + } + else { + return limit; + } +} +static inline Tcl_Size TclUpsizeRetry(Tcl_Size needed, Tcl_Size lastAttempt) { + /* assert (needed < lastAttempt) */ + if (needed < lastAttempt - 1) { + /* (needed+lastAttempt)/2 but that formula may overflow Tcl_Size */ + return needed + (lastAttempt - needed) / 2; + } else { + return needed; + } +} +MODULE_SCOPE void *TclAllocElemsEx(Tcl_Size elemCount, Tcl_Size elemSize, + Tcl_Size leadSize, Tcl_Size *capacityPtr); +MODULE_SCOPE void *TclReallocElemsEx(void *oldPtr, Tcl_Size elemCount, + Tcl_Size elemSize, Tcl_Size leadSize, + Tcl_Size *capacityPtr); +MODULE_SCOPE void *TclAttemptReallocElemsEx(void *oldPtr, + Tcl_Size elemCount, Tcl_Size elemSize, + Tcl_Size leadSize, Tcl_Size *capacityPtr); +/* Alloc elemCount elements of size elemSize with leadSize header + * returning actual capacity (in elements) in *capacityPtr. */ +static inline void *TclAttemptAllocElemsEx(Tcl_Size elemCount, Tcl_Size elemSize, + Tcl_Size leadSize, Tcl_Size *capacityPtr) { + return TclAttemptReallocElemsEx( + NULL, elemCount, elemSize, leadSize, capacityPtr); +} +/* Alloc numByte bytes, returning actual capacity in *capacityPtr. */ +static inline void *TclAllocEx(Tcl_Size numBytes, Tcl_Size *capacityPtr) { + return TclAllocElemsEx(numBytes, 1, 0, capacityPtr); +} +/* Alloc numByte bytes, returning actual capacity in *capacityPtr. */ +static inline void * +TclAttemptAllocEx(Tcl_Size numBytes, Tcl_Size *capacityPtr) +{ + return TclAttemptAllocElemsEx(numBytes, 1, 0, capacityPtr); +} +/* Realloc numByte bytes, returning actual capacity in *capacityPtr. */ +static inline void *TclReallocEx(void *oldPtr, Tcl_Size numBytes, Tcl_Size *capacityPtr) { + return TclReallocElemsEx(oldPtr, numBytes, 1, 0, capacityPtr); +} +/* Realloc numByte bytes, returning actual capacity in *capacityPtr. */ +static inline void *TclAttemptReallocEx(void *oldPtr, Tcl_Size numBytes, Tcl_Size *capacityPtr) { + return TclAttemptReallocElemsEx(oldPtr, numBytes, 1, 0, capacityPtr); +} + +/* *---------------------------------------------------------------- * Variables shared among Tcl modules but not used by the outside world. *---------------------------------------------------------------- |
