Commit 14e7eb6d authored by Maria Matejka's avatar Maria Matejka
Browse files

Resources converted to locked lists.

This commit adds one pointer to every resource, therefore every resource
eats up one more pointer. This is sad, yet affordable.
parent 128fcd42
Loading
Loading
Loading
Loading
+8 −3
Original line number Diff line number Diff line
@@ -10,11 +10,14 @@
#define _BIRD_LOCKED_H_

#include "lib/atomic.h"
#include "lib/worker.h"
#include "lib/lists.h"

typedef _Atomic u64 spinlock;

/* Exporting worker ID for spinlock use */
#define NOWORKER (~((u64) 0))
extern _Thread_local u64 worker_id;

#define SPIN_LOCK(_sp) do { \
  while (1) { \
    u64 noworker = NOWORKER; \
@@ -48,11 +51,13 @@ typedef _Atomic u64 spinlock;
  SPIN_INIT(((list_)->_lsp)); \
} while (0)

#define NODE_IN_LOCKED_LIST(node_) (!!((node_)->_lsp))

#define LOCKED_LIST_LOCK(list_, token) do { typeof(&((list_)->_llist)) token = &((list_)->_llist); SPIN_LOCK((list_)->_lsp); do
#define LOCKED_LIST_UNLOCK(list_) while (0); SPIN_UNLOCK((list_)->_lsp); } while (0)

#define GET_HEAD_LOCKED(list_) ({ \
    TLIST_NODE_TYPE((list_)->_llist) *node_ = NULL; \
    TLIST_NODE_TYPE(&((list_)->_llist)) *node_ = NULL; \
    SPIN_LOCK((list_)->_lsp); \
    if (!TLIST_EMPTY(&((list_)->_llist))) \
      node_ = THEAD(&((list_)->_llist)); \
@@ -68,7 +73,7 @@ typedef _Atomic u64 spinlock;
} while (0)

#define ADD_TAIL_LOCKED(list_, node_) do { \
  node_->_lsp = &((list_)->_lsp); \
  (node_)->_lsp = &((list_)->_lsp); \
  SPIN_LOCK((list_)->_lsp); \
  TADD_TAIL(&((list_)->_llist), node_); \
  SPIN_UNLOCK((list_)->_lsp); \
+37 −18
Original line number Diff line number Diff line
@@ -13,6 +13,7 @@
#include "lib/birdlib.h"
#include "lib/resource.h"
#include "lib/string.h"
#include "lib/locked.h"

/**
 * DOC: Resource pools
@@ -30,7 +31,7 @@

struct pool {
  resource r;
  TLIST(resource) inside;
  LOCKED_LIST(resource) inside;
  const char *name;
};

@@ -65,7 +66,7 @@ rp_new(pool *p, const char *name)
{
  pool *z = ralloc(p, &pool_class);
  z->name = name;
  INIT_TLIST(&z->inside);
  INIT_LOCKED_LIST(&z->inside);
  return z;
}

@@ -75,7 +76,7 @@ pool_free(resource *P)
  pool *p = (pool *) P;
  resource *r;

  WALK_TLIST_DELSAFE(r, &(p->inside))
  while (r = REM_HEAD_LOCKED(&(p->inside)))
    {
      r->class->free(r);
      xfree(r);
@@ -90,8 +91,12 @@ pool_dump(resource *P)

  debug("%s\n", p->name);
  indent += 3;
  WALK_LIST(r, p->inside)
  LOCKED_LIST_LOCK(&(p->inside), l)
  {
    WALK_TLIST(r, l)
      rdump(r);
  }
  LOCKED_LIST_UNLOCK(&(p->inside));
  indent -= 3;
}

@@ -102,8 +107,12 @@ pool_memsize(resource *P)
  resource *r;
  size_t sum = sizeof(pool) + ALLOC_OVERHEAD;

  WALK_LIST(r, p->inside)
  LOCKED_LIST_LOCK(&(p->inside), l)
  {
    WALK_TLIST(r, l)
      sum += rmemsize(r);
  }
  LOCKED_LIST_UNLOCK(&(p->inside));

  return sum;
}
@@ -113,11 +122,20 @@ pool_lookup(resource *P, unsigned long a)
{
  pool *p = (pool *) P;
  resource *r, *q;
  resource *ret = NULL;

  WALK_LIST(r, p->inside)
  LOCKED_LIST_LOCK(&(p->inside), l)
  {
    WALK_TLIST(r, l)
    if (r->class->lookup && (q = r->class->lookup(r, a)))
      return q;
  return NULL;
    {
      ret = q;
      break;
    }
  }
  LOCKED_LIST_UNLOCK(&(p->inside));

  return ret;
}

/**
@@ -134,9 +152,9 @@ void rmove(void *res, pool *p)

  if (r)
    {
      if (TNODE_IN_LIST(r))
        TREM_NODE(r);
      TADD_TAIL(&p->inside, r);
      if (NODE_IN_LOCKED_LIST(r))
	REM_NODE_LOCKED(r);
      ADD_TAIL_LOCKED(&p->inside, r);
    }
}

@@ -158,8 +176,9 @@ rfree(void *res)
  if (!r)
    return;

  if (TNODE_IN_LIST(r))
    TREM_NODE(r);
  if (NODE_IN_LOCKED_LIST(r))
    REM_NODE_LOCKED(r);

  r->class->free(r);
  r->class = NULL;
  xfree(r);
@@ -220,7 +239,7 @@ ralloc(pool *p, struct resclass *c)

  r->class = c;
  if (p)
    TADD_TAIL(&p->inside, r);
    ADD_TAIL_LOCKED(&p->inside, r);
  return r;
}

@@ -259,7 +278,7 @@ resource_init(void)
{
  root_pool.r.class = &pool_class;
  root_pool.name = "Root";
  INIT_TLIST(&root_pool.inside);
  INIT_LOCKED_LIST(&root_pool.inside);
}

/**
@@ -338,7 +357,7 @@ mb_alloc(pool *p, unsigned size)
  struct mblock *b = xmalloc(sizeof(struct mblock) + size);

  b->r.class = &mb_class;
  TADD_TAIL(&p->inside, &b->r);
  ADD_TAIL_LOCKED(&p->inside, &b->r);
  b->size = size;
  return b->data;
}
+2 −1
Original line number Diff line number Diff line
@@ -10,11 +10,12 @@
#define _BIRD_RESOURCE_H_

#include "lib/lists.h"
#include "lib/locked.h"

/* Resource */

typedef struct resource {
  TLIST_NODE(struct resource);	/* Inside resource pool */
  LOCKED_LIST_NODE(struct resource);	/* Inside resource pool */
  struct resclass *class;	/* Resource class */
} resource;

+2 −5
Original line number Diff line number Diff line
@@ -11,6 +11,8 @@

#include "lib/birdlib.h"
#include "lib/atomic.h"
#include "lib/locked.h"
#include "lib/resource.h"

struct config;

@@ -62,11 +64,6 @@ static inline void task_init(struct task *t, enum task_flags tf, struct domain *
  };
}

/* Sometimes it is needed to know the worker ID.
 * Don't rely on it unless you know what you are doing. */
#define NOWORKER (~((u64) 0))
extern _Thread_local u64 worker_id;

/* Initialize the worker queue. Run once and never more. */
void worker_queue_init(void);