|
|
@ -2,7 +2,7 @@ |
|
|
|
#define CACHE_GENERIC_H |
|
|
|
#define CACHE_GENERIC_H |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#include "hash.h" |
|
|
|
#include "generic_hash.h" |
|
|
|
|
|
|
|
|
|
|
|
#define CACHE_SIZE 512 |
|
|
|
#define CACHE_SIZE 512 |
|
|
|
#define CACHE_NCYCLES (CACHE_SIZE/2) |
|
|
|
#define CACHE_NCYCLES (CACHE_SIZE/2) |
|
|
@ -11,6 +11,9 @@ |
|
|
|
#define CACHE_BSET(b, x) b[(x)>>6] |= (uint64_t)1<<((x)%64) |
|
|
|
#define CACHE_BSET(b, x) b[(x)>>6] |= (uint64_t)1<<((x)%64) |
|
|
|
#define CACHE_BTEST(b, x) (b[(x)>>6]&((uint64_t)1<<((x)%64))) |
|
|
|
#define CACHE_BTEST(b, x) (b[(x)>>6]&((uint64_t)1<<((x)%64))) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// FIXME: this cache implementation is not really generic since it expects an unsigned
|
|
|
|
|
|
|
|
// as the code and not a generic type
|
|
|
|
|
|
|
|
|
|
|
|
#define CACHE_SET(c, x) \ |
|
|
|
#define CACHE_SET(c, x) \ |
|
|
|
{ \
|
|
|
|
{ \
|
|
|
|
c->cycles = (c->cycles+1)%CACHE_NCYCLES; \
|
|
|
|
c->cycles = (c->cycles+1)%CACHE_NCYCLES; \
|
|
|
@ -19,9 +22,10 @@ |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#define CACHE_DECL(cachename, type) \ |
|
|
|
#define CACHE_DECL(cachename, type, hashfn, comparefn) \ |
|
|
|
|
|
|
|
HASH_DECL(cachename##table, unsigned int, void *) \
|
|
|
|
struct cachename { \
|
|
|
|
struct cachename { \
|
|
|
|
struct hm_ref *table; \
|
|
|
|
struct cachename##table_ref *table; \
|
|
|
|
type *array; \
|
|
|
|
type *array; \
|
|
|
|
uint64_t *bitmap; \
|
|
|
|
uint64_t *bitmap; \
|
|
|
|
int cycles; \
|
|
|
|
int cycles; \
|
|
|
@ -30,7 +34,9 @@ struct cachename { \ |
|
|
|
\
|
|
|
|
\
|
|
|
|
struct cachename cachename##_init(void) \
|
|
|
|
struct cachename cachename##_init(void) \
|
|
|
|
{ \
|
|
|
|
{ \
|
|
|
|
struct hm_ref *t = hm_create(CACHE_SIZE); \
|
|
|
|
struct cachename##table_ref *t = cachename##table_create( \
|
|
|
|
|
|
|
|
CACHE_SIZE, hashfn, comparefn \
|
|
|
|
|
|
|
|
); \
|
|
|
|
type *a = malloc(sizeof(type)*CACHE_SIZE); \
|
|
|
|
type *a = malloc(sizeof(type)*CACHE_SIZE); \
|
|
|
|
uint64_t *b = malloc(sizeof(uint64_t)*CACHE_BSIZE); \
|
|
|
|
uint64_t *b = malloc(sizeof(uint64_t)*CACHE_BSIZE); \
|
|
|
|
CACHE_BRESET(b); \
|
|
|
|
CACHE_BRESET(b); \
|
|
|
@ -41,7 +47,7 @@ struct cachename cachename##_init(void) \ |
|
|
|
void cachename##_free(struct cachename *cache) \
|
|
|
|
void cachename##_free(struct cachename *cache) \
|
|
|
|
{ \
|
|
|
|
{ \
|
|
|
|
if (cache) { \
|
|
|
|
if (cache) { \
|
|
|
|
hm_destroy(cache->table); \
|
|
|
|
cachename##table_destroy(cache->table); \
|
|
|
|
free(cache->array); \
|
|
|
|
free(cache->array); \
|
|
|
|
free(cache->bitmap); \
|
|
|
|
free(cache->bitmap); \
|
|
|
|
} \
|
|
|
|
} \
|
|
|
@ -52,7 +58,8 @@ const type * cachename##_search(struct cachename *cache, unsigned int code) \ |
|
|
|
{ \
|
|
|
|
{ \
|
|
|
|
if (!cache) \
|
|
|
|
if (!cache) \
|
|
|
|
return NULL; \
|
|
|
|
return NULL; \
|
|
|
|
struct hm_entry *r = hm_search(cache->table, code); \
|
|
|
|
struct cachename##table_entry *r; \
|
|
|
|
|
|
|
|
r = cachename##table_search(cache->table, code); \
|
|
|
|
/* MISS */ \
|
|
|
|
/* MISS */ \
|
|
|
|
if (!r) \
|
|
|
|
if (!r) \
|
|
|
|
return NULL; \
|
|
|
|
return NULL; \
|
|
|
@ -90,8 +97,8 @@ const type * cachename##_insert(struct cachename *cache, const type *g, unsigned |
|
|
|
CACHE_SET(cache, x) \
|
|
|
|
CACHE_SET(cache, x) \
|
|
|
|
spot = &(cache->array[x]); \
|
|
|
|
spot = &(cache->array[x]); \
|
|
|
|
*spot = *g; \
|
|
|
|
*spot = *g; \
|
|
|
|
struct hm_entry e = { .code = code, .data = spot}; \
|
|
|
|
struct cachename##table_entry e = { .code = code, .data = spot}; \
|
|
|
|
if (!hm_insert(cache->table, &e)) \
|
|
|
|
if (!cachename##table_insert(cache->table, &e)) \
|
|
|
|
return NULL; \
|
|
|
|
return NULL; \
|
|
|
|
return spot; \
|
|
|
|
return spot; \
|
|
|
|
} \
|
|
|
|
} \
|
|
|
|