VirtualBox

Changeset 3479 in kBuild


Ignore:
Timestamp:
Sep 21, 2020 10:59:41 AM (4 years ago)
Author:
bird
Message:

kmk: Added some refinements to the recent repeat-output-from-failing-command-in-die hack.

Location:
trunk/src/kmk
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/kmk/main.c

    r3432 r3479  
    43884388        {
    43894389          need_2nd_error = 1;
    4390           need_2nd_error_output = job_slots_used > 2
    4391                                && out == NULL
     4390          need_2nd_error_output = job_slots_used >= 2
     4391                               && out != NULL
    43924392                               && out != &make_sync;
     4393          if (need_2nd_error_output)
     4394            output_metered = 0;
    43934395        }
    43944396#endif /* KMK */
     
    44704472  {
    44714473      out->dont_truncate = 0;
    4472       if (need_2nd_error_output)
     4474fprintf(stderr, "output_metered=%d\n", output_metered);
     4475      if (need_2nd_error_output && output_metered > 20)
    44734476        output_dump (out);
     4477      else
     4478        output_reset (out);
    44744479      output_close (out);
    44754480  }
     
    44804485
    44814486#ifdef KMK
    4482 void die(int status)
     4487void die (int status)
    44834488{
    44844489    die_with_job_output (status, NULL);
  • trunk/src/kmk/output.c

    r3432 r3479  
    5858#else
    5959# define STREAM_OK(_s) 1
     60#endif
     61
     62
     63#if defined(KMK) && !defined(NO_OUTPUT_SYNC)
     64/* Non-negative if we're counting output lines.
     65
     66   This is used by die_with_job_output to decide whether the initial build
     67   error needs to be repeated because there was too much output from parallel
     68   jobs between it and the actual make termination. */
     69int output_metered = -1;
     70
     71static void meter_output_block (char const *buffer, size_t len)
     72{
     73  while (len > 0)
     74    {
     75      char *nl = (char *)memchr (buffer, '\n', len);
     76      size_t linelen;
     77      if (nl)
     78        {
     79          linelen = nl - buffer + 1;
     80          output_metered++;
     81        }
     82      else
     83          linelen = len;
     84      output_metered += linelen / 132;
     85
     86      /* advance */
     87      buffer += linelen;
     88      len    -= linelen;
     89    }
     90}
    6091#endif
    6192
     
    78109static int combined_output = -1;
    79110
     111/* Helper for membuf_reset and output_reset */
     112static membuf_reset (struct output *out)
     113{
     114  struct output_segment *seg;
     115  while ((seg = out->out.head_seg))
     116    {
     117     out->out.head_seg = seg->next;
     118     free (seg);
     119    }
     120  out->out.tail_seg = NULL;
     121  out->out.tail_run = NULL;
     122  out->out.head_run = NULL;
     123  out->out.left     = 0;
     124  out->out.total    = 0;
     125
     126  while ((seg = out->err.head_seg))
     127    {
     128     out->err.head_seg = seg->next;
     129     free (seg);
     130    }
     131  out->err.tail_seg = NULL;
     132  out->err.tail_run = NULL;
     133  out->err.head_run = NULL;
     134  out->err.left     = 0;
     135  out->err.total    = 0;
     136
     137  out->seqno = 0;
     138}
     139
     140/* Used by die_with_job_output to suppress output when it shouldn't be repeated. */
     141void output_reset (struct output *out)
     142{
     143  if (out && (out->out.total || out->err.total))
     144    membuf_reset (out);
     145}
     146
    80147/* Internal worker for output_dump and membuf_dump_most. */
    81148static void membuf_dump (struct output *out)
     
    86153      struct output_run *err_run;
    87154      struct output_run *out_run;
    88       struct output_segment *seg;
    89155      FILE *prevdst;
    90156
     
    130196            fflush(prevdst);
    131197          prevdst = dst;
     198#ifdef KMK
     199          if (output_metered < 0)
     200            { /* likely */ }
     201          else
     202            meter_output_block (src, len);
     203#endif
    132204# if 0 /* for debugging */
    133205          while (len > 0)
     
    179251
    180252      /* Free the segments and reset the state. */
    181       while ((seg = out->out.head_seg))
    182         {
    183          out->out.head_seg = seg->next;
    184          free (seg);
    185         }
    186       out->out.tail_seg = NULL;
    187       out->out.tail_run = NULL;
    188       out->out.head_run = NULL;
    189       out->out.left     = 0;
    190       out->out.total    = 0;
    191 
    192       while ((seg = out->err.head_seg))
    193         {
    194          out->err.head_seg = seg->next;
    195          free (seg);
    196         }
    197       out->err.tail_seg = NULL;
    198       out->err.tail_run = NULL;
    199       out->err.head_run = NULL;
    200       out->err.left     = 0;
    201       out->err.total    = 0;
    202 
    203       out->seqno = 0;
     253      membuf_reset (out);
    204254    }
    205255  else
     
    756806      if (len <= 0)
    757807        break;
     808#ifdef KMK
     809      if (output_metered < 0)
     810        { /* likely */ }
     811      else
     812        meter_output_block (buffer, len);
     813#endif
    758814      if (fwrite (buffer, len, 1, to) < 1)
    759815        {
     
    9531009#endif
    9541010}
     1011
     1012# if defined(KMK) && !defined(CONFIG_WITH_OUTPUT_IN_MEMORY)
     1013/* Used by die_with_job_output to suppress output when it shouldn't be repeated. */
     1014void output_reset (struct output *out)
     1015{
     1016  if (out)
     1017    {
     1018      if (out->out != OUTPUT_NONE)
     1019        {
     1020          int e;
     1021          lseek (out->out, 0, SEEK_SET);
     1022          EINTRLOOP (e, ftruncate (out->out, 0));
     1023        }
     1024      if (out->err != OUTPUT_NONE && out->err != out->out)
     1025        {
     1026          int e;
     1027          lseek (out->err, 0, SEEK_SET);
     1028          EINTRLOOP (e, ftruncate (out->err, 0));
     1029        }
     1030    }
     1031}
     1032# endif
    9551033#endif /* NO_OUTPUT_SYNC */
    9561034
  • trunk/src/kmk/output.h

    r3432 r3479  
    6767extern struct output *output_context;
    6868extern unsigned int stdio_traced;
     69#if defined(KMK) && !defined(NO_OUTPUT_SYNC)
     70extern int output_metered;
     71#endif
    6972
    7073#define OUTPUT_SET(_new)    do{ output_context = (_new)->syncout ? (_new) : NULL; }while(0)
     
    9699/* Dump any child output content to stdout, and reset it.  */
    97100void output_dump (struct output *out);
     101# ifdef KMK
     102void output_reset (struct output *out);
     103# endif
    98104#endif
    99105
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette