* limitations under the License.
*/
#define _GNU_SOURCE
-#include <sched.h>
#include <signal.h>
#include <math.h>
return n;
}
+uword
+os_get_ncpus (void)
+{
+ u32 len;
+
+ len = vec_len (vlib_thread_stacks);
+ if (len == 0)
+ return 1;
+ else
+ return len;
+}
+
void
vlib_set_thread_name (char *name)
{
int pthread_setname_np (pthread_t __target_thread, const char *__name);
+ int rv;
pthread_t thread = pthread_self ();
if (thread)
- pthread_setname_np (thread, name);
+ {
+ rv = pthread_setname_np (thread, name);
+ if (rv)
+ clib_warning ("pthread_setname_np returned %d", rv);
+ }
}
static int
unformat_input_t in;
unformat_init_string (&in, (char *) buffer,
strlen ((char *) buffer));
- unformat (&in, "%U", unformat_bitmap_list, &r);
+ if (unformat (&in, "%U", unformat_bitmap_list, &r) != 1)
+ clib_warning ("unformat_bitmap_list failed");
unformat_free (&in);
}
vec_free (buffer);
w->lwp = syscall (SYS_gettid);
tm->n_vlib_mains = 1;
+ if (tm->sched_policy != ~0)
+ {
+ struct sched_param sched_param;
+ if (!sched_getparam (w->lwp, &sched_param))
+ {
+ if (tm->sched_priority != ~0)
+ sched_param.sched_priority = tm->sched_priority;
+ sched_setscheduler (w->lwp, tm->sched_policy, &sched_param);
+ }
+ }
+
/* assign threads to cores and set n_vlib_mains */
tr = tm->next;
}
}
+u32
+unformat_sched_policy (unformat_input_t * input, va_list * args)
+{
+ u32 *r = va_arg (*args, u32 *);
+
+ if (0);
+#define _(v,f,s) else if (unformat (input, s)) *r = SCHED_POLICY_##f;
+ foreach_sched_policy
+#undef _
+ else
+ return 0;
+ return 1;
+}
+
static clib_error_t *
cpu_config (vlib_main_t * vm, unformat_input_t * input)
{
u32 count;
tm->thread_registrations_by_name = hash_create_string (0, sizeof (uword));
+
tm->n_thread_stacks = 1; /* account for main thread */
+ tm->sched_policy = ~0;
+ tm->sched_priority = ~0;
tr = tm->next;
tr->coremask = bitmap;
tr->count = clib_bitmap_count_set_bits (tr->coremask);
}
+ else
+ if (unformat
+ (input, "scheduler-policy %U", unformat_sched_policy,
+ &tm->sched_policy))
+ ;
+ else if (unformat (input, "scheduler-prio %u", &tm->sched_priority))
+ ;
else if (unformat (input, "%s %u", &name, &count))
{
p = hash_get_mem (tm->thread_registrations_by_name, name);
if (p == 0)
- return clib_error_return (0, "no such thread type '%s'", name);
+ return clib_error_return (0, "no such thread type 3 '%s'", name);
tr = (vlib_thread_registration_t *) p[0];
if (tr->fixed_count)
break;
}
+ if (tm->sched_policy != ~0)
+ {
+ if (tm->sched_priority != ~0
+ && (tm->sched_policy == SCHED_FIFO || tm->sched_policy == SCHED_RR))
+ {
+ u32 prio_max = sched_get_priority_max (tm->sched_policy);
+ u32 prio_min = sched_get_priority_min (tm->sched_policy);
+ if (tm->sched_priority > prio_max)
+ tm->sched_priority = prio_max;
+ if (tm->sched_priority < prio_min)
+ tm->sched_priority = prio_min;
+ }
+ else
+ tm->sched_priority = 0;
+ }
tr = tm->next;
if (!tm->thread_prefix)
vlib_node_main_t *nm = &vm->node_main;
u64 cpu_time_now = clib_cpu_time_now ();
+ vec_alloc (nm->pending_interrupt_node_runtime_indices, 32);
+
while (1)
{
vlib_worker_thread_barrier_check ();
cpu_time_now);
}
+ /* Next handle interrupts. */
+ {
+ uword l = _vec_len (nm->pending_interrupt_node_runtime_indices);
+ uword i;
+ if (l > 0)
+ {
+ _vec_len (nm->pending_interrupt_node_runtime_indices) = 0;
+ for (i = 0; i < l; i++)
+ {
+ n = vec_elt_at_index (nm->nodes_by_type[VLIB_NODE_TYPE_INPUT],
+ nm->
+ pending_interrupt_node_runtime_indices
+ [i]);
+ cpu_time_now =
+ dispatch_node (vm, n, VLIB_NODE_TYPE_INPUT,
+ VLIB_NODE_STATE_INTERRUPT,
+ /* frame */ 0,
+ cpu_time_now);
+ }
+ }
+ }
+
if (_vec_len (nm->pending_frames))
{
int i;