cachesim
A cache simulator
direct_cache.c
Go to the documentation of this file.
00001 /* -*- mode:c; coding: utf-8 -*- */
00002 
00003 #include "direct_cache.h"
00004 
00005 #include <stdlib.h>
00006 #include <string.h>
00007 
00011 enum
00012 {
00013     MAX_CACHE_SIZE = 16 * MiB, 
00014     MAX_READ_TIME = 100000, 
00015     MAX_WRITE_TIME = MAX_READ_TIME, 
00016 };
00017 
00022 typedef struct DirectCacheBlock
00023 {
00024     memaddr_t addr; 
00025     MemoryCell *mem; 
00026     int dirty; 
00027 } DirectCacheBlock;
00028 
00029 struct DirectCache;
00030 typedef struct DirectCache DirectCache;
00031 
00036 typedef struct DirectCacheOps
00037 {
00045     void (*finalize)(DirectCache *c, DirectCacheBlock *b);
00046 } DirectCacheOps;
00047 
00052 struct DirectCache
00053 {
00054     AbstractMemory b; 
00055     DirectCacheOps direct_ops; 
00056     DirectCacheBlock *blocks; 
00057     AbstractMemory *mem; 
00058     int cache_size; 
00059     int block_size; 
00060     int block_count; 
00061     int cache_read_time; 
00062     int cache_write_time; 
00063 };
00064 
00065 static AbstractMemory *
00066 direct_cache_free(AbstractMemory *m)
00067 {
00068     // FIXME: реализовать
00069     return NULL;
00070 }
00071 
00072 static DirectCacheBlock *
00073 direct_cache_find(DirectCache *c, memaddr_t aligned_addr)
00074 {
00075     int index = (aligned_addr / c->block_size) % c->block_count;
00076     if (c->blocks[index].addr != aligned_addr) return NULL;
00077     return &c->blocks[index];
00078 }
00079 
00080 static DirectCacheBlock *
00081 direct_cache_place(DirectCache *c, memaddr_t aligned_addr)
00082 {
00083     int index = (aligned_addr / c->block_size) % c->block_count;
00084     DirectCacheBlock *b = &c->blocks[index];
00085     if (b->addr != -1) {
00086         c->direct_ops.finalize(c, b);
00087         b->addr = -1;
00088         memset(b->mem, 0, c->block_size * sizeof(b->mem[0]));
00089     }
00090     return b;
00091 }
00092 
00093 static void
00094 direct_cache_read(AbstractMemory *m, memaddr_t addr, int size, MemoryCell *dst)
00095 {
00096     DirectCache *c = (DirectCache*) m;
00097     memaddr_t aligned_addr = addr & -c->block_size;
00098     // FIXME: реализовать до конца
00099 }
00100 
00104 static void
00105 direct_cache_wt_write(AbstractMemory *m, memaddr_t addr, int size, const MemoryCell *src)
00106 {
00107     // FIXME: реализовать до конца
00108 }
00109 
00113 static void
00114 direct_cache_wb_write(AbstractMemory *m, memaddr_t addr, int size, const MemoryCell *src)
00115 {
00116     DirectCache *c = (DirectCache*) m;
00117     memaddr_t aligned_addr = addr & -c->block_size;
00118     statistics_add_counter(c->b.info, c->cache_write_time);
00119     DirectCacheBlock *b = direct_cache_find(c, aligned_addr);
00120     if (!b) {
00121         b = direct_cache_place(c, aligned_addr);
00122         b->addr = aligned_addr;
00123         c->mem->ops->read(c->mem, aligned_addr, c->block_size, b->mem);
00124     }
00125     memcpy(b->mem + (addr - aligned_addr), src, size * sizeof(b->mem[0]));
00126     b->dirty = 1;
00127 }
00128 
00129 static void
00130 direct_cache_reveal(AbstractMemory *m, memaddr_t addr, int size, const MemoryCell *src)
00131 {
00132     DirectCache *c = (DirectCache*) m;
00133     memaddr_t aligned_addr = addr & -c->block_size;
00134     DirectCacheBlock *b = direct_cache_find(c, aligned_addr);
00135     if (b) {
00136         memcpy(b->mem + (addr - aligned_addr), src, size * sizeof(b->mem[0]));
00137     }
00138     c->mem->ops->reveal(c->mem, addr, size, src);
00139 }
00140 
00144 static void
00145 direct_cache_wt_finalize(DirectCache *c, DirectCacheBlock *b)
00146 {
00147     // FIXME: реализовать до конца
00148 }
00149 
00153 static void
00154 direct_cache_wb_finalize(DirectCache *c, DirectCacheBlock *b)
00155 {
00156     // FIXME: реализовать до конца
00157 }
00158 
00159 static void
00160 direct_cache_flush(AbstractMemory *m)
00161 {
00162     // FIXME: реализовать до конца
00163 }
00164 
00165 static AbstractMemoryOps direct_cache_wt_ops =
00166 {
00167     direct_cache_free,
00168     direct_cache_read,
00169     direct_cache_wt_write,
00170     direct_cache_reveal,
00171     direct_cache_flush,
00172 };
00173 
00174 static AbstractMemoryOps direct_cache_wb_ops =
00175 {
00176     direct_cache_free,
00177     direct_cache_read,
00178     direct_cache_wb_write,
00179     direct_cache_reveal,
00180     direct_cache_flush,
00181 };
00182 
00183 AbstractMemory *
00184 direct_cache_create(ConfigFile *cfg, const char *var_prefix, StatisticsInfo *info, AbstractMemory *mem, Random *rnd)
00185 {
00186     char buf[1024];
00187     DirectCache *c = (DirectCache*) calloc(1, sizeof(*c));
00188     c->b.info = info;
00189     const char *strategy = config_file_get(cfg, make_param_name(buf, sizeof(buf), var_prefix, "write_strategy"));
00190     if (!strategy) {
00191         error_undefined("direct_cache_create", buf);
00192     } else if (!strcmp(strategy, "write-through")) {
00193         c->b.ops = &direct_cache_wt_ops;
00194         c->direct_ops.finalize = direct_cache_wt_finalize;
00195     } else if (!strcmp(strategy, "write-back")) {
00196         c->b.ops = &direct_cache_wb_ops;
00197         c->direct_ops.finalize = direct_cache_wb_finalize;
00198     } else {
00199         error_invalid("direct_cache_create", buf);
00200     }
00201     c->mem = mem;
00202 
00203     // FIXME: реализовать до конца
00204 
00205     return (AbstractMemory*) c;
00206 }
00207 
00208 /*
00209  * Local variables:
00210  *  c-basic-offset: 4
00211  * End:
00212  */