Ignore:
Timestamp:
Sep 8, 2016, 6:14:46 AM (9 years ago)
Author:
bird
Message:

variables.c/target_environment: Cache the exported variables in the global_variable_set since there are likely to be very very many of them and they aren't usually changing when we've loaded the makefiles and start running make jobs. Also, use smaller hash tables for collecting exported variables (I've bumped VARIABLE_BUCKETS up a lot).

File:
1 edited

Legend:

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

    r2771 r2893  
    5959#endif
    6060
     61#ifdef KMK
     62/* Incremented every time a variable is modified, so that target_environment
     63   knows when to regenerate the table of exported global variables.  */
     64static size_t global_variable_generation = 0;
     65#endif
     66
    6167
    6268/* Chain of all pattern-specific variables.  */
     
    217223#define SMALL_SCOPE_VARIABLE_BUCKETS    13
    218224# endif
     225#endif
     226#ifndef ENVIRONMENT_VARIABLE_BUCKETS    /* added by bird. */
     227# define ENVIRONMENT_VARIABLE_BUCKETS   256
    219228#endif
    220229
     
    271280  struct variable **var_slot;
    272281  struct variable var_key;
     282
     283#ifdef KMK
     284  if (set == NULL || set == &global_variable_set)
     285    global_variable_generation++;
     286#endif
    273287
    274288  if (env_overrides && origin == o_env)
     
    518532  var_slot = (struct variable **) hash_find_slot_strcached (&set->table, &var_key);
    519533#endif
     534#ifdef KMK
     535  if (set == &global_variable_set)
     536    global_variable_generation++;
     537#endif
    520538
    521539  if (env_overrides && origin == o_env)
     
    566584  struct variable     *v;
    567585  struct variable     **var_slot;
     586
     587#ifdef KMK
     588  if (set == NULL || set == &global_variable_set)
     589    global_variable_generation++;
     590#endif
    568591
    569592  /* Look it up the hash table slot for it. */
     
    19701993int export_all_variables;
    19711994
     1995#ifdef KMK
     1996/* Cached table containing the exports of the global_variable_set.  When
     1997   there are many global variables, it can be so expensive to construct the
     1998   child environment that we have a majority of job slot idle.  */
     1999static size_t             global_variable_set_exports_generation = ~(size_t)0;
     2000static struct hash_table  global_variable_set_exports;
     2001
     2002static void update_global_variable_set_exports(void)
     2003{
     2004  struct variable **v_slot;
     2005  struct variable **v_end;
     2006
     2007  /* Re-initialize the table. */
     2008  if (global_variable_set_exports_generation != ~(size_t)0)
     2009    hash_free (&global_variable_set_exports, 0);
     2010  hash_init_strcached (&global_variable_set_exports, ENVIRONMENT_VARIABLE_BUCKETS,
     2011                       &variable_strcache, offsetof (struct variable, name));
     2012
     2013  /* do pretty much the same as target_environment. */
     2014  v_slot = (struct variable **) global_variable_set.table.ht_vec;
     2015  v_end = v_slot + global_variable_set.table.ht_size;
     2016  for ( ; v_slot < v_end; v_slot++)
     2017    if (! HASH_VACANT (*v_slot))
     2018      {
     2019        struct variable **new_slot;
     2020        struct variable *v = *v_slot;
     2021
     2022        switch (v->export)
     2023          {
     2024          case v_default:
     2025            if (v->origin == o_default || v->origin == o_automatic)
     2026              /* Only export default variables by explicit request.  */
     2027              continue;
     2028
     2029            /* The variable doesn't have a name that can be exported.  */
     2030            if (! v->exportable)
     2031              continue;
     2032
     2033            if (! export_all_variables
     2034                && v->origin != o_command
     2035                && v->origin != o_env && v->origin != o_env_override)
     2036              continue;
     2037            break;
     2038
     2039          case v_export:
     2040            break;
     2041
     2042          case v_noexport:
     2043            {
     2044              /* If this is the SHELL variable and it's not exported,
     2045                 then add the value from our original environment, if
     2046                 the original environment defined a value for SHELL.  */
     2047              extern struct variable shell_var;
     2048              if (streq (v->name, "SHELL") && shell_var.value)
     2049                {
     2050                  v = &shell_var;
     2051                  break;
     2052                }
     2053              continue;
     2054            }
     2055
     2056          case v_ifset:
     2057            if (v->origin == o_default)
     2058              continue;
     2059            break;
     2060          }
     2061
     2062        assert (strcache2_is_cached (&variable_strcache, v->name));
     2063        new_slot = (struct variable **) hash_find_slot_strcached (&global_variable_set_exports, v);
     2064        if (HASH_VACANT (*new_slot))
     2065          hash_insert_at (&global_variable_set_exports, v, new_slot);
     2066      }
     2067
     2068  /* done */
     2069  global_variable_set_exports_generation = global_variable_generation;
     2070}
     2071
     2072#endif
     2073
    19722074/* Create a new environment for FILE's commands.
    19732075   If FILE is nil, this is for the `shell' function.
     
    19892091#endif
    19902092
     2093#ifdef KMK
     2094  if (global_variable_set_exports_generation != global_variable_generation)
     2095    update_global_variable_set_exports();
     2096#endif
     2097
    19912098  if (file == 0)
    19922099    set_list = current_variable_set_list;
     
    19952102
    19962103#ifndef CONFIG_WITH_STRCACHE2
    1997   hash_init (&table, VARIABLE_BUCKETS,
     2104  hash_init (&table, ENVIRONMENT_VARIABLE_BUCKETS,
    19982105             variable_hash_1, variable_hash_2, variable_hash_cmp);
    19992106#else  /* CONFIG_WITH_STRCACHE2 */
    2000   hash_init_strcached (&table, VARIABLE_BUCKETS,
     2107  hash_init_strcached (&table, ENVIRONMENT_VARIABLE_BUCKETS,
    20012108                       &variable_strcache, offsetof (struct variable, name));
    20022109#endif /* CONFIG_WITH_STRCACHE2 */
     
    20072114    {
    20082115      struct variable_set *set = s->set;
     2116#ifdef KMK
     2117      if (set == &global_variable_set)
     2118        {
     2119          assert(s->next == NULL);
     2120          break;
     2121        }
     2122#endif
    20092123      v_slot = (struct variable **) set->table.ht_vec;
    20102124      v_end = v_slot + set->table.ht_size;
     
    20842198          }
    20852199    }
     2200
     2201#ifdef KMK
     2202  /* Add the global exports to table. */
     2203  v_slot = (struct variable **) global_variable_set_exports.ht_vec;
     2204  v_end = v_slot + global_variable_set_exports.ht_size;
     2205  for ( ; v_slot < v_end; v_slot++)
     2206    if (! HASH_VACANT (*v_slot))
     2207      {
     2208        struct variable **new_slot;
     2209        struct variable *v = *v_slot;
     2210        assert (strcache2_is_cached (&variable_strcache, v->name));
     2211        new_slot = (struct variable **) hash_find_slot_strcached (&table, v);
     2212        if (HASH_VACANT (*new_slot))
     2213          hash_insert_at (&table, v, new_slot);
     2214      }
     2215#endif
    20862216
    20872217#ifndef CONFIG_WITH_STRCACHE2
Note: See TracChangeset for help on using the changeset viewer.