cachesim
A cache simulator
|
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 */