VirtualBox

Changeset 3619 in kBuild for trunk


Ignore:
Timestamp:
Oct 21, 2024 8:46:49 PM (6 months ago)
Author:
bird
Message:

kmk/incdep.c: better accounting for debugging race/whatever

File:
1 edited

Legend:

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

    r3565 r3619  
    9797*   Structures and Typedefs                                                    *
    9898*******************************************************************************/
     99struct incdep_worker_data
     100{
     101    int worker_tid;                         /* -1 for main, index for the others. */
     102    unsigned int done_count;                /* workers increment this */
     103    unsigned int flushed_count;             /* main thread: flushed done count. */
     104    unsigned int todo_count;                /* main thread: queued on todo */
     105};
     106
    99107struct incdep_variable_in_set
    100108{
     
    195203
    196204/* the list of files that needs reading. */
    197 static struct incdep * volatile incdep_head_todo;
    198 static struct incdep * volatile incdep_tail_todo;
     205static struct incdep * volatile incdep_head_todo  = NULL;
     206static struct incdep * volatile incdep_tail_todo  = NULL;
     207static unsigned int volatile    incdep_count_todo = 0;
    199208
    200209/* the number of files that are currently being read. */
    201 static int volatile incdep_num_reading;
     210static int volatile incdep_num_reading = 0;
    202211
    203212/* the list of files that have been read. */
    204 static struct incdep * volatile incdep_head_done;
    205 static struct incdep * volatile incdep_tail_done;
     213static struct incdep * volatile incdep_head_done  = NULL;
     214static struct incdep * volatile incdep_tail_done  = NULL;
     215static unsigned int volatile    incdep_count_done = 0;
    206216
    207217
     
    233243static malloc_zone_t *incdep_zone;
    234244#endif
     245
     246/* Worker specific data, the extra entry is for the main thread.
     247   TODO: Move all parallel arrays in here to avoid unnecessary cacheline
     248         sharing between worker threads. */
     249static struct incdep_worker_data incdep_worker_data[INCDEP_MAX_THREADS + 1];
    235250
    236251
     
    396411#elif defined (__OS2__)
    397412  _fmutex_request (&incdep_mtx, 0);
     413#elif !defined(CONFIG_WITHOUT_THREADS)
     414# error Misconfig?
    398415#endif
    399416}
     
    585602incdep_worker (int thrd)
    586603{
     604  struct incdep_worker_data *thrd_data = &incdep_worker_data[thrd];
     605  thrd_data->worker_tid = thrd;
     606
    587607  incdep_lock ();
    588608
     
    591611      /* get job from the todo list. */
    592612
     613      struct incdep *tmp;
    593614      struct incdep *cur = incdep_head_todo;
    594615      if (!cur)
     
    598619        }
    599620      if (cur->next)
    600         incdep_head_todo = cur->next;
     621        {
     622          assert (incdep_count_todo > 1);
     623          assert (cur != incdep_tail_todo);
     624          incdep_head_todo = cur->next;
     625        }
    601626      else
    602         incdep_head_todo = incdep_tail_todo = NULL;
     627        {
     628          assert (incdep_count_todo == 1);
     629          assert (cur == incdep_tail_todo);
     630          incdep_head_todo = incdep_tail_todo = NULL;
     631        }
     632      incdep_count_todo--;
    603633      incdep_num_reading++;
    604634
     
    620650      incdep_num_reading--;
    621651      cur->next = NULL;
    622       if (incdep_tail_done)
    623         incdep_tail_done->next = cur;
     652      tmp = incdep_tail_done;
     653      if (tmp)
     654        {
     655          tmp->next = cur;
     656          assert (incdep_count_done > 0);
     657        }
    624658      else
    625         incdep_head_done = cur;
     659        {
     660          assert (!incdep_head_done);
     661          assert (incdep_count_done == 0);
     662          incdep_head_done = cur;
     663        }
    626664      incdep_tail_done = cur;
     665      incdep_count_done++;
     666
     667      thrd_data->done_count++;
    627668
    628669      incdep_signal_done ();
     
    866907{
    867908  unsigned i;
     909  unsigned total_done = 0;
    868910
    869911  if (!incdep_initialized)
     
    892934      strcache2_term (&incdep_dep_strcaches[i]);
    893935      strcache2_term (&incdep_var_strcaches[i]);
     936
     937      /* accounting */
     938      total_done += incdep_worker_data[i].done_count;
    894939    }
    895940  incdep_num_threads = 0;
     941
     942  /* sanity check */
     943  if (total_done != incdep_worker_data[INCDEP_MAX_THREADS].flushed_count)
     944    fprintf (stderr, "kmk/incdep: warning: total_done=%#x does not equal flushed_count=%#x!\n",
     945             total_done, incdep_worker_data[INCDEP_MAX_THREADS].flushed_count);
     946  if (total_done != incdep_worker_data[INCDEP_MAX_THREADS].todo_count)
     947    fprintf (stderr, "kmk/incdep: warning: total_done=%#x does not equal todo_count=%#x!\n",
     948             total_done, incdep_worker_data[INCDEP_MAX_THREADS].todo_count);
    896949
    897950  /* destroy the lock and condition variables / event objects. */
     
    20902143incdep_flush_it (floc *f)
    20912144{
     2145  struct incdep_worker_data *thrd_data = &incdep_worker_data[INCDEP_MAX_THREADS];
     2146
    20922147  incdep_lock ();
    20932148  for (;;)
    20942149    {
    2095       struct incdep *cur = incdep_head_done;
     2150      struct incdep *cur   = incdep_head_done;
     2151      unsigned int   count = incdep_count_done;
    20962152
    20972153      /* if the done list is empty, grab a todo list entry. */
    2098       if (!cur && incdep_head_todo)
     2154      if (!cur)
    20992155        {
    21002156          cur = incdep_head_todo;
    2101           if (cur->next)
    2102             incdep_head_todo = cur->next;
    2103           else
    2104             incdep_head_todo = incdep_tail_todo = NULL;
    2105           incdep_unlock ();
    2106 
    2107           incdep_read_file (cur, f);
    2108           eval_include_dep_file (cur, f);
    2109           incdep_freeit (cur);
    2110 
    2111           incdep_lock ();
    2112           continue;
     2157          if (cur)
     2158            {
     2159              if (cur->next)
     2160                {
     2161                  assert (incdep_count_todo > 1);
     2162                  assert (cur != incdep_tail_todo);
     2163                  incdep_head_todo = cur->next;
     2164                }
     2165              else
     2166                {
     2167                  assert (incdep_count_todo == 1);
     2168                  assert (cur == incdep_tail_todo);
     2169                  incdep_head_todo = incdep_tail_todo = NULL;
     2170                }
     2171              incdep_count_todo--;
     2172              thrd_data->todo_count--;
     2173              incdep_unlock ();
     2174
     2175              incdep_read_file (cur, f);
     2176              eval_include_dep_file (cur, f);
     2177              incdep_freeit (cur);
     2178
     2179              incdep_lock ();
     2180              continue;
     2181            }
    21132182        }
    21142183
     
    21262195      /* we grab the entire done list and work thru it. */
    21272196      incdep_head_done = incdep_tail_done = NULL;
     2197      incdep_count_done = 0;
     2198
    21282199      incdep_unlock ();
    21292200
     
    21312202        {
    21322203          struct incdep *next = cur->next;
     2204          assert (count > 0);
    21332205#ifdef PARSE_IN_WORKER
    21342206          incdep_flush_recorded_instructions (cur);
     
    21372209#endif
    21382210          incdep_freeit (cur);
     2211          thrd_data->flushed_count++;
     2212          count--;
    21392213          cur = next;
    21402214        }
     2215      assert (count == 0);
    21412216
    21422217      incdep_lock ();
     
    21512226eval_include_dep (const char *names, floc *f, enum incdep_op op)
    21522227{
     2228  struct incdep_worker_data *thrd_data = &incdep_worker_data[INCDEP_MAX_THREADS];
    21532229  struct incdep *head = 0;
    21542230  struct incdep *tail = 0;
    21552231  struct incdep *cur;
     2232  unsigned int count = 0;
    21562233  const char *names_iterator = names;
    21572234  const char *name;
     
    22002277         head = cur;
    22012278       tail = cur;
     2279       count++;
    22022280    }
    22032281
     
    22222300  else
    22232301    {
     2302      struct incdep *tmp;
     2303
    22242304      /* initialize the worker threads and related stuff the first time around. */
    22252305
     
    22312311      incdep_lock ();
    22322312
    2233       if (incdep_tail_todo)
    2234         incdep_tail_todo->next = head;
     2313      tmp = incdep_tail_todo;
     2314      if (tmp)
     2315        {
     2316          assert (incdep_count_todo > 0);
     2317          assert (incdep_head_todo != NULL);
     2318          tmp->next = head;
     2319        }
    22352320      else
    2236         incdep_head_todo = head;
     2321        {
     2322          assert (incdep_count_todo == 0);
     2323          assert (incdep_head_todo == NULL);
     2324          incdep_head_todo = head;
     2325        }
    22372326      incdep_tail_todo = tail;
     2327      incdep_count_todo += count;
     2328      thrd_data->todo_count += count;
    22382329
    22392330      incdep_signal_todo ();
Note: See TracChangeset for help on using the changeset viewer.

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