From: Jameson Miller <jamill@microsoft.com>
To: git@vger.kernel.org
Cc: gitster@pobox.com, peff@peff.net, Jameson Miller <jamill@microsoft.com>
Subject: [PATCH v2 4/5] Move the reusable parts of memory pool into its own file
Date: Fri, 23 Mar 2018 10:44:07 -0400 [thread overview]
Message-ID: <20180323144408.213145-5-jamill@microsoft.com> (raw)
In-Reply-To: <20180321164152.204869-1-jamill@microsoft.com>
This moves the reusable parts of the memory pool logic used by
fast-import.c into its own file for use by other components.
Signed-off-by: Jameson Miller <jamill@microsoft.com>
---
Makefile | 1 +
fast-import.c | 118 +---------------------------------------------------------
mem-pool.c | 103 ++++++++++++++++++++++++++++++++++++++++++++++++++
mem-pool.h | 34 +++++++++++++++++
4 files changed, 139 insertions(+), 117 deletions(-)
create mode 100644 mem-pool.c
create mode 100644 mem-pool.h
diff --git a/Makefile b/Makefile
index a1d8775adb..1e142b1dd9 100644
--- a/Makefile
+++ b/Makefile
@@ -832,6 +832,7 @@ LIB_OBJS += lockfile.o
LIB_OBJS += log-tree.o
LIB_OBJS += mailinfo.o
LIB_OBJS += mailmap.o
+LIB_OBJS += mem-pool.o
LIB_OBJS += match-trees.o
LIB_OBJS += merge.o
LIB_OBJS += merge-blobs.o
diff --git a/fast-import.c b/fast-import.c
index 519e1cbd7f..36ac5760d6 100644
--- a/fast-import.c
+++ b/fast-import.c
@@ -168,6 +168,7 @@ Format of STDIN stream:
#include "dir.h"
#include "run-command.h"
#include "packfile.h"
+#include "mem-pool.h"
#define PACK_ID_BITS 16
#define MAX_PACK_ID ((1<<PACK_ID_BITS)-1)
@@ -209,26 +210,6 @@ struct last_object {
unsigned no_swap : 1;
};
-struct mp_block {
- struct mp_block *next_block;
- char *next_free;
- char *end;
- uintmax_t space[FLEX_ARRAY]; /* more */
-};
-
-struct mem_pool {
- struct mp_block *mp_block;
-
- /*
- * The amount of available memory to grow the pool by.
- * This size does not include the overhead for the mp_block.
- */
- size_t block_alloc;
-
- /* The total amount of memory allocated by the pool. */
- size_t pool_alloc;
-};
-
struct atom_str {
struct atom_str *next_atom;
unsigned short str_len;
@@ -646,103 +627,6 @@ static unsigned int hc_str(const char *s, size_t len)
return r;
}
-static struct mp_block *mem_pool_alloc_block(struct mem_pool *mem_pool)
-{
- struct mp_block *p;
-
- mem_pool->pool_alloc += sizeof(struct mp_block) + mem_pool->block_alloc;
- p = xmalloc(st_add(sizeof(struct mp_block), mem_pool->block_alloc));
- p->next_block = mem_pool->mp_block;
- p->next_free = (char *)p->space;
- p->end = p->next_free + mem_pool->block_alloc;
- mem_pool->mp_block = p;
-
- return p;
-}
-
-/*
- * Allocates a block of memory with a specific size and
- * appends it to the memory pool's list of blocks.
- *
- * This function is used to allocate blocks with sizes
- * different than the default "block_alloc" size for the mem_pool.
- *
- * There are two use cases:
- * 1) The initial block allocation for a memory pool.
- *
- * 2) large" blocks of a specific size, where the entire memory block
- * is going to be used. This means the block will not have any
- * available memory for future allocations. The block is placed at
- * the end of the list so that it will be the last block searched
- * for available space.
- */
-static struct mp_block *mem_pool_alloc_block_with_size(struct mem_pool *mem_pool, size_t block_alloc)
-{
- struct mp_block *p, *block;
-
- mem_pool->pool_alloc += sizeof(struct mp_block) + block_alloc;
- p = xmalloc(st_add(sizeof(struct mp_block), block_alloc));
-
- block = mem_pool->mp_block;
- if (block) {
- while (block->next_block)
- block = block->next_block;
-
- block->next_block = p;
- } else {
- mem_pool->mp_block = p;
- }
-
- p->next_block = NULL;
- p->next_free = (char *)p->space;
- p->end = p->next_free + block_alloc;
-
- return p;
-}
-
-static void *mem_pool_alloc(struct mem_pool *mem_pool, size_t len)
-{
- struct mp_block *p;
- void *r;
-
- /* round up to a 'uintmax_t' alignment */
- if (len & (sizeof(uintmax_t) - 1))
- len += sizeof(uintmax_t) - (len & (sizeof(uintmax_t) - 1));
-
- p = mem_pool->mp_block;
-
- /*
- * In performance profiling, there was a minor perf benefit to
- * check for available memory in the head block via the if
- * statement, and only going through the loop when needed.
- */
- if (p &&
- (p->end - p->next_free < len)) {
- for (p = p->next_block; p; p = p->next_block)
- if (p->end - p->next_free >= len)
- break;
- }
-
- if (!p) {
- if (len >= (mem_pool->block_alloc / 2))
- p = mem_pool_alloc_block_with_size(mem_pool, len);
- else
- p = mem_pool_alloc_block(mem_pool);
- }
-
- r = p->next_free;
- p->next_free += len;
- return r;
-}
-
-static void *mem_pool_calloc(struct mem_pool *mem_pool, size_t count, size_t size)
-{
- size_t len = st_mult(count, size);
- void *r = mem_pool_alloc(mem_pool, len);
- memset(r, 0, len);
- return r;
-}
-
static char *pool_strdup(const char *s)
{
size_t len = strlen(s) + 1;
diff --git a/mem-pool.c b/mem-pool.c
new file mode 100644
index 0000000000..992e354e12
--- /dev/null
+++ b/mem-pool.c
@@ -0,0 +1,103 @@
+/*
+ * Memory Pool implementation logic.
+ */
+
+#include "cache.h"
+#include "mem-pool.h"
+
+static struct mp_block *mem_pool_alloc_block(struct mem_pool *mem_pool)
+{
+ struct mp_block *p;
+
+ mem_pool->pool_alloc += sizeof(struct mp_block) + mem_pool->block_alloc;
+ p = xmalloc(st_add(sizeof(struct mp_block), mem_pool->block_alloc));
+ p->next_block = mem_pool->mp_block;
+ p->next_free = (char *)p->space;
+ p->end = p->next_free + mem_pool->block_alloc;
+ mem_pool->mp_block = p;
+
+ return p;
+}
+
+/*
+ * Allocates a block of memory with a specific size and
+ * appends it to the memory pool's list of blocks.
+ *
+ * This function is used to allocate blocks with sizes
+ * different than the default "block_alloc" size for the mem_pool.
+ *
+ * There are two use cases:
+ * 1) The initial block allocation for a memory pool.
+ *
+ * 2) large" blocks of a specific size, where the entire memory block
+ * is going to be used. This means the block will not have any
+ * available memory for future allocations. The block is placed at
+ * the end of the list so that it will be the last block searched
+ * for available space.
+ */
+static struct mp_block *mem_pool_alloc_block_with_size(struct mem_pool *mem_pool, size_t block_alloc)
+{
+ struct mp_block *p, *block;
+
+ mem_pool->pool_alloc += sizeof(struct mp_block) + block_alloc;
+ p = xmalloc(st_add(sizeof(struct mp_block), block_alloc));
+
+ block = mem_pool->mp_block;
+ if (block) {
+ while (block->next_block)
+ block = block->next_block;
+
+ block->next_block = p;
+ } else {
+ mem_pool->mp_block = p;
+ }
+
+ p->next_block = NULL;
+ p->next_free = (char *)p->space;
+ p->end = p->next_free + block_alloc;
+
+ return p;
+}
+
+void *mem_pool_alloc(struct mem_pool *mem_pool, size_t len)
+{
+ struct mp_block *p;
+ void *r;
+
+ /* round up to a 'uintmax_t' alignment */
+ if (len & (sizeof(uintmax_t) - 1))
+ len += sizeof(uintmax_t) - (len & (sizeof(uintmax_t) - 1));
+
+ p = mem_pool->mp_block;
+
+ /*
+ * In performance profiling, there was a minor perf benefit to
+ * check for available memory in the head block via the if
+ * statement, and only going through the loop when needed.
+ */
+ if (p &&
+ (p->end - p->next_free < len)) {
+ for (p = p->next_block; p; p = p->next_block)
+ if (p->end - p->next_free >= len)
+ break;
+ }
+
+ if (!p) {
+ if (len >= (mem_pool->block_alloc / 2))
+ p = mem_pool_alloc_block_with_size(mem_pool, len);
+ else
+ p = mem_pool_alloc_block(mem_pool);
+ }
+
+ r = p->next_free;
+ p->next_free += len;
+ return r;
+}
+
+void *mem_pool_calloc(struct mem_pool *mem_pool, size_t count, size_t size)
+{
+ size_t len = st_mult(count, size);
+ void *r = mem_pool_alloc(mem_pool, len);
+ memset(r, 0, len);
+ return r;
+}
diff --git a/mem-pool.h b/mem-pool.h
new file mode 100644
index 0000000000..829ad58ecf
--- /dev/null
+++ b/mem-pool.h
@@ -0,0 +1,34 @@
+#ifndef MEM_POOL_H
+#define MEM_POOL_H
+
+struct mp_block {
+ struct mp_block *next_block;
+ char *next_free;
+ char *end;
+ uintmax_t space[FLEX_ARRAY]; /* more */
+};
+
+struct mem_pool {
+ struct mp_block *mp_block;
+
+ /*
+ * The amount of available memory to grow the pool by.
+ * This size does not include the overhead for the mp_block.
+ */
+ size_t block_alloc;
+
+ /* The total amount of memory allocated by the pool. */
+ size_t pool_alloc;
+};
+
+/*
+ * Alloc memory from the mem_pool.
+ */
+void *mem_pool_alloc(struct mem_pool *pool, size_t len);
+
+/*
+ * Allocate and zero memory from the memory pool.
+ */
+void *mem_pool_calloc(struct mem_pool *pool, size_t count, size_t size);
+
+#endif
--
2.14.3
next prev parent reply other threads:[~2018-03-23 14:45 UTC|newest]
Thread overview: 29+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-03-21 16:41 [PATCH 0/3] Extract memory pool logic into reusable component jameson.miller81
2018-03-21 16:41 ` [PATCH 1/3] fast-import: rename mem_pool to fi_mem_pool jameson.miller81
2018-03-21 16:41 ` [PATCH 2/3] Introduce a reusable memory pool type jameson.miller81
2018-03-21 16:41 ` [PATCH 3/3] fast-import: use built-in mem pool jameson.miller81
2018-03-21 19:27 ` [PATCH 0/3] Extract memory pool logic into reusable component Junio C Hamano
2018-03-23 14:44 ` [PATCH v2 " Jameson Miller
2018-03-23 14:44 ` [PATCH v2 1/5] fast-import: rename mem_pool type to mp_block Jameson Miller
2018-03-23 16:42 ` Junio C Hamano
2018-03-23 14:44 ` [PATCH v2 2/5] fast-import: introduce mem_pool type Jameson Miller
2018-03-23 17:15 ` Junio C Hamano
2018-03-23 14:44 ` [PATCH v2 3/5] fast-import: update pool_* functions to work on local pool Jameson Miller
2018-03-23 17:19 ` Junio C Hamano
2018-03-23 14:44 ` Jameson Miller [this message]
2018-03-23 20:27 ` [PATCH v2 4/5] Move the reusable parts of memory pool into its own file Junio C Hamano
2018-03-23 14:44 ` [PATCH v2 5/5] Expand implementation of mem-pool type Jameson Miller
2018-03-23 20:41 ` Junio C Hamano
2018-03-26 17:03 ` [PATCH v3 0/3] Extract memory pool logic into reusable component Jameson Miller
2018-03-26 17:03 ` [PATCH v3 1/3] fast-import: rename mem_pool type to mp_block Jameson Miller
2018-03-26 17:03 ` [PATCH v3 2/3] fast-import: introduce mem_pool type Jameson Miller
2018-03-26 17:34 ` Eric Sunshine
2018-03-27 16:09 ` Junio C Hamano
2018-03-26 17:03 ` [PATCH v3 3/3] Move reusable parts of memory pool into its own file Jameson Miller
2018-03-27 16:43 ` Junio C Hamano
2018-03-29 14:12 ` Jameson Miller
2018-04-11 18:37 ` [PATCH v4 0/3] Extract memory pool logic into reusable component Jameson Miller
2018-04-17 16:43 ` Jameson Miller
2018-04-11 18:37 ` [PATCH v4 1/3] fast-import: rename mem_pool type to mp_block Jameson Miller
2018-04-11 18:37 ` [PATCH v4 2/3] fast-import: introduce mem_pool type Jameson Miller
2018-04-11 18:37 ` [PATCH v4 3/3] Move reusable parts of memory pool into its own file Jameson Miller
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: http://vger.kernel.org/majordomo-info.html
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20180323144408.213145-5-jamill@microsoft.com \
--to=jamill@microsoft.com \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
--cc=peff@peff.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://80x24.org/mirrors/git.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).