1 /* 2 * Copyright (C) 2021 Jakub Kruszona-Zawadzki, Core Technology Sp. z o.o. 3 * 4 * This file is part of MooseFS. 5 * 6 * MooseFS is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation, version 2 (only). 9 * 10 * MooseFS is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with MooseFS; if not, write to the Free Software 17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02111-1301, USA 18 * or visit http://www.gnu.org/licenses/gpl-2.0.html 19 */ 20 21 #ifndef _BUCKETS_H_ 22 #define _BUCKETS_H_ 23 24 25 #ifdef BUCKETS_MMAP_ALLOC 26 #include <sys/mman.h> 27 #define BUCKETS_ALLOC(size) mmap(NULL,size,PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE,-1,0) 28 #define BUCKETS_FREE(p,size) munmap(p,size) 29 #else 30 #define BUCKETS_ALLOC(size) malloc(size) 31 #define BUCKETS_FREE(p,size) free(p) 32 #endif 33 34 #define CREATE_BUCKET_ALLOCATOR(allocator_name,element_type,bucket_size) \ 35 typedef struct _##allocator_name##_bucket { \ 36 element_type bucket[bucket_size]; \ 37 uint32_t firstfree; \ 38 struct _##allocator_name##_bucket *next; \ 39 } allocator_name##_bucket; \ 40 static allocator_name##_bucket *allocator_name##_buckets_head = NULL; \ 41 static void *allocator_name##_free_head = NULL; \ 42 static uint64_t allocator_name##_allocated = 0; \ 43 static uint64_t allocator_name##_used = 0; \ 44 static inline void allocator_name##_free_all(void) { \ 45 allocator_name##_bucket *srb,*nsrb; \ 46 for (srb = allocator_name##_buckets_head ; srb ; srb = nsrb) { \ 47 nsrb = srb->next; \ 48 BUCKETS_FREE(srb,sizeof(allocator_name##_bucket)); \ 49 } \ 50 allocator_name##_buckets_head = NULL; \ 51 allocator_name##_free_head = NULL; \ 52 allocator_name##_allocated = 0; \ 53 allocator_name##_used = 0; \ 54 } \ 55 static inline element_type* allocator_name##_malloc() { \ 56 allocator_name##_bucket *srb; \ 57 element_type *ret; \ 58 if (allocator_name##_free_head) { \ 59 ret = (element_type*)allocator_name##_free_head; \ 60 allocator_name##_free_head = *((void**)(ret)); \ 61 allocator_name##_used += sizeof(element_type); \ 62 return ret; \ 63 } \ 64 if (allocator_name##_buckets_head==NULL || allocator_name##_buckets_head->firstfree==(bucket_size)) { \ 65 srb = (allocator_name##_bucket*)BUCKETS_ALLOC(sizeof(allocator_name##_bucket)); \ 66 passert(srb); \ 67 srb->next = allocator_name##_buckets_head; \ 68 srb->firstfree = 0; \ 69 allocator_name##_buckets_head = srb; \ 70 allocator_name##_allocated += sizeof(allocator_name##_bucket); \ 71 } \ 72 ret = (allocator_name##_buckets_head->bucket)+(allocator_name##_buckets_head->firstfree); \ 73 allocator_name##_buckets_head->firstfree++; \ 74 allocator_name##_used += sizeof(element_type); \ 75 return ret; \ 76 } \ 77 static inline void allocator_name##_free(element_type *p) { \ 78 *((void**)p) = allocator_name##_free_head; \ 79 allocator_name##_free_head = (void*)p; \ 80 allocator_name##_used -= sizeof(element_type); \ 81 } \ 82 static inline void allocator_name##_getusage(uint64_t *allocated,uint64_t *used) { \ 83 *allocated = allocator_name##_allocated ; \ 84 *used = allocator_name##_used ; \ 85 } 86 87 #endif 88