From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 20854 invoked by alias); 3 Nov 2013 05:56:55 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Received: (qmail 20750 invoked by uid 89); 3 Nov 2013 05:56:53 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.6 required=5.0 tests=AWL,BAYES_00,RDNS_NONE,URIBL_BLOCKED autolearn=no version=3.3.2 X-HELO: relay1.mentorg.com Received: from Unknown (HELO relay1.mentorg.com) (192.94.38.131) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Sun, 03 Nov 2013 05:56:05 +0000 Received: from svr-orw-fem-01.mgc.mentorg.com ([147.34.98.93]) by relay1.mentorg.com with esmtp id 1VcqfA-00021Q-6B from Yao_Qi@mentor.com for gdb-patches@sourceware.org; Sat, 02 Nov 2013 22:55:52 -0700 Received: from SVR-ORW-FEM-02.mgc.mentorg.com ([147.34.96.206]) by svr-orw-fem-01.mgc.mentorg.com over TLS secured channel with Microsoft SMTPSVC(6.0.3790.4675); Sat, 2 Nov 2013 22:55:51 -0700 Received: from qiyao.dyndns.org (147.34.91.1) by svr-orw-fem-02.mgc.mentorg.com (147.34.96.168) with Microsoft SMTP Server id 14.2.247.3; Sat, 2 Nov 2013 22:55:51 -0700 From: Yao Qi To: Subject: [PATCH 05/10] Invalidate or shrink dcache when setting is changed. Date: Sun, 03 Nov 2013 05:56:00 -0000 Message-ID: <1383458049-20893-6-git-send-email-yao@codesourcery.com> In-Reply-To: <1383458049-20893-1-git-send-email-yao@codesourcery.com> References: <1383458049-20893-1-git-send-email-yao@codesourcery.com> MIME-Version: 1.0 Content-Type: text/plain X-IsSubscribed: yes X-SW-Source: 2013-11/txt/msg00037.txt.bz2 Nowadays, when cache size or line size is changed by command, 'target_dcache' is invalidated. It is too conservative. We can optimize in the following ways, - Don't have to invalidate dcache immediately after cache size or line size is changed. We can postpone the invalidation to the moment using 'target_dcache'. - Don't have to invalidate dcache if the cache size is changed. If cache size is changed to the value which is still greater than dcache's size, nothing should be done. If change to the value which is less than dcache's size, just evict cache lines. This is what this patch does. gdb: 2013-11-02 Yao Qi * dcache.c (dcache_evict): New function. (dcache_shrink): New function. (dcache_invalidate_p): New function. (dcache_alloc): Call dcache_evict. (set_dcache_size): Remove call target_dcache_invalidate. (set_dcache_line_size): Likewise. * dcache.h (dcache_shrink): Declare. (dcache_invalidate_p): Declare. * target-dcache.c (target_dcache_get): Invalidate and shrink cache if necessary. (target_dcache_get_or_init): Likewise. gdb/doc: 2013-11-02 Yao Qi * gdb.texinfo (Caching Target Data): Update document of commands 'set dcache size' and 'set dcache line-size'. --- gdb/dcache.c | 47 ++++++++++++++++++++++++++++++++++++++--------- gdb/dcache.h | 4 ++++ gdb/doc/gdb.texinfo | 7 +++++-- gdb/target-dcache.c | 17 ++++++++++++++++- 4 files changed, 63 insertions(+), 12 deletions(-) diff --git a/gdb/dcache.c b/gdb/dcache.c index 5b32629..09ff2db 100644 --- a/gdb/dcache.c +++ b/gdb/dcache.c @@ -243,6 +243,43 @@ invalidate_block (struct dcache_block *block, void *param) append_block (&dcache->freelist, block); } +/* Evict the cache line decided by the eviction algorithm. Return the + evicted cache line. */ + +static struct dcache_block * +dcache_evict (DCACHE *dcache) +{ + /* Evict the least recently allocated line. */ + struct dcache_block *db = dcache->oldest; + + remove_block (&dcache->oldest, db); + splay_tree_remove (dcache->tree, (splay_tree_key) db->addr); + + return db; +} + +/* Shrink DCACHE if it is over-sized. */ + +void +dcache_shrink (DCACHE *dcache) +{ + while (dcache->size > dcache_size) + { + struct dcache_block *db = dcache_evict (dcache); + + free_block (db, NULL); + dcache->size--; + } +} + +/* Return true if DCACHE should be invalidated. */ + +int +dcache_invalidate_p (DCACHE *dcache) +{ + return (dcache->line_size != dcache_line_size); +} + /* Free all the data cache blocks, thus discarding all cached data. */ void @@ -359,13 +396,7 @@ dcache_alloc (DCACHE *dcache, CORE_ADDR addr) struct dcache_block *db; if (dcache->size >= dcache_size) - { - /* Evict the least recently allocated line. */ - db = dcache->oldest; - remove_block (&dcache->oldest, db); - - splay_tree_remove (dcache->tree, (splay_tree_key) db->addr); - } + db = dcache_evict (dcache); else { db = dcache->freelist; @@ -669,7 +700,6 @@ set_dcache_size (char *args, int from_tty, dcache_size = DCACHE_DEFAULT_SIZE; error (_("Dcache size must be greater than 0.")); } - target_dcache_invalidate (); } static void @@ -683,7 +713,6 @@ set_dcache_line_size (char *args, int from_tty, dcache_line_size = DCACHE_DEFAULT_LINE_SIZE; error (_("Invalid dcache line size: %u (must be power of 2)."), d); } - target_dcache_invalidate (); } static void diff --git a/gdb/dcache.h b/gdb/dcache.h index 720a887..101c2ce 100644 --- a/gdb/dcache.h +++ b/gdb/dcache.h @@ -40,4 +40,8 @@ int dcache_xfer_memory (struct target_ops *ops, DCACHE *cache, CORE_ADDR mem, void dcache_update (DCACHE *dcache, CORE_ADDR memaddr, gdb_byte *myaddr, int len); +void dcache_shrink (DCACHE *dcache); + +int dcache_invalidate_p (DCACHE *dcache); + #endif /* DCACHE_H */ diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo index 4d72983..561243b 100644 --- a/gdb/doc/gdb.texinfo +++ b/gdb/doc/gdb.texinfo @@ -10863,13 +10863,16 @@ printed in hex. @item set dcache size @var{size} @cindex dcache size @kindex set dcache size -Set maximum number of entries in dcache (dcache depth above). +Set maximum number of entries in dcache (dcache depth above). When +the dcache is being used, its size is greater than this setting, it +is shrunk. @item set dcache line-size @var{line-size} @cindex dcache line-size @kindex set dcache line-size Set number of bytes each dcache entry caches (dcache width above). -Must be a power of 2. +Must be a power of 2. When the dcache is being used, its width is +different from this setting, it is invalidated. @item show dcache size @kindex show dcache size diff --git a/gdb/target-dcache.c b/gdb/target-dcache.c index bf04679..28f1aa6 100644 --- a/gdb/target-dcache.c +++ b/gdb/target-dcache.c @@ -45,6 +45,14 @@ target_dcache_invalidate (void) DCACHE * target_dcache_get (void) { + if (target_dcache_init_p ()) + { + if (dcache_invalidate_p (target_dcache)) + dcache_invalidate (target_dcache); + + dcache_shrink (target_dcache); + } + return target_dcache; } @@ -54,7 +62,14 @@ target_dcache_get (void) DCACHE * target_dcache_get_or_init (void) { - if (!target_dcache_init_p ()) + if (target_dcache_init_p ()) + { + if (dcache_invalidate_p (target_dcache)) + dcache_invalidate (target_dcache); + + dcache_shrink (target_dcache); + } + else target_dcache = dcache_init (); return target_dcache; -- 1.7.7.6