VirtualBox

Changeset 1863 in kBuild for trunk/src/kmk


Ignore:
Timestamp:
Oct 14, 2008 9:46:23 AM (16 years ago)
Author:
bird
Message:

kmk: Allocation caches for nameseq, dep and idep. next: variable.

Location:
trunk/src/kmk
Files:
14 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/kmk/Makefile.am

    r1797 r1863  
    108108        -DCONFIG_WITH_LOCAL_VARIABLES \
    109109        -DCONFIG_WITH_2ND_TARGET_EXPANSION \
     110        -DCONFIG_WITH_ALLOC_CACHES \
    110111        \
    111112        -DKMK \
  • trunk/src/kmk/Makefile.kmk

    r1797 r1863  
    139139        CONFIG_WITH_LOCAL_VARIABLES \
    140140        CONFIG_WITH_2ND_TARGET_EXPANSION \
     141        CONFIG_WITH_ALLOC_CACHES \
    141142        \
    142143        KMK \
  • trunk/src/kmk/default.c

    r903 r1863  
    555555      char *p = default_suffixes;
    556556      suffix_file->deps = (struct dep *)
     557#ifndef CONFIG_WITH_ALLOC_CACHES
    557558        multi_glob (parse_file_seq (&p, '\0', sizeof (struct dep), 1),
    558559                    sizeof (struct dep));
     560#else
     561        multi_glob (parse_file_seq (&p, '\0', &dep_cache, 1), &dep_cache);
     562#endif
    559563      define_variable ("SUFFIXES", 8, default_suffixes, o_default, 0);
    560564    }
  • trunk/src/kmk/dep.h

    r1848 r1863  
    5959
    6060
     61
     62#ifndef CONFIG_WITH_ALLOC_CACHES
    6163struct nameseq *multi_glob (struct nameseq *chain, unsigned int size);
     64#else
     65struct nameseq *multi_glob (struct nameseq *chain, struct alloccache *cache);
     66#endif
    6267#ifdef VMS
    6368struct nameseq *parse_file_seq ();
    6469#else
     70# ifndef CONFIG_WITH_ALLOC_CACHES
    6571struct nameseq *parse_file_seq (char **stringp, int stopchar, unsigned int size, int strip);
     72# else
     73struct nameseq *parse_file_seq (char **stringp, int stopchar, struct alloccache *cache, int strip);
     74# endif
    6675#endif
    6776char *tilde_expand (const char *name);
  • trunk/src/kmk/file.c

    r1857 r1863  
    524524parse_prereqs (char *p)
    525525{
     526#ifndef CONFIG_WITH_ALLOC_CACHES
    526527  struct dep *new = (struct dep *)
    527528    multi_glob (parse_file_seq (&p, '|', sizeof (struct dep), 1),
    528529                sizeof (struct dep));
     530#else
     531  struct dep *new = (struct dep *)
     532    multi_glob (parse_file_seq (&p, '|', &dep_cache, 1), &dep_cache);
     533#endif
    529534
    530535  if (*p)
     
    535540
    536541      ++p;
     542#ifndef CONFIG_WITH_ALLOC_CACHES
    537543      ood = (struct dep *)
    538544        multi_glob (parse_file_seq (&p, '\0', sizeof (struct dep), 1),
    539545                    sizeof (struct dep));
    540 
     546#else
     547      ood = (struct dep *)
     548        multi_glob (parse_file_seq (&p, '\0', &dep_cache, 1), &dep_cache);
     549#endif
    541550      if (! new)
    542551        new = ood;
  • trunk/src/kmk/function.c

    r1847 r1863  
    514514  unsigned int idx;
    515515
     516#ifndef CONFIG_WITH_ALLOC_CACHES
    516517  chain = multi_glob (parse_file_seq
    517518                      (&line, '\0', sizeof (struct nameseq),
     
    521522                       0),
    522523                      sizeof (struct nameseq));
     524#else
     525  chain = multi_glob (parse_file_seq
     526                      (&line, '\0', &nameseq_cache,
     527                       /* We do not want parse_file_seq to strip `./'s.
     528                          That would break examples like:
     529                          $(patsubst ./%.c,obj/%.o,$(wildcard ./?*.c)).  */
     530                       0),
     531                      &nameseq_cache);
     532#endif
    523533
    524534  if (result == 0)
     
    535545
    536546      struct nameseq *next = chain->next;
     547#ifndef CONFIG_WITH_ALLOC_CACHES
    537548      free (chain);
     549#else
     550      alloccache_free (&nameseq_cache, chain);
     551#endif
    538552      chain = next;
    539553
  • trunk/src/kmk/implicit.c

    r903 r1863  
    6666
    6767
     68#ifdef CONFIG_WITH_ALLOC_CACHES
     69struct alloccache idep_cache;
     70#endif
     71
    6872/* Struct idep captures information about implicit prerequisites
    6973   that come from implicit rules. */
     
    8690    {
    8791      n = p->next;
     92#ifndef CONFIG_WITH_ALLOC_CACHES
    8893      free (p);
     94#else
     95      alloccache_free (&idep_cache, p);
     96#endif
    8997    }
    9098}
     
    254262
    255263  PATH_VAR (stem_str); /* @@ Need to get rid of stem, stemlen, etc. */
     264
     265#ifdef CONFIG_WITH_ALLOC_CACHES
     266  if (!idep_cache.size)
     267    alloccache_init (&idep_cache, sizeof(struct idep), "dep", NULL, NULL);
     268#endif
    256269
    257270#ifndef NO_ARCHIVES
     
    583596                        ;
    584597
     598#ifndef CONFIG_WITH_ALLOC_CACHES
    585599                      *id_ptr = (struct idep *)
    586600                        multi_glob (
     
    589603                                          sizeof (struct idep),
    590604                                          1), sizeof (struct idep));
     605#else
     606                      *id_ptr = (struct idep *)
     607                        multi_glob (
     608                          parse_file_seq (&p2,
     609                                          order_only ? '\0' : '|',
     610                                          &idep_cache, 1),
     611                          &idep_cache);
     612#endif
    591613
    592614                      /* @@ It would be nice to teach parse_file_seq or
  • trunk/src/kmk/incdep.c

    r1862 r1863  
    145145  char *file_end;
    146146
    147   int is_worker;
     147  int worker_tid;
    148148#ifdef PARSE_IN_WORKER
    149149  unsigned int err_line_no;
    150150  const char *err_msg;
    151 
    152   struct dep *dep_start;            /* start of the current dep block. */
    153   struct dep *dep_end;              /* end of the current dep block. */
    154151
    155152  struct incdep_variable_in_set *recorded_variables_in_set_head;
     
    207204static struct incdep * volatile incdep_tail_done;
    208205
     206
    209207/* The handles to the worker threads. */
    210208#ifdef HAVE_PTHREAD
    211209static pthread_t incdep_threads[1];
     210static struct alloccache incdep_dep_caches[1];
     211static struct alloccache incdep_nameseq_caches[1];
     212
    212213#elif defined (WINDOWS32)
    213214static HANDLE incdep_threads[2];
     215static struct alloccache incdep_dep_caches[2];
     216static struct alloccache incdep_nameseq_caches[2];
     217
    214218#elif defined (__OS2__)
    215219static TID incdep_threads[2];
     220static struct alloccache incdep_dep_caches[2];
     221static struct alloccache incdep_nameseq_caches[2];
    216222#endif
    217223static unsigned incdep_num_threads;
     
    242248
    243249#ifdef __APPLE__
    244   if (cur && cur->is_worker)
     250  if (cur && cur->worker_tid != -1)
    245251    {
    246252      ptr = malloc_zone_malloc (incdep_zone, size);
     
    258264}
    259265
     266#if 0
    260267/* memset(malloc(sz),'\0',sz) wrapper. */
    261268static void *
     
    265272
    266273#ifdef __APPLE__
    267   if (cur && cur->is_worker)
     274  if (cur && cur->worker_tid != -1)
    268275    ptr = malloc_zone_calloc (incdep_zone, size, 1);
    269276  else
     
    278285  return ptr;
    279286}
     287#endif /* unused */
    280288
    281289/* free wrapper */
     
    289297}
    290298
     299/* alloc a nameseq structure.  */
     300struct nameseq *
     301incdep_alloc_nameseq (struct incdep *cur)
     302{
     303  struct alloccache *cache;
     304  if (cur->worker_tid != -1)
     305    cache = &incdep_nameseq_caches[cur->worker_tid];
     306  else
     307    cache = &nameseq_cache;
     308  return alloccache_calloc (cache);
     309}
     310
    291311/* alloc a dep structure. These are allocated in bunches to save time. */
    292312struct dep *
    293313incdep_alloc_dep (struct incdep *cur)
    294314{
    295   if (cur->dep_start != cur->dep_end)
    296     return cur->dep_start++;
    297 
    298   cur->dep_start = (struct dep *)incdep_xcalloc (cur, sizeof(struct dep) * 256);
    299   cur->dep_end = cur->dep_start + 256;
    300   return cur->dep_start++;
    301 }
    302 
     315  struct alloccache *cache;
     316  if (cur->worker_tid != -1)
     317    cache = &incdep_dep_caches[cur->worker_tid];
     318  else
     319    cache = &dep_cache;
     320  return alloccache_calloc (cache);
     321}
     322
     323/* grow a cache. */
     324static void *
     325incdep_cache_allocator (void *thrd, unsigned int size)
     326{
     327  (void)thrd;
     328#ifdef __APPLE__
     329  return malloc_zone_malloc (incdep_zone, size);
     330#else
     331  return xmalloc (size);
     332#endif
     333}
    303334
    304335/* acquires the lock */
     
    472503/* A worker thread. */
    473504void
    474 incdep_worker (void)
    475 {
    476 #ifdef PARSE_IN_WORKER
    477   struct dep *dep_start = NULL;
    478   struct dep *dep_end = NULL;
    479 #endif
    480 
     505incdep_worker (int thrd)
     506{
    481507  incdep_lock ();
    482508
     
    500526
    501527      incdep_unlock ();
    502       cur->is_worker = 1;
     528      cur->worker_tid = thrd;
     529
    503530      incdep_read_file (cur, NILF);
    504 
    505531#ifdef PARSE_IN_WORKER
    506       cur->dep_start = dep_start;
    507       cur->dep_end = dep_end;
    508 
    509532      eval_include_dep_file (cur, NILF);
    510 
    511       dep_start = cur->dep_start;
    512       cur->dep_start = NULL;
    513       dep_end = cur->dep_end;
    514       cur->dep_end = NULL;
    515 #endif
    516 
    517       cur->is_worker = 0;
     533#endif
     534
     535      cur->worker_tid = -1;
    518536      incdep_lock ();
    519537
     
    537555#ifdef HAVE_PTHREAD
    538556static void *
    539 incdep_worker_pthread (void *ignore)
    540 {
    541   incdep_worker ();
    542   (void)ignore;
     557incdep_worker_pthread (void *thrd)
     558{
     559  incdep_worker ((size_t)thrd);
    543560  return NULL;
    544561}
     
    546563#elif defined (WINDOWS32)
    547564static unsigned __stdcall
    548 incdep_worker_windows (void *ignore)
    549 {
    550   incdep_worker ();
    551   (void)ignore;
     565incdep_worker_windows (void *thrd)
     566{
     567  incdep_worker ((size_t)thrd);
    552568  return 0;
    553569}
     
    555571#elif defined (__OS2__)
    556572static void
    557 incdep_worker_os2 (void *ignore)
    558 {
    559   incdep_worker ();
    560   (void)ignore;
     573incdep_worker_os2 (void *thrd)
     574{
     575  incdep_worker ((size_t)thrd);
    561576}
    562577#endif
     
    633648  for (i = 0; i < incdep_num_threads; i++)
    634649    {
     650      alloccache_init (&incdep_dep_caches[i], sizeof(struct dep), "incdep dep",
     651                       incdep_cache_allocator, (void *)i);
     652      alloccache_init (&incdep_nameseq_caches[i], sizeof(struct nameseq),
     653                       "incdep nameseq", incdep_cache_allocator, (void *)i);
     654
    635655#ifdef HAVE_PTHREAD
    636656      rc = pthread_attr_init (&attr);
     
    641661      if (rc)
    642662        fatal (f, _("pthread_attr_setdetachstate failed: err=%d"), rc);
    643       rc = pthread_create (&incdep_threads[i], &attr,
    644                            incdep_worker_pthread, f);
     663      rc = pthread_create(&incdep_threads[i], &attr,
     664                           incdep_worker_pthread, (void *)i);
    645665      if (rc)
    646666        fatal (f, _("pthread_mutex_init failed: err=%d"), rc);
     
    650670      tid = 0;
    651671      hThread = _beginthreadex (NULL, 128*1024, incdep_worker_windows,
    652                                 NULL, 0, &tid);
     672                                (void *)i, 0, &tid);
    653673      if (hThread == 0 || hThread == ~(uintptr_t)0)
    654674        fatal (f, _("_beginthreadex failed: err=%d"), errno);
     
    656676
    657677#elif defined (__OS2__)
    658       tid = _beginthread (incdep_worker_os2, NULL, 128*1024, NULL);
     678      tid = _beginthread (incdep_worker_os2, NULL, 128*1024, (void *)i);
    659679      if (tid <= 0)
    660680        fatal (f, _("_beginthread failed: err=%d"), errno);
     
    691711  for (i = 0; i < incdep_num_threads; i++)
    692712    {
    693       /* later? */
     713      /* more later? */
     714
     715      alloccache_join (&dep_cache, &incdep_dep_caches[i]);
     716      alloccache_join (&nameseq_cache, &incdep_nameseq_caches[i]);
    694717    }
    695718  incdep_num_threads = 0;
     
    803826incdep_warn (struct incdep *cur, unsigned int line_no, const char *msg)
    804827{
    805   if (!cur->is_worker)
     828  if (cur->worker_tid == -1)
    806829    error (NILF, "%s(%d): %s", cur->name, line_no, msg);
    807830#ifdef PARSE_IN_WORKER
     
    819842{
    820843  const char *ret;
    821   if (!cur->is_worker)
     844  if (cur->worker_tid == -1)
    822845    {
    823846      /* Make sure the string is terminated before we hand it to
     
    860883{
    861884  assert (!duplicate_value);
    862   if (!cur->is_worker)
     885  if (cur->worker_tid == -1)
    863886    define_variable_in_set (name, name_length, value, value_length,
    864887                            duplicate_value, origin, recursive, set, flocp);
     
    898921                            int target_var)
    899922{
    900   if (!cur->is_worker)
     923  if (cur->worker_tid == -1)
    901924    do_variable_definition_2 (flocp, name, value, value_length, 0, value,
    902925                              origin, flavor, target_var);
     
    934957                     const struct floc *flocp)
    935958{
    936   if (!cur->is_worker)
     959  if (cur->worker_tid == -1)
    937960    record_files (filenames, pattern, pattern_percent, deps, cmds_started,
    938961                  commands, commands_idx, two_colon, flocp);
     
    13291352                  break;
    13301353                }
    1331               filenames = incdep_xmalloc (curdep, sizeof (struct nameseq));
     1354              filenames = incdep_alloc_nameseq (curdep);
    13321355              memset (filenames, 0, sizeof (*filenames));
    13331356              filenames->name = incdep_record_strcache (curdep, cur, endp - cur);
     
    14691492       memcpy (cur->name, name, name_len);
    14701493       cur->name[name_len] = '\0';
    1471        cur->is_worker = 0;
     1494       cur->worker_tid = -1;
    14721495#ifdef PARSE_IN_WORKER
    14731496       cur->err_line_no = 0;
    14741497       cur->err_msg = NULL;
    1475        cur->dep_start = NULL;
    1476        cur->dep_end = NULL;
    14771498       cur->recorded_variables_in_set_head = NULL;
    14781499       cur->recorded_variables_in_set_tail = NULL;
     
    14911512    }
    14921513
     1514#ifdef ELECTRIC_HEAP
     1515  if (1)
     1516#else
    14931517  if (op == incdep_read_it)
     1518#endif
    14941519    {
    14951520      /* work our way thru the files directly */
  • trunk/src/kmk/main.c

    r1856 r1863  
    644644#endif
    645645
     646#ifdef CONFIG_WITH_ALLOC_CACHES
     647struct alloccache dep_cache;
     648struct alloccache nameseq_cache;
     649struct alloccache variable_cache;
     650
     651static void
     652initialize_global_alloc_caches (void)
     653{
     654  alloccache_init (&dep_cache,      sizeof (struct dep),      "dep",      NULL, NULL);
     655  alloccache_init (&nameseq_cache,  sizeof (struct nameseq),  "nameseq",  NULL, NULL);
     656  alloccache_init (&variable_cache, sizeof (struct variable), "variable", NULL, NULL);
     657}
     658#endif
     659
    646660static void
    647661initialize_global_hash_tables (void)
     
    12711285#ifndef ELECTRIC_HEAP /* Drop this because it prevent JIT debugging. */
    12721286  SetUnhandledExceptionFilter(handle_runtime_exceptions);
    1273 #endif /* !ELECTRICT_HEAP */
     1287#endif /* !ELECTRIC_HEAP */
    12741288
    12751289  /* start off assuming we have no shell */
     
    14681482  user_access ();
    14691483
     1484#ifdef CONFIG_WITH_ALLOC_CACHES
     1485  initialize_global_alloc_caches ();
     1486#endif
    14701487  initialize_global_hash_tables ();
    14711488
     
    26742691                    char *p = *default_goal_name;
    26752692
     2693#ifndef CONFIG_WITH_ALLOC_CACHES
    26762694                    ns = multi_glob (
    26772695                      parse_file_seq (&p, '\0', sizeof (struct nameseq), 1),
    26782696                      sizeof (struct nameseq));
     2697#else
     2698                    ns = multi_glob (
     2699                      parse_file_seq (&p, '\0', &nameseq_cache, 1),
     2700                      &nameseq_cache);
     2701#endif
    26792702
    26802703                    /* .DEFAULT_GOAL should contain one target. */
     
    36043627  print_vpath_data_base ();
    36053628  strcache_print_stats ("#");
     3629#ifdef CONFIG_WITH_ALLOC_CACHES
     3630  alloccache_print_all ();
     3631#endif
    36063632
    36073633  when = time ((time_t *) 0);
  • trunk/src/kmk/make.h

    r1857 r1863  
    496496
    497497char *strip_whitespace (const char **begpp, const char **endpp);
     498
     499#ifdef CONFIG_WITH_ALLOC_CACHES
     500/* alloccache (misc.c) */
     501
     502struct alloccache_free_ent
     503{
     504  struct alloccache_free_ent *next;
     505};
     506
     507struct alloccache
     508{
     509  char *free_start;
     510  char *free_end;
     511  struct alloccache_free_ent *free_head;
     512  unsigned int size;
     513  unsigned int alloc_count;
     514  unsigned int total_count;
     515  const char *name;
     516  struct alloccache *next;
     517  void *grow_arg;
     518  void *(*grow_alloc)(void *grow_arg, unsigned int size);
     519};
     520
     521void alloccache_init (struct alloccache *cache, unsigned int size, const char *name,
     522                      void *(*grow_alloc)(void *grow_arg, unsigned int size), void *grow_arg);
     523void alloccache_join (struct alloccache *cache, struct alloccache *eat);
     524void alloccache_print (struct alloccache *cache);
     525void alloccache_print_all (void);
     526struct alloccache_free_ent *alloccache_alloc_grow (struct alloccache *cache);
     527
     528/* Allocate an item. */
     529MY_INLINE void *
     530alloccache_alloc (struct alloccache *cache)
     531{
     532  struct alloccache_free_ent *f = cache->free_head;
     533  if (f)
     534    cache->free_head = f->next;
     535  else if (cache->free_start != cache->free_end)
     536    {
     537      f = (struct alloccache_free_ent *)cache->free_start;
     538      cache->free_start += cache->size;
     539    }
     540  else
     541    f = alloccache_alloc_grow (cache);
     542  cache->alloc_count++;
     543  return f;
     544}
     545
     546/* Allocate a cleared item. */
     547MY_INLINE void *
     548alloccache_calloc (struct alloccache *cache)
     549{
     550  void *item = alloccache_alloc (cache);
     551  memset (item, '\0', cache->size);
     552  return item;
     553}
     554
     555/* Free an item. */
     556MY_INLINE void
     557alloccache_free (struct alloccache *cache, void *item)
     558{
     559  struct alloccache_free_ent *f = (struct alloccache_free_ent *)item;
     560#if 0 /*ndef NDEBUG*/
     561  struct alloccache_free_ent *c;
     562  unsigned int i = 0;
     563  for (c = cache->free_head; c != NULL; c = c->next, i++)
     564    MY_ASSERT_MSG (c != f && i < 0x10000000,
     565                   ("i=%u total_count=%u\n", i, cache->total_count));
     566#endif
     567
     568  f->next = cache->free_head;
     569  cache->free_head = f;
     570  cache->alloc_count--;
     571}
     572
     573/* the alloc caches */
     574extern struct alloccache dep_cache;
     575extern struct alloccache nameseq_cache;
     576extern struct alloccache variable_cache;
     577
     578#endif /* CONFIG_WITH_ALLOC_CACHES */
     579
    498580
    499581/* String caching  */
  • trunk/src/kmk/misc.c

    r1862 r1863  
    709709
    710710
    711 #ifdef KMK
    712 /* Cache free struct dep to save time in free during snap_deps.
    713    free is esp. slow on darwin for some reason. */
    714 static struct dep *free_deps = NULL;
    715 static struct dep *free_deps_start = NULL;
    716 static struct dep *free_deps_end = NULL;
    717 
    718 static struct dep *
    719 alloc_dep_int (void)
    720 {
    721   struct dep *d = free_deps;
    722   if (MY_PREDICT_TRUE(d))
    723     free_deps = d->next;
    724   else if (free_deps_start != free_deps_end)
    725     d = free_deps_start++;
    726   else
    727     {
    728       /* allocate another chunk block. */
    729       free_deps_start = xmalloc (sizeof (struct dep) * 256);
    730       free_deps_end = free_deps_start + 256;
    731       d = free_deps_start++;
    732     }
    733   return d;
    734 }
    735 
    736 static void
    737 free_dep_int (struct dep *d)
    738 {
    739   d->next = free_deps;
    740   free_deps = d;
    741 }
    742 #endif /* KMK */
    743 
    744 
    745711/* Allocate a new `struct dep' with all fields initialized to 0.   */
    746712
     
    748714alloc_dep ()
    749715{
    750 #ifndef KMK
     716#ifndef CONFIG_WITH_ALLOC_CACHES
    751717  struct dep *d = xmalloc (sizeof (struct dep));
    752 #else
    753   struct dep *d = alloc_dep_int ();
    754 #endif
    755718  memset (d, '\0', sizeof (struct dep));
    756719  return d;
     720#else
     721  return (struct dep *) alloccache_calloc (&dep_cache);
     722#endif
    757723}
    758724
     
    763729free_dep (struct dep *d)
    764730{
    765 #ifndef KMK
     731#ifndef CONFIG_WITH_ALLOC_CACHES
    766732  free (d);
    767733#else
    768   free_dep_int (d);
     734  alloccache_free (&dep_cache, d);
    769735#endif
    770736}
     
    781747  while (d != 0)
    782748    {
    783 #ifndef KMK
     749#ifndef CONFIG_WITH_ALLOC_CACHES
    784750      struct dep *c = xmalloc (sizeof (struct dep));
    785751#else
    786       struct dep *c = alloc_dep_int ();
     752      struct dep *c = (struct dep *) alloccache_alloc (&dep_cache);
    787753#endif
    788754      memcpy (c, d, sizeof (struct dep));
     
    809775      struct dep *df = d;
    810776      d = d->next;
    811 #ifndef KMK
     777#ifndef CONFIG_WITH_ALLOC_CACHES
    812778      free_dep (df);
    813779#else
    814       free_dep_int (df);
     780      alloccache_free (&dep_cache, df);
    815781#endif
    816782    }
     
    827793      struct nameseq *t = ns;
    828794      ns = ns->next;
     795#ifndef CONFIG_WITH_ALLOC_CACHES
    829796      free (t);
     797#else
     798      alloccache_free (&nameseq_cache, t);
     799#endif
    830800    }
    831801}
     
    11911161#endif
    11921162
     1163
     1164#ifdef CONFIG_WITH_ALLOC_CACHES
     1165
     1166/* Default allocator. */
     1167static void *
     1168alloccache_default_grow_alloc(void *ignore, unsigned int size)
     1169{
     1170  return xmalloc (size);
     1171}
     1172
     1173/* Worker for growing the cache. */
     1174struct alloccache_free_ent *
     1175alloccache_alloc_grow (struct alloccache *cache)
     1176{
     1177  void *item;
     1178  unsigned int items = (64*1024 - 32) / cache->size;
     1179  cache->free_start  = cache->grow_alloc (cache->grow_arg, items * cache->size);
     1180  cache->free_end    = cache->free_start + items * cache->size;
     1181  cache->total_count+= items;
     1182
     1183#ifndef NDEBUG /* skip the first item so the heap can detect free(). */
     1184  cache->total_count--;
     1185  cache->free_start += cache->size;
     1186#endif
     1187
     1188  item = cache->free_start;
     1189  cache->free_start += cache->size;
     1190  /* caller counts */
     1191  return (struct alloccache_free_ent *)item;
     1192}
     1193
     1194/* List of alloc caches, for printing. */
     1195static struct alloccache *alloccache_head = NULL;
     1196
     1197/* Initializes an alloc cache */
     1198void
     1199alloccache_init (struct alloccache *cache, unsigned int size, const char *name,
     1200                 void *(*grow_alloc)(void *grow_arg, unsigned int size), void *grow_arg)
     1201{
     1202  /* ensure aligned and min sizeof (struct alloccache_free_ent). */
     1203  if (size & (sizeof (void *) - 1))
     1204    size += sizeof (void *) - (size & (sizeof (void *) - 1));
     1205
     1206  cache->free_start  = NULL;
     1207  cache->free_end    = NULL;
     1208  cache->free_head   = NULL;
     1209  cache->size        = size;
     1210  cache->alloc_count = 0;
     1211  cache->total_count = 0;
     1212  cache->name        = name;
     1213  cache->grow_arg    = grow_arg;
     1214  cache->grow_alloc  = grow_alloc ? grow_alloc : alloccache_default_grow_alloc;
     1215
     1216  cache->next        = alloccache_head;
     1217  alloccache_head    = cache;
     1218}
     1219
     1220/* Joins to caches, unlinking the 2nd one. */
     1221void
     1222alloccache_join (struct alloccache *cache, struct alloccache *eat)
     1223{
     1224  assert (cache->size == eat->size);
     1225
     1226#if 0 /* probably a waste of time */ /* FIXME: Optimize joining, avoid all list walking. */
     1227  /* add the free list... */
     1228  if (eat->free_head)
     1229    {
     1230     if (!cache->free_head)
     1231       cache->free_head = eat->free_head;
     1232     else if (eat->total_count - eat->alloc_count < cache->total_count - cache->alloc_count)
     1233       {
     1234         struct alloccache_free_ent *last = eat->free_head;
     1235         while (last->next)
     1236           last = last->next;
     1237         last->next = cache->free_head;
     1238         cache->free_head = eat->free_head;
     1239       }
     1240     else
     1241       {
     1242         struct alloccache_free_ent *last = cache->free_head;
     1243         while (last->next)
     1244           last = last->next;
     1245         last->next = eat->free_head;
     1246       }
     1247    }
     1248
     1249  /* ... and the free space. */
     1250  while (eat->free_start != eat->free_end)
     1251    {
     1252      struct alloccache_free_ent *f = (struct alloccache_free_ent *)eat->free_start;
     1253      eat->free_start += eat->size;
     1254      f->next = cache->free_head;
     1255      cache->free_head = f;
     1256    }
     1257
     1258  /* and statistics */
     1259  cache->alloc_count += eat->alloc_count;
     1260  cache->total_count += eat->total_count;
     1261#else
     1262  /* and statistics */
     1263  cache->alloc_count += eat->alloc_count;
     1264  cache->total_count += eat->alloc_count;
     1265#endif
     1266
     1267  /* unlink and disable the eat cache */
     1268  if (alloccache_head == eat)
     1269    alloccache_head = eat->next;
     1270  else
     1271    {
     1272      struct alloccache *cur = alloccache_head;
     1273      while (cur->next != eat)
     1274        cur = cur->next;
     1275      assert (cur && cur->next == eat);
     1276      cur->next = eat->next;
     1277    }
     1278
     1279  eat->size = 0;
     1280  eat->free_end = eat->free_start = NULL;
     1281  eat->free_head = NULL;
     1282}
     1283
     1284/* Print one alloc cache. */
     1285void
     1286alloccache_print (struct alloccache *cache)
     1287{
     1288  printf (_("\n# Alloc Cache: %s item size: %u  alloc: %d  total: %u\n"),
     1289          cache->name, cache->size, (int)cache->alloc_count, cache->total_count);
     1290}
     1291
     1292/* Print all alloc caches. */
     1293void
     1294alloccache_print_all (void)
     1295{
     1296  struct alloccache *cur;
     1297  for (cur = alloccache_head; cur; cur = cur->next)
     1298    alloccache_print (cur);
     1299}
     1300
     1301#endif /* CONFIG_WITH_ALLOC_CACHES */
  • trunk/src/kmk/read.c

    r1862 r1863  
    10171017          /* Parse the list of file names.  */
    10181018          p2 = p;
     1019#ifndef CONFIG_WITH_ALLOC_CACHES
    10191020          files = multi_glob (parse_file_seq (&p2, '\0',
    10201021                                              sizeof (struct nameseq),
    10211022                                              1),
    10221023                              sizeof (struct nameseq));
     1024#else
     1025          files = multi_glob (parse_file_seq (&p2, '\0', &nameseq_cache, 1),
     1026                              &nameseq_cache);
     1027#endif
    10231028          free (p);
    10241029
     
    10381043              int r;
    10391044
     1045#ifndef CONFIG_WITH_ALLOC_CACHES
    10401046              free (files);
     1047#else
     1048              alloccache_free (&nameseq_cache, files);
     1049#endif
    10411050              files = next;
    10421051
     
    12511260           looking for targets.  */
    12521261        *colonp = '\0';
     1262#ifndef CONFIG_WITH_ALLOC_CACHES
    12531263        filenames = multi_glob (parse_file_seq (&p2, '\0',
    12541264                                                sizeof (struct nameseq),
    12551265                                                1),
    12561266                                sizeof (struct nameseq));
     1267#else
     1268        filenames = multi_glob (parse_file_seq (&p2, '\0', &nameseq_cache, 1),
     1269                                &nameseq_cache);
     1270#endif
    12571271        *p2 = ':';
    12581272
     
    14061420          {
    14071421            struct nameseq *target;
     1422#ifndef CONFIG_WITH_ALLOC_CACHES
    14081423            target = parse_file_seq (&p2, ':', sizeof (struct nameseq), 1);
     1424#else
     1425            target = parse_file_seq (&p2, ':', &nameseq_cache, 1);
     1426#endif
    14091427            ++p2;
    14101428            if (target == 0)
     
    14161434            if (pattern_percent == 0)
    14171435              fatal (fstart, _("target pattern contains no `%%' (target `%s')"), target->name); /* bird */
     1436#ifndef CONFIG_WITH_ALLOC_CACHES
    14181437            free (target);
     1438#else
     1439            alloccache_free (&nameseq_cache, target);
     1440#endif
    14191441          }
    14201442        else
     
    24242446
    24252447      nextf = filenames->next;
     2448#ifndef CONFIG_WITH_ALLOC_CACHES
    24262449      free (filenames);
     2450#else
     2451      alloccache_free (&nameseq_cache, filenames);
     2452#endif
    24272453
    24282454      /* Check for special targets.  Do it here instead of, say, snap_deps()
     
    29592985   If STRIP is nonzero, strip `./'s off the beginning.  */
    29602986
     2987#ifndef CONFIG_WITH_ALLOC_CACHES
    29612988struct nameseq *
    29622989parse_file_seq (char **stringp, int stopchar, unsigned int size, int strip)
     2990#else
     2991struct nameseq *
     2992parse_file_seq (char **stringp, int stopchar, struct alloccache *cache, int strip)
     2993#endif
    29632994{
    29642995  struct nameseq *new = 0;
     
    30793110
    30803111      /* Add it to the front of the chain.  */
    3081 #if !defined(KMK) || !defined(NO_ARCHIVES)
     3112#ifndef CONFIG_WITH_ALLOC_CACHES
    30823113      new1 = xmalloc (size);
    30833114#else
    3084       if (sizeof (struct dep) == size) /* use the cache */
    3085         new1 = (struct nameseq *)alloc_dep ();
    3086       else
    3087         new1 = xmalloc (size);
     3115      new1 = (struct nameseq *)alloccache_alloc (cache);
    30883116#endif
    30893117      new1->name = name;
     
    31383166                   Edit it out of the chain and free its storage.  */
    31393167                lastn->next = n->next;
     3168#ifndef CONFIG_WITH_ALLOC_CACHES
    31403169                free (n);
     3170#else
     3171                alloccache_free (cache, n);
     3172#endif
    31413173                /* LASTN->next is the new stopping elt for the loop below.  */
    31423174                n = lastn->next;
     
    31583190                lastn = new1;
    31593191                new1 = new1->next;
     3192#ifndef CONFIG_WITH_ALLOC_CACHES
    31603193                free (lastn);
     3194#else
     3195                alloccache_free (cache, lastn);
     3196#endif
    31613197              }
    31623198            else
     
    37943830   that have room for additional info.  */
    37953831
     3832#ifndef CONFIG_WITH_ALLOC_CACHES
    37963833struct nameseq *
    37973834multi_glob (struct nameseq *chain, unsigned int size)
     3835#else
     3836struct nameseq *
     3837multi_glob (struct nameseq *chain, struct alloccache *cache)
     3838#endif
    37983839{
    37993840  void dir_setup_glob (glob_t *);
     
    38963937#endif /* !NO_ARCHIVES */
    38973938                  {
    3898 #if !defined(KMK) && !defined(NO_ARCHIVES)
     3939#ifndef CONFIG_WITH_ALLOC_CACHES
    38993940                    struct nameseq *elt = xmalloc (size);
    3900 #else
    3901                     struct nameseq *elt = size == sizeof(struct dep)
    3902                                         ? (void *)alloc_dep() : xmalloc (size);
    3903 #endif
    39043941                    memset (elt, '\0', size);
     3942#else
     3943                    struct nameseq *elt = alloccache_calloc (cache);
     3944#endif
    39053945                    elt->name = strcache_add (gl.gl_pathv[i]);
    39063946                    elt->next = new;
     
    39123952#endif
    39133953            globfree (&gl);
    3914 #if !defined(KMK) && !defined(NO_ARCHIVES)
     3954#ifndef CONFIG_WITH_ALLOC_CACHES
    39153955            free (old);
    39163956#else
    3917             if (size == sizeof(struct dep))
    3918               free_dep ((struct dep *)old);
    3919             else
    3920               free (old);
     3957            alloccache_free (cache, old);
    39213958#endif
    39223959            break;
  • trunk/src/kmk/rule.c

    r903 r1863  
    380380
    381381  ptr = p->dep;
     382#ifndef CONFIG_WITH_ALLOC_CACHES
    382383  r->deps = (struct dep *) multi_glob (parse_file_seq (&ptr, '\0',
    383384                                                       sizeof (struct dep), 1),
    384385                                       sizeof (struct dep));
     386#else
     387  r->deps = (struct dep *) multi_glob (parse_file_seq (&ptr, '\0',
     388                                                       &dep_cache, 1),
     389                                       &dep_cache);
     390#endif
    385391
    386392  if (new_pattern_rule (r, 0))
  • trunk/src/kmk/variable.c

    r1840 r1863  
    429429variable_hash_cmp_2_inlined (const char *xs, const char *ys, unsigned int length)
    430430{
     431#ifndef ELECTRIC_HEAP
    431432  assert ( !((size_t)ys & 3) );
     433#endif
    432434  if (!((size_t)xs & 3))
    433435    {
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