Fix tcp tx buffer allocation
[vpp.git] / src / vlib / node_funcs.h
index f49a8d6..c4c0645 100644 (file)
@@ -46,6 +46,7 @@
 #define included_vlib_node_funcs_h
 
 #include <vppinfra/fifo.h>
+#include <vppinfra/tw_timer_1t_3w_1024sl_ov.h>
 
 /** \brief Get vlib node by index.
  @warning This function will ASSERT if @c i is out of range.
@@ -177,13 +178,29 @@ vlib_node_set_state (vlib_main_t * vm, u32 node_index,
   r->state = new_state;
 }
 
+/** \brief Get node dispatch state.
+ @param vm vlib_main_t pointer, varies by thread
+ @param node_index index of the node
+ @return state for node, see vlib_node_state_t
+*/
+always_inline vlib_node_state_t
+vlib_node_get_state (vlib_main_t * vm, u32 node_index)
+{
+  vlib_node_main_t *nm = &vm->node_main;
+  vlib_node_t *n;
+  n = vec_elt (nm->nodes, node_index);
+  return n->state;
+}
+
 always_inline void
 vlib_node_set_interrupt_pending (vlib_main_t * vm, u32 node_index)
 {
   vlib_node_main_t *nm = &vm->node_main;
   vlib_node_t *n = vec_elt (nm->nodes, node_index);
   ASSERT (n->type == VLIB_NODE_TYPE_INPUT);
+  clib_spinlock_lock_if_init (&nm->pending_interrupt_lock);
   vec_add1 (nm->pending_interrupt_node_runtime_indices, n->runtime_index);
+  clib_spinlock_unlock_if_init (&nm->pending_interrupt_lock);
 }
 
 always_inline vlib_process_t *
@@ -199,9 +216,9 @@ always_inline vlib_frame_t *
 vlib_get_frame_no_check (vlib_main_t * vm, uword frame_index)
 {
   vlib_frame_t *f;
-  u32 cpu_index = frame_index & VLIB_CPU_MASK;
+  u32 thread_index = frame_index & VLIB_CPU_MASK;
   u32 offset = frame_index & VLIB_OFFSET_MASK;
-  vm = vlib_mains ? vlib_mains[cpu_index] : vm;
+  vm = vlib_mains[thread_index];
   f = vm->heap_base + offset;
   return f;
 }
@@ -213,10 +230,10 @@ vlib_frame_index_no_check (vlib_main_t * vm, vlib_frame_t * f)
 
   ASSERT (((uword) f & VLIB_CPU_MASK) == 0);
 
-  vm = vlib_mains ? vlib_mains[f->cpu_index] : vm;
+  vm = vlib_mains[f->thread_index];
 
   i = ((u8 *) f - (u8 *) vm->heap_base);
-  return i | f->cpu_index;
+  return i | f->thread_index;
 }
 
 always_inline vlib_frame_t *
@@ -393,33 +410,35 @@ vlib_frame_t *vlib_get_frame_to_node (vlib_main_t * vm, u32 to_node_index);
 void vlib_put_frame_to_node (vlib_main_t * vm, u32 to_node_index,
                             vlib_frame_t * f);
 
-always_inline vlib_process_t *
-vlib_get_current_process (vlib_main_t * vm)
-{
-  vlib_node_main_t *nm = &vm->node_main;
-  return vec_elt (nm->processes, nm->current_process_index);
-}
-
 always_inline uword
 vlib_in_process_context (vlib_main_t * vm)
 {
   return vm->node_main.current_process_index != ~0;
 }
 
+always_inline vlib_process_t *
+vlib_get_current_process (vlib_main_t * vm)
+{
+  vlib_node_main_t *nm = &vm->node_main;
+  if (vlib_in_process_context (vm))
+    return vec_elt (nm->processes, nm->current_process_index);
+  return 0;
+}
+
 always_inline uword
 vlib_current_process (vlib_main_t * vm)
 {
   return vlib_get_current_process (vm)->node_runtime.node_index;
 }
 
-/** Returns TRUE if a process suspend time is less than 1us
+/** Returns TRUE if a process suspend time is less than 10us
     @param dt - remaining poll time in seconds
-    @returns 1 if dt < 1e-6, 0 otherwise
+    @returns 1 if dt < 10e-6, 0 otherwise
 */
 always_inline uword
 vlib_process_suspend_time_is_zero (f64 dt)
 {
-  return dt < 1e-6;
+  return dt < 10e-6;
 }
 
 /** Suspend a vlib cooperative multi-tasking thread for a period of time
@@ -434,7 +453,6 @@ vlib_process_suspend (vlib_main_t * vm, f64 dt)
   uword r;
   vlib_node_main_t *nm = &vm->node_main;
   vlib_process_t *p = vec_elt (nm->processes, nm->current_process_index);
-  u64 dt_cpu = dt * vm->clib_time.clocks_per_second;
 
   if (vlib_process_suspend_time_is_zero (dt))
     return VLIB_PROCESS_RESUME_LONGJMP_RESUME;
@@ -443,7 +461,8 @@ vlib_process_suspend (vlib_main_t * vm, f64 dt)
   r = clib_setjmp (&p->resume_longjmp, VLIB_PROCESS_RESUME_LONGJMP_SUSPEND);
   if (r == VLIB_PROCESS_RESUME_LONGJMP_SUSPEND)
     {
-      p->resume_cpu_time = clib_cpu_time_now () + dt_cpu;
+      /* expiration time in 10us ticks */
+      p->resume_clock_interval = dt * 1e5;
       clib_longjmp (&p->return_longjmp, VLIB_PROCESS_RETURN_LONGJMP_SUSPEND);
     }
 
@@ -702,8 +721,7 @@ vlib_process_wait_for_event_or_clock (vlib_main_t * vm, f64 dt)
   r = clib_setjmp (&p->resume_longjmp, VLIB_PROCESS_RESUME_LONGJMP_SUSPEND);
   if (r == VLIB_PROCESS_RESUME_LONGJMP_SUSPEND)
     {
-      p->resume_cpu_time = (clib_cpu_time_now ()
-                           + (dt * vm->clib_time.clocks_per_second));
+      p->resume_clock_interval = dt * 1e5;
       clib_longjmp (&p->return_longjmp, VLIB_PROCESS_RETURN_LONGJMP_SUSPEND);
     }
 
@@ -818,7 +836,8 @@ vlib_process_signal_event_helper (vlib_node_main_t * nm,
       p->flags = p_flags | VLIB_PROCESS_RESUME_PENDING;
       vec_add1 (nm->data_from_advancing_timing_wheel, x);
       if (delete_from_wheel)
-       timing_wheel_delete (&nm->timing_wheel, x);
+       TW (tw_timer_stop) ((TWT (tw_timer_wheel) *) nm->timing_wheel,
+                           p->stop_timer_handle);
     }
 
   return data_to_be_written_by_caller;
@@ -879,7 +898,6 @@ vlib_process_signal_event_at_time (vlib_main_t * vm,
   else
     {
       vlib_signal_timed_event_data_t *te;
-      u64 dt_cpu = dt * vm->clib_time.clocks_per_second;
 
       pool_get_aligned (nm->signal_timed_event_data_pool, te, sizeof (te[0]));
 
@@ -895,10 +913,12 @@ vlib_process_signal_event_at_time (vlib_main_t * vm,
       te->process_node_index = n->runtime_index;
       te->event_type_index = t;
 
-      timing_wheel_insert (&nm->timing_wheel, clib_cpu_time_now () + dt_cpu,
-                          vlib_timing_wheel_data_set_timed_event (te -
-                                                                  nm->
-                                                                  signal_timed_event_data_pool));
+      p->stop_timer_handle =
+       TW (tw_timer_start) ((TWT (tw_timer_wheel) *) nm->timing_wheel,
+                            vlib_timing_wheel_data_set_timed_event
+                            (te - nm->signal_timed_event_data_pool),
+                            0 /* timer_id */ ,
+                            (vlib_time_now (vm) + dt) * 1e5);
 
       /* Inline data big enough to hold event? */
       if (te->n_data_bytes < sizeof (te->inline_event_data))
@@ -1052,6 +1072,9 @@ vlib_node_vectors_per_main_loop_as_integer (vlib_main_t * vm, u32 node_index)
 void
 vlib_frame_free (vlib_main_t * vm, vlib_node_runtime_t * r, vlib_frame_t * f);
 
+/* Return the edge index if present, ~0 otherwise */
+uword vlib_node_get_next (vlib_main_t * vm, uword node, uword next_node);
+
 /* Add next node to given node in given slot. */
 uword
 vlib_node_add_next_with_slot (vlib_main_t * vm,