|
Packit Service |
20376f |
/*
|
|
Packit Service |
20376f |
* Copyright (C) the libgit2 contributors. All rights reserved.
|
|
Packit Service |
20376f |
*
|
|
Packit Service |
20376f |
* This file is part of libgit2, distributed under the GNU GPL v2 with
|
|
Packit Service |
20376f |
* a Linking Exception. For full terms see the included COPYING file.
|
|
Packit Service |
20376f |
*/
|
|
Packit Service |
20376f |
#ifndef INCLUDE_pool_h__
|
|
Packit Service |
20376f |
#define INCLUDE_pool_h__
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
#include "common.h"
|
|
Packit Service |
20376f |
#include "vector.h"
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
typedef struct git_pool_page git_pool_page;
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
#ifndef GIT_DEBUG_POOL
|
|
Packit Service |
20376f |
/**
|
|
Packit Service |
20376f |
* Chunked allocator.
|
|
Packit Service |
20376f |
*
|
|
Packit Service |
20376f |
* A `git_pool` can be used when you want to cheaply allocate
|
|
Packit Service |
20376f |
* multiple items of the same type and are willing to free them
|
|
Packit Service |
20376f |
* all together with a single call. The two most common cases
|
|
Packit Service |
20376f |
* are a set of fixed size items (such as lots of OIDs) or a
|
|
Packit Service |
20376f |
* bunch of strings.
|
|
Packit Service |
20376f |
*
|
|
Packit Service |
20376f |
* Internally, a `git_pool` allocates pages of memory and then
|
|
Packit Service |
20376f |
* deals out blocks from the trailing unused portion of each page.
|
|
Packit Service |
20376f |
* The pages guarantee that the number of actual allocations done
|
|
Packit Service |
20376f |
* will be much smaller than the number of items needed.
|
|
Packit Service |
20376f |
*
|
|
Packit Service |
20376f |
* For examples of how to set up a `git_pool` see `git_pool_init`.
|
|
Packit Service |
20376f |
*/
|
|
Packit Service |
20376f |
typedef struct {
|
|
Packit Service |
20376f |
git_pool_page *pages; /* allocated pages */
|
|
Packit Service |
20376f |
uint32_t item_size; /* size of single alloc unit in bytes */
|
|
Packit Service |
20376f |
uint32_t page_size; /* size of page in bytes */
|
|
Packit Service |
20376f |
} git_pool;
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
#define GIT_POOL_INIT { NULL, 0, 0 }
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
#else
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
/**
|
|
Packit Service |
20376f |
* Debug chunked allocator.
|
|
Packit Service |
20376f |
*
|
|
Packit Service |
20376f |
* Acts just like `git_pool` but instead of actually pooling allocations it
|
|
Packit Service |
20376f |
* passes them through to `git__malloc`. This makes it possible to easily debug
|
|
Packit Service |
20376f |
* systems that use `git_pool` using valgrind.
|
|
Packit Service |
20376f |
*
|
|
Packit Service |
20376f |
* In order to track allocations during the lifetime of the pool we use a
|
|
Packit Service |
20376f |
* `git_vector`. When the pool is deallocated everything in the vector is
|
|
Packit Service |
20376f |
* freed.
|
|
Packit Service |
20376f |
*
|
|
Packit Service |
20376f |
* `API is exactly the same as the standard `git_pool` with one exception.
|
|
Packit Service |
20376f |
* Since we aren't allocating pages to hand out in chunks we can't easily
|
|
Packit Service |
20376f |
* implement `git_pool__open_pages`.
|
|
Packit Service |
20376f |
*/
|
|
Packit Service |
20376f |
typedef struct {
|
|
Packit Service |
20376f |
git_vector allocations;
|
|
Packit Service |
20376f |
uint32_t item_size;
|
|
Packit Service |
20376f |
uint32_t page_size;
|
|
Packit Service |
20376f |
} git_pool;
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
#define GIT_POOL_INIT { GIT_VECTOR_INIT, 0, 0 }
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
#endif
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
/**
|
|
Packit Service |
20376f |
* Initialize a pool.
|
|
Packit Service |
20376f |
*
|
|
Packit Service |
20376f |
* To allocation strings, use like this:
|
|
Packit Service |
20376f |
*
|
|
Packit Service |
20376f |
* git_pool_init(&string_pool, 1);
|
|
Packit Service |
20376f |
* my_string = git_pool_strdup(&string_pool, your_string);
|
|
Packit Service |
20376f |
*
|
|
Packit Service |
20376f |
* To allocate items of fixed size, use like this:
|
|
Packit Service |
20376f |
*
|
|
Packit Service |
20376f |
* git_pool_init(&pool, sizeof(item));
|
|
Packit Service |
20376f |
* my_item = git_pool_malloc(&pool, 1);
|
|
Packit Service |
20376f |
*
|
|
Packit Service |
20376f |
* Of course, you can use this in other ways, but those are the
|
|
Packit Service |
20376f |
* two most common patterns.
|
|
Packit Service |
20376f |
*/
|
|
Packit Service |
20376f |
extern void git_pool_init(git_pool *pool, uint32_t item_size);
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
/**
|
|
Packit Service |
20376f |
* Free all items in pool
|
|
Packit Service |
20376f |
*/
|
|
Packit Service |
20376f |
extern void git_pool_clear(git_pool *pool);
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
/**
|
|
Packit Service |
20376f |
* Swap two pools with one another
|
|
Packit Service |
20376f |
*/
|
|
Packit Service |
20376f |
extern void git_pool_swap(git_pool *a, git_pool *b);
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
/**
|
|
Packit Service |
20376f |
* Allocate space for one or more items from a pool.
|
|
Packit Service |
20376f |
*/
|
|
Packit Service |
20376f |
extern void *git_pool_malloc(git_pool *pool, uint32_t items);
|
|
Packit Service |
20376f |
extern void *git_pool_mallocz(git_pool *pool, uint32_t items);
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
/**
|
|
Packit Service |
20376f |
* Allocate space and duplicate string data into it.
|
|
Packit Service |
20376f |
*
|
|
Packit Service |
20376f |
* This is allowed only for pools with item_size == sizeof(char)
|
|
Packit Service |
20376f |
*/
|
|
Packit Service |
20376f |
extern char *git_pool_strndup(git_pool *pool, const char *str, size_t n);
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
/**
|
|
Packit Service |
20376f |
* Allocate space and duplicate a string into it.
|
|
Packit Service |
20376f |
*
|
|
Packit Service |
20376f |
* This is allowed only for pools with item_size == sizeof(char)
|
|
Packit Service |
20376f |
*/
|
|
Packit Service |
20376f |
extern char *git_pool_strdup(git_pool *pool, const char *str);
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
/**
|
|
Packit Service |
20376f |
* Allocate space and duplicate a string into it, NULL is no error.
|
|
Packit Service |
20376f |
*
|
|
Packit Service |
20376f |
* This is allowed only for pools with item_size == sizeof(char)
|
|
Packit Service |
20376f |
*/
|
|
Packit Service |
20376f |
extern char *git_pool_strdup_safe(git_pool *pool, const char *str);
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
/**
|
|
Packit Service |
20376f |
* Allocate space for the concatenation of two strings.
|
|
Packit Service |
20376f |
*
|
|
Packit Service |
20376f |
* This is allowed only for pools with item_size == sizeof(char)
|
|
Packit Service |
20376f |
*/
|
|
Packit Service |
20376f |
extern char *git_pool_strcat(git_pool *pool, const char *a, const char *b);
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
/*
|
|
Packit Service |
20376f |
* Misc utilities
|
|
Packit Service |
20376f |
*/
|
|
Packit Service |
20376f |
#ifndef GIT_DEBUG_POOL
|
|
Packit Service |
20376f |
extern uint32_t git_pool__open_pages(git_pool *pool);
|
|
Packit Service |
20376f |
#endif
|
|
Packit Service |
20376f |
extern bool git_pool__ptr_in_pool(git_pool *pool, void *ptr);
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
#endif
|