static apr_status_t cleanup_cache_mem(void *sconfv) { cache_object_t *obj; mem_cache_conf *co = (mem_cache_conf*) sconfv; if (!co) { return APR_SUCCESS; } if (!co->cache_cache) { return APR_SUCCESS; } if (sconf->lock) { apr_thread_mutex_lock(sconf->lock); } obj = cache_pop(co->cache_cache); while (obj) { /* Iterate over the cache and clean up each unreferenced entry */ if (!apr_atomic_dec32(&obj->refcount)) { cleanup_cache_object(obj); } obj = cache_pop(co->cache_cache); } /* Cache is empty, free the cache table */ cache_free(co->cache_cache); if (sconf->lock) { apr_thread_mutex_unlock(sconf->lock); } return APR_SUCCESS; }
static void test1(void) { printf("***************************\n" "* TEST 1 *\n" "***************************\n"); init_cache(&cache); printf("\n--- Initial cache ---\n"); print_all_cache(stdout, &cache); test_elem(A, 1, 1); test_elem(A, 1, 1); printf("\n--- After addition ---\n"); print_all_cache(stdout, &cache); test_elem(B, 2, 2); test_elem(B, 2, 2); printf("\n--- After more addition ---\n"); print_all_cache(stdout, &cache); cache_push(&cache); cache_push(&cache); printf("\n--- Push: level 2 ---\n"); print_all_cache(stdout, &cache); test_elem(A, 0, 1); test_elem(A, 0, 1); test_elem(A, 1, 0); test_elem(A, 1, 0); printf("\n--- Content ---\n"); print_all_cache(stdout, &cache); cache_push(&cache); printf("\n--- Push: level 3 ---\n"); print_all_cache(stdout, &cache); cache_pop(&cache); printf("\n--- Pop: level 2 ---\n"); print_all_cache(stdout, &cache); cache_pop(&cache); printf("\n--- Pop: level 1 ---\n"); print_all_cache(stdout, &cache); cache_pop(&cache); printf("\n--- Pop: level 0 ---\n"); print_all_cache(stdout, &cache); delete_cache(&cache); }
void cache_prune() { pthread_mutex_lock(&lock); size_t freed = 0; size_t size = 0; struct lnode *cur = cache_list; while (cur){ struct lnode *temp = cur; struct cache_entry *ce = cur->data; cur = cur->next; size += ce->len; if (size > config->max_cache_size){ freed += ce->len; cache_pop(temp); } } if (freed > 0){ char strtime[512]; time_t t = time(0); strftime(strtime, 512, TIME_FORMAT, localtime(&t)); printf("\033[1m%s, (GC):\033[0m Pruned %zu bytes from cache\n", strtime, freed); } pthread_mutex_unlock(&lock); }
T *cache_swap(T *next){ if(!next){ GLCacheEntry *e=cache_pop(next); return static_cast<T*>(e); } GLCacheEntry *&e=cache_get(typeid(T)), *old=e; e=next; return static_cast<T*>(old); }
void cache_set(T *next){ if(!next){ GLCacheEntry *e=cache_pop(next); if(e) delete e; return; } GLCacheEntry *&e=cache_get(typeid(T)); if(e) delete e; e=next; return; }
int cache_rm(unsigned long long id) { struct lnode *n = cache_get_node(id); if (n){ pthread_mutex_lock(&lock); cache_pop(n); pthread_mutex_unlock(&lock); return 0; } return 1; }
static void test2(void) { uint16_t tag; int32_t x, y; uint32_t i; cache_elem_t *e0, *e1; uint32_t level; printf("***************************\n" "* TEST 2 *\n" "***************************\n"); level = 1; init_cache(&cache); printf("---- INITIAL ----\n"); print_cache_stack(stdout, &cache); print_cache_bank(stdout, &cache); printf("\n"); for (i=0; i<4000; i++) { tag = (uint16_t) (random() % NUMTAGS); x = (int32_t) (random() % 20); y = (int32_t) (random() % 20); e0 = cache_find(&cache, tag, x, y); e1 = cache_get(&cache, tag, x, y); if (e0 == NULL && e1->flag != NEW_CACHE_ELEM) { printf("*** caching bug ***\n"); printf(" element: [%s %"PRId32" %"PRId32"]\n", tag2string[tag], x, y); printf(" find: returned NULL\n"); printf(" get: returned %p: ", e1); print_cache_elem(stdout, e1); printf("\n"); } if (e0 != NULL && e1 != e0) { printf("*** caching bug ***\n"); printf(" element: [%s %"PRId32" %"PRId32"]\n", tag2string[tag], x, y); printf(" find: returned %p: ", e0); print_cache_elem(stdout, e0); printf("\n"); printf(" get: returned %p: ", e1); print_cache_elem(stdout, e1); printf("\n"); } if (e1->flag == NEW_CACHE_ELEM) { e1->flag = (uint16_t) level; } if (i % 100 == 49) { printf("\n--- Push to level %"PRIu32" ---\n", level); cache_push(&cache); level ++; print_cache_stack(stdout, &cache); print_cache_bank(stdout, &cache); } } printf("\n--- After random additions (level = %"PRIu32") ---\n", level); print_all_cache(stdout, &cache); print_cache_stack(stdout, &cache); print_cache_bank(stdout, &cache); while (level > 1) { level --; printf("\n--- Pop to level %"PRIu32" ---\n", level); cache_pop(&cache); print_all_cache(stdout, &cache); print_cache_stack(stdout, &cache); print_cache_bank(stdout, &cache); } printf("\n--- After reset ---\n"); reset_cache(&cache); print_all_cache(stdout, &cache); print_cache_stack(stdout, &cache); print_cache_bank(stdout, &cache); delete_cache(&cache); }
void cache_remove(T *next){ GLCacheEntry *e=cache_pop(typeid(T)); if(e) delete e; return; }