+ segment_manager_segment_reader_unlock (sm);
+}
+
+/*
+ * Init segment vm address allocator
+ */
+void
+segment_manager_main_init (void)
+{
+ segment_manager_main_t *sm = &sm_main;
+
+ sm->default_fifo_size = 1 << 12;
+ sm->default_segment_size = 1 << 20;
+ sm->default_app_mq_size = 128;
+ sm->default_max_fifo_size = 4 << 20;
+ sm->default_high_watermark = 80;
+ sm->default_low_watermark = 50;
+}
+
+static u8 *
+format_segment_manager (u8 *s, va_list *args)
+{
+ segment_manager_t *sm = va_arg (*args, segment_manager_t *);
+ int verbose = va_arg (*args, int);
+ app_worker_t *app_wrk;
+ uword max_fifo_size;
+ fifo_segment_t *seg;
+ application_t *app;
+ u8 custom_logic;
+
+ app_wrk = app_worker_get_if_valid (sm->app_wrk_index);
+ app = app_wrk ? application_get (app_wrk->app_index) : 0;
+ custom_logic = (app && (app->cb_fns.fifo_tuning_callback)) ? 1 : 0;
+ max_fifo_size = sm->max_fifo_size;
+
+ s = format (s,
+ "[%u] %v app-wrk: %u segs: %u max-fifo-sz: %U "
+ "wmarks: %u %u %s flags: 0x%x",
+ segment_manager_index (sm), app ? app->name : 0,
+ sm->app_wrk_index, pool_elts (sm->segments), format_memory_size,
+ max_fifo_size, sm->high_watermark, sm->low_watermark,
+ custom_logic ? "custom-tuning" : "no-tuning", sm->flags);
+
+ if (!verbose || !pool_elts (sm->segments))
+ return s;
+
+ s = format (s, "\n\n");
+
+ segment_manager_foreach_segment_w_lock (
+ seg, sm, ({ s = format (s, " *%U", format_fifo_segment, seg, verbose); }));
+
+ return s;
+}
+
+static clib_error_t *
+segment_manager_show_fn (vlib_main_t * vm, unformat_input_t * input,
+ vlib_cli_command_t * cmd)
+{
+ unformat_input_t _line_input, *line_input = &_line_input;
+ segment_manager_main_t *smm = &sm_main;
+ u8 show_segments = 0, verbose = 0;
+ segment_manager_t *sm;
+ u32 sm_index = ~0;
+
+ if (!unformat_user (input, unformat_line_input, line_input))
+ {
+ vlib_cli_output (vm, "%d segment managers allocated",
+ pool_elts (smm->segment_managers));
+ return 0;
+ }
+
+ while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
+ {
+ if (unformat (line_input, "segments"))
+ show_segments = 1;
+ else if (unformat (line_input, "verbose"))
+ verbose = 1;
+ else if (unformat (line_input, "index %u", &sm_index))
+ ;
+ else
+ {
+ vlib_cli_output (vm, "unknown input [%U]", format_unformat_error,
+ line_input);
+ goto done;
+ }
+ }
+
+ if (!pool_elts (smm->segment_managers))
+ goto done;
+
+ if (sm_index != ~0)
+ {
+ sm = segment_manager_get_if_valid (sm_index);
+ if (!sm)
+ {
+ vlib_cli_output (vm, "segment manager %u not allocated", sm_index);
+ goto done;
+ }
+ vlib_cli_output (vm, "%U", format_segment_manager, sm, 1 /* verbose */);
+ goto done;
+ }
+
+ if (verbose || show_segments)
+ {
+ pool_foreach (sm, smm->segment_managers) {
+ vlib_cli_output (vm, "%U", format_segment_manager, sm,
+ show_segments);
+ }
+
+ vlib_cli_output (vm, "\n");
+ }
+
+done:
+
+ unformat_free (line_input);
+
+ return 0;
+}
+
+/* *INDENT-OFF* */
+VLIB_CLI_COMMAND (segment_manager_show_command, static) = {
+ .path = "show segment-manager",
+ .short_help = "show segment-manager [segments][verbose][index <nn>]",
+ .function = segment_manager_show_fn,
+};
+/* *INDENT-ON* */
+
+void
+segment_manager_format_sessions (segment_manager_t * sm, int verbose)
+{
+ vlib_main_t *vm = vlib_get_main ();
+ app_worker_t *app_wrk;
+ fifo_segment_t *fs;
+ const u8 *app_name;
+ int slice_index;
+ u8 *s = 0, *str;
+ svm_fifo_t *f;
+
+ if (!sm)
+ {
+ if (verbose)
+ vlib_cli_output (vm, "%-" SESSION_CLI_ID_LEN "s%-20s%-15s%-10s",
+ "Connection", "App", "API Client", "SegManager");
+ else
+ vlib_cli_output (vm, "%-" SESSION_CLI_ID_LEN "s%-20s", "Connection",
+ "App");
+ return;
+ }
+
+ app_wrk = app_worker_get (sm->app_wrk_index);
+ app_name = application_name_from_index (app_wrk->app_index);
+
+ clib_rwlock_reader_lock (&sm->segments_rwlock);
+
+ /* *INDENT-OFF* */
+ pool_foreach (fs, sm->segments) {
+ for (slice_index = 0; slice_index < fs->n_slices; slice_index++)
+ {
+ f = fifo_segment_get_slice_fifo_list (fs, slice_index);
+ while (f)
+ {
+ u32 session_index, thread_index;
+ session_t *session;
+
+ session_index = f->shr->master_session_index;
+ thread_index = f->master_thread_index;
+
+ session = session_get (session_index, thread_index);
+ str = format (0, "%U", format_session, session, verbose);
+
+ if (verbose)
+ s = format (s, "%-" SESSION_CLI_ID_LEN "v%-20v%-15u%-10u", str,
+ app_name, app_wrk->api_client_index,
+ app_wrk->connects_seg_manager);
+ else
+ s = format (s, "%-" SESSION_CLI_ID_LEN "v%-20v", str, app_name);
+
+ vlib_cli_output (vm, "%v", s);
+ vec_reset_length (s);
+ vec_free (str);
+
+ f = f->next;
+ }
+ vec_free (s);
+ }
+ }
+ /* *INDENT-ON* */
+
+ clib_rwlock_reader_unlock (&sm->segments_rwlock);
+}
+
+void
+segment_manager_set_watermarks (segment_manager_t * sm,
+ u8 high_watermark, u8 low_watermark)
+{
+ ASSERT (high_watermark <= 100 && low_watermark <= 100 &&
+ low_watermark <= high_watermark);
+
+ sm->high_watermark = high_watermark;
+ sm->low_watermark = low_watermark;