From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-9.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,HTML_MESSAGE,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id E5225C47083 for ; Wed, 2 Jun 2021 03:16:34 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 4FD9461003 for ; Wed, 2 Jun 2021 03:16:34 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 4FD9461003 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:55302 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1loHMu-0003od-CS for qemu-devel@archiver.kernel.org; Tue, 01 Jun 2021 23:16:32 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:45548) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1loHM1-000312-BJ for qemu-devel@nongnu.org; Tue, 01 Jun 2021 23:15:37 -0400 Received: from mail-il1-x134.google.com ([2607:f8b0:4864:20::134]:36438) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1loHLz-0004y9-7l for qemu-devel@nongnu.org; Tue, 01 Jun 2021 23:15:37 -0400 Received: by mail-il1-x134.google.com with SMTP id e7so816595ils.3 for ; Tue, 01 Jun 2021 20:15:34 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:references:in-reply-to:from:date:message-id:subject:to; bh=TPkpwluhJAROvlOc0h48vOErBeWjsOfdGXGlqCa+xxE=; b=X8Yb5d1eA5I1u9lXBAa+8xlFJi308EUxEwQAU6sZUxK6rmWphoO6KvdTRF5HaFNi3g SdhWf9emslIWwvGPmFZUcHnFrNYbS0DvU5GT8Urbf5nXRBy0Am3TaDh4DIng6GFnE4NE MAeSqxleMjSEE8m6mxxZNFpU5id8cXoI/QciI+rwZ6uCajySemvsC19KcMBnTQIvb9I1 h+ovw1GxvX4dGynd7w4cIj1777vNPJel2xn0P4WGvj4aOv01ZjwshFAoOSpjEbhVUwoR AIHoYAyZz4UnDlto04zQoqFyoK4NYUk6850hMy6jfFbW/swxPhcWvX3Gcuk82+aQMMn0 0ZEg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to; bh=TPkpwluhJAROvlOc0h48vOErBeWjsOfdGXGlqCa+xxE=; b=eL6YjXLSRgJWfH1EGXwIaAIOKDn9e29SwkOEG5i87lJyd8aqFfx2E3T1N9sHXwsf7r 7SaNdC7c7TQcWmQFG/ySeTHuZDtXnzN6duVKlcKulmZMrU7hmvkuSGMpFvOX3a1wymZt 7wKTfTNh5t8E4DHjAnAMxvg0M1sibXi+LKi30nsBnShQ2+F8rw/nsCOA2OLtWGyxAptY o5DhjlPwVEQEIEvDjiv3oHDkGdXo9DielO9zEMf3iQ1HyevSGLrl6x4po9viYcXl4C/f mTzOVYBkkUF2es7o2Mnj11SBM0zYAlsdvnMlQjXAiU3gzpSRiyqlKGDAPJA/J1LIVEth KgiQ== X-Gm-Message-State: AOAM530+IzFO7U0uL/K9QLHUIOZ1EixLhYBmMTnpP9v7+r2As/uMFVpW giqeJwntzmRmGhg3Z2rS1vppzgsCmwpABe4PaWPwnvZBaR0= X-Google-Smtp-Source: ABdhPJzu8NvQTkfZ6gbzkoW6GLnTzlfMtGfp9vC6BfL8jADb9GQ1rnLIaMFjaFcGK0J80zCbtAuzRUNQcAMHELTlex4= X-Received: by 2002:a05:6e02:1e0d:: with SMTP id g13mr14331263ila.178.1622603734051; Tue, 01 Jun 2021 20:15:34 -0700 (PDT) MIME-Version: 1.0 References: <20210530063712.6832-1-ma.mandourr@gmail.com> <20210530063712.6832-3-ma.mandourr@gmail.com> In-Reply-To: <20210530063712.6832-3-ma.mandourr@gmail.com> From: Mahmoud Mandour Date: Wed, 2 Jun 2021 05:15:23 +0200 Message-ID: Subject: Re: [RFC PATCH v2 2/3] plugins: cache: Enabled parameterization and added trace printing To: qemu-devel@nongnu.org, "Emilio G. Cota" , =?UTF-8?B?QWxleCBCZW5uw6ll?= Content-Type: multipart/alternative; boundary="0000000000002ded8305c3bfdfdd" Received-SPF: pass client-ip=2607:f8b0:4864:20::134; envelope-from=ma.mandourr@gmail.com; helo=mail-il1-x134.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, HTML_MESSAGE=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" --0000000000002ded8305c3bfdfdd Content-Type: text/plain; charset="UTF-8" CC'ing Emilio On Sun, May 30, 2021 at 8:37 AM Mahmoud Mandour wrote: > Made both icache and dcache configurable through plugin arguments > and added memory trace printing in a separate file. > > Signed-off-by: Mahmoud Mandour > --- > contrib/plugins/cache.c | 68 +++++++++++++++++++++++++++++++++++++++-- > 1 file changed, 66 insertions(+), 2 deletions(-) > > diff --git a/contrib/plugins/cache.c b/contrib/plugins/cache.c > index 8c9d1dd538..fa0bf1dd40 100644 > --- a/contrib/plugins/cache.c > +++ b/contrib/plugins/cache.c > @@ -22,7 +22,7 @@ static GRand *rng; > static GHashTable *dmiss_ht; > static GHashTable *imiss_ht; > > -static GMutex dmtx, imtx; > +static GMutex dmtx, imtx, fmtx; > > static int limit; > static bool sys; > @@ -33,6 +33,8 @@ static uint64_t dmisses; > static uint64_t imem_accesses; > static uint64_t imisses; > > +FILE *tracefile; > + > static enum qemu_plugin_mem_rw rw = QEMU_PLUGIN_MEM_RW; > > enum AccessResult { > @@ -205,6 +207,16 @@ static void vcpu_mem_access(unsigned int cpu_index, > qemu_plugin_meminfo_t info, > insn_addr = ((struct InsnData *) userdata)->addr; > effective_addr = hwaddr ? qemu_plugin_hwaddr_phys_addr(hwaddr) : > vaddr; > > + if (tracefile) { > + g_mutex_lock(&fmtx); > + g_autoptr(GString) rep = g_string_new(""); > + bool is_store = qemu_plugin_mem_is_store(info); > + g_string_append_printf(rep, "%c: 0x%" PRIx64, > + is_store ? 'S' : 'L', effective_addr); > + fprintf(tracefile, "%s\n", rep->str); > + g_mutex_unlock(&fmtx); > + } > + > if (access_cache(dcache, effective_addr) == MISS) { > struct InsnData *insn = get_or_create(dmiss_ht, userdata, > insn_addr); > insn->misses++; > @@ -221,11 +233,20 @@ static void vcpu_insn_exec(unsigned int vcpu_index, > void *userdata) > g_mutex_lock(&imtx); > addr = ((struct InsnData *) userdata)->addr; > > + if (tracefile) { > + g_mutex_lock(&fmtx); > + g_autoptr(GString) rep = g_string_new(""); > + g_string_append_printf(rep, "I: 0x%" PRIx64, addr); > + fprintf(tracefile, "%s\n", rep->str); > + g_mutex_unlock(&fmtx); > + } > + > if (access_cache(icache, addr) == MISS) { > struct InsnData *insn = get_or_create(imiss_ht, userdata, addr); > insn->misses++; > imisses++; > } > + > imem_accesses++; > g_mutex_unlock(&imtx); > } > @@ -352,6 +373,15 @@ static void plugin_exit() > > g_mutex_unlock(&dmtx); > g_mutex_unlock(&imtx); > + > + if (tracefile) { > + fclose(tracefile); > + } > +} > + > +static bool bad_cache_params(int blksize, int assoc, int cachesize) > +{ > + return (cachesize % blksize) != 0 || (cachesize % (blksize * assoc) > != 0); > } > > QEMU_PLUGIN_EXPORT > @@ -377,14 +407,48 @@ int qemu_plugin_install(qemu_plugin_id_t id, const > qemu_info_t *info, > > for (i = 0; i < argc; i++) { > char *opt = argv[i]; > - if (g_str_has_prefix(opt, "limit=")) { > + if (g_str_has_prefix(opt, "I=")) { > + gchar **toks = g_strsplit(opt + 2, " ", -1); > + if (g_strv_length(toks) != 3) { > + fprintf(stderr, "option parsing failed: %s\n", opt); > + return -1; > + } > + icachesize = g_ascii_strtoull(toks[0], NULL, 10); > + iassoc = g_ascii_strtoull(toks[1], NULL, 10); > + iblksize = g_ascii_strtoull(toks[2], NULL, 10); > + } else if (g_str_has_prefix(opt, "D=")) { > + gchar **toks = g_strsplit(opt + 2, " ", -1); > + if (g_strv_length(toks) != 3) { > + fprintf(stderr, "option parsing failed: %s\n", opt); > + return -1; > + } > + dcachesize = g_ascii_strtoull(toks[0], NULL, 10); > + dassoc = g_ascii_strtoull(toks[1], NULL, 10); > + dblksize = g_ascii_strtoull(toks[2], NULL, 10); > + } else if (g_str_has_prefix(opt, "limit=")) { > limit = g_ascii_strtoull(opt + 6, NULL, 10); > + } else if (g_str_has_prefix(opt, "tracefile=")) { > + char *file_name = opt + 10; > + tracefile = fopen(file_name, "w"); > + if (!tracefile) { > + fprintf(stderr, "could not open: %s for writing\n", > file_name); > + } > } else { > fprintf(stderr, "option parsing failed: %s\n", opt); > return -1; > } > } > > + if (bad_cache_params(iblksize, iassoc, icachesize)) { > + fprintf(stderr, "icache cannot be constructed from given > parameters\n"); > + return -1; > + } > + > + if (bad_cache_params(dblksize, dassoc, dcachesize)) { > + fprintf(stderr, "dcache cannot be constructed from given > parameters\n"); > + return -1; > + } > + > dcache = cache_init(dblksize, dassoc, dcachesize); > icache = cache_init(iblksize, iassoc, icachesize); > > -- > 2.25.1 > > --0000000000002ded8305c3bfdfdd Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
CC'ing Emilio

On Sun, May 30, 2021 at 8:37 AM Mahmoud M= andour <ma.mandourr@gmail.com> wrote:
Ma= de both icache and dcache configurable through plugin arguments
and added memory trace printing in a separate file.

Signed-off-by: Mahmoud Mandour <
ma.mandourr@gmail.com>
---
=C2=A0contrib/plugins/cache.c | 68 +++++++++++++++++++++++++++++++++++++++-= -
=C2=A01 file changed, 66 insertions(+), 2 deletions(-)

diff --git a/contrib/plugins/cache.c b/contrib/plugins/cache.c
index 8c9d1dd538..fa0bf1dd40 100644
--- a/contrib/plugins/cache.c
+++ b/contrib/plugins/cache.c
@@ -22,7 +22,7 @@ static GRand *rng;
=C2=A0static GHashTable *dmiss_ht;
=C2=A0static GHashTable *imiss_ht;

-static GMutex dmtx, imtx;
+static GMutex dmtx, imtx, fmtx;

=C2=A0static int limit;
=C2=A0static bool sys;
@@ -33,6 +33,8 @@ static uint64_t dmisses;
=C2=A0static uint64_t imem_accesses;
=C2=A0static uint64_t imisses;

+FILE *tracefile;
+
=C2=A0static enum qemu_plugin_mem_rw rw =3D QEMU_PLUGIN_MEM_RW;

=C2=A0enum AccessResult {
@@ -205,6 +207,16 @@ static void vcpu_mem_access(unsigned int cpu_index, qe= mu_plugin_meminfo_t info,
=C2=A0 =C2=A0 =C2=A0insn_addr =3D ((struct InsnData *) userdata)->addr;<= br> =C2=A0 =C2=A0 =C2=A0effective_addr =3D hwaddr ? qemu_plugin_hwaddr_phys_add= r(hwaddr) : vaddr;

+=C2=A0 =C2=A0 if (tracefile) {
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 g_mutex_lock(&fmtx);
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 g_autoptr(GString) rep =3D g_string_new("= ");
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 bool is_store =3D qemu_plugin_mem_is_store(inf= o);
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 g_string_append_printf(rep, "%c: 0x%"= ; PRIx64,
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 is_store ? 'S&= #39; : 'L', effective_addr);
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 fprintf(tracefile, "%s\n", rep->s= tr);
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 g_mutex_unlock(&fmtx);
+=C2=A0 =C2=A0 }
+
=C2=A0 =C2=A0 =C2=A0if (access_cache(dcache, effective_addr) =3D=3D MISS) {=
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0struct InsnData *insn =3D get_or_create(d= miss_ht, userdata, insn_addr);
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0insn->misses++;
@@ -221,11 +233,20 @@ static void vcpu_insn_exec(unsigned int vcpu_index, v= oid *userdata)
=C2=A0 =C2=A0 =C2=A0g_mutex_lock(&imtx);
=C2=A0 =C2=A0 =C2=A0addr =3D ((struct InsnData *) userdata)->addr;

+=C2=A0 =C2=A0 if (tracefile) {
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 g_mutex_lock(&fmtx);
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 g_autoptr(GString) rep =3D g_string_new("= ");
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 g_string_append_printf(rep, "I: 0x%"= PRIx64, addr);
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 fprintf(tracefile, "%s\n", rep->s= tr);
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 g_mutex_unlock(&fmtx);
+=C2=A0 =C2=A0 }
+
=C2=A0 =C2=A0 =C2=A0if (access_cache(icache, addr) =3D=3D MISS) {
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0struct InsnData *insn =3D get_or_create(i= miss_ht, userdata, addr);
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0insn->misses++;
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0imisses++;
=C2=A0 =C2=A0 =C2=A0}
+
=C2=A0 =C2=A0 =C2=A0imem_accesses++;
=C2=A0 =C2=A0 =C2=A0g_mutex_unlock(&imtx);
=C2=A0}
@@ -352,6 +373,15 @@ static void plugin_exit()

=C2=A0 =C2=A0 =C2=A0g_mutex_unlock(&dmtx);
=C2=A0 =C2=A0 =C2=A0g_mutex_unlock(&imtx);
+
+=C2=A0 =C2=A0 if (tracefile) {
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 fclose(tracefile);
+=C2=A0 =C2=A0 }
+}
+
+static bool bad_cache_params(int blksize, int assoc, int cachesize)
+{
+=C2=A0 =C2=A0 return (cachesize % blksize) !=3D 0 || (cachesize % (blksize= * assoc) !=3D 0);
=C2=A0}

=C2=A0QEMU_PLUGIN_EXPORT
@@ -377,14 +407,48 @@ int qemu_plugin_install(qemu_plugin_id_t id, const qe= mu_info_t *info,

=C2=A0 =C2=A0 =C2=A0for (i =3D 0; i < argc; i++) {
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0char *opt =3D argv[i];
-=C2=A0 =C2=A0 =C2=A0 =C2=A0 if (g_str_has_prefix(opt, "limit=3D"= )) {
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 if (g_str_has_prefix(opt, "I=3D")) {=
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 gchar **toks =3D g_strsplit(opt = + 2, " ", -1);
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 if (g_strv_length(toks) !=3D 3) = {
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 fprintf(stderr, &q= uot;option parsing failed: %s\n", opt);
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return -1;
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 }
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 icachesize =3D g_ascii_strtoull(= toks[0], NULL, 10);
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 iassoc =3D g_ascii_strtoull(toks= [1], NULL, 10);
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 iblksize =3D g_ascii_strtoull(to= ks[2], NULL, 10);
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 } else if (g_str_has_prefix(opt, "D=3D&qu= ot;)) {
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 gchar **toks =3D g_strsplit(opt = + 2, " ", -1);
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 if (g_strv_length(toks) !=3D 3) = {
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 fprintf(stderr, &q= uot;option parsing failed: %s\n", opt);
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return -1;
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 }
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 dcachesize =3D g_ascii_strtoull(= toks[0], NULL, 10);
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 dassoc =3D g_ascii_strtoull(toks= [1], NULL, 10);
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 dblksize =3D g_ascii_strtoull(to= ks[2], NULL, 10);
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 } else if (g_str_has_prefix(opt, "limit= =3D")) {
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0limit =3D g_ascii_strtoull(= opt + 6, NULL, 10);
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 } else if (g_str_has_prefix(opt, "tracefi= le=3D")) {
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 char *file_name =3D opt + 10; +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 tracefile =3D fopen(file_name, &= quot;w");
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 if (!tracefile) {
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 fprintf(stderr, &q= uot;could not open: %s for writing\n", file_name);
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 }
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0} else {
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0fprintf(stderr, "optio= n parsing failed: %s\n", opt);
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return -1;
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0}
=C2=A0 =C2=A0 =C2=A0}

+=C2=A0 =C2=A0 if (bad_cache_params(iblksize, iassoc, icachesize)) {
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 fprintf(stderr, "icache cannot be constru= cted from given parameters\n");
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 return -1;
+=C2=A0 =C2=A0 }
+
+=C2=A0 =C2=A0 if (bad_cache_params(dblksize, dassoc, dcachesize)) {
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 fprintf(stderr, "dcache cannot be constru= cted from given parameters\n");
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 return -1;
+=C2=A0 =C2=A0 }
+
=C2=A0 =C2=A0 =C2=A0dcache =3D cache_init(dblksize, dassoc, dcachesize); =C2=A0 =C2=A0 =C2=A0icache =3D cache_init(iblksize, iassoc, icachesize);
--
2.25.1

--0000000000002ded8305c3bfdfdd--