|
|
| version 1.1.2.6, 2012/02/28 09:28:00 | version 1.1.2.8, 2012/02/28 12:01:12 |
|---|---|
| Line 168 void * | Line 168 void * |
| mpool_malloc(mpool_t * __restrict mp, u_int size, const char *memname) | mpool_malloc(mpool_t * __restrict mp, u_int size, const char *memname) |
| { | { |
| struct tagAlloc *m; | struct tagAlloc *m; |
| int idx, align; | int idx; |
| u_int align; | |
| if (!mp) { | if (!mp) { |
| sess_SetErr(EINVAL, "Pool not specified"); | sess_SetErr(EINVAL, "Pool not specified"); |
| Line 231 mpool_malloc(mpool_t * __restrict mp, u_int size, cons | Line 232 mpool_malloc(mpool_t * __restrict mp, u_int size, cons |
| } | } |
| /* | /* |
| * mpool_realloc() Reallocate memory block with new size | |
| * | |
| * @mp = Memory pool | |
| * @data = Allocated memory data | |
| * @newsize = New size of memory block | |
| * @memname = Optional new memory block name | |
| * return: NULL error or !=NULL new reallocated memory block | |
| */ | |
| void * | |
| mpool_realloc(mpool_t * __restrict mp, void * __restrict data, u_int newsize, const char *memname) | |
| { | |
| struct tagAlloc *m, *tmp; | |
| int idx, oidx; | |
| void *p; | |
| u_int align, osize; | |
| /* if !data execute mpool_malloc() */ | |
| if (!data) | |
| return mpool_malloc(mp, newsize, memname); | |
| if (!mp) { | |
| sess_SetErr(EINVAL, "Pool not specified"); | |
| return NULL; | |
| } | |
| /* check address range & sentinel */ | |
| if (MEM_BADADDR(data) || MEM_CORRUPT(data)) { | |
| sess_SetErr(EFAULT, "Corrupted memory address"); | |
| return NULL; | |
| } else { | |
| osize = ((u_int*)data)[-2] * sizeof(u_int); | |
| oidx = BucketIndex(osize); | |
| } | |
| /* prepare new size */ | |
| if (newsize > MEM_ALLOC_MAX) { | |
| sess_SetErr(ENOMEM, "Memory size is too large"); | |
| return NULL; | |
| } else { | |
| newsize = (newsize + 3) & ~3; /* must align to 4 because needed room for sentinels */ | |
| idx = BucketIndex(newsize); | |
| } | |
| mpool_lock(mp); | |
| /* quota */ | |
| if (mp->pool_quota.max && | |
| (mp->pool_quota.curr + (newsize - osize)) > mp->pool_quota.max) { | |
| sess_SetErr(ENOMEM, "Max.allocate memory quota has been reached"); | |
| mpool_unlock(mp); | |
| return NULL; | |
| } | |
| /* find old memory block */ | |
| TAILQ_FOREACH_SAFE(m, &mp->pool_active[oidx], alloc_node, tmp) { | |
| if (mem_data(m, void*) == data && mem_size(m) == osize) { | |
| /* case in different buckets */ | |
| if (oidx != idx) { | |
| TAILQ_REMOVE(&mp->pool_active[oidx], m, alloc_node); | |
| /* statistics */ | |
| mp->pool_calls.alloc--; | |
| } | |
| mp->pool_bytes.alloc -= osize; | |
| break; | |
| } | |
| } | |
| /* memory block not found! */ | |
| if (!m) { | |
| mpool_unlock(mp); | |
| sess_SetErr(EFAULT, "Memory block not found"); | |
| return NULL; | |
| } | |
| /* try to reallocate memory block to new bucket */ | |
| if (oidx != idx) { | |
| align = 1 << (idx + MEM_MIN_BUCKET); | |
| p = realloc(m->alloc_mem, align + 12); | |
| if (!p) { | |
| LOGERR; | |
| /* restore to old bucket pulled memory block for reallocation */ | |
| TAILQ_INSERT_HEAD(&mp->pool_active[oidx], m, alloc_node); | |
| /* statistics */ | |
| mp->pool_calls.alloc++; | |
| mp->pool_bytes.alloc += osize; | |
| mpool_unlock(mp); | |
| return NULL; | |
| } | |
| } | |
| /* quota */ | |
| mp->pool_quota.curr += (newsize - osize); | |
| m->alloc_mem[0] = newsize / sizeof(u_int); | |
| m->alloc_mem[1] = MEM_MAGIC_START; | |
| m->alloc_mem[2 + newsize / sizeof(u_int)] = MEM_MAGIC_STOP; | |
| if (oidx != idx) { | |
| TAILQ_INSERT_HEAD(&mp->pool_active[idx], m, alloc_node); | |
| /* statistics */ | |
| mp->pool_calls.alloc++; | |
| } | |
| mp->pool_bytes.alloc += newsize; | |
| if (memname) | |
| strlcpy(m->alloc_name, memname, sizeof m->alloc_name); | |
| mpool_unlock(mp); | |
| return mem_data(m, void*); | |
| } | |
| /* | |
| * mpool_purge() - Purge memory block cache and release resources | * mpool_purge() - Purge memory block cache and release resources |
| * | * |
| * @mp = Memory pool | * @mp = Memory pool |
| Line 290 int | Line 401 int |
| mpool_free(mpool_t * __restrict mp, void * __restrict data, int purge) | mpool_free(mpool_t * __restrict mp, void * __restrict data, int purge) |
| { | { |
| int idx; | int idx; |
| struct tagAlloc *m; | struct tagAlloc *m, *tmp; |
| if (!mp) { | if (!mp) { |
| sess_SetErr(EINVAL, "Pool not specified"); | sess_SetErr(EINVAL, "Pool not specified"); |
| Line 304 mpool_free(mpool_t * __restrict mp, void * __restrict | Line 415 mpool_free(mpool_t * __restrict mp, void * __restrict |
| idx = BucketIndex(((u_int*)data)[-2] * sizeof(u_int)); | idx = BucketIndex(((u_int*)data)[-2] * sizeof(u_int)); |
| mpool_lock(mp); | mpool_lock(mp); |
| TAILQ_FOREACH(m, &mp->pool_active[idx], alloc_node) | TAILQ_FOREACH_SAFE(m, &mp->pool_active[idx], alloc_node, tmp) |
| if (mem_data(m, void*) == data) { | if (mem_data(m, void*) == data) { |
| TAILQ_REMOVE(&mp->pool_active[idx], m, alloc_node); | TAILQ_REMOVE(&mp->pool_active[idx], m, alloc_node); |
| /* statistics */ | /* statistics */ |
| Line 347 int | Line 458 int |
| mpool_free2(mpool_t * __restrict mp, u_int size, const char *memname, int purge) | mpool_free2(mpool_t * __restrict mp, u_int size, const char *memname, int purge) |
| { | { |
| int idx; | int idx; |
| struct tagAlloc *m; | struct tagAlloc *m, *tmp; |
| if (!mp || !memname) { | if (!mp || !memname) { |
| sess_SetErr(EINVAL, "Pool or memory name is not specified"); | sess_SetErr(EINVAL, "Pool or memory name is not specified"); |
| Line 356 mpool_free2(mpool_t * __restrict mp, u_int size, const | Line 467 mpool_free2(mpool_t * __restrict mp, u_int size, const |
| idx = BucketIndex(size); | idx = BucketIndex(size); |
| mpool_lock(mp); | mpool_lock(mp); |
| TAILQ_FOREACH(m, &mp->pool_active[idx], alloc_node) | TAILQ_FOREACH_SAFE(m, &mp->pool_active[idx], alloc_node, tmp) |
| if (!strcmp(m->alloc_name, memname)) { | if (!strcmp(m->alloc_name, memname)) { |
| TAILQ_REMOVE(&mp->pool_active[idx], m, alloc_node); | TAILQ_REMOVE(&mp->pool_active[idx], m, alloc_node); |
| /* statistics */ | /* statistics */ |
| Line 470 mpool_setquota(mpool_t * __restrict mp, u_long maxmem) | Line 581 mpool_setquota(mpool_t * __restrict mp, u_long maxmem) |
| mpool_purge(mp, 0); | mpool_purge(mp, 0); |
| return ret; | return ret; |
| } | |
| /* | |
| * mpool_getquota() - Get memory quota | |
| * | |
| * @mp = Memory pool | |
| * @currmem = Return current memory | |
| * @maxmem = Return max quota size | |
| * return: none | |
| */ | |
| inline void | |
| mpool_getquota(mpool_t * __restrict mp, u_long *currmem, u_long *maxmem) | |
| { | |
| if (!mp) | |
| return; | |
| if (maxmem) | |
| *maxmem = mp->pool_quota.max; | |
| if (currmem) | |
| *currmem = mp->pool_quota.curr; | |
| } | } |
| /* ----------------------------------------------------------- */ | /* ----------------------------------------------------------- */ |