<commit_before>// Licensed GNU LGPL v2.1 or later: http://www.gnu.org/licenses/lgpl.html
#include "bstprofiler.hh"
#include <string.h>
/* --- thread view --- */
enum {
  TCOL_NAME,
  TCOL_TID,
  TCOL_PROC,
  TCOL_PRIO,
  TCOL_PERC,
  TCOL_UTIME,
  TCOL_STIME,
  N_TCOLS
};
/* --- variables --- */
static GtkWidget     *profiler_dialog = NULL;
static GxkRadget     *profiler = NULL;
static guint          timer_id = 0;
static guint          n_thread_infos = 0;
static BseThreadInfo *thread_infos = NULL;
/* --- funtions --- */
#if 0
static gchar
char_state_from_thread_state (BseThreadState thread_state)
{
  switch (thread_state)
    {
    default:
    case BSE_THREAD_STATE_UNKNOWN:      return SFI_THREAD_UNKNOWN;
    case BSE_THREAD_STATE_RUNNING:      return SFI_THREAD_RUNNING;
    case BSE_THREAD_STATE_SLEEPING:     return SFI_THREAD_SLEEPING;
    case BSE_THREAD_STATE_DISKWAIT:     return SFI_THREAD_DISKWAIT;
    case BSE_THREAD_STATE_TRACED:       return SFI_THREAD_TRACED;
    case BSE_THREAD_STATE_PAGING:       return SFI_THREAD_PAGING;
    case BSE_THREAD_STATE_ZOMBIE:       return SFI_THREAD_ZOMBIE;
    case BSE_THREAD_STATE_DEAD:         return SFI_THREAD_DEAD;
    }
}
#endif
static BseThreadState
thread_state_from_char_state (gchar thread_state)
{
  switch (thread_state)
    {
    default:
    case SFI_THREAD_UNKNOWN:    return BSE_THREAD_STATE_UNKNOWN;
    case SFI_THREAD_RUNNING:    return BSE_THREAD_STATE_RUNNING;
    case SFI_THREAD_SLEEPING:   return BSE_THREAD_STATE_SLEEPING;
    case SFI_THREAD_DISKWAIT:   return BSE_THREAD_STATE_DISKWAIT;
    case SFI_THREAD_TRACED:     return BSE_THREAD_STATE_TRACED;
    case SFI_THREAD_PAGING:     return BSE_THREAD_STATE_PAGING;
    case SFI_THREAD_ZOMBIE:     return BSE_THREAD_STATE_ZOMBIE;
    case SFI_THREAD_DEAD:       return BSE_THREAD_STATE_DEAD;
    }
}
static void
thread_info_cell_fill_value (GtkWidget *profiler,
                             guint      column,
                             guint      row,
                             GValue    *value)
{
  BseThreadInfo *info = thread_infos + row;
  switch (column)
    {
    case TCOL_NAME:
      sfi_value_take_string (value, g_strdup_printf ("%s", info->name));
      break;
    case TCOL_PROC:
      sfi_value_take_string (value, info->processor ? g_strdup_printf ("%d", info->processor) : g_strdup (""));
      break;
    case TCOL_TID:
      sfi_value_take_string (value, info->thread_id ? g_strdup_printf ("%u", info->thread_id) : g_strdup (""));
      break;
    case TCOL_PRIO:
      sfi_value_take_string (value, info->thread_id ? g_strdup_printf ("%d", info->priority) : g_strdup (""));
      break;
    case TCOL_PERC:
      sfi_value_take_string (value, g_strdup_printf ("%5.2f%%", (info->utime + info->stime) * 0.0001));
      break;
    case TCOL_UTIME:
      sfi_value_take_string (value, g_strdup_printf ("%7.3f", info->utime * 0.001));
      break;
    case TCOL_STIME:
      sfi_value_take_string (value, g_strdup_printf ("%7.3f", info->stime * 0.001));
      break;
    }
}
static void
update_infos (GSList         *slist,
              GxkListWrapper *lw)
{
  guint i, n = g_slist_length (slist) + 1;
  while (n_thread_infos > n)
    {
      BseThreadInfo *info = thread_infos + --n_thread_infos;
      g_free (info->name);
      gxk_list_wrapper_notify_delete (lw, n_thread_infos);
    }
  if (n > n_thread_infos)
    {
      thread_infos = g_renew (BseThreadInfo, thread_infos, n);
      guint delta = n - n_thread_infos;
      memset (thread_infos + n_thread_infos, 0, sizeof (thread_infos[0]) * delta);
      n_thread_infos = n;
      gxk_list_wrapper_notify_append (lw, delta);
    }
  BseThreadInfo *totals = thread_infos + n - 1;
  gboolean totals_changed = !totals->name;
  totals->utime = 0;
  totals->stime = 0;
  totals->priority = G_MAXINT;
  for (i = 0; i < n - 1; i++)
    {
      BseThreadInfo *oinfo = thread_infos + i;
      BseThreadInfo *ninfo = (BseThreadInfo*) slist->data;
      slist = slist->next;
      if (!oinfo->name || strcmp (oinfo->name, ninfo->name) ||
          oinfo->thread_id != ninfo->thread_id ||
          oinfo->state != ninfo->state ||
          oinfo->priority != ninfo->priority ||
          oinfo->processor != ninfo->processor ||
          oinfo->utime != ninfo->utime ||
          oinfo->stime != ninfo->stime)
        {
          g_free (oinfo->name);
          oinfo->name = g_strdup (ninfo->name);
          oinfo->thread_id = ninfo->thread_id;
          oinfo->state = ninfo->state;
          oinfo->priority = ninfo->priority;
          oinfo->processor = ninfo->processor;
          oinfo->utime = ninfo->utime;
          oinfo->stime = ninfo->stime;
          gxk_list_wrapper_notify_change (lw, i);
          totals_changed = TRUE;
        }
      totals->utime += oinfo->utime;
      totals->stime += oinfo->stime;
      totals->priority = MIN (oinfo->priority, totals->priority);
    }
  if (totals_changed)
    {
      g_free (totals->name);
      totals->name = g_strdup (_("Totals"));
      totals->state = BSE_THREAD_STATE_RUNNING;
      totals->processor = 0;
      gxk_list_wrapper_notify_change (lw, n - 1);
    }
}
static void
profiler_update (void)
{
  GxkListWrapper *lwrapper = (GxkListWrapper*) g_object_get_data ((GObject*) profiler_dialog, "list-wrapper");
  BseThreadTotals *tt = bse_collect_thread_totals ();
  sfi_thread_sleep (0); /* update accounting for self */
  BirnetThreadInfo *si = sfi_thread_info_collect (sfi_thread_self());
  BseThreadInfo bi = { 0, };
  GSList *slist = NULL;
  guint i;
  bi.name = si->name;
  bi.thread_id = si->thread_id;
  bi.state = thread_state_from_char_state (si->state);
  bi.priority = si->priority;
  bi.processor = si->processor;
  bi.utime = si->utime;
  bi.stime = si->stime;
  bi.cutime = si->cutime;
  bi.cstime = si->cstime;
  for (i = 0; i < tt->synthesis->n_thread_infos; i++)
    slist = g_slist_prepend (slist, tt->synthesis->thread_infos[i]);
  if (tt->sequencer)
    slist = g_slist_prepend (slist, tt->sequencer);
  slist = g_slist_prepend (slist, tt->main);
  slist = g_slist_prepend (slist, &bi);
  update_infos (slist, lwrapper);
  g_slist_free (slist);
  sfi_thread_info_free (si);
}
static gboolean
profiler_timer (gpointer data)<commit_msg>BST: guard against missing thread stats for main BSE thread<commit_after>// Licensed GNU LGPL v2.1 or later: http://www.gnu.org/licenses/lgpl.html
#include "bstprofiler.hh"
#include <string.h>
/* --- thread view --- */
enum {
  TCOL_NAME,
  TCOL_TID,
  TCOL_PROC,
  TCOL_PRIO,
  TCOL_PERC,
  TCOL_UTIME,
  TCOL_STIME,
  N_TCOLS
};
/* --- variables --- */
static GtkWidget     *profiler_dialog = NULL;
static GxkRadget     *profiler = NULL;
static guint          timer_id = 0;
static guint          n_thread_infos = 0;
static BseThreadInfo *thread_infos = NULL;
/* --- funtions --- */
#if 0
static gchar
char_state_from_thread_state (BseThreadState thread_state)
{
  switch (thread_state)
    {
    default:
    case BSE_THREAD_STATE_UNKNOWN:      return SFI_THREAD_UNKNOWN;
    case BSE_THREAD_STATE_RUNNING:      return SFI_THREAD_RUNNING;
    case BSE_THREAD_STATE_SLEEPING:     return SFI_THREAD_SLEEPING;
    case BSE_THREAD_STATE_DISKWAIT:     return SFI_THREAD_DISKWAIT;
    case BSE_THREAD_STATE_TRACED:       return SFI_THREAD_TRACED;
    case BSE_THREAD_STATE_PAGING:       return SFI_THREAD_PAGING;
    case BSE_THREAD_STATE_ZOMBIE:       return SFI_THREAD_ZOMBIE;
    case BSE_THREAD_STATE_DEAD:         return SFI_THREAD_DEAD;
    }
}
#endif
static BseThreadState
thread_state_from_char_state (gchar thread_state)
{
  switch (thread_state)
    {
    default:
    case SFI_THREAD_UNKNOWN:    return BSE_THREAD_STATE_UNKNOWN;
    case SFI_THREAD_RUNNING:    return BSE_THREAD_STATE_RUNNING;
    case SFI_THREAD_SLEEPING:   return BSE_THREAD_STATE_SLEEPING;
    case SFI_THREAD_DISKWAIT:   return BSE_THREAD_STATE_DISKWAIT;
    case SFI_THREAD_TRACED:     return BSE_THREAD_STATE_TRACED;
    case SFI_THREAD_PAGING:     return BSE_THREAD_STATE_PAGING;
    case SFI_THREAD_ZOMBIE:     return BSE_THREAD_STATE_ZOMBIE;
    case SFI_THREAD_DEAD:       return BSE_THREAD_STATE_DEAD;
    }
}
static void
thread_info_cell_fill_value (GtkWidget *profiler,
                             guint      column,
                             guint      row,
                             GValue    *value)
{
  BseThreadInfo *info = thread_infos + row;
  switch (column)
    {
    case TCOL_NAME:
      sfi_value_take_string (value, g_strdup_printf ("%s", info->name));
      break;
    case TCOL_PROC:
      sfi_value_take_string (value, info->processor ? g_strdup_printf ("%d", info->processor) : g_strdup (""));
      break;
    case TCOL_TID:
      sfi_value_take_string (value, info->thread_id ? g_strdup_printf ("%u", info->thread_id) : g_strdup (""));
      break;
    case TCOL_PRIO:
      sfi_value_take_string (value, info->thread_id ? g_strdup_printf ("%d", info->priority) : g_strdup (""));
      break;
    case TCOL_PERC:
      sfi_value_take_string (value, g_strdup_printf ("%5.2f%%", (info->utime + info->stime) * 0.0001));
      break;
    case TCOL_UTIME:
      sfi_value_take_string (value, g_strdup_printf ("%7.3f", info->utime * 0.001));
      break;
    case TCOL_STIME:
      sfi_value_take_string (value, g_strdup_printf ("%7.3f", info->stime * 0.001));
      break;
    }
}
static void
update_infos (GSList         *slist,
              GxkListWrapper *lw)
{
  guint i, n = g_slist_length (slist) + 1;
  while (n_thread_infos > n)
    {
      BseThreadInfo *info = thread_infos + --n_thread_infos;
      g_free (info->name);
      gxk_list_wrapper_notify_delete (lw, n_thread_infos);
    }
  if (n > n_thread_infos)
    {
      thread_infos = g_renew (BseThreadInfo, thread_infos, n);
      guint delta = n - n_thread_infos;
      memset (thread_infos + n_thread_infos, 0, sizeof (thread_infos[0]) * delta);
      n_thread_infos = n;
      gxk_list_wrapper_notify_append (lw, delta);
    }
  BseThreadInfo *totals = thread_infos + n - 1;
  gboolean totals_changed = !totals->name;
  totals->utime = 0;
  totals->stime = 0;
  totals->priority = G_MAXINT;
  for (i = 0; i < n - 1; i++)
    {
      BseThreadInfo *oinfo = thread_infos + i;
      BseThreadInfo *ninfo = (BseThreadInfo*) slist->data;
      slist = slist->next;
      if (!oinfo->name || strcmp (oinfo->name, ninfo->name) ||
          oinfo->thread_id != ninfo->thread_id ||
          oinfo->state != ninfo->state ||
          oinfo->priority != ninfo->priority ||
          oinfo->processor != ninfo->processor ||
          oinfo->utime != ninfo->utime ||
          oinfo->stime != ninfo->stime)
        {
          g_free (oinfo->name);
          oinfo->name = g_strdup (ninfo->name);
          oinfo->thread_id = ninfo->thread_id;
          oinfo->state = ninfo->state;
          oinfo->priority = ninfo->priority;
          oinfo->processor = ninfo->processor;
          oinfo->utime = ninfo->utime;
          oinfo->stime = ninfo->stime;
          gxk_list_wrapper_notify_change (lw, i);
          totals_changed = TRUE;
        }
      totals->utime += oinfo->utime;
      totals->stime += oinfo->stime;
      totals->priority = MIN (oinfo->priority, totals->priority);
    }
  if (totals_changed)
    {
      g_free (totals->name);
      totals->name = g_strdup (_("Totals"));
      totals->state = BSE_THREAD_STATE_RUNNING;
      totals->processor = 0;
      gxk_list_wrapper_notify_change (lw, n - 1);
    }
}
static void
profiler_update (void)
{
  GxkListWrapper *lwrapper = (GxkListWrapper*) g_object_get_data ((GObject*) profiler_dialog, "list-wrapper");
  BseThreadTotals *tt = bse_collect_thread_totals ();
  sfi_thread_sleep (0); /* update accounting for self */
  BirnetThreadInfo *si = sfi_thread_info_collect (sfi_thread_self());
  BseThreadInfo bi = { 0, };
  GSList *slist = NULL;
  guint i;
  bi.name = si->name;
  bi.thread_id = si->thread_id;
  bi.state = thread_state_from_char_state (si->state);
  bi.priority = si->priority;
  bi.processor = si->processor;
  bi.utime = si->utime;
  bi.stime = si->stime;
  bi.cutime = si->cutime;
  bi.cstime = si->cstime;
  for (i = 0; i < tt->synthesis->n_thread_infos; i++)
    slist = g_slist_prepend (slist, tt->synthesis->thread_infos[i]);
  if (tt->sequencer)
    slist = g_slist_prepend (slist, tt->sequencer);
  if (tt->main)
    slist = g_slist_prepend (slist, tt->main);
  slist = g_slist_prepend (slist, &bi);
  update_infos (slist, lwrapper);
  g_slist_free (slist);
  sfi_thread_info_free (si);
}
static gboolean
profiler_timer (gpointer data)
{'fraction_non_alphanumeric': 0.11619549592716819, 'fraction_numerical': 0.00590959910557419, 'mean_word_length': 2.9742938749603303, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 160, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4477647', 'n_tokens_mistral': 4717, 'n_tokens_neox': 4679, 'n_words': 890}