/[pspp]/pspp/src/pool.c
ViewVC logotype

Diff of /pspp/src/pool.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.15 by blp, Thu Nov 3 06:21:46 2005 UTC revision 1.16 by blp, Sat Nov 5 03:45:28 2005 UTC
# Line 97  union align Line 97  union align
97    
98  /* This should be the alignment size used by malloc().  The size of  /* This should be the alignment size used by malloc().  The size of
99     the union above is correct, if not optimal, in all known cases. */     the union above is correct, if not optimal, in all known cases. */
 #if defined (i386) || defined (__i386__)  
 #define ALIGN_SIZE 4            /* Save some extra memory. */  
 #else  
100  #define ALIGN_SIZE sizeof (union align)  #define ALIGN_SIZE sizeof (union align)
 #endif  
101    
102  /* DISCRETE_BLOCKS may be declared as nonzero to prevent  /* DISCRETE_BLOCKS may be declared as nonzero to prevent
103     suballocation of blocks.  This is useful under memory     suballocation of blocks.  This is useful under memory
# Line 245  pool_clear (struct pool *pool) Line 241  pool_clear (struct pool *pool)
241  /* Suballocation routines. */  /* Suballocation routines. */
242    
243  /* Allocates a memory region AMT bytes in size from POOL and returns a  /* Allocates a memory region AMT bytes in size from POOL and returns a
244     pointer to the region's start. */     pointer to the region's start.
245       The region is properly aligned for storing any object. */
246  void *  void *
247  pool_alloc (struct pool *pool, size_t amt)  pool_alloc (struct pool *pool, size_t amt)
248  {  {
249    assert (pool != NULL);    assert (pool != NULL);
250    
251      if (amt == 0)
252        return NULL;
253        
254  #ifndef DISCRETE_BLOCKS  #ifndef DISCRETE_BLOCKS
255    if (amt <= MAX_SUBALLOC)    if (amt <= MAX_SUBALLOC)
# Line 295  pool_alloc (struct pool *pool, size_t am Line 295  pool_alloc (struct pool *pool, size_t am
295      return pool_malloc (pool, amt);      return pool_malloc (pool, amt);
296  }  }
297    
298    /* Allocates a memory region AMT bytes in size from POOL and
299       returns a pointer to the region's start.  The region is not
300       necessarily aligned, so it is most suitable for storing
301       strings. */
302    void *
303    pool_alloc_unaligned (struct pool *pool, size_t amt)
304    {
305      assert (pool != NULL);
306    
307    #ifndef DISCRETE_BLOCKS
308      /* Strings need not be aligned on any boundary, but some
309         operations may be more efficient when they are.  However,
310         that's only going to help with reasonably long strings. */
311      if (amt < ALIGN_SIZE)
312        {
313          if (amt == 0)
314            return NULL;
315          else
316            {
317              struct pool_block *const b = pool->blocks;
318    
319              if (b->ofs + amt <= BLOCK_SIZE)
320                {
321                  void *p = ((char *) b) + b->ofs;
322                  b->ofs += amt;
323                  return p;
324                }
325            }
326        }
327    #endif
328    
329      return pool_alloc (pool, amt);
330    }
331    
332  /* Allocates a memory region N * S bytes in size from POOL and  /* Allocates a memory region N * S bytes in size from POOL and
333     returns a pointer to the region's start.     returns a pointer to the region's start.
334     N must be nonnegative, S must be positive.     N must be nonnegative, S must be positive.
# Line 318  pool_clone (struct pool *pool, const voi Line 352  pool_clone (struct pool *pool, const voi
352    return block;    return block;
353  }  }
354    
355  /* Duplicates STRING, which has LENGTH characters, within POOL,  /* Allocates SIZE bytes of unaligned data in POOL, copies BUFFER
356     and returns a pointer to the duplicate.  LENGTH should not     into it, and returns the new copy. */
357     include the null terminator, which is always added to the  void *
358     duplicate.  For use only with strings, because the returned  pool_clone_unaligned (struct pool *pool, const void *buffer, size_t size)
    pointere may not be aligned properly for other types. */  
 char *  
 pool_strndup (struct pool *pool, const char *string, size_t length)  
359  {  {
360    size_t size;    void *block = pool_alloc_unaligned (pool, size);
361    char *copy;    memcpy (block, buffer, size);
362      return block;
   assert (pool && string);  
   size = length + 1;  
   
   /* Note that strings need not be aligned on any boundary. */  
 #ifndef DISCRETE_BLOCKS  
   {  
     struct pool_block *const b = pool->blocks;  
   
     if (b->ofs + size <= BLOCK_SIZE)  
       {  
         copy = ((char *) b) + b->ofs;  
         b->ofs += size;  
       }  
     else  
       copy = pool_alloc (pool, size);  
   }  
 #else  
   copy = pool_alloc (pool, size);  
 #endif  
   
   memcpy (copy, string, length);  
   copy[length] = '\0';  
   return copy;  
363  }  }
364    
365  /* Duplicates null-terminated STRING, within POOL, and returns a  /* Duplicates null-terminated STRING, within POOL, and returns a
# Line 361  pool_strndup (struct pool *pool, const c Line 369  pool_strndup (struct pool *pool, const c
369  char *  char *
370  pool_strdup (struct pool *pool, const char *string)  pool_strdup (struct pool *pool, const char *string)
371  {  {
372    return pool_strndup (pool, string, strlen (string));    return pool_clone_unaligned (pool, string, strlen (string) + 1);
373  }  }
374    
375  /* Standard allocation routines. */  /* Standard allocation routines. */

Legend:
Removed from v.1.15  
changed lines
  Added in v.1.16

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26