Commit 74c838a8 authored by Ondrej Zajicek (work)'s avatar Ondrej Zajicek (work)
Browse files

Move ID allocator to a separate file and use it also in OSPF

parent 9a70c8d6
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -7,8 +7,10 @@ sha1.h
birdlib.h
bitops.c
bitops.h
ip.h
idm.c
idm.h
ip.c
ip.h
lists.c
lists.h
md5.c

lib/idm.c

0 → 100644
+76 −0
Original line number Diff line number Diff line
/*
 *	BIRD Library -- ID Map
 *
 *	(c) 2013--2015 Ondrej Zajicek <santiago@crfreenet.org>
 *	(c) 2013--2015 CZ.NIC z.s.p.o.
 *
 *	Can be freely distributed and used under the terms of the GNU GPL.
 */

#include <stdlib.h>

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


void
idm_init(struct idm *m, pool *p, uint size)
{
  m->pos = 0;
  m->used = 1;
  m->size = size;
  m->data = mb_allocz(p, m->size * sizeof(u32));

  /* ID 0 is reserved */
  m->data[0] = 1;
}

static inline int u32_cto(uint x) { return ffs(~x) - 1; }

u32
idm_alloc(struct idm *m)
{
  uint i, j;

  for (i = m->pos; i < m->size; i++)
    if (m->data[i] != 0xffffffff)
      goto found;

  /* If we are at least 7/8 full, expand */
  if (m->used > (m->size * 28))
  {
    m->size *= 2;
    m->data = mb_realloc(m->data, m->size * sizeof(u32));
    memset(m->data + i, 0, (m->size - i) * sizeof(u32));
    goto found;
  }

  for (i = 0; i < m->pos; i++)
    if (m->data[i] != 0xffffffff)
      goto found;

  ASSERT(0);

 found:
  ASSERT(i < 0x8000000);

  m->pos = i;
  j = u32_cto(m->data[i]);

  m->data[i] |= (1 << j);
  m->used++;
  return 32 * i + j;
}

void
idm_free(struct idm *m, u32 id)
{
  uint i = id / 32;
  uint j = id % 32;

  ASSERT((i < m->size) && (m->data[i] & (1 << j)));
  m->data[i] &= ~(1 << j);
  m->used--;
}

lib/idm.h

0 → 100644
+25 −0
Original line number Diff line number Diff line
/*
 *	BIRD Library -- ID Map
 *
 *	(c) 2013--2015 Ondrej Zajicek <santiago@crfreenet.org>
 *	(c) 2013--2015 CZ.NIC z.s.p.o.
 *
 *	Can be freely distributed and used under the terms of the GNU GPL.
 */

#ifndef _BIRD_IDM_H_
#define _BIRD_IDM_H_

struct idm
{
  u32 *data;
  u32 pos;
  u32 used;
  u32 size;
};

void idm_init(struct idm *m, pool *p, uint size);
u32 idm_alloc(struct idm *m);
void idm_free(struct idm *m, u32 id);

#endif
+0 −1
Original line number Diff line number Diff line
@@ -36,7 +36,6 @@ struct fib_node {
  struct fib_node *next;		/* Next in hash chain */
  struct fib_iterator *readers;		/* List of readers of this node */
  byte flags;				/* User-defined, will be removed */
  u32 uid;				/* Unique ID based on hash, will be removed */
  net_addr addr[0];
};

+5 −59
Original line number Diff line number Diff line
@@ -52,6 +52,7 @@
#include "nest/attrs.h"
#include "lib/alloca.h"
#include "lib/hash.h"
#include "lib/idm.h"
#include "lib/resource.h"
#include "lib/string.h"

@@ -61,9 +62,7 @@ static slab *rta_slab;
static slab *mpnh_slab;
static slab *rte_src_slab;

/* rte source ID bitmap */
static u32 *src_ids;
static u32 src_id_size, src_id_used, src_id_pos;
static struct idm src_ids;
#define SRC_ID_INIT_SIZE 4

/* rte source hash */
@@ -87,64 +86,11 @@ rte_src_init(void)
{
  rte_src_slab = sl_new(rta_pool, sizeof(struct rte_src));

  src_id_pos = 0;
  src_id_size = SRC_ID_INIT_SIZE;
  src_ids = mb_allocz(rta_pool, src_id_size * sizeof(u32));

 /* ID 0 is reserved */
  src_ids[0] = 1;
  src_id_used = 1;
  idm_init(&src_ids, rta_pool, SRC_ID_INIT_SIZE);

  HASH_INIT(src_hash, rta_pool, RSH_INIT_ORDER);
}

static inline int u32_cto(uint x) { return ffs(~x) - 1; }

static inline u32
rte_src_alloc_id(void)
{
  int i, j;
  for (i = src_id_pos; i < src_id_size; i++)
    if (src_ids[i] != 0xffffffff)
      goto found;

  /* If we are at least 7/8 full, expand */
  if (src_id_used > (src_id_size * 28))
    {
      src_id_size *= 2;
      src_ids = mb_realloc(src_ids, src_id_size * sizeof(u32));
      bzero(src_ids + i, (src_id_size - i) * sizeof(u32));
      goto found;
    }

  for (i = 0; i < src_id_pos; i++)
    if (src_ids[i] != 0xffffffff)
      goto found;

  ASSERT(0);

 found:
  ASSERT(i < 0x8000000);

  src_id_pos = i;
  j = u32_cto(src_ids[i]);

  src_ids[i] |= (1 << j);
  src_id_used++;
  return 32 * i + j;
}

static inline void
rte_src_free_id(u32 id)
{
  int i = id / 32;
  int j = id % 32;

  ASSERT((i < src_id_size) && (src_ids[i] & (1 << j)));
  src_ids[i] &= ~(1 << j);
  src_id_used--;
}


HASH_DEFINE_REHASH_FN(RSH, struct rte_src)

@@ -165,7 +111,7 @@ rt_get_source(struct proto *p, u32 id)
  src = sl_alloc(rte_src_slab);
  src->proto = p;
  src->private_id = id;
  src->global_id = rte_src_alloc_id();
  src->global_id = idm_alloc(&src_ids);
  src->uc = 0;

  HASH_INSERT2(src_hash, RSH, rta_pool, src);
@@ -181,7 +127,7 @@ rt_prune_sources(void)
    if (src->uc == 0)
    {
      HASH_DO_REMOVE(src_hash, RSH, sp);
      rte_src_free_id(src->global_id);
      idm_free(&src_ids, src->global_id);
      sl_free(rte_src_slab, src);
    }
  }
Loading