alloc.con commit alloc: write out allocator definitions (52604d7)
   1/*
   2 * alloc.c  - specialized allocator for internal objects
   3 *
   4 * Copyright (C) 2006 Linus Torvalds
   5 *
   6 * The standard malloc/free wastes too much space for objects, partly because
   7 * it maintains all the allocation infrastructure (which isn't needed, since
   8 * we never free an object descriptor anyway), but even more because it ends
   9 * up with maximal alignment because it doesn't know what the object alignment
  10 * for the new allocation is.
  11 */
  12#include "cache.h"
  13#include "object.h"
  14#include "blob.h"
  15#include "tree.h"
  16#include "commit.h"
  17#include "tag.h"
  18
  19#define BLOCKING 1024
  20
  21union any_object {
  22        struct object object;
  23        struct blob blob;
  24        struct tree tree;
  25        struct commit commit;
  26        struct tag tag;
  27};
  28
  29struct alloc_state {
  30        int count; /* total number of nodes allocated */
  31        int nr;    /* number of nodes left in current allocation */
  32        void *p;   /* first free node in current allocation */
  33};
  34
  35static inline void *alloc_node(struct alloc_state *s, size_t node_size)
  36{
  37        void *ret;
  38
  39        if (!s->nr) {
  40                s->nr = BLOCKING;
  41                s->p = xmalloc(BLOCKING * node_size);
  42        }
  43        s->nr--;
  44        s->count++;
  45        ret = s->p;
  46        s->p = (char *)s->p + node_size;
  47        memset(ret, 0, node_size);
  48        return ret;
  49}
  50
  51static struct alloc_state blob_state;
  52void *alloc_blob_node(void)
  53{
  54        struct blob *b = alloc_node(&blob_state, sizeof(struct blob));
  55        return b;
  56}
  57
  58static struct alloc_state tree_state;
  59void *alloc_tree_node(void)
  60{
  61        struct tree *t = alloc_node(&tree_state, sizeof(struct tree));
  62        return t;
  63}
  64
  65static struct alloc_state tag_state;
  66void *alloc_tag_node(void)
  67{
  68        struct tag *t = alloc_node(&tag_state, sizeof(struct tag));
  69        return t;
  70}
  71
  72static struct alloc_state object_state;
  73void *alloc_object_node(void)
  74{
  75        struct object *obj = alloc_node(&object_state, sizeof(union any_object));
  76        return obj;
  77}
  78
  79static struct alloc_state commit_state;
  80
  81void *alloc_commit_node(void)
  82{
  83        static int commit_count;
  84        struct commit *c = alloc_node(&commit_state, sizeof(struct commit));
  85        c->index = commit_count++;
  86        return c;
  87}
  88
  89static void report(const char *name, unsigned int count, size_t size)
  90{
  91        fprintf(stderr, "%10s: %8u (%"PRIuMAX" kB)\n",
  92                        name, count, (uintmax_t) size);
  93}
  94
  95#define REPORT(name, type)      \
  96    report(#name, name##_state.count, name##_state.count * sizeof(type) >> 10)
  97
  98void alloc_report(void)
  99{
 100        REPORT(blob, struct blob);
 101        REPORT(tree, struct tree);
 102        REPORT(commit, struct commit);
 103        REPORT(tag, struct tag);
 104        REPORT(object, union any_object);
 105}