summaryrefslogtreecommitdiffstats
path: root/generic/tclInt.h
diff options
context:
space:
mode:
Diffstat (limited to 'generic/tclInt.h')
-rw-r--r--generic/tclInt.h69
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.
*----------------------------------------------------------------