├── .gitignore ├── COPYING ├── README ├── SConstruct ├── mpool.c ├── mpool.h └── test ├── SConstruct └── mpool_test.c /.gitignore: -------------------------------------------------------------------------------- 1 | *~ 2 | *.o 3 | *.so 4 | *.a 5 | *.dylib 6 | test/mpool_test 7 | GPATH 8 | GTAGS 9 | GRTAGS 10 | GSYMS 11 | .sconsign.dblite 12 | -------------------------------------------------------------------------------- /COPYING: -------------------------------------------------------------------------------- 1 | In short, mpool is distributed under so called "BSD license", 2 | 3 | Copyright (c) 2009-2010 Tatsuhiko Kubo 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without modification, 7 | are permitted provided that the following conditions are met: 8 | 9 | * Redistributions of source code must retain the above copyright notice, 10 | this list of conditions and the following disclaimer. 11 | 12 | * Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | * Neither the name of the authors nor the names of its contributors 17 | may be used to endorse or promote products derived from this software 18 | without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 26 | TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 27 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 28 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 29 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 30 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | 2 | mpool is the memory pool implimentation written by C with C99 style. 3 | 4 | Copyright(C) 2009-2010 Tatsuhiko Kubo 5 | 6 | 7 | -------------------------------------------------------------------------------- /SConstruct: -------------------------------------------------------------------------------- 1 | target = 'mpool' 2 | sources = [Glob('*.c')] 3 | env = Environment(CPPFLAGS=['-Wall', '-g', '-O2', '-std=c99', '-fPIC']) 4 | test = env.SharedLibrary(target, sources) 5 | -------------------------------------------------------------------------------- /mpool.c: -------------------------------------------------------------------------------- 1 | /** 2 | In short, mpool is distributed under so called "BSD license", 3 | 4 | Copyright (c) 2009-2010 Tatsuhiko Kubo 5 | All rights reserved. 6 | 7 | Redistribution and use in source and binary forms, with or without modification, 8 | are permitted provided that the following conditions are met: 9 | 10 | * Redistributions of source code must retain the above copyright notice, 11 | this list of conditions and the following disclaimer. 12 | 13 | * Redistributions in binary form must reproduce the above copyright notice, 14 | this list of conditions and the following disclaimer in the documentation 15 | and/or other materials provided with the distribution. 16 | 17 | * Neither the name of the authors nor the names of its contributors 18 | may be used to endorse or promote products derived from this software 19 | without specific prior written permission. 20 | 21 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 24 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 27 | TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 28 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 29 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 30 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 31 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 | */ 33 | 34 | /* written by C99 style */ 35 | 36 | #include "mpool.h" 37 | 38 | /** 39 | * private function 40 | */ 41 | static inline bool mpool_extend(mpool_pool_t *p, size_t siz, mpool_t *pool); 42 | static inline size_t mpool_align(size_t siz); 43 | static inline size_t mpool_decide_create_siz(size_t siz); 44 | 45 | /** 46 | * create memory pool 47 | */ 48 | mpool_t *mpool_create (size_t siz) { 49 | mpool_t *pool; 50 | siz = mpool_decide_create_siz(siz); 51 | 52 | pool = malloc(sizeof(*pool)); 53 | if (pool == NULL) { 54 | return NULL; 55 | } 56 | 57 | pool->mpool = malloc(sizeof(*pool->mpool)); 58 | if (pool->mpool == NULL) { 59 | return NULL; 60 | } 61 | 62 | pool->mpool->pool = malloc(siz); 63 | if (pool->mpool->pool == NULL) { 64 | return NULL; 65 | } 66 | 67 | pool->mpool->next = NULL; 68 | 69 | pool->begin = pool->mpool->pool; 70 | pool->head = pool->mpool; 71 | pool->usiz = 0; 72 | pool->msiz = siz; 73 | 74 | return pool; 75 | } 76 | 77 | /** 78 | * allocate memory from memory pool 79 | */ 80 | void *mpool_alloc(size_t siz, mpool_t *pool) { 81 | mpool_pool_t **p = &pool->mpool; 82 | mpool_pool_t *pp = *p; 83 | size_t usiz = mpool_align(pool->usiz + siz); 84 | size_t msiz = pool->msiz; 85 | void *d = pool->begin; 86 | if (usiz > msiz) { 87 | if (!mpool_extend(pp, usiz * 2 + 1, pool)) { 88 | return NULL; 89 | } 90 | pool->usiz = 0; 91 | pool->msiz = usiz * 2; 92 | d = pool->begin; 93 | pool->begin += mpool_align(siz); 94 | *p = pp->next; 95 | } else { 96 | pool->usiz = usiz; 97 | pool->begin += mpool_align(siz); 98 | } 99 | 100 | return d; 101 | } 102 | 103 | /** 104 | * release all memory pool 105 | */ 106 | void mpool_destroy (mpool_t *pool) { 107 | for (mpool_pool_t *cur = pool->head, *next; cur; cur = next){ 108 | next = cur->next; 109 | MPOOL_FREE(cur->pool); 110 | MPOOL_FREE(cur); 111 | } 112 | 113 | MPOOL_FREE(pool); 114 | } 115 | 116 | /* following is private function */ 117 | 118 | /** 119 | * extend memory pool 120 | */ 121 | static inline bool mpool_extend(mpool_pool_t *p, size_t siz, mpool_t *pool) { 122 | siz = mpool_decide_create_siz(siz); 123 | mpool_pool_t *pp; 124 | 125 | pp = malloc(sizeof(*pp)); 126 | if (pp == NULL) { 127 | return false; 128 | } 129 | 130 | pp->pool = malloc(siz); 131 | if (pp->pool == NULL) { 132 | return false; 133 | } 134 | 135 | memset(pp->pool, 0, siz); 136 | 137 | pp->next = NULL; 138 | 139 | p->next = pp; 140 | 141 | pool->begin = pp->pool; 142 | 143 | return true; 144 | } 145 | 146 | /** 147 | * align byte boundary 148 | */ 149 | static inline size_t mpool_align(size_t siz) { 150 | return (siz + (MPOOL_ALIGN_SIZE - 1)) & ~(MPOOL_ALIGN_SIZE - 1); 151 | } 152 | 153 | /** 154 | * decide mpool size 155 | */ 156 | static inline size_t mpool_decide_create_siz(size_t siz) { 157 | return siz <= 0 ? MPOOL_POOL_SIZ : mpool_align(siz); 158 | } 159 | 160 | -------------------------------------------------------------------------------- /mpool.h: -------------------------------------------------------------------------------- 1 | /** 2 | In short, mpool is distributed under so called "BSD license", 3 | 4 | Copyright (c) 2009-2010 Tatsuhiko Kubo 5 | All rights reserved. 6 | 7 | Redistribution and use in source and binary forms, with or without modification, 8 | are permitted provided that the following conditions are met: 9 | 10 | * Redistributions of source code must retain the above copyright notice, 11 | this list of conditions and the following disclaimer. 12 | 13 | * Redistributions in binary form must reproduce the above copyright notice, 14 | this list of conditions and the following disclaimer in the documentation 15 | and/or other materials provided with the distribution. 16 | 17 | * Neither the name of the authors nor the names of its contributors 18 | may be used to endorse or promote products derived from this software 19 | without specific prior written permission. 20 | 21 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 24 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 27 | TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 28 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 29 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 30 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 31 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 | */ 33 | 34 | /* written by C99 style */ 35 | 36 | #ifndef MPOOL_H 37 | #define MPOOL_H 38 | 39 | #include 40 | #include 41 | #include 42 | #include 43 | 44 | #define MPOOL_POOL_SIZ (64 * 1024) 45 | #define MPOOL_ALIGN_SIZE (8) 46 | 47 | #define MPOOL_FREE(p) \ 48 | do { \ 49 | if (p != NULL) { \ 50 | free(p); \ 51 | (p) = NULL; \ 52 | } \ 53 | } while(false) 54 | 55 | /** 56 | * memory pool structure 57 | */ 58 | typedef struct mpool_pool_t { 59 | void *pool; // memory pool field 60 | struct mpool_pool_t *next; // next memory pool's pointer 61 | } mpool_pool_t; 62 | 63 | typedef struct mpool_t { 64 | mpool_pool_t *head; // memory pool's head 65 | void *begin; // data for internal conduct 66 | size_t usiz; // used pool size of current pool 67 | size_t msiz; // max pool size of current pool 68 | mpool_pool_t *mpool; // memory pool 69 | } mpool_t; 70 | 71 | mpool_t *mpool_create (size_t siz); 72 | void *mpool_alloc(size_t siz, mpool_t *pool); 73 | void mpool_destroy (mpool_t *pool); 74 | 75 | #endif 76 | 77 | 78 | -------------------------------------------------------------------------------- /test/SConstruct: -------------------------------------------------------------------------------- 1 | target = 'mpool_test' 2 | sources = [Glob('*.c'), Glob('../*.c')] 3 | env = Environment(CPPFLAGS=['-Wall', '-g', '-O2', '-std=c99'], 4 | LIBS=['cunit'], 5 | CPPPATH='..') 6 | test = env.Program(target, sources) 7 | test_alias = env.Alias('check', test, test[0].abspath) 8 | env.AlwaysBuild(test_alias) 9 | -------------------------------------------------------------------------------- /test/mpool_test.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | #define IS_ALIGNED(ptr) ((uintptr_t)(ptr) % (MPOOL_ALIGN_SIZE) == 0) 14 | 15 | static void mpool_test001(void); 16 | static void mpool_test002(void); 17 | static void mpool_test003(void); 18 | static void mpool_test004(void); 19 | static void mpool_test005(void); 20 | 21 | static void mpool_test001(void){ 22 | mpool_t *pool; 23 | pool = mpool_create(0); 24 | char *c; 25 | c = mpool_alloc(sizeof(*c), pool); 26 | *c = 'a'; 27 | CU_ASSERT(*c == 'a'); 28 | CU_ASSERT(IS_ALIGNED(c)); 29 | mpool_destroy(pool); 30 | } 31 | 32 | static void mpool_test002(void){ 33 | mpool_t *pool; 34 | pool = mpool_create(0); 35 | char *c1; 36 | char *c2; 37 | char *c3; 38 | char *c4; 39 | char *c5; 40 | c1 = mpool_alloc(sizeof(*c1), pool); 41 | c2 = mpool_alloc(sizeof(*c2), pool); 42 | c3 = mpool_alloc(sizeof(*c3), pool); 43 | c4 = mpool_alloc(sizeof(*c4), pool); 44 | c5 = mpool_alloc(sizeof(*c5), pool); 45 | *c1 = 'a'; 46 | *c2 = 'b'; 47 | *c3 = 'c'; 48 | *c4 = 'd'; 49 | *c5 = 'e'; 50 | CU_ASSERT(*c1 == 'a'); 51 | CU_ASSERT(*c2 == 'b'); 52 | CU_ASSERT(*c3 == 'c'); 53 | CU_ASSERT(*c4 == 'd'); 54 | CU_ASSERT(*c5 == 'e'); 55 | 56 | CU_ASSERT(IS_ALIGNED(c1)); 57 | CU_ASSERT(IS_ALIGNED(c2)); 58 | CU_ASSERT(IS_ALIGNED(c3)); 59 | CU_ASSERT(IS_ALIGNED(c4)); 60 | CU_ASSERT(IS_ALIGNED(c5)); 61 | 62 | mpool_destroy(pool); 63 | } 64 | 65 | static void mpool_test003(void){ 66 | mpool_t *pool; 67 | pool = mpool_create(16); 68 | bool *b; 69 | short *s; 70 | char *c; 71 | unsigned char *uc; 72 | int *n; 73 | unsigned int *un; 74 | long *l; 75 | unsigned long *ul; 76 | long long *ll; 77 | unsigned long long *ull; 78 | float *f; 79 | double *d; 80 | long double *ld; 81 | time_t *t; 82 | off_t *ot; 83 | intptr_t *ipt; 84 | size_t *siz; 85 | ptrdiff_t *pdt; 86 | 87 | b = mpool_alloc(sizeof(*b), pool); 88 | s = mpool_alloc(sizeof(*s), pool); 89 | c = mpool_alloc(sizeof(*c), pool); 90 | uc = mpool_alloc(sizeof(*uc), pool); 91 | n = mpool_alloc(sizeof(*n), pool); 92 | un = mpool_alloc(sizeof(*un), pool); 93 | l = mpool_alloc(sizeof(*l), pool); 94 | ul = mpool_alloc(sizeof(*ul), pool); 95 | ll = mpool_alloc(sizeof(*ll), pool); 96 | ull = mpool_alloc(sizeof(*ull), pool); 97 | f = mpool_alloc(sizeof(*f), pool); 98 | d = mpool_alloc(sizeof(*d), pool); 99 | ld = mpool_alloc(sizeof(*ld), pool); 100 | t = mpool_alloc(sizeof(*t), pool); 101 | ot = mpool_alloc(sizeof(*ot), pool); 102 | ipt = mpool_alloc(sizeof(*ipt), pool); 103 | siz = mpool_alloc(sizeof(*siz), pool); 104 | pdt = mpool_alloc(sizeof(*pdt), pool); 105 | 106 | *b = true; 107 | *s = 2; 108 | *c = 'a'; 109 | *uc = 'b'; 110 | *n = 5; 111 | *un = 255; 112 | *l = 550; 113 | *ul = 333; 114 | *ll = 950; 115 | *ull = 111; 116 | *f = 113.5; 117 | *d = 50.8; 118 | *ld = 115.3; 119 | *t = 123; 120 | *ot = 22; 121 | *ipt = 33; 122 | *siz = 55; 123 | *pdt = 150; 124 | 125 | CU_ASSERT(*b == true); 126 | CU_ASSERT(*s == 2); 127 | CU_ASSERT(*c == 'a'); 128 | CU_ASSERT(*uc == 'b'); 129 | CU_ASSERT(*n == 5); 130 | CU_ASSERT(*un == 255); 131 | CU_ASSERT(*l == 550); 132 | CU_ASSERT(*ul == 333); 133 | CU_ASSERT(*ll == 950); 134 | CU_ASSERT(*ull == 111); 135 | CU_ASSERT(*f == 113.5); 136 | CU_ASSERT(*d == 50.8); 137 | CU_ASSERT(*ld == 115.3); 138 | CU_ASSERT(*t == 123); 139 | CU_ASSERT(*ot == 22); 140 | CU_ASSERT(*ipt == 33); 141 | CU_ASSERT(*siz == 55); 142 | CU_ASSERT(*pdt == 150); 143 | 144 | CU_ASSERT(IS_ALIGNED(b)); 145 | CU_ASSERT(IS_ALIGNED(s)); 146 | CU_ASSERT(IS_ALIGNED(c)); 147 | CU_ASSERT(IS_ALIGNED(uc)); 148 | CU_ASSERT(IS_ALIGNED(n)); 149 | CU_ASSERT(IS_ALIGNED(un)); 150 | CU_ASSERT(IS_ALIGNED(l)); 151 | CU_ASSERT(IS_ALIGNED(ul)); 152 | CU_ASSERT(IS_ALIGNED(ll)); 153 | CU_ASSERT(IS_ALIGNED(ull)); 154 | CU_ASSERT(IS_ALIGNED(f)); 155 | CU_ASSERT(IS_ALIGNED(d)); 156 | CU_ASSERT(IS_ALIGNED(ld)); 157 | CU_ASSERT(IS_ALIGNED(t)); 158 | CU_ASSERT(IS_ALIGNED(ot)); 159 | CU_ASSERT(IS_ALIGNED(ipt)); 160 | CU_ASSERT(IS_ALIGNED(siz)); 161 | CU_ASSERT(IS_ALIGNED(pdt)); 162 | 163 | mpool_destroy(pool); 164 | } 165 | 166 | static void mpool_test004(void){ 167 | mpool_t *pool; 168 | pool = mpool_create(0); 169 | const char *cs[] = {"cubicdaiya", "bokko"}; 170 | char *s1; 171 | char *s2; 172 | 173 | s1 = mpool_alloc(strlen(cs[0]) + 1, pool); 174 | s2 = mpool_alloc(strlen(cs[1]) + 1, pool); 175 | strcpy(s1, cs[0]); 176 | strcpy(s2, cs[1]); 177 | CU_ASSERT(strncmp(s1, cs[0], strlen(s1)) == 0); 178 | CU_ASSERT(strncmp(s2, cs[1], strlen(s2)) == 0); 179 | CU_ASSERT(IS_ALIGNED(s1)); 180 | CU_ASSERT(IS_ALIGNED(s2)); 181 | 182 | mpool_destroy(pool); 183 | } 184 | 185 | static void mpool_test005(void){ 186 | mpool_t *pool; 187 | pool = mpool_create(10); 188 | 189 | typedef struct st_s { 190 | int n; 191 | char c; 192 | } st_t; 193 | 194 | st_t *st; 195 | int *n; 196 | st = mpool_alloc(sizeof(*st), pool); 197 | n = mpool_alloc(sizeof(*n), pool); 198 | 199 | st->n = 5; 200 | st->c = 'a'; 201 | *n = 10; 202 | 203 | CU_ASSERT(st->n == 5); 204 | CU_ASSERT(st->c == 'a'); 205 | CU_ASSERT(*n == 10); 206 | 207 | CU_ASSERT(IS_ALIGNED(st)); 208 | CU_ASSERT(IS_ALIGNED(n)); 209 | 210 | mpool_destroy(pool); 211 | } 212 | 213 | int main (int argc, char *argv[]) { 214 | CU_pSuite suite_mpool; 215 | CU_initialize_registry(); 216 | suite_mpool = CU_add_suite("mpool", NULL, NULL); 217 | CU_add_test(suite_mpool, "mpool_test001", mpool_test001); 218 | CU_add_test(suite_mpool, "mpool_test002", mpool_test002); 219 | CU_add_test(suite_mpool, "mpool_test003", mpool_test003); 220 | CU_add_test(suite_mpool, "mpool_test004", mpool_test004); 221 | CU_add_test(suite_mpool, "mpool_test005", mpool_test005); 222 | CU_basic_run_tests(); 223 | CU_cleanup_registry(); 224 | return 0; 225 | } 226 | --------------------------------------------------------------------------------