Diff for /libaitsess/src/Attic/mem.c between versions 1.1 and 1.1.2.1

version 1.1, 2012/02/27 20:56:38 version 1.1.2.1, 2012/02/27 20:56:38
Line 0 Line 1
   #include "global.h"
   
   
   /*
    * mpool_init() - Init memory pool
    *
    * return: =NULL error or !=NULL new allocated pool
    */
   mpool_t *
   mpool_init(void)
   {
           mpool_t *mp;
   
           mp = malloc(sizeof(mpool_t));
           if (!mp) {
                   LOGERR;
                   return NULL;
           } else
                   memset(mp, 0, sizeof(mpool_t));
   
           pthread_mutex_init(&mp->pool_mtx, NULL);
           return mp;
   }
   
   /*
    * mpool_destroy() - Destroy memory pool
    *
    * @mp = Memory pool
    * return: none
    */
   void
   mpool_destroy(mpool_t ** __restrict mp)
   {
           struct tagAlloc *m;
           register int i;
   
           if (!mp && !*mp)
                   return;
   
           mpool_lock(*mp);
   
           for (i = 0; i < MEM_BUCKETS; i++) {
                   while ((m = TAILQ_FIRST(&(*mp)->pool_active[i]))) {
                           TAILQ_REMOVE(&(*mp)->pool_active[i], m, alloc_node);
                           if (m->alloc_mem)
                                   free(m->alloc_mem);
                           free(m);
                   }
                   while ((m = TAILQ_FIRST(&(*mp)->pool_inactive[i]))) {
                           TAILQ_REMOVE(&(*mp)->pool_inactive[i], m, alloc_node);
                           if (m->alloc_mem)
                                   free(m->alloc_mem);
                           free(m);
                   }
           }
   
           mpool_unlock(*mp);
           pthread_mutex_destroy(&(*mp)->pool_mtx);
   
           free(*mp);
           *mp = NULL;
   }
   
   /* ----------------------------------------------------------- */
   
   static inline long
   BucketIndex(u_int size)
   {
           register long b;
   
           if (!size--)
                   return 0;               /* min bucket position in array */
   
           for (b = MEM_MIN_BUCKET; b < MEM_MAX_BUCKET; b++)
                   if (!(size >> b))
                           break;
   
           return b - MEM_MIN_BUCKET;      /* convert to bucket array index */
   }
   
   static inline struct tagAlloc *
   pullInactive(mpool_t * __restrict mp, int idx)
   {
           struct tagAlloc *m = NULL;
   
           /* must be locked pool before use this function */ 
           if ((m = TAILQ_FIRST(&mp->pool_inactive[idx]))) {
                   TAILQ_REMOVE(&mp->pool_inactive[idx], m, alloc_node);
   
                   /* clear name */
                   *m->alloc_name = 0;
                   /* clear flags */
                   m->alloc_flags ^= m->alloc_flags;
           }
   
           return m;
   }
   
   /*
    * mpool_malloc() - Memory allocation
    *
    * @mp = Memory pool
    * @size = Size
    * @memname = Optional memory block name
    * return: NULL error or !=NULL ok allocated memory
    */
   void *
   mpool_malloc(mpool_t * __restrict mp, u_int size, const char *memname)
   {
           struct tagAlloc *m;
           int idx, align;
   
           if (!mp) {
                   sess_SetErr(EINVAL, "Pool not specified");
                   return NULL;
           }
           if (size > MEM_ALLOC_MAX) {
                   sess_SetErr(ENOMEM, "Memory size is too large");
                   return NULL;
           } else
                   size = (size + 3) & ~3; /* must align to 4 because needed room for sentinels */
   
           idx = BucketIndex(size);
   
           mpool_lock(mp);
   
           /* get memory from cache if exists */
           if (!(m = pullInactive(mp, idx))) {
                   /* quota */
                   if (mp->pool_quota.max && 
                                   (mp->pool_quota.curr + size) > mp->pool_quota.max) {
                           sess_SetErr(ENOMEM, "Max.allocate memory quota has been reached");
                           mpool_unlock(mp);
                           return NULL;
                   }
   
                   m = malloc(sizeof(struct tagAlloc));
                   if (!m) {
                           LOGERR;
                           mpool_unlock(mp);
                           return NULL;
                   } else
                           memset(m, 0, sizeof(struct tagAlloc));
           }
   
           if (memname)
                   strlcpy(m->alloc_name, memname, sizeof m->alloc_name);
   
           if (!m->alloc_mem) {
                   align = 1 << (idx + MEM_MIN_BUCKET);
                   m->alloc_mem = malloc(align + 12);      /* +12 sentinel bytes */
                   if (!m->alloc_mem) {
                           LOGERR;
                           free(m);
                           mpool_unlock(mp);
                           return NULL;
                   } else  /* quota */
                           mp->pool_quota.curr += size;
           }
   
           m->alloc_mem[0] = size / sizeof(u_int);
           m->alloc_mem[1] = MEM_MAGIC_START;
           m->alloc_mem[2 + size / sizeof(u_int)] = MEM_MAGIC_STOP;
           TAILQ_INSERT_HEAD(&mp->pool_active[idx], m, alloc_node);
           /* statistics */
           mp->pool_calls.alloc++;
           mp->pool_bytes.alloc += size;
   
           mpool_unlock(mp);
           return mem_data(m, void*);
   }
   
   /*
    * mpool_free() Free allocated memory with mpool_alloc()
    *
    * @mp = Memory pool
    * @data = Allocated memory data
    * @purge = if !=0 force release memory block
    * return: <0 error or 0 ok released memory block
    */
   int
   mpool_free(mpool_t * __restrict mp, void * __restrict data, int purge)
   {
           int idx;
           struct tagAlloc *m;
   
           if (!mp) {
                   sess_SetErr(EINVAL, "Pool not specified");
                   return -1;
           }
           /* check address range & sentinel */
           if (MEM_BADADDR(data) || MEM_CORRUPT(data)) {
                   sess_SetErr(EFAULT, "Corrupted memory address");
                   return -2;
           } else
                   idx = BucketIndex(((u_int*)data)[-2]);
   
           mpool_lock(mp);
           TAILQ_FOREACH(m, &mp->pool_active[idx], alloc_node)
                   if (mem_data(m, void*) == data) {
                           TAILQ_REMOVE(&mp->pool_active[idx], m, alloc_node);
   
                           if (!purge) {
                                   TAILQ_INSERT_HEAD(&mp->pool_inactive[idx], m, alloc_node);
                                   /* statistics */
                                   mp->pool_calls.cache++;
                                   mp->pool_bytes.cache += mem_size(m);
                           } else {
                                   if (m->alloc_mem)
                                           free(m->alloc_mem);
                                   free(m);
                                   /* statistics */
                                   mp->pool_calls.free++;
                                   mp->pool_bytes.free += mem_size(m);
                           }
                           break;
                   }
           mpool_unlock(mp);
   
           return 0;
   }
   
   /*
    * mpool_free2() Free allocated memory with mpool_alloc() by size and memory name
    *
    * @mp = Memory pool
    * @size = Allocated memory data size
    * @memname = Memory name
    * @purge = if !=0 force release memory block
    * return: <0 error or 0 ok released memory block
    */
   int
   mpool_free2(mpool_t * __restrict mp, u_int size, const char *memname, int purge)
   {
           int idx;
           struct tagAlloc *m;
   
           if (!mp || !memname) {
                   sess_SetErr(EINVAL, "Pool or memory name is not specified");
                   return -1;
           } else
                   idx = BucketIndex(size);
   
           mpool_lock(mp);
           TAILQ_FOREACH(m, &mp->pool_active[idx], alloc_node)
                   if (!strcmp(m->alloc_name, memname)) {
                           TAILQ_REMOVE(&mp->pool_active[idx], m, alloc_node);
   
                           if (!purge) {
                                   TAILQ_INSERT_HEAD(&mp->pool_inactive[idx], m, alloc_node);
                                   /* statistics */
                                   mp->pool_calls.cache++;
                                   mp->pool_bytes.cache += mem_size(m);
                           } else {
                                   if (m->alloc_mem)
                                           free(m->alloc_mem);
                                   free(m);
                                   /* statistics */
                                   mp->pool_calls.free++;
                                   mp->pool_bytes.free += mem_size(m);
                           }
                           break;
                   }
           mpool_unlock(mp);
   
           return 0;
   }
   
   /*
    * mpool_getmembynam() Find allocated memory block by size and memory name
    *
    * @mp = Memory pool
    * @size = Memory size
    * @memname = Memory name
    * return: NULL error or not found and !=NULL allocated memory 
    */
   inline struct tagAlloc *
   mpool_getmembynam(mpool_t * __restrict mp, u_int size, const char *memname)
   {
           int idx;
           struct tagAlloc *m = NULL;
   
           if (!mp || !memname)
                   return NULL;
   
           idx = BucketIndex(size);
           TAILQ_FOREACH(m, &mp->pool_active[idx], alloc_node)
                   if (!strcmp(m->alloc_name, memname))
                           break;
   
           return mem_data(m, void*);
   }

Removed from v.1.1  
changed lines
  Added in v.1.1.2.1


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>