memory.c (1649B)
1 /* memory.c 2 * (c) 2002 Mikulas Patocka 3 * This file is a part of the Links program, released under GPL. 4 */ 5 6 #include "links.h" 7 8 struct cache_upcall { 9 list_entry_1st; 10 int (*upcall)(int); 11 unsigned char flags; 12 unsigned char name[1]; 13 }; 14 15 static struct list_head cache_upcalls = { &cache_upcalls, 16 &cache_upcalls }; /* cache_upcall */ 17 18 int 19 shrink_memory(int type) 20 { 21 struct cache_upcall *c = NULL; 22 struct list_head *lc; 23 int a = 0; 24 foreach (struct cache_upcall, c, lc, cache_upcalls) { 25 a |= c->upcall(type); 26 } 27 return a; 28 } 29 30 void 31 register_cache_upcall(int (*upcall)(int), int flags, unsigned char *name) 32 { 33 struct cache_upcall *c; 34 c = xmalloc(sizeof(struct cache_upcall) + strlen(cast_const_char name)); 35 c->upcall = upcall; 36 c->flags = (unsigned char)flags; 37 strcpy(cast_char c->name, cast_const_char name); 38 add_to_list(cache_upcalls, c); 39 } 40 41 void 42 free_all_caches(void) 43 { 44 struct cache_upcall *c = NULL; 45 struct list_head *lc; 46 int a, b; 47 do { 48 a = 0; 49 b = ~0; 50 foreach (struct cache_upcall, c, lc, cache_upcalls) { 51 int x = c->upcall(SH_FREE_ALL); 52 a |= x; 53 b &= x; 54 } 55 } while (a & ST_SOMETHING_FREED); 56 if (!(b & ST_CACHE_EMPTY)) { 57 unsigned char *m = NULL; 58 size_t l = 0; 59 foreach (struct cache_upcall, c, lc, cache_upcalls) 60 if (!(c->upcall(SH_FREE_ALL) & ST_CACHE_EMPTY)) { 61 if (l) 62 l = add_to_str(&m, l, cast_uchar ", "); 63 l = add_to_str(&m, l, c->name); 64 } 65 internal("could not release entries from caches: %s", m); 66 free(m); 67 } 68 free_list(struct cache_upcall, cache_upcalls); 69 } 70 71 int 72 out_of_memory(void) 73 { 74 if (shrink_memory(SH_FREE_SOMETHING)) 75 return 1; 76 77 return 0; 78 }