AbstractMemory * direct_cache_create(ConfigFile *cfg, const char *var_prefix, StatisticsInfo *info, AbstractMemory *mem, Random *rnd) { char buf[1024]; DirectCache *c = (DirectCache*) xcalloc(1, sizeof(*c)); c->b.info = info; const char *strategy = config_file_get(cfg, make_param_name(buf, sizeof(buf), var_prefix, "write_strategy")); if (!strategy) { error_undefined("direct_cache_create", buf); } else if (!strcmp(strategy, "write-through")) { c->b.ops = &direct_cache_wt_ops; c->direct_ops.finalize = direct_cache_wt_finalize; } else if (!strcmp(strategy, "write-back")) { c->b.ops = &direct_cache_wb_ops; c->direct_ops.finalize = direct_cache_wb_finalize; } else { error_invalid("direct_cache_create", buf); } c->mem = mem; int r; r = config_file_get_int(cfg, make_param_name(buf, sizeof(buf), var_prefix, "block_count"), &c->block_count); if (!r) { error_undefined("direct_cache_create", buf); } else if (r < 0) { error_invalid("direct_cache_create", buf); } r = config_file_get_int(cfg, make_param_name(buf, sizeof(buf), var_prefix, "block_size"), &c->block_size); if (!r) { error_undefined("direct_cache_create", buf); } else if (r < 0 || c->block_size <= 0 || c->block_size % 16 != 0 || c->block_size == 0 || c->block_size > 64 || c->block_size == 48) { error_invalid("direct_cache_create", buf); } r = config_file_get_int(cfg, make_param_name(buf, sizeof(buf), var_prefix, "cache_size"), &c->cache_size); if (!r) { error_undefined("direct_cache_create", buf); } else if (r < 0 || c->cache_size <= 0 || c->cache_size > MAX_CACHE_SIZE || c->cache_size % c->block_size != 0) { error_invalid("direct_cache_create", buf); } r = config_file_get_int(cfg, make_param_name(buf, sizeof(buf), var_prefix, "cache_read_time"), &c->cache_read_time); if (!r) { error_undefined("direct_cache_create", buf); } else if (r < 0 || c->cache_read_time <= 0 || c->cache_read_time > MAX_READ_TIME) { error_invalid("direct_cache_create", buf); } r = config_file_get_int(cfg, make_param_name(buf, sizeof(buf), var_prefix, "cache_write_time"), &c->cache_write_time); if (!r) { error_undefined("direct_cache_create", buf); } else if (r < 0 || c->cache_write_time <= 0 || c->cache_write_time > MAX_WRITE_TIME) { error_invalid("direct_cache_create", buf); } c->blocks = (DirectCacheBlock *) xcalloc(1, c->block_count); for (int i = 0; i < c->block_count; ++i) { c->blocks[i].addr = 0; c->blocks[i].dirty = 0; c->blocks[i].mem = (MemoryCell *) xcalloc(1, c->block_size); for (int j = 0; j < c->block_size; ++j) { c->blocks[i].mem[j].flags = 0; c->blocks[i].mem[j].value = 42; } } return (AbstractMemory*) c; }
/*! Создать модель полноассоциативного кеша \param cfg Указатель на структуру, хранящую конфигурационные параметры \param var_prefix Префикс имен параметров \param info Указатель на структуру, хранящую статистику моделирования \return Указатель на структуру описания модели полноассоциативного кеша (в виде указателя на базовую структуру), NULL в случае ошибки */ AbstractMemory * full_cache_create( ConfigFile *cfg, const char *var_prefix, StatisticsInfo *info, AbstractMemory *mem, Random *rnd) { char buf[PARAM_BUF_SIZE]; FullCache *c = (FullCache*) calloc(1, sizeof(*c)); c->b.info = info; c->rnd = rnd; c->mem = mem; c->blocks = NULL; c->block_count = 0; //определяем стратегию записи и соответственно задаём операции: const char fn[] = "full_cache_create"; const char *strategy = config_file_get(cfg, make_param_name(buf, sizeof(buf), var_prefix, "write_strategy")); if (!strategy) { error_undefined(fn, buf); goto full_cache_create_failed; } else if (strcmp(strategy, "write-through") == 0) { c->b.ops = &full_cache_wt_ops; c->full_ops.finalize = full_cache_wt_finalize; } else if (strcmp(strategy, "write-back") == 0) { c->b.ops = &full_cache_wb_ops; c->full_ops.finalize = full_cache_wb_finalize; c->b.info->write_back_needed = 1; } else { error_invalid(fn, buf); goto full_cache_create_failed; } //определяем стратегию замещения и соответственно задаём функцию размещения: strategy = config_file_get(cfg, make_param_name(buf, sizeof(buf), var_prefix, "replacement_strategy")); if (!strategy) { error_undefined(fn, buf); goto full_cache_create_failed; } else if (strcmp(strategy, "random") == 0) { c->full_ops.cache_place = full_cache_random_place; } else { error_invalid(fn, buf); goto full_cache_create_failed; } // считываем и проверяем параметр block_size: int r = config_file_get_int(cfg, make_param_name(buf, sizeof(buf), var_prefix, "block_size"), &c->block_size); if (!r) { error_undefined(fn, buf); goto full_cache_create_failed; } else if (r < 0 || !is_correct_block_size(c->block_size)) { error_invalid(fn, buf); goto full_cache_create_failed; } // считываем и проверяем параметр cache_size: r = config_file_get_int(cfg, make_param_name(buf, sizeof(buf), var_prefix, "cache_size"), &c->cache_size); if (!r) { error_undefined(fn, buf); goto full_cache_create_failed; } else if (r < 0 || c->cache_size <= 0 || c->cache_size > MAX_CACHE_SIZE || c->cache_size % c->block_size != 0) { error_invalid(fn, buf); goto full_cache_create_failed; } // считываем и проверяем параметр cache_read_time: r = config_file_get_int(cfg, make_param_name(buf, sizeof(buf), var_prefix, "cache_read_time"), &c->cache_read_time); if (!r) { error_undefined(fn, buf); goto full_cache_create_failed; } else if (r < 0 || c->cache_read_time <= 0 || c->cache_read_time > MAX_READ_TIME) { error_invalid(fn, buf); goto full_cache_create_failed; } // считываем и проверяем параметр cache_write_time: r = config_file_get_int(cfg, make_param_name(buf, sizeof(buf), var_prefix, "cache_write_time"), &c->cache_write_time); if (!r) { error_undefined(fn, buf); goto full_cache_create_failed; } else if (r < 0 || c->cache_write_time <= 0 || c->cache_write_time > MAX_WRITE_TIME) { error_invalid(fn, buf); goto full_cache_create_failed; } //выделяем блоки кэша: c->block_count = c->cache_size / c->block_size; c->blocks = calloc(c->block_count, sizeof(*c->blocks)); for (int i = 0; i < c->block_count; i++) { c->blocks[i].addr = NO_BLOCK; c->blocks[i].mem = calloc(c->block_size, sizeof(c->blocks[i].mem[0])); } return (AbstractMemory*) c; full_cache_create_failed: return full_cache_free((AbstractMemory*) c); }