2 * Copyright (c) 2003-2004 MontaVista Software, Inc.
6 * Author: Steven Dake (sdake@mvista.com)
8 * This software licensed under BSD license, the text of which follows:
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions are met:
13 * - Redistributions of source code must retain the above copyright notice,
14 * this list of conditions and the following disclaimer.
15 * - Redistributions in binary form must reproduce the above copyright notice,
16 * this list of conditions and the following disclaimer in the documentation
17 * and/or other materials provided with the distribution.
18 * - Neither the name of the MontaVista Software, Inc. nor the names of its
19 * contributors may be used to endorse or promote products derived from this
20 * software without specific prior written permission.
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
26 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
32 * THE POSSIBILITY OF SUCH DAMAGE.
39 #include "../include/list.h"
42 int mempool_bytes
= 0;
45 struct list_head free
;
50 struct mempool_entry
{
51 struct list_head list
;
56 struct mempool_list mempool_group
[MEMPOOL_GROUP_SIZE
];
59 int mempool_init (int pool_sizes
[MEMPOOL_GROUP_SIZE
])
62 struct mempool_entry
*entry
;
67 for (i
= 0; i
< MEMPOOL_GROUP_SIZE
; i
++) {
68 for (j
= 0; j
< pool_sizes
[i
]; j
++) {
69 bytes_to_alloc
= sizeof (struct mempool_entry
) + (1 << i
) + 3;
70 bytes_to_alloc
&= 0xFFFFFFFC;
71 mempool_bytes
+= bytes_to_alloc
;
74 mempool
= malloc (mempool_bytes
);
78 memset (mempool
, 0, mempool_bytes
);
80 for (p
= (char *)mempool
, i
= 0; i
< MEMPOOL_GROUP_SIZE
; i
++) {
81 list_init (&mempool_group
[i
].free
);
82 mempool_group
[i
].free_entries
= pool_sizes
[i
];
83 mempool_group
[i
].used_entries
= 0;
85 for (j
= 0; j
< pool_sizes
[i
]; j
++) {
86 entry
= (struct mempool_entry
*)p
;
88 entry
->mempool_entry
= i
;
89 list_add (&entry
->list
, &mempool_group
[i
].free
);
91 bytes_to_alloc
= sizeof (struct mempool_entry
) + (1 << i
) + 3;
92 bytes_to_alloc
&= 0xFFFFFFFC;
100 void *mempool_malloc (size_t size
)
102 struct mempool_entry
*mempool_entry
;
107 int stats_inuse
[MEMPOOL_GROUP_SIZE
];
108 int stats_avail
[MEMPOOL_GROUP_SIZE
];
109 int stats_memoryused
[MEMPOOL_GROUP_SIZE
];
112 for (i
= 0; i
< MEMPOOL_GROUP_SIZE
; i
++) {
114 if (((i
<< 1) >= size
) && first
== 0) {
119 if (((1 << i
) >= size
) &&
120 mempool_group
[i
].free_entries
) {
122 mempool_group
[i
].used_entries
+= 1;
123 mempool_group
[i
].free_entries
-= 1;
124 mempool_entry
= list_entry (mempool_group
[i
].free
.next
,
125 struct mempool_entry
, list
);
126 list_del (mempool_group
[i
].free
.next
);
127 return (&mempool_entry
->mem
);
132 mempool_getstats (stats_inuse
, stats_avail
, stats_memoryused
);
133 printf ("MEMORY POOLS first %d %d:\n", first
, size
);
134 for (i
= 0; i
< MEMPOOL_GROUP_SIZE
; i
++) {
135 printf ("order %d size %d inuse %d avail %d memory used %d\n",
136 i
, 1<<i
, stats_inuse
[i
], stats_avail
[i
], stats_memoryused
[i
]);
142 void mempool_free (void *ptr
) {
143 struct mempool_entry
*mempool_entry
;
145 mempool_entry
= ((struct mempool_entry
*)((unsigned long)(ptr
) - (unsigned long)(&((struct mempool_entry
*)0)->mem
)));
147 mempool_group
[mempool_entry
->mempool_entry
].free_entries
+= 1;
148 mempool_group
[mempool_entry
->mempool_entry
].used_entries
-= 1;
149 list_add (&mempool_entry
->list
, &mempool_group
[mempool_entry
->mempool_entry
].free
);
152 void *mempool_realloc (void *ptr
, size_t size
) {
153 struct mempool_entry
*mempool_entry
;
156 mempool_entry
= ((struct mempool_entry
*)((unsigned long)(ptr
) - (unsigned long)(&((struct mempool_entry
*)0)->mem
)));
158 if (ptr
== 0 || (1 << mempool_entry
->mempool_entry
) < size
) {
160 * Must grow allocated block, copy memory, free old block
162 new_ptr
= (void *)mempool_malloc (size
);
167 memcpy (new_ptr
, ptr
, (1 << mempool_entry
->mempool_entry
));
176 char *mempool_strdup (const char *s
)
180 mem
= mempool_malloc (strlen (s
));
185 void mempool_getstats (
186 int stats_inuse
[MEMPOOL_GROUP_SIZE
],
187 int stats_avail
[MEMPOOL_GROUP_SIZE
],
188 int stats_memoryused
[MEMPOOL_GROUP_SIZE
])
192 for (i
= 0; i
< MEMPOOL_GROUP_SIZE
; i
++) {
193 stats_inuse
[i
] = mempool_group
[i
].used_entries
;
194 stats_avail
[i
] = mempool_group
[i
].free_entries
;
195 stats_memoryused
[i
] = (mempool_group
[i
].used_entries
+ mempool_group
[i
].free_entries
) * (sizeof (struct mempool_entry
) + (1<<i
));
198 #else /* MEMPOOL_ON NOT SET */
199 int mempool_init (int pool_sizes
[MEMPOOL_GROUP_SIZE
]) {
203 void *mempool_malloc (size_t size
) {
204 return (malloc (size
));
206 void mempool_free (void *ptr
) {
210 void *mempool_realloc (void *ptr
, size_t size
) {
211 return (realloc (ptr
, size
));
214 char *mempool_strdup (const char *s
) {
217 void mempool_getstats (
218 int stats_inuse
[MEMPOOL_GROUP_SIZE
],
219 int stats_avail
[MEMPOOL_GROUP_SIZE
],
220 int stats_memoryused
[MEMPOOL_GROUP_SIZE
]) {