RPM Package Manager, CVS Repository
  http://rpm5.org/cvs/
  ____________________________________________________________________________

  Server: rpm5.org                         Name:   Jeff Johnson
  Root:   /v/rpm/cvs                       Email:  j...@rpm5.org
  Module: rpm                              Date:   17-Mar-2009 23:48:56
  Branch: HEAD                             Handle: 2009031722485501

  Modified files:
    rpm                     CHANGES
    rpm/rpmio               librpmio.vers rpmio.h rpmmalloc.c

  Log:
    - yarn: add a pool allocator.

  Summary:
    Revision    Changes     Path
    1.2829      +1  -0      rpm/CHANGES
    2.94        +4  -0      rpm/rpmio/librpmio.vers
    1.83        +49 -0      rpm/rpmio/rpmio.h
    1.15        +122 -0     rpm/rpmio/rpmmalloc.c
  ____________________________________________________________________________

  patch -p0 <<'@@ .'
  Index: rpm/CHANGES
  ============================================================================
  $ cvs diff -u -r1.2828 -r1.2829 CHANGES
  --- rpm/CHANGES       17 Mar 2009 17:29:50 -0000      1.2828
  +++ rpm/CHANGES       17 Mar 2009 22:48:55 -0000      1.2829
  @@ -1,5 +1,6 @@
   
   5.2a3 -> 5.2a4:
  +    - jbj: yarn: add a pool allocator.
       - devzero2000: add mkdtemp portability function to -lrpmmisc 
       - proyvind: do lazy mkdir of %_builddir, %_rpmdir & %_srcrpmdir when 
doing
        --install for src.rpms as well.
  @@ .
  patch -p0 <<'@@ .'
  Index: rpm/rpmio/librpmio.vers
  ============================================================================
  $ cvs diff -u -r2.93 -r2.94 librpmio.vers
  --- rpm/rpmio/librpmio.vers   16 Mar 2009 14:25:48 -0000      2.93
  +++ rpm/rpmio/librpmio.vers   17 Mar 2009 22:48:56 -0000      2.94
  @@ -306,15 +306,19 @@
       rpmioDigestHashAlgo;
       rpmioDigestPoptTable;
       rpmioFini;
  +    rpmioFreePool;
       rpmioFtsOpts;
       rpmioFtsPoptTable;
  +    rpmioGetPool;
       rpmioHttpAccept;
       rpmioHttpConnectTimeoutSecs;
       rpmioHttpReadTimeoutSecs;
       rpmioHttpUserAgent;
       rpmioInit;
       rpmioMkpath;
  +    rpmioNewPool;
       rpmioPipeOutput;
  +    rpmioPutPool;
       rpmioRootDir;
       rpmKeyringAddKey;
       rpmKeyringFindKeyid;
  @@ .
  patch -p0 <<'@@ .'
  Index: rpm/rpmio/rpmio.h
  ============================================================================
  $ cvs diff -u -r1.82 -r1.83 rpmio.h
  --- rpm/rpmio/rpmio.h 12 Mar 2009 20:01:32 -0000      1.82
  +++ rpm/rpmio/rpmio.h 17 Mar 2009 22:48:56 -0000      1.83
  @@ -734,6 +734,55 @@
        /*...@globals internalState, fileSystem @*/
        /*...@modifies internalState, fileSystem @*/;
   
  +/**
  + */
  +typedef      struct rpmioItem_s * rpmioItem;
  +struct rpmioItem_s {
  +    yarnLock use;
  +    void *pool;
  +};
  +
  +/**
  + */
  +typedef struct rpmioPool_s * rpmioPool;
  +
  +/**
  + * Reclaim memory pool items.
  + * @param pool               memory pool (NULL uses global rpmio pool)
  + * @return           NULL always
  + */
  +/*...@null@*/
  +rpmioPool rpmioFreePool(/*...@only@*//*...@null@*/ rpmioPool pool)
  +     /*...@modifies pool @*/;
  +
  +/**
  + * Create a memory pool.
  + * @param name               pool name
  + * @param size               item size
  + * @param limit              no. of items permitted (-1 for unlimited)
  + * @return           memory pool
  + */
  +rpmioPool rpmioNewPool(const char * name, size_t size, int limit)
  +        /*...@*/;
  +
  +/**
  + * Get unused item from pool, or alloc a new item.
  + * @param pool               memory pool (NULL will always alloc a new item)
  + * @param size               item size
  + * @return           new item
  + */
  +rpmioItem rpmioGetPool(/*...@null@*/ rpmioPool pool, size_t size)
  +        /*...@modifies pool @*/;
  +
  +/**
  + * Put unused item into pool (or free).
  + * @param _item              unused item
  + * @return           NULL always
  + */
  +/*...@null@*/
  +rpmioItem rpmioPutPool(rpmioItem item)
  +        /*...@modifies item @*/;
  +
   #ifdef __cplusplus
   }
   #endif
  @@ .
  patch -p0 <<'@@ .'
  Index: rpm/rpmio/rpmmalloc.c
  ============================================================================
  $ cvs diff -u -r1.14 -r1.15 rpmmalloc.c
  --- rpm/rpmio/rpmmalloc.c     11 Dec 2008 21:55:14 -0000      1.14
  +++ rpm/rpmio/rpmmalloc.c     17 Mar 2009 22:48:56 -0000      1.15
  @@ -3,6 +3,9 @@
    */
   
   #include "system.h"
  +#include <rpmiotypes.h>
  +#include <rpmio.h>
  +#include <rpmlog.h>
   #include "debug.h"
   
   #if defined(WITH_DMALLOC)
  @@ -28,6 +31,125 @@
   }
   /*...@=modfilesys@*/
   
  +/**
  + */
  +struct rpmioPool_s {
  +    yarnLock have;           /*!< unused items available, lock for list */
  +    void *pool;
  +/*...@relnull@*/
  +    rpmioItem head;          /*!< linked list of available items */
  +    rpmioItem * tail;
  +    size_t size;             /*!< size of items in this pool */
  +    int limit;                       /*!< number of new items allowed, or -1 
*/
  +    int made;                        /*!< number of items made */
  +    const char *name;
  +};
  +
  +/*...@unchecked@*/
  +static rpmioPool _rpmioPool;
  +
  +rpmioPool rpmioFreePool(rpmioPool pool)
  +{
  +    if (pool == NULL) {
  +     pool = _rpmioPool;
  +     _rpmioPool = NULL;
  +    }
  +    if (pool != NULL) {
  +     rpmioItem item;
  +     int count = 0;
  +     yarnPossess(pool->have);
  +     while ((item = pool->head) != NULL) {
  +         pool->head = item->pool;    /* XXX pool == next */
  +         if (item->use != NULL)
  +             item->use = yarnFreeLock(item->use);
  +         item = _free(item);
  +         count++;
  +     }
  +     yarnRelease(pool->have);
  +     pool->have = yarnFreeLock(pool->have);
  +     rpmlog(RPMLOG_DEBUG, ("rpm%s: pool alloc'd %d, free'd %d, items.\n"), 
pool->name, pool->made, count);
  +assert(pool->made == count);
  +     pool = _free(pool);
  +    }
  +    return NULL;
  +}
  +
  +rpmioPool rpmioNewPool(const char * name, size_t size, int limit)
  +     /*...@*/
  +{
  +    rpmioPool pool = xcalloc(1, sizeof(*pool));
  +    pool->have = yarnNewLock(0);
  +    pool->pool = NULL;
  +    pool->head = NULL;
  +    pool->tail = &pool->head;
  +    pool->size = size;
  +    pool->limit = limit;
  +    pool->made = 0;
  +    pool->name = name;
  +    rpmlog(RPMLOG_DEBUG, ("rpm%s: pool created.\n"), pool->name);
  +    return pool;
  +}
  +
  +rpmioItem rpmioGetPool(rpmioPool pool, size_t size)
  +{
  +    rpmioItem item;
  +
  +    if (pool != NULL) {
  +     /* if can't create any more, wait for a space to show up */
  +     yarnPossess(pool->have);
  +     if (pool->limit == 0)
  +         yarnWaitFor(pool->have, NOT_TO_BE, 0);
  +
  +     /* if a space is available, pull it from the list and return it */
  +     if (pool->head != NULL) {
  +         item = pool->head;
  +         pool->head = item->pool;    /* XXX pool == next */
  +         if (pool->head == NULL)
  +             pool->tail = &pool->head;
  +         item->pool = pool;          /* remember the pool this belongs to */
  +         yarnTwist(pool->have, BY, -1);      /* one less in pool */
  +         return item;
  +     }
  +
  +     /* nothing available, don't want to wait, make a new item */
  +assert(pool->limit != 0);
  +     if (pool->limit > 0)
  +         pool->limit--;
  +     pool->made++;
  +     yarnRelease(pool->have);
  +    }
  +
  +    item = xcalloc(1, size);
  +    item->use = yarnNewLock(0);              /* XXX newref? */
  +    item->pool = pool;
  +    return item;
  +}
  +
  +rpmioItem rpmioPutPool(rpmioItem item)
  +{
  +    rpmioPool pool;
  +
  +    if ((pool = item->pool) != NULL) {
  +     yarnPossess(pool->have);
  +     item->pool = NULL;              /* XXX pool == next */
  +     *pool->tail = item;
  +     pool->tail = (rpmioItem *)&item->pool;/* XXX pool == next */
  +     yarnTwist(pool->have, BY, 1);
  +     if (item->use != NULL)
  +         yarnTwist(item->use, BY, -1);
  +     return NULL;
  +    }
  +
  +    if (item->use != NULL) {
  +     yarnTwist(item->use, BY, -1);
  +     item->use = yarnFreeLock(item->use);
  +    }
  +    if (pool != NULL && pool->size > 0)
  +     memset(item, 0, pool->size);    /* XXX trash & burn */
  +    item = _free(item);
  +    return NULL;
  +}
  +
   #if !(HAVE_MCHECK_H && defined(__GNUC__)) && !defined(__LCLINT__)
   
   /*...@out@*/ /*...@only@*/ void * xmalloc (size_t size)
  @@ .
______________________________________________________________________
RPM Package Manager                                    http://rpm5.org
CVS Sources Repository                                rpm-cvs@rpm5.org

Reply via email to