Stackdb
Stackdb is a stackable, multi-target and -level source debugger and memory forensics library.
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
memcache.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2014 The University of Utah
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License as
6  * published by the Free Software Foundation; either version 2 of
7  * the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
17  */
18 
19 #include "config.h"
20 #include <sys/mman.h>
21 #include "common.h"
22 #include "log.h"
23 #include "clfit.h"
24 #include "memcache.h"
25 #include "glib.h"
26 
27 /*
28  * Local prototypes.
29  */
30 static void __memcache_clrangesimple_dtor(ADDR start,ADDR end,void *data,
31  void *dtor_data);
32 
33 struct memcache *memcache_create(unsigned long int max_v2p,
34  unsigned long int max_mmap_size,
35  memcache_tag_priv_dtor pdtor) {
36  struct memcache *retval;
37 
38  retval = (struct memcache *)calloc(1,sizeof(*retval));
39  retval->max_v2p = max_v2p;
40  retval->max_mmap_size = max_mmap_size;
41  retval->current_mmap_size = 0;
42  retval->cache = g_hash_table_new_full(g_direct_hash,g_direct_equal,
43  NULL,NULL);
44  retval->tag_priv_dtor = pdtor;
45 
46  return retval;
47 }
48 
50  GHashTableIter iter;
51  gpointer kp,vp;
52  struct memcache_tag_entry *mte;
53 
54  g_hash_table_iter_init(&iter,memcache->cache);
55  while (g_hash_table_iter_next(&iter,&kp,&vp)) {
56  mte = (struct memcache_tag_entry *)vp;
57  memcache_invalidate_all_v2p(memcache,(ADDR)kp);
58  memcache_invalidate_all_mmap(memcache,(ADDR)kp);
59  g_hash_table_destroy(mte->v2p_cache);
60 
61  clrangesimple_free(mte->mmap_cache_p,__memcache_clrangesimple_dtor,
62  memcache);
64  clrangesimple_free(mte->mmap_cache_v,__memcache_clrangesimple_dtor,
65  memcache);
67 
68  if (memcache->tag_priv_dtor)
69  memcache->tag_priv_dtor((ADDR)kp,mte->priv);
70  free(mte);
71  g_hash_table_iter_remove(&iter);
72  }
73 
74  g_hash_table_destroy(memcache->cache);
75  free(memcache);
76 }
77 
79  GHashTableIter iter;
80  gpointer kp,vp;
81  struct memcache_tag_entry *mte;
82 
83  mte = (struct memcache_tag_entry *) \
84  g_hash_table_lookup(memcache->cache,(gpointer)tag);
85  if (!mte)
86  return 0;
87 
88  g_hash_table_iter_init(&iter,mte->v2p_cache);
89  while (g_hash_table_iter_next(&iter,&kp,&vp)) {
90  free(vp);
91  g_hash_table_iter_remove(&iter);
92  }
93 
94  mte->oldest_v2p = ADDRMAX;
95 
96  return 0;
97 }
98 
99 static void __memcache_clrangesimple_dtor(ADDR start,ADDR end,void *data,
100  void *dtor_data) {
101  struct memcache *memcache;
102  struct memcache_mmap_entry *mme;
103 
104  memcache = (struct memcache *)dtor_data;
105  mme = (struct memcache_mmap_entry *)data;
106 
107  munmap(mme->mem,mme->mem_len);
108  memcache->current_mmap_size -= mme->mem_len;
109 
111  "munmap(0x%p,%lu) (0x%"PRIxADDR",0x%"PRIxADDR")\n",
112  mme->mem,mme->mem_len,start,end);
113 
114  free(mme);
115 }
116 
118  struct memcache_tag_entry *mte;
119 
120  mte = (struct memcache_tag_entry *) \
121  g_hash_table_lookup(memcache->cache,(gpointer)tag);
122  if (!mte)
123  return 0;
124 
125  clrangesimple_free(mte->mmap_cache_p,__memcache_clrangesimple_dtor,memcache);
127  clrangesimple_free(mte->mmap_cache_v,__memcache_clrangesimple_dtor,memcache);
129 
130  mte->oldest_mmap_p = ADDRMAX;
131  mte->oldest_mmap_v = ADDRMAX;
132  mte->oldest_mmap_p_ticks = 0;
133  mte->oldest_mmap_v_ticks = 0;
134 
135  return 0;
136 }
137 
139  GHashTableIter iter;
140  gpointer kp;
141 
142  g_hash_table_iter_init(&iter,memcache->cache);
143  while (g_hash_table_iter_next(&iter,&kp,NULL)) {
144  memcache_invalidate_all_v2p(memcache,(ADDR)kp);
145  memcache_invalidate_all_mmap(memcache,(ADDR)kp);
146  }
147 
148  return 0;
149 }
150 
152  unsigned int new_ticks;
153  unsigned int max_unused_ticks;
155 };
156 
157 int __memcache_clrangesimple_foreach_inc_ticks(Word_t start,Word_t end,void *data,
158  void *hpriv) {
160  (struct __clrs_foreach_inc_ticks_data *)hpriv;
161  struct memcache_mmap_entry *mme = (struct memcache_mmap_entry *)data;
162 
163  mme->unused_ticks += d->new_ticks;
164  if (mme->unused_ticks > d->max_unused_ticks) {
165  d->max_unused_ticks = mme->unused_ticks;
166  d->max_unused_ticks_addr = start;
167  }
168 
169  return 0;
170 }
171 
172 static void _memcache_inc_ticks_tag_entry(struct memcache *memcache,
173  struct memcache_tag_entry *mte,
174  unsigned int new_ticks) {
175  GHashTableIter iter2;
176  gpointer kp2,vp2;
177  ADDR vaddr;
178  struct memcache_v2p_entry *mve;
179  ADDR oldest;
180  unsigned int ticks;
182 
183  /*
184  * Use ADDRMAX as our magic value because mmaps only happen at
185  * page boundaries, and anything ending in 0xfff is not a page
186  * boundary, basically. And nobody has < 4096B pages.
187  */
188  oldest = ADDRMAX;
189  ticks = 0;
190  g_hash_table_iter_init(&iter2,mte->v2p_cache);
191  while (g_hash_table_iter_next(&iter2,&kp2,&vp2)) {
192  vaddr = (ADDR)kp2;
193  mve = (struct memcache_v2p_entry *)vp2;
194 
195  mve->unused_ticks += new_ticks;
196  if (mve->unused_ticks > ticks) {
197  ticks = mve->unused_ticks;
198  oldest = vaddr;
199  }
200  }
201  mte->oldest_v2p = oldest;
202 
203  d.new_ticks = new_ticks;
204  d.max_unused_ticks = 0;
205  d.max_unused_ticks_addr = ADDRMAX;
208  mte->oldest_mmap_p = d.max_unused_ticks_addr;
209  mte->oldest_mmap_p_ticks = d.max_unused_ticks;
210 
211  d.new_ticks = new_ticks;
212  d.max_unused_ticks = 0;
213  d.max_unused_ticks_addr = ADDRMAX;
216  mte->oldest_mmap_v = d.max_unused_ticks_addr;
217  mte->oldest_mmap_v_ticks = d.max_unused_ticks;
218 }
219 
220 void memcache_inc_ticks(struct memcache *memcache,unsigned int new_ticks) {
221  GHashTableIter iter;
222  gpointer vp;
223  struct memcache_tag_entry *mte;
224 
225  g_hash_table_iter_init(&iter,memcache->cache);
226  while (g_hash_table_iter_next(&iter,NULL,&vp)) {
227  mte = (struct memcache_tag_entry *)vp;
228  _memcache_inc_ticks_tag_entry(memcache,mte,new_ticks);
229  }
230 }
231 
232 int memcache_get_v2p(struct memcache *memcache,ADDR tag,ADDR va,
233  ADDR *pa,void **tag_priv) {
234  struct memcache_tag_entry *mte;
235  struct memcache_v2p_entry *mve;
236 
237  mte = (struct memcache_tag_entry *) \
238  g_hash_table_lookup(memcache->cache,(gpointer)tag);
239  if (!mte)
240  return 1;
241 
242  mve = (struct memcache_v2p_entry *) \
243  g_hash_table_lookup(mte->v2p_cache,(gpointer)va);
244  if (!mve)
245  return 1;
246 
247  /* Found it! */
249  "CACHE HIT: v 0x%"PRIxADDR" -> p 0x%"PRIxADDR" (tag 0x%"PRIxADDR")\n",
250  va,mve->pa,tag);
251 
252  /* Invalidate this entry and our current guess of oldest, if necessary. */
253  mve->unused_ticks = 1;
254  if (mte->oldest_v2p == va)
255  mte->oldest_v2p = ADDRMAX;
256 
257  if (pa)
258  *pa = mve->pa;
259  if (tag_priv)
260  *tag_priv = mte->priv;
261 
262  return 0;
263 }
264 
265 int memcache_get_mmap(struct memcache *memcache,ADDR tag,ADDR pa,
266  unsigned long int pa_len,memcache_flags_t flags,
267  ADDR *pa_start,OFFSET *pa_offset,
268  void **mem,unsigned long int *mem_len,void **tag_priv) {
269  struct memcache_tag_entry *mte;
270  ADDR __pa_start;
271  void *data;
272  struct memcache_mmap_entry *mme;
273  int rc;
274  clrangesimple_t *clr;
275 
276  mte = (struct memcache_tag_entry *) \
277  g_hash_table_lookup(memcache->cache,(gpointer)tag);
278  if (!mte)
279  return 1;
280 
281  clr = &mte->mmap_cache_p;
282  if (flags & MEMCACHE_VIRT)
283  clr = &mte->mmap_cache_v;
284 
285  rc = clrangesimple_find(clr,pa,&__pa_start,NULL,&data);
286  if (rc == -1 || rc == 1)
287  return 1;
288 
289  /* Found it! */
290  mme = (struct memcache_mmap_entry *)data;
291 
292  if ((mme->mem_len - (pa - __pa_start)) < pa_len) {
294  "CACHE MISS LEN %s 0x%"PRIxADDR" len %lu (for p 0x%"PRIxADDR"),"
295  " but not long enough (needed %lu; %lu short)!\n",
296  (flags & MEMCACHE_VIRT) ? "v" : "p",
297  __pa_start,mme->mem_len,pa,pa_len,
298  pa_len - (mme->mem_len - (pa - __pa_start)));
299  return 1;
300  }
301 
303  "CACHE HIT %s 0x%"PRIxADDR" len %lu (at 0x%p) (for p 0x%"PRIxADDR" %lu)\n",
304  (flags & MEMCACHE_VIRT) ? "v" : "p",
305  __pa_start,mme->mem_len,mme->mem,pa,pa_len);
306 
307  /* Invalidate this entry and our current guess of oldest, if necessary. */
308  mme->unused_ticks = 1;
309  if (flags & MEMCACHE_VIRT) {
310  if (mte->oldest_mmap_v == __pa_start) {
311  mte->oldest_mmap_v = ADDRMAX;
312  mte->oldest_mmap_v_ticks = 0;
313  }
314  }
315  else {
316  if (mte->oldest_mmap_p == __pa_start) {
317  mte->oldest_mmap_p = ADDRMAX;
318  mte->oldest_mmap_p_ticks = 0;
319  }
320  }
321 
322  if (pa_start)
323  *pa_start = __pa_start;
324  if (pa_offset)
325  *pa_offset = pa - __pa_start;
326  if (mem)
327  *mem = mme->mem;
328  if (mem_len)
329  *mem_len = mme->mem_len;
330  if (tag_priv)
331  *tag_priv = mte->priv;
332 
333  return 0;
334 }
335 
336 static struct memcache_tag_entry *__memcache_mte_create(void *tag_priv) {
337  struct memcache_tag_entry *mte;
338 
339  mte = (struct memcache_tag_entry *)calloc(1,sizeof(*mte));
340  mte->priv = tag_priv;
341  mte->oldest_v2p = ADDRMAX;
342  mte->oldest_mmap_p = ADDRMAX;
343  mte->oldest_mmap_v = ADDRMAX;
344  mte->oldest_mmap_p_ticks = 0;
345  mte->oldest_mmap_v_ticks = 0;
346  mte->v2p_cache = g_hash_table_new_full(g_direct_hash,g_direct_equal,
347  NULL,NULL);
350 
351  return mte;
352 }
353 
354 int memcache_set_tag_priv(struct memcache *memcache,ADDR tag,void *tag_priv) {
355  struct memcache_tag_entry *mte;
356 
357  mte = (struct memcache_tag_entry *) \
358  g_hash_table_lookup(memcache->cache,(gpointer)tag);
359  if (!mte) {
360  mte = __memcache_mte_create(tag_priv);
361  g_hash_table_insert(memcache->cache,(gpointer)tag,mte);
362  }
363 
364  mte->priv = tag_priv;
365 
366  return 0;
367 }
368 
369 int memcache_set_v2p(struct memcache *memcache,ADDR tag,ADDR va,ADDR pa) {
370  struct memcache_tag_entry *mte;
371  struct memcache_v2p_entry *mve;
372 
373  mte = (struct memcache_tag_entry *) \
374  g_hash_table_lookup(memcache->cache,(gpointer)tag);
375  if (!mte) {
376  mte = __memcache_mte_create(NULL);
377  g_hash_table_insert(memcache->cache,(gpointer)tag,mte);
378  }
379 
380  mve = (struct memcache_v2p_entry *) \
381  g_hash_table_lookup(mte->v2p_cache,(gpointer)va);
382  if (!mve) {
383  mve = (struct memcache_v2p_entry *)calloc(1,sizeof(*mve));
384  g_hash_table_insert(mte->v2p_cache,(gpointer)va,mve);
386  "CACHE ENTRY: v 0x%"PRIxADDR" -> p 0x%"PRIxADDR" (tag 0x%"PRIxADDR")\n",
387  va,pa,tag);
388  }
389  else {
391  "CACHE REPLACE: v 0x%"PRIxADDR", old p 0x%"PRIxADDR
392  " new p 0x%"PRIxADDR" (tag 0x%"PRIxADDR")\n",
393  va,mve->pa,pa,tag);
394  }
395 
396  mve->unused_ticks = 1;
397  mve->pa = pa;
398 
399  return 0;
400 }
401 
402 int memcache_set_mmap(struct memcache *memcache,ADDR tag,ADDR pa,
403  memcache_flags_t flags,
404  void *mem,unsigned long int mem_len) {
405  struct memcache_tag_entry *mte;
406  struct memcache_mmap_entry *mme;
407  int rc;
408  clrangesimple_t *clr;
409  unsigned long int overage = 0;
410  unsigned long int evicted = 0;
411 
412  mte = (struct memcache_tag_entry *) \
413  g_hash_table_lookup(memcache->cache,(gpointer)tag);
414  if (!mte) {
415  mte = __memcache_mte_create(NULL);
416  g_hash_table_insert(memcache->cache,(gpointer)tag,mte);
417  }
418 
419  mme = (struct memcache_mmap_entry *)calloc(1,sizeof(*mme));
420  mme->mem = mem;
421  mme->mem_len = mem_len;
422  mme->unused_ticks = 1;
423 
424  clr = &mte->mmap_cache_p;
425  if (flags & MEMCACHE_VIRT)
426  clr = &mte->mmap_cache_v;
427 
428  if ((memcache->current_mmap_size + mem_len) > memcache->max_mmap_size) {
429  overage =
430  (memcache->current_mmap_size + mem_len) - memcache->max_mmap_size;
431 
433  "need to evict %lu bytes to make room for new %lu byte chunk!\n",
434  overage,mem_len);
435 
436  evicted = memcache_lru_evict_mmap(memcache,MEMCACHE_TAG_ANY,
437  MEMCACHE_VIRT,overage);
438  if (evicted < overage)
439  evicted += memcache_lru_evict_mmap(memcache,MEMCACHE_TAG_ANY,
440  MEMCACHE_PHYS,overage - evicted);
441 
442  if (evicted < overage) {
444  "could not evict %lu bytes to make room for new %lu byte"
445  " chunk; only evited %lu bytes; cannot cache mmap!\n",
446  overage,mem_len,evicted);
447  errno = ENOMEM;
448  return -1;
449  }
450  }
451 
452  rc = clrangesimple_add(clr,pa,pa + mem_len,mme);
453  if (rc == -1) {
454  vwarn("internal error; cannot cache mmap of %s 0x%"PRIxADDR" at 0x%p!\n",
455  (flags & MEMCACHE_VIRT) ? "v" : "p",pa,mem);
456  free(mme);
457  return -1;
458  }
459  else if (rc == 1) {
461  "cannot cache mmap of %s 0x%"PRIxADDR" at 0x%p; already used!\n",
462  (flags & MEMCACHE_VIRT) ? "v" : "p",pa,mem);
463  free(mme);
464  return 1;
465  }
466 
467  memcache->current_mmap_size += mem_len;
468 
470  "CACHE ENTRY %s 0x%"PRIxADDR" len %lu tag 0x%"PRIxADDR" (at 0x%p)\n",
471  (flags & MEMCACHE_VIRT) ? "v" : "p",pa,mem_len,tag,mem);
472 
473  return 0;
474 }
475 
476 int __memcache_clrangesimple_print(ADDR start,ADDR end,void *data,void *hpriv) {
477  struct memcache_mmap_entry *mme = (struct memcache_mmap_entry *)data;
478 
480  "Range 0x%"PRIxADDR",0x%"PRIxADDR" (ticks %u len %lu)\n",
481  start,end,mme->unused_ticks,mme->mem_len);
482 
483  return 0;
484 }
485 
486 unsigned long int memcache_lru_evict_mmap(struct memcache *memcache,ADDR tag,
487  memcache_flags_t flags,
488  unsigned long int mem_len) {
489  GHashTableIter iter;
490  gpointer kp,vp;
491  struct memcache_tag_entry *mte;
492  struct memcache_tag_entry *oldest_mte;
493  struct memcache_mmap_entry *mme;
494  ADDR oldest,end;
495  unsigned int ticks;
496  int is_phys;
497  unsigned long int evicted = 0;
498  int rc;
499  int didinc = 0;
500 
501  if (flags == 0)
502  flags = MEMCACHE_VIRT | MEMCACHE_PHYS;
503 
504  while (evicted < mem_len) {
505  if (memcache->current_mmap_size == 0) {
507  "cache is empty; evicted %lu of requested %lu bytes\n",
508  evicted,mem_len);
509  break;
510  }
511 
512  ticks = 0;
513  is_phys = 0;
514  oldest = ADDRMAX;
515  oldest_mte = NULL;
516 
517  g_hash_table_iter_init(&iter,memcache->cache);
518  while (g_hash_table_iter_next(&iter,&kp,&vp)) {
519  didinc = 0;
520  mte = (struct memcache_tag_entry *)vp;
521  if (tag != MEMCACHE_TAG_ANY && (ADDR)kp != tag)
522  continue;
523 
524  if (flags & MEMCACHE_PHYS) {
525  if (mte->oldest_mmap_p == ADDRMAX) {
526  _memcache_inc_ticks_tag_entry(memcache,mte,0);
527  didinc = 1;
528  }
529 
530  if (mte->oldest_mmap_p < ADDRMAX
531  && mte->oldest_mmap_p_ticks > ticks) {
532  ticks = mte->oldest_mmap_p_ticks;
533  oldest = mte->oldest_mmap_p;
534  oldest_mte = mte;
535  is_phys = 1;
536  }
537  }
538 
539  if (flags & MEMCACHE_VIRT) {
540  if (mte->oldest_mmap_v == ADDRMAX && !didinc)
541  _memcache_inc_ticks_tag_entry(memcache,mte,0);
542 
543  if (mte->oldest_mmap_v < ADDRMAX
544  && mte->oldest_mmap_v_ticks > ticks) {
545  ticks = mte->oldest_mmap_v_ticks;
546  oldest = mte->oldest_mmap_v;
547  oldest_mte = mte;
548  is_phys = 0;
549  }
550  }
551  }
552 
553  mme = NULL;
554  if (oldest_mte) {
555  /* We have one to evict; do it! */
556  if (is_phys)
557  rc = clrangesimple_remove(&oldest_mte->mmap_cache_p,oldest,&end,
558  (void **)&mme);
559  else
560  rc = clrangesimple_remove(&oldest_mte->mmap_cache_v,oldest,&end,
561  (void **)&mme);
562 
563  if (rc < 0) {
564  verror("failed to remove range in eviction; aborting!");
565  break;
566  }
567  else if (rc == 1) {
568  verror("could not find cached range 0x%"PRIxADDR
569  " in eviction; BUG!; aborting!\n",oldest);
570  if (is_phys)
573  else
576  break;
577  }
578  else {
579  evicted += mme->mem_len;
580 
581  munmap(mme->mem,mme->mem_len);
582  memcache->current_mmap_size -= mme->mem_len;
583 
584  if (is_phys) {
585  oldest_mte->oldest_mmap_p = ADDRMAX;
586  oldest_mte->oldest_mmap_p_ticks = 0;
587  }
588  else {
589  oldest_mte->oldest_mmap_v = ADDRMAX;
590  oldest_mte->oldest_mmap_v_ticks = 0;
591  }
592 
594  "munmap(0x%p,%lu) (%s 0x%"PRIxADDR",0x%"PRIxADDR")\n",
595  mme->mem,mme->mem_len,is_phys ? "p" : "v",oldest,end);
596 
597  free(mme);
598  }
599  }
600  else {
601  vwarn("could not find anything to evict; evicted %lu of %lu bytes\n",
602  evicted,mem_len);
603  break;
604  }
605  }
606 
608  "evicted %lu of requested %lu bytes\n",evicted,mem_len);
609 
610  return evicted;
611 }
#define MEMCACHE_TAG_ANY
Definition: memcache.h:45
int memcache_get_mmap(struct memcache *memcache, ADDR tag, ADDR pa, unsigned long int pa_len, memcache_flags_t flags, ADDR *pa_start, OFFSET *pa_offset, void **mem, unsigned long int *mem_len, void **tag_priv)
Definition: memcache.c:265
#define vwarnopt(level, area, flags, format,...)
Definition: log.h:37
void clrangesimple_free(clrangesimple_t clr, clrangesimple_free_dtor dtor, void *dtor_data)
Definition: clfit.c:804
Definition: memcache.h:62
unsigned int oldest_mmap_v_ticks
Definition: memcache.h:101
ADDR pa
Definition: memcache.h:107
int __memcache_clrangesimple_print(ADDR start, ADDR end, void *data, void *hpriv)
Definition: memcache.c:476
int memcache_set_mmap(struct memcache *memcache, ADDR tag, ADDR pa, memcache_flags_t flags, void *mem, unsigned long int mem_len)
Definition: memcache.c:402
clrangesimple_t clrangesimple_create(void)
Definition: clfit.c:648
int memcache_invalidate_all_mmap(struct memcache *memcache, ADDR tag)
Definition: memcache.c:117
unsigned long int max_mmap_size
Definition: memcache.h:56
int32_t OFFSET
Definition: common.h:65
#define verror(format,...)
Definition: log.h:30
int memcache_invalidate_all_v2p(struct memcache *memcache, ADDR tag)
Definition: memcache.c:78
int __memcache_clrangesimple_foreach_inc_ticks(Word_t start, Word_t end, void *data, void *hpriv)
Definition: memcache.c:157
#define vwarn(format,...)
Definition: log.h:33
#define ADDRMAX
Definition: common.h:74
clrangesimple_t mmap_cache_v
Definition: memcache.h:86
void free(void *ptr)
Definition: debugserver.c:207
GHashTable * cache
Definition: memcache.h:58
int memcache_get_v2p(struct memcache *memcache, ADDR tag, ADDR va, ADDR *pa, void **tag_priv)
Definition: memcache.c:232
memcache_flags_t
Definition: memcache.h:49
GHashTable * v2p_cache
Definition: memcache.h:64
clrangesimple_t mmap_cache_p
Definition: memcache.h:85
memcache_tag_priv_dtor tag_priv_dtor
Definition: memcache.h:59
int memcache_set_v2p(struct memcache *memcache, ADDR tag, ADDR va, ADDR pa)
Definition: memcache.c:369
ADDR oldest_v2p
Definition: memcache.h:97
Pvoid_t clrangesimple_t
Definition: clfit.h:95
int clrangesimple_remove(clrangesimple_t *clr, Word_t index, Word_t *end, void **data)
Definition: clfit.c:739
unsigned long int memcache_lru_evict_mmap(struct memcache *memcache, ADDR tag, memcache_flags_t flags, unsigned long int mem_len)
Definition: memcache.c:486
void memcache_destroy(struct memcache *memcache)
Definition: memcache.c:49
unsigned int oldest_mmap_p_ticks
Definition: memcache.h:100
ADDR oldest_mmap_p
Definition: memcache.h:98
#define vdebug(devel, areas, flags, format,...)
Definition: log.h:302
int memcache_invalidate_all(struct memcache *memcache)
Definition: memcache.c:138
void * calloc(size_t nmemb, size_t size)
Definition: debugserver.c:200
Definition: log.h:70
int memcache_set_tag_priv(struct memcache *memcache, ADDR tag, void *tag_priv)
Definition: memcache.c:354
unsigned long int current_mmap_size
Definition: memcache.h:57
void * priv
Definition: memcache.h:63
unsigned long int mem_len
Definition: memcache.h:113
uint32_t ADDR
Definition: common.h:64
struct memcache * memcache_create(unsigned long int max_v2p, unsigned long int max_mmap_size, memcache_tag_priv_dtor pdtor)
Definition: memcache.c:33
int clrangesimple_add(clrangesimple_t *clr, Word_t start, Word_t end, void *data)
Definition: clfit.c:652
void memcache_inc_ticks(struct memcache *memcache, unsigned int new_ticks)
Definition: memcache.c:220
Definition: memcache.h:110
#define PRIxADDR
Definition: common.h:67
int clrangesimple_foreach(clrangesimple_t clr, clrangesimple_foreach_handler handler, void *hpriv)
Definition: clfit.c:779
int clrangesimple_find(clrangesimple_t *clr, Word_t index, Word_t *start, Word_t *end, void **data)
Definition: clfit.c:713
ADDR oldest_mmap_v
Definition: memcache.h:99
Definition: memcache.h:104
unsigned int unused_ticks
Definition: memcache.h:106
unsigned int unused_ticks
Definition: memcache.h:112
unsigned long int max_v2p
Definition: memcache.h:55
unsigned int max_unused_ticks
Definition: memcache.c:153
void * mem
Definition: memcache.h:114
void(* memcache_tag_priv_dtor)(ADDR tag, void *tag_priv)
Definition: memcache.h:47