resource.c 2.36 KB
Newer Older
1 2 3 4 5 6 7 8 9 10
/*
 *	BIRD Resource Manager
 *
 *	(c) 1998 Martin Mares <mj@ucw.cz>
 *
 *	Can be freely distributed and used under the terms of the GNU GPL.
 */

#include <stdio.h>
#include <stdlib.h>
11
#include <string.h>
12 13 14 15 16 17 18

#include "nest/bird.h"
#include "lib/resource.h"

struct pool {
  resource r;
  list inside;
19
  char *name;
20 21
};

22 23
static void pool_dump(resource *);
static void pool_free(resource *);
24 25 26 27 28 29 30 31 32 33 34 35 36

static struct resclass pool_class = {
  "Pool",
  sizeof(pool),
  pool_free,
  pool_dump
};

pool root_pool;

static int indent;

pool *
37
rp_new(pool *p, char *name)
38 39
{
  pool *z = ralloc(p, &pool_class);
40
  z->name = name;
41 42 43 44
  init_list(&z->inside);
  return z;
}

45
static void
46 47 48 49 50 51 52 53 54 55 56 57 58 59
pool_free(resource *P)
{
  pool *p = (pool *) P;
  resource *r, *rr;

  r = HEAD(p->inside);
  while (rr = (resource *) r->n.next)
    {
      r->class->free(r);
      xfree(r);
      r = rr;
    }
}

60
static void
61 62 63 64 65
pool_dump(resource *P)
{
  pool *p = (pool *) P;
  resource *r;

66
  debug("%s\n", p->name);
67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
  indent += 3;
  WALK_LIST(r, p->inside)
    rdump(r);
  indent -= 3;
}

void
rfree(void *res)
{
  resource *r = res;

  if (r)
    {
      if (r->n.next)
	rem_node(&r->n);
      r->class->free(r);
      xfree(r);
    }
}

void
rdump(void *res)
{
  char x[16];
  resource *r = res;

  sprintf(x, "%%%ds%%08x ", indent);
  debug(x, "", (int) r);
  if (r)
    {
97
      debug("%s ", r->class->name);
98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117
      r->class->dump(r);
    }
  else
    debug("NULL\n");
}

void *
ralloc(pool *p, struct resclass *c)
{
  resource *r = xmalloc(c->size);

  r->class = c;
  add_tail(&p->inside, &r->n);
  return r;
}

void
resource_init(void)
{
  root_pool.r.class = &pool_class;
118
  root_pool.name = "Root";
119 120 121 122 123 124 125 126 127 128 129 130 131
  init_list(&root_pool.inside);
}

/*
 *	Memory blocks.
 */

struct mblock {
  resource r;
  unsigned size;
  byte data[0];
};

132
static void mbl_free(resource *r)
133 134 135
{
}

136
static void mbl_debug(resource *r)
137 138 139 140 141 142
{
  struct mblock *m = (struct mblock *) r;

  debug("(size=%d)\n", m->size);
}

143
static struct resclass mb_class = {
144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160
  "Memory",
  0,
  mbl_free,
  mbl_debug,
};

void *
mb_alloc(pool *p, unsigned size)
{
  struct mblock *b = xmalloc(sizeof(struct mblock) + size);

  b->r.class = &mb_class;
  add_tail(&p->inside, &b->r.n);
  b->size = size;
  return b->data;
}

161 162 163 164 165 166 167 168
void *
mb_allocz(pool *p, unsigned size)
{
  void *x = mb_alloc(p, size);
  bzero(x, size);
  return x;
}

169 170 171 172 173 174
void
mb_free(void *m)
{
  struct mblock *b = SKIP_BACK(struct mblock, data, m);
  rfree(b);
}