示例#1
0
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;
}
示例#2
0
/*!
  Создать модель полноассоциативного кеша
  \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);
}