Changeset 1854


Ignore:
Timestamp:
Oct 13, 2008, 3:50:33 AM (17 years ago)
Author:
bird
Message:

kmk: offload hashing of strcache entries to the includedep thread(s).

Location:
trunk/src/kmk
Files:
3 edited

Legend:

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

    r1852 r1854  
    8585*   Structures and Typedefs                                                    *
    8686*******************************************************************************/
     87struct incdep_strcache_entry
     88{
     89    unsigned int length;
     90    unsigned int alignment;
     91    unsigned long hash1;
     92    unsigned long hash2;
     93    char str[1];
     94};
    8795
    8896struct incdep_variable_in_set
     
    9098    struct incdep_variable_in_set *next;
    9199    /* the parameters */
    92     char *name;                     /* xmalloc'ed -> strcache */
    93     unsigned int name_length;
     100    struct incdep_strcache_entry *name_entry;
    94101    const char *value;              /* xmalloc'ed */
    95102    unsigned int value_length;
     
    106113    /* the parameters */
    107114    const struct floc *flocp;       /* NILF */
    108     char *name;                     /* xmalloc'ed -> strcache */
    109     unsigned int name_length;       /* (not an actual parameter) */
     115    struct incdep_strcache_entry *name_entry;
    110116    char *value;                    /* xmalloc'ed, free it */
    111117    unsigned int value_length;
     
    120126
    121127    /* the parameters */
    122     struct nameseq *filenames;      /* only one file? its name needs be strcache'ed */
     128    struct nameseq *filenames;      /* One only, its name is a strcache entry. */
    123129    const char *pattern;            /* NULL */
    124130    const char *pattern_percent;    /* NULL */
    125     struct dep *deps;               /* names need to be strcache'ed */
     131    struct dep *deps;               /* All the names are strcache entries. */
    126132    unsigned int cmds_started;      /* 0 */
    127133    char *commands;                 /* NULL */
     
    665671
    666672#ifdef PARSE_IN_WORKER
     673/* Flushes a strcache entry returning the actual string cache entry.
     674   The input is freed! */
     675static const char *
     676incdep_flush_strcache_entry (const void *pv_entry)
     677{
     678  struct incdep_strcache_entry *entry = (struct incdep_strcache_entry *)pv_entry;
     679  const char *result;
     680  result = strcache_add_prehashed (entry->str, entry->length, entry->hash1, entry->hash2);
     681  free (entry);
     682  return result;
     683}
     684
    667685/* Flushes the recorded instructions. */
    668686static void
     
    681699      {
    682700        void *free_me = rec_vis;
    683         define_variable_in_set (strcache_add_len (rec_vis->name, rec_vis->name_length),
    684                                 rec_vis->name_length,
     701        unsigned int name_length = rec_vis->name_entry->length;
     702        define_variable_in_set (incdep_flush_strcache_entry (rec_vis->name_entry),
     703                                name_length,
    685704                                rec_vis->value,
    686705                                rec_vis->value_length,
     
    690709                                rec_vis->set,
    691710                                rec_vis->flocp);
    692         incdep_xfree (cur, rec_vis->name);
    693711        rec_vis = rec_vis->next;
    694712        incdep_xfree (cur, free_me);
     
    705723        void *free_me = rec_vd;
    706724        do_variable_definition_2 (rec_vd->flocp,
    707                                   strcache_add_len(rec_vd->name, rec_vd->name_length),
     725                                  incdep_flush_strcache_entry (rec_vd->name_entry),
    708726                                  rec_vd->value,
    709727                                  rec_vd->value_length,
     
    713731                                  rec_vd->flavor,
    714732                                  rec_vd->target_var);
    715         incdep_xfree (cur, rec_vd->name);
    716733        rec_vd = rec_vd->next;
    717734        incdep_xfree (cur, free_me);
     
    728745        void *free_me = rec_f;
    729746        struct dep *dep;
    730         const char *newname;
    731747
    732748        for (dep = rec_f->deps; dep; dep = dep->next)
    733           {
    734             newname = strcache_add (dep->name);
    735             free ((char *)dep->name);
    736             dep->name = newname;
    737           }
    738 
    739         newname = strcache_add (rec_f->filenames->name);
    740         incdep_xfree (cur, (char *)rec_f->filenames->name);
    741         rec_f->filenames->name = newname;
     749          dep->name = incdep_flush_strcache_entry (dep->name);
     750        rec_f->filenames->name = incdep_flush_strcache_entry (rec_f->filenames->name);
    742751
    743752        record_files (rec_f->filenames,
     
    790799  else
    791800    {
    792       /* Duplicate the string. The other recorders knows which arguments
    793          needs to be added to the string cache later. */
    794       char *newstr = incdep_xmalloc (cur, len + 1);
    795       memcpy (newstr, str, len);
    796       newstr[len] = '\0';
    797       ret = newstr;
     801      /* Allocate a strcache record for it, pre-hashing the string to save
     802         time later on in the main thread. */
     803      struct incdep_strcache_entry *entry = incdep_xmalloc (cur, sizeof (*entry) + len);
     804      memcpy (entry->str, str, len);
     805      entry->str[len] = '\0';
     806      entry->length = len;
     807      strcache_prehash_str (entry->str, &entry->hash1, &entry->hash2);
     808
     809      ret = (const char *)entry;
    798810    }
    799811  return ret;
     
    823835    {
    824836      struct incdep_variable_in_set *rec = incdep_xmalloc (cur, sizeof (*rec));
    825       rec->name = (char *)name;
    826       rec->name_length = name_length;
     837      rec->name_entry = (struct incdep_strcache_entry *)name;
    827838      rec->value = value;
    828839      rec->value_length = value_length;
     
    863874      struct incdep_variable_def *rec = incdep_xmalloc (cur, sizeof (*rec));
    864875      rec->flocp = flocp;
    865       rec->name = (char *)name;
    866       rec->name_length = name_length;
     876      rec->name_entry = (struct incdep_strcache_entry *)name;
    867877      rec->value = value;
    868878      rec->value_length = value_length;
  • trunk/src/kmk/make.h

    r1843 r1854  
    504504const char *strcache_add_len (const char *str, int len);
    505505int strcache_setbufsize (int size);
     506#ifdef CONFIG_WITH_INCLUDEDEP
     507const char *strcache_add_prehashed (const char *str, int len,
     508                                    unsigned long hash1, unsigned long hash2);
     509void strcache_prehash_str (const char *str, unsigned long *hash1p,
     510                           unsigned long *hash2p);
     511#endif
    506512#ifdef CONFIG_WITH_VALUE_LENGTH
    507513MY_INLINE unsigned int strcache_get_len (const char *str)
  • trunk/src/kmk/strcache.c

    r1845 r1854  
    131131
    132132#ifdef CONFIG_WITH_VALUE_LENGTH
     133/* Hackish globals for passing data to the hash functions.
     134   There isn't really any other way without running the
     135   risk of breaking rehashing. */
    133136static const char *lookup_string;
    134137static unsigned int lookup_string_len;
    135 #endif
     138# ifdef CONFIG_WITH_INCLUDEDEP
     139static unsigned long lookup_string_hash1;
     140static unsigned long lookup_string_hash2;
     141# endif /* CONFIG_WITH_INCLUDEDEP */
     142#endif /* CONFIG_WITH_VALUE_LENGTH */
    136143
    137144static unsigned long
    138145str_hash_1 (const void *key)
    139146{
     147#ifdef CONFIG_WITH_INCLUDEDEP
     148  if ((const char *) key == lookup_string && lookup_string_hash1)
     149    return lookup_string_hash1;
     150#endif
    140151  return_ISTRING_HASH_1 ((const char *) key);
    141152}
     
    144155str_hash_2 (const void *key)
    145156{
     157#ifdef CONFIG_WITH_INCLUDEDEP
     158  if ((const char *) key == lookup_string && lookup_string_hash2)
     159    return lookup_string_hash2;
     160#endif
    146161  return_ISTRING_HASH_2 ((const char *) key);
    147162}
     
    157172     kBuild scenario.  */
    158173
    159   if (x == lookup_string)
     174  if ((const char *) x == lookup_string)
    160175    {
    161176      assert (lookup_string_len == strlen ((const char *)x));
     
    237252}
    238253
     254#ifdef CONFIG_WITH_INCLUDEDEP
     255
     256/* A special variant used by the includedep worker threads, it off loads
     257   the main thread when it adds the strings to the cache later. */
     258const char *
     259strcache_add_prehashed (const char *str, int len, unsigned long hash1,
     260                        unsigned long hash2)
     261{
     262  const char *retstr;
     263
     264  assert (hash1 == str_hash_1 (str));
     265  assert (hash2 == str_hash_2 (str));
     266
     267  lookup_string_hash1 = hash1;
     268  lookup_string_hash2 = hash2;
     269
     270  retstr = add_hash (str, len);
     271
     272  lookup_string_hash1 = 0;
     273  lookup_string_hash2 = 0;
     274
     275  return retstr;
     276}
     277
     278/* Performs the prehashing for use with strcache_add_prehashed(). */
     279void
     280strcache_prehash_str (const char *str, unsigned long *hash1p,
     281                      unsigned long *hash2p)
     282{
     283  *hash1p = str_hash_1 (str);
     284  *hash2p = str_hash_2 (str);
     285}
     286
     287#endif /* CONFIG_WITH_INCLUDEDEP */
     288
    239289int
    240290strcache_setbufsize(int size)
Note: See TracChangeset for help on using the changeset viewer.