]>
git.proxmox.com Git - libgit2.git/blob - src/pool.c
11 GIT_ALIGN(char data
[GIT_FLEX_ARRAY
], 8);
14 static void *pool_alloc_page(git_pool
*pool
, uint32_t size
);
16 uint32_t git_pool__system_page_size(void)
18 static uint32_t size
= 0;
22 if (git__page_size(&page_size
) < 0)
24 /* allow space for malloc overhead */
25 size
= page_size
- (2 * sizeof(void *)) - sizeof(git_pool_page
);
31 #ifndef GIT_DEBUG_POOL
32 void git_pool_init(git_pool
*pool
, uint32_t item_size
)
35 assert(item_size
>= 1);
37 memset(pool
, 0, sizeof(git_pool
));
38 pool
->item_size
= item_size
;
39 pool
->page_size
= git_pool__system_page_size();
42 void git_pool_clear(git_pool
*pool
)
44 git_pool_page
*scan
, *next
;
46 for (scan
= pool
->pages
; scan
!= NULL
; scan
= next
) {
54 static void *pool_alloc_page(git_pool
*pool
, uint32_t size
)
57 const uint32_t new_page_size
= (size
<= pool
->page_size
) ? pool
->page_size
: size
;
60 if (GIT_ADD_SIZET_OVERFLOW(&alloc_size
, new_page_size
, sizeof(git_pool_page
)) ||
61 !(page
= git__malloc(alloc_size
)))
64 page
->size
= new_page_size
;
65 page
->avail
= new_page_size
- size
;
66 page
->next
= pool
->pages
;
73 static void *pool_alloc(git_pool
*pool
, uint32_t size
)
75 git_pool_page
*page
= pool
->pages
;
78 if (!page
|| page
->avail
< size
)
79 return pool_alloc_page(pool
, size
);
81 ptr
= &page
->data
[page
->size
- page
->avail
];
87 uint32_t git_pool__open_pages(git_pool
*pool
)
91 for (scan
= pool
->pages
; scan
!= NULL
; scan
= scan
->next
) ct
++;
95 bool git_pool__ptr_in_pool(git_pool
*pool
, void *ptr
)
98 for (scan
= pool
->pages
; scan
!= NULL
; scan
= scan
->next
)
99 if ((void *)scan
->data
<= ptr
&&
100 (void *)(((char *)scan
->data
) + scan
->size
) > ptr
)
107 static int git_pool__ptr_cmp(const void * a
, const void * b
)
120 void git_pool_init(git_pool
*pool
, uint32_t item_size
)
123 assert(item_size
>= 1);
125 memset(pool
, 0, sizeof(git_pool
));
126 pool
->item_size
= item_size
;
127 pool
->page_size
= git_pool__system_page_size();
128 git_vector_init(&pool
->allocations
, 100, git_pool__ptr_cmp
);
131 void git_pool_clear(git_pool
*pool
)
133 git_vector_free_deep(&pool
->allocations
);
136 static void *pool_alloc(git_pool
*pool
, uint32_t size
) {
138 if((ptr
= git__malloc(size
)) == NULL
) {
141 git_vector_insert_sorted(&pool
->allocations
, ptr
, NULL
);
145 bool git_pool__ptr_in_pool(git_pool
*pool
, void *ptr
)
148 return git_vector_bsearch(&pos
, &pool
->allocations
, ptr
) != GIT_ENOTFOUND
;
152 void git_pool_swap(git_pool
*a
, git_pool
*b
)
159 memcpy(&temp
, a
, sizeof(temp
));
160 memcpy(a
, b
, sizeof(temp
));
161 memcpy(b
, &temp
, sizeof(temp
));
164 static uint32_t alloc_size(git_pool
*pool
, uint32_t count
)
166 const uint32_t align
= sizeof(void *) - 1;
168 if (pool
->item_size
> 1) {
169 const uint32_t item_size
= (pool
->item_size
+ align
) & ~align
;
170 return item_size
* count
;
173 return (count
+ align
) & ~align
;
176 void *git_pool_malloc(git_pool
*pool
, uint32_t items
)
178 return pool_alloc(pool
, alloc_size(pool
, items
));
181 void *git_pool_mallocz(git_pool
*pool
, uint32_t items
)
183 const uint32_t size
= alloc_size(pool
, items
);
184 void *ptr
= pool_alloc(pool
, size
);
186 memset(ptr
, 0x0, size
);
190 char *git_pool_strndup(git_pool
*pool
, const char *str
, size_t n
)
194 assert(pool
&& str
&& pool
->item_size
== sizeof(char));
196 if ((uint32_t)(n
+ 1) < n
)
199 if ((ptr
= git_pool_malloc(pool
, (uint32_t)(n
+ 1))) != NULL
) {
207 char *git_pool_strdup(git_pool
*pool
, const char *str
)
209 assert(pool
&& str
&& pool
->item_size
== sizeof(char));
210 return git_pool_strndup(pool
, str
, strlen(str
));
213 char *git_pool_strdup_safe(git_pool
*pool
, const char *str
)
215 return str
? git_pool_strdup(pool
, str
) : NULL
;
218 char *git_pool_strcat(git_pool
*pool
, const char *a
, const char *b
)
223 assert(pool
&& pool
->item_size
== sizeof(char));
225 len_a
= a
? strlen(a
) : 0;
226 len_b
= b
? strlen(b
) : 0;
228 if ((ptr
= git_pool_malloc(pool
, (uint32_t)(len_a
+ len_b
+ 1))) != NULL
) {
230 memcpy(ptr
, a
, len_a
);
232 memcpy(((char *)ptr
) + len_a
, b
, len_b
);
233 *(((char *)ptr
) + len_a
+ len_b
) = '\0';