Patch to remove segfault on the exiting of a service.
[openais.git] / exec / mempool.c
blob361530e1b6caa27a3f9fc877dc0c0180755abbe5
1 /*
2 * Copyright (c) 2003-2004 MontaVista Software, Inc.
4 * All rights reserved.
6 * Author: Steven Dake (sdake@mvista.com)
8 * This software licensed under BSD license, the text of which follows:
9 *
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.
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <string.h>
37 #include <errno.h>
39 #include "../include/list.h"
40 #include "mempool.h"
42 int mempool_bytes = 0;
44 struct mempool_list {
45 struct list_head free;
46 short free_entries;
47 short used_entries;
50 struct mempool_entry {
51 struct list_head list;
52 int mempool_entry;
53 char mem[0];
56 struct mempool_list mempool_group[MEMPOOL_GROUP_SIZE];
58 #ifdef MEMPOOL_ON
59 int mempool_init (int pool_sizes[MEMPOOL_GROUP_SIZE])
61 int i, j;
62 struct mempool_entry *entry;
63 void *mempool;
64 char *p;
65 int bytes_to_alloc;
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);
75 if (mempool == 0) {
76 return (ENOMEM);
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;
93 p += bytes_to_alloc;
97 return (0);
100 void *mempool_malloc (size_t size)
102 struct mempool_entry *mempool_entry;
103 int i;
104 #ifdef DEBUG
105 int first = 0;
107 int stats_inuse[MEMPOOL_GROUP_SIZE];
108 int stats_avail[MEMPOOL_GROUP_SIZE];
109 int stats_memoryused[MEMPOOL_GROUP_SIZE];
110 #endif
112 for (i = 0; i < MEMPOOL_GROUP_SIZE; i++) {
113 #ifdef DEBUG
114 if (((i << 1) >= size) && first == 0) {
115 first = i;
117 #endif
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);
131 #ifdef DEBUG
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]);
138 #endif
139 return (0);
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;
154 void *new_ptr;
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);
163 if (new_ptr == 0) {
164 return (0);
166 if (ptr) {
167 memcpy (new_ptr, ptr, (1 << mempool_entry->mempool_entry));
168 mempool_free (ptr);
170 ptr = new_ptr;
173 return (ptr);
176 char *mempool_strdup (const char *s)
178 char *mem;
180 mem = mempool_malloc (strlen (s));
181 strcpy (mem, s);
182 return (mem);
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])
190 int i;
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]) {
200 return (0);
203 void *mempool_malloc (size_t size) {
204 return (malloc (size));
206 void mempool_free (void *ptr) {
207 free (ptr);
210 void *mempool_realloc (void *ptr, size_t size) {
211 return (realloc (ptr, size));
214 char *mempool_strdup (const char *s) {
215 return (strdup (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]) {
222 return;
224 #endif