コード例 #1
0
ファイル: iptimer.c プロジェクト: majek/openonload
/* insert a non-pending timer into the scheduler */
void __ci_ip_timer_set(ci_netif *netif, ci_ip_timer *ts, ci_iptime_t t)
{
  ci_ni_dllist_t* bucket;
  int w;
  ci_iptime_t stime = IPTIMER_STATE(netif)->sched_ticks;

  ci_assert(TIME_GT(t, stime));
  /* this is absolute time */
  ts->time = t;

  if( TIME_LT(t, IPTIMER_STATE(netif)->closest_timer) )
    IPTIMER_STATE(netif)->closest_timer = t;

  /* Previous error in this code was to choose wheel based on time delta 
   * before timer fires (ts->time - stime). This is bogus as the timer wheels
   * work like a clock and we need to find wheel based on the absolute time
   */

  /* insert in wheel 0 if the top 3 wheels have the same time */
  if ((stime & WHEEL0_MASK) == (t & WHEEL0_MASK))
    w = 0;
  /* else, insert in wheel 1 if the top 2 wheels have the same time */
  else if ((stime & WHEEL1_MASK) == (t & WHEEL1_MASK))
    w = 1;
  /* else, insert in wheel 2 if the top wheel has the same time */
  else if ((stime & WHEEL2_MASK) == (t & WHEEL2_MASK))
    w = 2;
  else
    w = 3;

  bucket = BUCKET(netif, w, t);

  LOG_ITV(log("%s: delta=0x%x (t=0x%x-s=0x%x), w=0x%x, b=0x%x", 
         __FUNCTION__, 
         ts->time-stime, ts->time, stime, 
         w, BUCKETNO(w, ts->time)));

  /* append onto the correct bucket 
  **
  ** NB this might not be stable because a later insert with a
  ** smaller relative time will be before an earlier insert with a
  ** larger relative time. Oh well doesn't really matter
  */
  ci_ni_dllist_push_tail(netif, bucket, &ts->link);

  ci_assert(ci_ip_timer_is_link_valid(netif, ts));
  DETAILED_CHECK_TIMERS(netif);
}
コード例 #2
0
ファイル: tcp_synrecv.c プロジェクト: bmschwa/openonload
ci_inline ci_tcp_state*
get_ts_from_cache(ci_netif *netif, 
                  ci_tcp_state_synrecv* tsr, 
                  ci_tcp_socket_listen* tls)
{
  ci_tcp_state *ts = NULL;
#if CI_CFG_FD_CACHING
  if( ci_ni_dllist_not_empty(netif, &tls->epcache.cache) ) {
    /* Take the entry from the cache */
    ci_ni_dllist_link *link = ci_ni_dllist_pop(netif, &tls->epcache.cache);
    ts = CI_CONTAINER (ci_tcp_state, epcache_link, link);
    ci_assert (ts);
    ci_ni_dllist_self_link(netif, &ts->epcache_link);

    LOG_EP(ci_log("Taking cached fd %d off cached list, (onto acceptq)",
           ts->cached_on_fd));

    if( tcp_laddr_be32(ts) == tsr->l_addr ) {
      ci_tcp_state_init(netif, ts, 1);
      /* Shouldn't have touched these bits of state */
      ci_assert(!(ts->s.b.sb_aflags & CI_SB_AFLAG_ORPHAN));
      ci_assert(ci_tcp_is_cached(ts));

      CITP_STATS_NETIF(++netif->state->stats.sockcache_hit);
      CITP_STATS_TCP_LISTEN(++tls->stats.n_sockcache_hit);
    }
    else {
      /* Oh dear -- the tcp-state we cached was using a different local IP
       * address.  This means we've accepted a connection from a different
       * interface as we did for the thing we've cached.  Which means we
       * can't share the hardware filter after all.  For now, just bung it
       * back on the list.
       */
      LOG_EP(ci_log("changed interface of cached EP, re-queueing"));
      ci_ni_dllist_push_tail(netif, &tls->epcache.cache, &ts->epcache_link);
      ts = NULL;
      CITP_STATS_NETIF(++netif->state->stats.sockcache_miss_intmismatch);
    }
  }
#endif
  return ts;
}
コード例 #3
0
ファイル: tcp_synrecv.c プロジェクト: bmschwa/openonload
void ci_tcp_listenq_insert(ci_netif* ni, ci_tcp_socket_listen* tls,
                           ci_tcp_state_synrecv* tsr)
{
  int is_first;

  tls->n_listenq++;

  ci_tcp_listenq_bucket_insert(ni, tls,
                               ci_ni_aux_p2bucket(ni, tls->bucket),
                               tsr, 0);

  if( OO_SP_NOT_NULL(tsr->local_peer) )
    return;

  is_first = ci_ni_dllist_is_empty(ni, &tls->listenq[0]);
  ci_ni_dllist_push_tail(ni, &tls->listenq[0], ci_tcp_synrecv2link(tsr));
  tsr->retries = 0;
  tsr->timeout = ci_tcp_time_now(ni) + NI_CONF(ni).tconst_rto_initial;

  ++tls->n_listenq_new;
  if( is_first )
    ci_tcp_listen_timer_set(ni, tls, tsr->timeout);
}
コード例 #4
0
ファイル: iptimer.c プロジェクト: majek/openonload
/* take the bucket corresponding to time t in the given wheel and 
** reinsert them back into the wheel (i.e. into wheelno -1)
*/
static int ci_ip_timer_cascadewheel(ci_netif* netif, int wheelno,
				     ci_iptime_t stime)
{
  ci_ip_timer* ts;
  ci_ni_dllist_t* bucket;
  oo_p curid, buckid;
  int changed = 0;

  ci_assert(wheelno > 0 && wheelno < CI_IPTIME_WHEELS);
  /* check time is on the boundary expected by the wheel number passed in */
  ci_assert( (stime & ((unsigned)(-1) << (CI_IPTIME_BUCKETBITS*wheelno))) == stime );

  /* bucket to empty */
  bucket = BUCKET(netif, wheelno, stime);
  buckid = ci_ni_dllist_link_addr(netif, &bucket->l);
  curid = bucket->l.next;

  LOG_ITV(log(LN_FMT "cascading wheel=%u sched_ticks=0x%x bucket=%i",
	      LN_PRI_ARGS(netif), wheelno, stime, BUCKETNO(wheelno, stime)));

  /* ditch the timers in this dll, pointers held in curid and buckid */
  ci_ni_dllist_init(netif, bucket,
                    ci_ni_dllist_link_addr(netif, &bucket->l), "timw");

  while( ! OO_P_EQ(curid, buckid) ) {
    ts = ADDR2TIMER(netif, curid);
    
    /* get next in linked list */
    curid = ts->link.next;

#ifndef NDEBUG
    {
      /* if inserting in wheel 0 - top 3 wheels must have the same time */
      if (wheelno == 1)
        ci_assert( (stime & WHEEL0_MASK) == (ts->time & WHEEL0_MASK) );
      /* else, if inserting in wheel 1 - top 2 wheels must have the same time */
      else if (wheelno == 2)
        ci_assert( (stime & WHEEL1_MASK) == (ts->time & WHEEL1_MASK) );
      /* else, if inserting in wheel 2 - the top wheel must have the same time */
      else {
        ci_assert(wheelno == 3);
        ci_assert( (stime & WHEEL2_MASK) == (ts->time & WHEEL2_MASK) );
      }
    }    
#endif

    /* insert ts into wheel below */
    bucket = BUCKET(netif, wheelno-1, ts->time);
    changed = 1;

    /* append onto the correct bucket 
    **
    ** NB this might not be stable because a later insert with a
    ** smaller relative time will be before an earlier insert with a
    ** larger relative time. Oh well doesn't really matter
    */
    ci_ni_dllist_push_tail(netif, bucket, &ts->link);
    ci_assert(ci_ip_timer_is_link_valid(netif, ts));
  }
  return changed;
}