2 Copyright (C) Slava Astashonok <sla@0n.ru>
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License.
7 $Id: mem.c,v 1.4.2.2.2.1 2005/01/29 19:30:41 sla Exp $
23 static pthread_mutex_t mem_mutex = PTHREAD_MUTEX_INITIALIZER;
25 static struct Mem *root;
26 unsigned int total_elements;
27 unsigned int free_elements;
28 static unsigned int element_size;
29 static unsigned int bulk_quantity;
30 static unsigned int limit_memory;
31 unsigned int total_memory;
32 static unsigned int mem_index_table_size;
33 static unsigned int element_table_size;
34 static unsigned int malloc_size;
46 pthread_mutex_lock(&mem_mutex);
49 if (limit_memory && (total_memory + malloc_size) > limit_memory) {
50 #if ((DEBUG) & DEBUG_M)
51 my_log(LOG_DEBUG, "M: limit exhausted");
57 if (!(mptr = calloc(malloc_size, 1))) goto done;
58 iptr = (void *) mptr + sizeof(struct Mem);
60 eptr = (void *) iptr + mem_index_table_size;
62 for (i = 0; i < bulk_quantity; i++) {
70 mptr->free = bulk_quantity - 1;
71 free_elements += mptr->free;
72 total_elements += bulk_quantity;
73 total_memory += malloc_size;
75 mptr->last = (void *) iptr + element_table_size - element_size;
78 #if ((DEBUG) & DEBUG_M)
79 my_log(LOG_DEBUG, "M: alloc bulk: base:%x first:%x last:%x",
80 mptr, mptr->first, mptr->last);
81 my_log(LOG_DEBUG, "M: mem: total: %d (%dKB), free: %d",
82 total_elements, total_memory >> 10, free_elements);
89 while (mptr->free == 0) mptr = mptr->next;
92 iptr = (void *) mptr + sizeof(struct Mem);
94 mptr = iptr[mptr->free];
96 mptr = mptr->first + iptr[mptr->free] * element_size;
100 #if ((DEBUG) & DEBUG_M)
101 my_log(LOG_DEBUG, "M: alloc: %x", mptr);
103 #ifdef MEM_THREADSAFE
104 pthread_mutex_unlock(&mem_mutex);
109 void mem_free(void *eptr)
112 struct Mem *mptr, **pptr;
114 #ifdef MEM_THREADSAFE
115 pthread_mutex_lock(&mem_mutex);
117 #if ((DEBUG) & DEBUG_M)
118 my_log(LOG_DEBUG, "M: free: %x", eptr);
122 while (mptr->first > eptr || mptr->last < eptr) {
126 iptr = (void *) mptr + sizeof(struct Mem);
128 iptr[mptr->free] = eptr;
130 iptr[mptr->free] = (eptr - mptr->first) / element_size;
134 if (mptr->free == bulk_quantity) {
135 #if ((DEBUG) & DEBUG_M)
136 my_log(LOG_DEBUG, "M: free bulk: base:%x first:%x last:%x",
137 mptr, mptr->first, mptr->last);
141 total_elements -= bulk_quantity;
142 free_elements -= bulk_quantity;
143 total_memory -= malloc_size;
144 #if ((DEBUG) & DEBUG_M)
145 my_log(LOG_DEBUG, "M: mem: total: %d (%dKB), free: %d",
146 total_elements, total_memory >> 10, free_elements);
149 #ifdef MEM_THREADSAFE
150 pthread_mutex_unlock(&mem_mutex);
154 int mem_init(unsigned int element, unsigned int bulk, unsigned int limit)
156 bulk_quantity = (unsigned) (mem_index_t) bulk; /* for safety: movzbl, movzwl */
157 mem_index_table_size = sizeof(mem_index_t) * bulk_quantity;
158 element_size = element;
159 element_table_size = element_size * bulk_quantity;
160 malloc_size = sizeof(struct Mem) + mem_index_table_size + element_table_size;
161 limit_memory = limit;
162 #if ((DEBUG) & DEBUG_M)
163 my_log(LOG_DEBUG, "M: init: element size:%d quantity:%d bulk size:%d limit:%d",
164 element_size, bulk_quantity, malloc_size, limit_memory);