summaryrefslogtreecommitdiffstats
path: root/generic/tclCkalloc.c
diff options
context:
space:
mode:
authorapnadkarni <apnmbx-wits@yahoo.com>2023-05-15 23:08:17 (GMT)
committerapnadkarni <apnmbx-wits@yahoo.com>2023-05-15 23:08:17 (GMT)
commit6fa73194d556765f6a8dfe33c0f609377d5fb41c (patch)
tree29dee223243c848d4d1099cf29f38432ac65ba18 /generic/tclCkalloc.c
parent02563b1911feda87ad86d89bb18855a930ba178e (diff)
downloadtcl-6fa73194d556765f6a8dfe33c0f609377d5fb41c.zip
tcl-6fa73194d556765f6a8dfe33c0f609377d5fb41c.tar.gz
tcl-6fa73194d556765f6a8dfe33c0f609377d5fb41c.tar.bz2
Refactor couple more reallocations
Diffstat (limited to 'generic/tclCkalloc.c')
-rw-r--r--generic/tclCkalloc.c141
1 files changed, 141 insertions, 0 deletions
diff --git a/generic/tclCkalloc.c b/generic/tclCkalloc.c
index 09e140a..1539f4f 100644
--- a/generic/tclCkalloc.c
+++ b/generic/tclCkalloc.c
@@ -1194,6 +1194,147 @@ Tcl_DbCkfree(
}
/*
+ *------------------------------------------------------------------------
+ *
+ * TclAttemptOverAlloc --
+ *
+ * Attempts to allocates memory of the requested size plus some more for
+ * future growth.
+ *
+ * Results:
+ * Pointer to allocated memory block which is at least as large
+ * as the requested size or NULL if allocation failed.
+ *
+ *------------------------------------------------------------------------
+ */
+void *
+TclAttemptOverAlloc(
+ Tcl_Size needed, /* Requested size */
+ Tcl_Size *allocatedPtr) /* OUTPUT: Actual allocation size is stored
+ here if non-NULL. Only modified on success */
+{
+ void *ptr;
+ Tcl_Size attempt = TclUpsizeAlloc(0, needed, TCL_SIZE_MAX);
+ while (attempt > needed) {
+ ptr = Tcl_AttemptAlloc(attempt);
+ if (ptr)
+ break;
+ attempt = TclUpsizeRetry(needed, attempt);
+ }
+ if (ptr == NULL) {
+ /* Try exact size as a last resort */
+ attempt = needed;
+ ptr = Tcl_AttemptAlloc(attempt);
+ }
+ if (ptr && allocatedPtr) {
+ *allocatedPtr = attempt;
+ }
+ return ptr;
+}
+
+/*
+ *------------------------------------------------------------------------
+ *
+ * TclOverAlloc --
+ *
+ * Allocates memory of the requested size plus some more for future
+ * growth.
+ *
+ * Results:
+ * Non-NULL pointer to allocated memory block which is at least as large
+ * as the requested size.
+ *
+ * Side effects:
+ * Panics if memory of at least the requested size could not be
+ * allocated.
+ *
+ *------------------------------------------------------------------------
+ */
+void *
+TclOverAlloc(Tcl_Size needed, Tcl_Size *allocatedPtr)
+{
+ void *ptr = TclAttemptOverAlloc(needed, allocatedPtr);
+ if (ptr == NULL) {
+ Tcl_Panic("Failed to allocate %" TCL_SIZE_MODIFIER "d bytes.", needed);
+ }
+ return ptr;
+}
+
+/*
+ *------------------------------------------------------------------------
+ *
+ * TclAttemptOverRealloc --
+ *
+ * Attempts to reallocate memory of the requested size plus some more for
+ * future growth.
+ *
+ * Results:
+ * Pointer to allocated memory block which is at least as large
+ * as the requested size or NULL if allocation failed.
+ *
+ *------------------------------------------------------------------------
+ */
+void *
+TclAttemptOverRealloc(
+ Tcl_Size needed, /* Requested size */
+ void *oldPtr, /* Pointer to memory block to reallocate */
+ Tcl_Size oldSize, /* Old size if known, or 0 if unknown */
+ Tcl_Size *allocatedPtr) /* OUTPUT: Actual allocation size is stored
+ here if non-NULL. Only modified on success */
+{
+ void *ptr;
+ Tcl_Size attempt = TclUpsizeAlloc(oldSize, needed, TCL_SIZE_MAX);
+ while (attempt > needed) {
+ ptr = Tcl_AttemptRealloc(oldPtr, attempt);
+ if (ptr)
+ break;
+ attempt = TclUpsizeRetry(needed, attempt);
+ }
+ if (ptr == NULL) {
+ /* Try exact size as a last resort */
+ attempt = needed;
+ ptr = Tcl_AttemptRealloc(oldPtr, attempt);
+ }
+ if (ptr && allocatedPtr) {
+ *allocatedPtr = attempt;
+ }
+ return ptr;
+}
+
+/*
+ *------------------------------------------------------------------------
+ *
+ * TclOverRealloc --
+ *
+ * Reallocates memory of the requested size plus some more for future
+ * growth.
+ *
+ * Results:
+ * Non-NULL pointer to allocated memory block which is at least as large
+ * as the requested size.
+ *
+ * Side effects:
+ * Panics if memory of at least the requested size could not be
+ * allocated.
+ *
+ *------------------------------------------------------------------------
+ */
+void *
+TclOverRealloc(
+ Tcl_Size needed, /* Requested size */
+ void *oldPtr, /* Pointer to memory block to reallocate */
+ Tcl_Size oldSize, /* Old size if known, or 0 if unknown */
+ Tcl_Size *allocatedPtr) /* OUTPUT: Actual allocation size is stored
+ here if non-NULL. Only modified on success */
+{
+ void *ptr = TclAttemptOverRealloc(needed, oldPtr, oldSize, allocatedPtr);
+ if (ptr == NULL) {
+ Tcl_Panic("Failed to reallocate %" TCL_SIZE_MODIFIER "d bytes.", needed);
+ }
+ return ptr;
+}
+
+/*
*----------------------------------------------------------------------
*
* Tcl_InitMemory --