summaryrefslogtreecommitdiffstats
path: root/generic/tclInt.h
diff options
context:
space:
mode:
authorapnadkarni <apnmbx-wits@yahoo.com>2023-05-04 17:52:06 (GMT)
committerapnadkarni <apnmbx-wits@yahoo.com>2023-05-04 17:52:06 (GMT)
commit92dd14e77c81c060ff6ede641885b928afdb9ec3 (patch)
tree09f32df9e6435a6c51c396584c19e9d284869e2b /generic/tclInt.h
parent8a45e47c4c3881f7c0db88276adfa26ac9712459 (diff)
downloadtcl-92dd14e77c81c060ff6ede641885b928afdb9ec3.zip
tcl-92dd14e77c81c060ff6ede641885b928afdb9ec3.tar.gz
tcl-92dd14e77c81c060ff6ede641885b928afdb9ec3.tar.bz2
Refactor reallocation in preparation for experimentation with different growth factors
Diffstat (limited to 'generic/tclInt.h')
-rw-r--r--generic/tclInt.h43
1 files changed, 43 insertions, 0 deletions
diff --git a/generic/tclInt.h b/generic/tclInt.h
index 8f87523..4d2f85d 100644
--- a/generic/tclInt.h
+++ b/generic/tclInt.h
@@ -2872,6 +2872,49 @@ typedef struct ProcessGlobalValue {
} while (0)
/*
+ *----------------------------------------------------------------------
+ * Common functions for growing allocations. Trivial but allows for
+ * experimenting with growth factors without having to change code in
+ * multiple places. Usage example:
+ *
+ * allocated = TclUpsizeAlloc(oldSize, needed, TCL_SIZE_MAX);
+ * while (allocated > needed) {
+ * ptr = Tcl_AttemptRealloc(oldPtr, allocated);
+ * if (ptr)
+ * break;
+ * allocated = TclUpsizeRetry(needed, allocated);
+ * }
+ * if (ptr == NULL) {
+ * // Last resort - exact size
+ * allocated = needed;
+ * ptr = Tcl_Realloc(oldPtr, allocated);
+ * }
+ * ptr now points to an allocation of size 'allocated'
+ *----------------------------------------------------------------------
+ */
+static inline Tcl_Size
+TclUpsizeAlloc(TCL_UNUSED(Tcl_Size) /*oldSize*/,
+ Tcl_Size needed,
+ Tcl_Size limit)
+{
+ /* assert (oldCapacity < needed <= limit) */
+ if (needed < (limit - needed)) {
+ return 2 * needed;
+ } 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;
+ }
+}
+
+/*
*----------------------------------------------------------------
* Variables shared among Tcl modules but not used by the outside world.
*----------------------------------------------------------------