Commit d7976a55 authored by Maria Matejka's avatar Maria Matejka
Browse files

TMP

parent 5d4325be
Loading
Loading
Loading
Loading
+25 −5
Original line number Diff line number Diff line
@@ -24,22 +24,42 @@

#define CQ(type_, size_) CQ_N(type_, size_, 2)

#define CQ_PTR_COUNT(buf_) sizeof((buf_)->ptr) / sizeof((buf_)->ptr[0])
#define CQ_PTR_COUNT(buf_) (sizeof((buf_)->ptr) / sizeof((buf_)->ptr[0]))
#define CQ_PTRN(buf_, ptrn_) (&(buf_)->ptr[ptrn_])

#define CQ_BUF_SIZE(buf_) (sizeof((buf_)->buffer) / sizeof((buf_)->buffer[0]))

#define CQ_INIT(buf_, pool_) do { \
  memset((buf_)->buffer, 0, sizeof((buf_)->buffer)); \
  for (uint i_=0; i_<CQ_PTR_COUNT((buf_)); i_++) \
    (buf_)->ptr[i_].acquire = (buf_)->ptr[i_].release = ATOMIC_VAR_INIT(0); \
    CQ_PTRN((buf_), i_)->acquire = CQ_PTRN((buf_), i_)->release = ATOMIC_VAR_INIT(0); \
} while (0)

#define CQ_CLEANUP(buf_) do { \
  u64 val = atomic_load(&((buf_)->ptr[0].acquire)); \
  for (uint i_=0; i_<CQ_PTR_COUNT((buf_)); i_++) { \
    ASSERT(val == atomic_load(&((buf_)->ptr[i_].acquire))); \
    ASSERT(val == atomic_load(&((buf_)->ptr[i_].release))); \
    ASSERT(val == atomic_load(&(CQ_PTRN((buf_), i_)->acquire))); \
    ASSERT(val == atomic_load(&(CQ_PTRN((buf_), i_)->release))); \
  } \
} while (0)

#define CQ_ACQUIRE_TRY(buf_,
#define CQ_RELEASE(buf_, ptrn_, id_, released_) do { \
  released_ = 0; \
  /* Indicate that we're done */ \
  atomic_fetch_or_explicit(&(CQ_PTRN((buf_), (ptrn_))->mask[((id_) % CQ_BUF_SIZE((buf_))) / 64]), (((u64) 1) << ((id_) % 64)), memory_order_acq_rel); \
  /* First, check the release index */ \
  for (u64 release_; (release_ = atomic_load_explicit(&(CQ_PTRN((buf_), (ptrn_))->release), memory_order_acq_rel)) <= (id_); ) { \
    /* Get the first bits from mask */ \
    u64 mask_ = atomic_load_explicit(&(CQ_PTRN((buf_), (ptrn_))->mask[(release_ % CQ_BUF_SIZE((buf_))) / 64]), memory_order_acquire) >> (release_ % 64); \
    /* How many consecutive bits from release index up */ \
    u64 consec = (~mask_) ? u64_log2(mask_ ^ (mask_ + 1)) : 64; \
    if (!consec) \
      break; \
    /* Release what is to be released */ \
    u64 unmask_ = (~mask_) ? : ~(((mask_ ^ (mask_ + 1)) >> 1) << (release_ % 64)); \


  /* 


#endif
+0 −2
Original line number Diff line number Diff line
@@ -541,8 +541,6 @@ struct channel {
  /* Circular buffer for pending imports */
  CQ_N(struct rte_update_data, CHANNEL_QUEUE_SIZE, 3) import_queue;

  

  struct rtable *in_table;		/* Internal table for received routes */
  struct event *reload_event;		/* Event responsible for reloading from in_table */
  struct fib_iterator reload_fit;	/* FIB iterator in in_table used during reloading */
+12 −31
Original line number Diff line number Diff line
@@ -1404,39 +1404,20 @@ rte_unhide_dummy_routes(net *net, rte **dummy)
static void rte_finish_update_hook(struct task *task);

static void
rte_finish_update_schedule(struct rte_update_data *rud, _Bool tail)
rte_finish_update_schedule(struct rte_update_data *rud, u64 id)
{
  struct task *task = &(rud->task);

  struct channel *c = &(rud->channel);
  debug("rte_finish_update_schedule(%p, %d)\n", rud, tail);

  /* Check whether it is to be pushed now.
   * There are two cases.
   * 1. the task was first in list (and therefore is also now),
   *	no rte_finish_update_hook is running on this queue and we shall schedule it.
   * 2. the task was not first in list so it will happen that
   *	rte_finish_update_hook will pick it up in future.
   */
  LOCKED_LIST_LOCK(&(rud->channel->pending_imports), l)
  {
    /* Are we first? Then push it. */
    if (THEAD(l) == rud)
      rud_state_change(rud, RUS_UPDATING, RUS_RECALCULATING);
    else
    {
      /* Otherwise let it be. */
      rud_state_change(rud, RUS_UPDATING, RUS_PENDING_RECALCULATE);
      task = NULL;
    }
  }
  LOCKED_LIST_UNLOCK(&(rud->channel->pending_imports));
  uint released = 0;
  CQ_RELEASE(&(c->import_queue), CIQ_FILTER, id, released);
  if (!released)
    return;
 
  if (task)
  {
    /* Prepare the table-insert task */
    task_init(task, TF_EXCLUSIVE | (tail ? TF_TAIL : 0), rud->channel->table->domain, rte_finish_update_hook);
    task_push(task);
  }
  /* Prepare the table-insert task if needed */
  task_init(&(c->import_finish_task), TF_EXCLUSIVE | (tail ? TF_TAIL : 0), rud->channel->table->domain, rte_finish_update_hook);

  task_push(&(c->import_finish_task));
}

static void
@@ -1475,7 +1456,7 @@ rte_do_update(struct task *task)
  rte_store_tmp_attrs(new, rud->pool);
#undef new

  return rte_finish_update_schedule(rud, 1);
  return rte_finish_update_schedule(rud, ___id);
}

/**
@@ -1550,7 +1531,7 @@ rte_dispatch_update(struct rte_update_data *rud)
      rud->result = RUR_WITHDRAW;

    rud_state_change(rud, RUS_PENDING_UPDATE, RUS_UPDATING);
    rte_finish_update_schedule(rud, 0);
    rte_finish_update_schedule(rud, ___id);
  }
  else
  {