pspp-cvs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Pspp-cvs] Changes to pspp/src/pool.c


From: Ben Pfaff
Subject: [Pspp-cvs] Changes to pspp/src/pool.c
Date: Sat, 29 Oct 2005 19:35:58 -0400

Index: pspp/src/pool.c
diff -u pspp/src/pool.c:1.13 pspp/src/pool.c:1.14
--- pspp/src/pool.c:1.13        Sat Oct 29 05:50:06 2005
+++ pspp/src/pool.c     Sat Oct 29 23:35:55 2005
@@ -19,10 +19,11 @@
 
 #include <config.h>
 #include "pool.h"
-#include "command.h"
-#include "error.h"
 #include <stdlib.h>
 #include "alloc.h"
+#include "command.h"
+#include "error.h"
+#include "size_max.h"
 #include "str.h"
 
 /* Fast, low-overhead memory block suballocator. */
@@ -347,7 +348,7 @@
 /* Allocates AMT bytes using malloc(), to be managed by POOL, and
    returns a pointer to the beginning of the block.
    If POOL is a null pointer, then allocates a normal memory block
-   with malloc().  */
+   with xmalloc().  */
 void *
 pool_malloc (struct pool *pool, size_t amt)
 {
@@ -437,6 +438,100 @@
 {
   if (xalloc_oversized (n, s))
     xalloc_die ();
+  return pool_realloc (pool, p, n * s);
+}
+
+/* If P is null, allocate a block of at least *PN such objects;
+   otherwise, reallocate P so that it contains more than *PN
+   objects each of S bytes.  *PN must be nonzero unless P is
+   null, and S must be nonzero.  Set *PN to the new number of
+   objects, and return the pointer to the new block.  *PN is
+   never set to zero, and the returned pointer is never null.
+
+   The block returned is managed by POOL.  If POOL is a null
+   pointer, then the block is reallocated in the usual way with
+   x2nrealloc().
+
+   Terminates the program if the memory cannot be obtained,
+   including the case where the memory required overflows the
+   range of size_t.
+
+   Repeated reallocations are guaranteed to make progress, either by
+   allocating an initial block with a nonzero size, or by allocating a
+   larger block.
+
+   In the following implementation, nonzero sizes are doubled so that
+   repeated reallocations have O(N log N) overall cost rather than
+   O(N**2) cost, but the specification for this function does not
+   guarantee that sizes are doubled.
+
+   Here is an example of use:
+
+     int *p = NULL;
+     struct pool *pool;
+     size_t used = 0;
+     size_t allocated = 0;
+
+     void
+     append_int (int value)
+       {
+        if (used == allocated)
+          p = pool_2nrealloc (pool, p, &allocated, sizeof *p);
+        p[used++] = value;
+       }
+
+   This causes x2nrealloc to allocate a block of some nonzero size the
+   first time it is called.
+
+   To have finer-grained control over the initial size, set *PN to a
+   nonzero value before calling this function with P == NULL.  For
+   example:
+
+     int *p = NULL;
+     struct pool *pool;
+     size_t used = 0;
+     size_t allocated = 0;
+     size_t allocated1 = 1000;
+
+     void
+     append_int (int value)
+       {
+        if (used == allocated)
+          {
+            p = pool_2nrealloc (pool, p, &allocated1, sizeof *p);
+            allocated = allocated1;
+          }
+        p[used++] = value;
+       }
+
+   This function implementation is from gnulib. */
+void *
+pool_2nrealloc (struct pool *pool, void *p, size_t *pn, size_t s)
+{
+  size_t n = *pn;
+
+  if (p == NULL)
+    {
+      if (n == 0)
+       {
+         /* The approximate size to use for initial small allocation
+            requests, when the invoking code specifies an old size of
+            zero.  64 bytes is the largest "small" request for the
+            GNU C library malloc.  */
+         enum { DEFAULT_MXFAST = 64 };
+
+         n = DEFAULT_MXFAST / s;
+         n += !n;
+       }
+    }
+  else
+    {
+      if (SIZE_MAX / 2 / s < n)
+       xalloc_die ();
+      n *= 2;
+    }
+
+  *pn = n;
   return pool_realloc (pool, p, n * s);
 }
 




reply via email to

[Prev in Thread] Current Thread [Next in Thread]