Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: Paul Pluzhnikov <ppluzhnikov@google.com>
To: Eli Zaretskii <eliz@gnu.org>
Cc: tromey@redhat.com, gdb-patches@sourceware.org,
	       Pedro Alves <pedro@codesourcery.com>
Subject: Re: [RFC][patch] Make DCACHE_LINE runtime-settable
Date: Mon, 25 Jul 2011 21:04:00 -0000	[thread overview]
Message-ID: <CALoOobPQKQZuvSw9E6RvhCfM7kSPkaaZ9F1DeMA1wiAy5pTU6A@mail.gmail.com> (raw)
In-Reply-To: <83bowif96z.fsf@gnu.org>

[-- Attachment #1: Type: text/plain, Size: 1115 bytes --]

On Mon, Jul 25, 2011 at 12:32 PM, Eli Zaretskii <eliz@gnu.org> wrote:

>> +* Dcache size (number of lines) and line-size are now runtime-configurable.
>
> Please mention the names of the new commands.

Revised patch to address documentation and code comments attached.

Thanks,
-- 
Paul Pluzhnikov

2011-07-25  Paul Pluzhnikov  <ppluzhnikov@google.com>

	* NEWS: Mention dcache configuration.
	* dcache.c (dcache_set_list, dcache_show_list): New variables.
	(dcache_size, dcache_line_size): New variables.
	(LINE_SIZE_MASK, XFORM, MASK): Adjust.
	(struct dcache_block): Make it expandable.
	(struct dcache_struct): New field.
	(dcache_invalidate): Discard freelist upon dcache_line_size changes.
	(dcache_hit, dcache_alloc, dcache_peek_byte): Adjust.
	(dcache_poke_byte, dcache_print_line): Adjust.
	(set_dcache_size, set_dcache_line_size): New functions.
	(set_dcache_command, show_dcache_command): New functions.
	(_initialize_dcache): Add new commands.


doc/ChangeLog:

2011-07-25  Paul Pluzhnikov  <ppluzhnikov@google.com>

	* gdb.texinfo (Caching Remote Data): Document {set,show} dcache
	size and line-size.

[-- Attachment #2: gdb-dcache-line-size-20110725-2.txt --]
[-- Type: text/plain, Size: 11046 bytes --]

Index: NEWS
===================================================================
RCS file: /cvs/src/src/gdb/NEWS,v
retrieving revision 1.444
diff -u -p -r1.444 NEWS
--- NEWS	21 Jul 2011 17:23:55 -0000	1.444
+++ NEWS	25 Jul 2011 20:43:38 -0000
@@ -74,6 +74,9 @@ QTDisable
 
   Dynamically disable a tracepoint in a started trace experiment.
 
+* Dcache size (number of lines) and line-size are now runtime-configurable
+  via "set dcache line" and "set dcache line-size" commands.
+
 *** Changes in GDB 7.3
 
 * GDB has a new command: "thread find [REGEXP]".
Index: dcache.c
===================================================================
RCS file: /cvs/src/src/gdb/dcache.c,v
retrieving revision 1.45
diff -u -p -r1.45 dcache.c
--- dcache.c	7 Jan 2011 19:36:15 -0000	1.45
+++ dcache.c	25 Jul 2011 20:43:38 -0000
@@ -27,6 +27,10 @@
 #include "inferior.h"
 #include "splay-tree.h"
 
+/* Commands with a prefix of `{set,show} dcache'.  */
+static struct cmd_list_element *dcache_set_list = NULL;
+static struct cmd_list_element *dcache_show_list = NULL;
+
 /* The data cache could lead to incorrect results because it doesn't
    know about volatile variables, thus making it impossible to debug
    functions which use memory mapped I/O devices.  Set the nocache
@@ -71,20 +75,21 @@
 
 /* The maximum number of lines stored.  The total size of the cache is
    equal to DCACHE_SIZE times LINE_SIZE.  */
-#define DCACHE_SIZE 4096
+#define DCACHE_DEFAULT_SIZE 4096
+static unsigned dcache_size = DCACHE_DEFAULT_SIZE;
 
-/* The size of a cache line.  Smaller values reduce the time taken to
+/* The default size of a cache line.  Smaller values reduce the time taken to
    read a single byte and make the cache more granular, but increase
    overhead and reduce the effectiveness of the cache as a prefetcher.  */
-#define LINE_SIZE_POWER 6
-#define LINE_SIZE (1 << LINE_SIZE_POWER)
+#define DCACHE_DEFAULT_LINE_SIZE 64
+static unsigned dcache_line_size = DCACHE_DEFAULT_LINE_SIZE;
 
 /* Each cache block holds LINE_SIZE bytes of data
    starting at a multiple-of-LINE_SIZE address.  */
 
-#define LINE_SIZE_MASK  ((LINE_SIZE - 1))
-#define XFORM(x) 	((x) & LINE_SIZE_MASK)
-#define MASK(x)         ((x) & ~LINE_SIZE_MASK)
+#define LINE_SIZE_MASK(dcache)  ((dcache->line_size - 1))
+#define XFORM(dcache, x) 	((x) & LINE_SIZE_MASK (dcache))
+#define MASK(dcache, x)         ((x) & ~LINE_SIZE_MASK (dcache))
 
 struct dcache_block
 {
@@ -93,8 +98,8 @@ struct dcache_block
   struct dcache_block *next;
 
   CORE_ADDR addr;		/* address of data */
-  gdb_byte data[LINE_SIZE];	/* bytes at given address */
   int refs;			/* # hits */
+  gdb_byte data[1];		/* line_size bytes at given address */
 };
 
 struct dcache_struct
@@ -108,6 +113,7 @@ struct dcache_struct
 
   /* The number of in-use lines in the cache.  */
   int size;
+  CORE_ADDR line_size;  /* current line_size.  */
 
   /* The ptid of last inferior to use cache or null_ptid.  */
   ptid_t ptid;
@@ -207,6 +213,29 @@ for_each_block (struct dcache_block **bl
   while (*blist && db != *blist);
 }
 
+/* BLOCK_FUNC routine for dcache_free.  */
+
+static void
+free_block (struct dcache_block *block, void *param)
+{
+  xfree (block);
+}
+
+/* Free a data cache.  */
+
+void
+dcache_free (DCACHE *dcache)
+{
+  if (last_cache == dcache)
+    last_cache = NULL;
+
+  splay_tree_delete (dcache->tree);
+  for_each_block (&dcache->oldest, free_block, NULL);
+  for_each_block (&dcache->freelist, free_block, NULL);
+  xfree (dcache);
+}
+
+
 /* BLOCK_FUNC function for dcache_invalidate.
    This doesn't remove the block from the oldest list on purpose.
    dcache_invalidate will do it later.  */
@@ -230,6 +259,16 @@ dcache_invalidate (DCACHE *dcache)
   dcache->oldest = NULL;
   dcache->size = 0;
   dcache->ptid = null_ptid;
+
+  if (dcache->line_size != dcache_line_size)
+    {
+      /* We've been asked to use a different line size.
+	 All of our freelist blocks are now the wrong size, so free them.  */
+
+      for_each_block (&dcache->freelist, free_block, dcache);
+      dcache->freelist = NULL;
+      dcache->line_size = dcache_line_size;
+    }
 }
 
 /* Invalidate the line associated with ADDR.  */
@@ -257,7 +296,7 @@ dcache_hit (DCACHE *dcache, CORE_ADDR ad
   struct dcache_block *db;
 
   splay_tree_node node = splay_tree_lookup (dcache->tree,
-					    (splay_tree_key) MASK (addr));
+					    (splay_tree_key) MASK (dcache, addr));
 
   if (!node)
     return NULL;
@@ -281,7 +320,7 @@ dcache_read_line (DCACHE *dcache, struct
   int reg_len;
   struct mem_region *region;
 
-  len = LINE_SIZE;
+  len = dcache->line_size;
   memaddr = db->addr;
   myaddr  = db->data;
 
@@ -325,7 +364,7 @@ dcache_alloc (DCACHE *dcache, CORE_ADDR 
 {
   struct dcache_block *db;
 
-  if (dcache->size >= DCACHE_SIZE)
+  if (dcache->size >= dcache_size)
     {
       /* Evict the least recently allocated line.  */
       db = dcache->oldest;
@@ -339,12 +378,13 @@ dcache_alloc (DCACHE *dcache, CORE_ADDR 
       if (db)
 	remove_block (&dcache->freelist, db);
       else
-	db = xmalloc (sizeof (struct dcache_block));
+	db = xmalloc (offsetof (struct dcache_block, data) +
+		      dcache->line_size);
 
       dcache->size++;
     }
 
-  db->addr = MASK (addr);
+  db->addr = MASK (dcache, addr);
   db->refs = 0;
 
   /* Put DB at the end of the list, it's the newest.  */
@@ -374,7 +414,7 @@ dcache_peek_byte (DCACHE *dcache, CORE_A
          return 0;
     }
 
-  *ptr = db->data[XFORM (addr)];
+  *ptr = db->data[XFORM (dcache, addr)];
   return 1;
 }
 
@@ -395,7 +435,7 @@ dcache_poke_byte (DCACHE *dcache, CORE_A
   struct dcache_block *db = dcache_hit (dcache, addr);
 
   if (db)
-    db->data[XFORM (addr)] = *ptr;
+    db->data[XFORM (dcache, addr)] = *ptr;
 
   return 1;
 }
@@ -427,33 +467,13 @@ dcache_init (void)
   dcache->oldest = NULL;
   dcache->freelist = NULL;
   dcache->size = 0;
+  dcache->line_size = dcache_line_size;
   dcache->ptid = null_ptid;
   last_cache = dcache;
 
   return dcache;
 }
 
-/* BLOCK_FUNC routine for dcache_free.  */
-
-static void
-free_block (struct dcache_block *block, void *param)
-{
-  free (block);
-}
-
-/* Free a data cache.  */
-
-void
-dcache_free (DCACHE *dcache)
-{
-  if (last_cache == dcache)
-    last_cache = NULL;
-
-  splay_tree_delete (dcache->tree);
-  for_each_block (&dcache->oldest, free_block, NULL);
-  for_each_block (&dcache->freelist, free_block, NULL);
-  xfree (dcache);
-}
 
 /* Read or write LEN bytes from inferior memory at MEMADDR, transferring
    to or from debugger address MYADDR.  Write to inferior if SHOULD_WRITE is
@@ -571,12 +591,12 @@ dcache_print_line (int index)
   printf_filtered (_("Line %d: address %s [%d hits]\n"),
 		   index, paddress (target_gdbarch, db->addr), db->refs);
 
-  for (j = 0; j < LINE_SIZE; j++)
+  for (j = 0; j < last_cache->line_size; j++)
     {
       printf_filtered ("%02x ", db->data[j]);
 
       /* Print a newline every 16 bytes (48 characters).  */
-      if ((j % 16 == 15) && (j != LINE_SIZE - 1))
+      if ((j % 16 == 15) && (j != last_cache->line_size - 1))
 	printf_filtered ("\n");
     }
   printf_filtered ("\n");
@@ -603,8 +623,10 @@ dcache_info (char *exp, int tty)
       return;
     }
 
-  printf_filtered (_("Dcache line width %d, maximum size %d\n"),
-		   LINE_SIZE, DCACHE_SIZE);
+  printf_filtered (_("Dcache %u lines of %u bytes each.\n"),
+		   dcache_size,
+		   last_cache ? (unsigned) last_cache->line_size
+		   : dcache_line_size);
 
   if (!last_cache || ptid_equal (last_cache->ptid, null_ptid))
     {
@@ -635,6 +657,49 @@ dcache_info (char *exp, int tty)
   printf_filtered (_("Cache state: %d active lines, %d hits\n"), i, refcount);
 }
 
+static void
+set_dcache_size (char *args, int from_tty,
+		 struct cmd_list_element *c)
+{
+  if (dcache_size == 0)
+    {
+      unsigned d = dcache_size;
+      dcache_size = DCACHE_DEFAULT_SIZE;
+      error (_("Dcache size must be greater than 0."));
+    }
+  if (last_cache)
+    dcache_invalidate (last_cache);
+}
+
+static void
+set_dcache_line_size (char *args, int from_tty,
+		      struct cmd_list_element *c)
+{
+  if (dcache_line_size < 2
+      || (dcache_line_size & (dcache_line_size - 1)) != 0)
+    {
+      unsigned d = dcache_line_size;
+      dcache_line_size = DCACHE_DEFAULT_LINE_SIZE;
+      error (_("Invalid dcache line size: %u (must be power of 2)."), d);
+    }
+  if (last_cache)
+    dcache_invalidate (last_cache);
+}
+
+static void
+set_dcache_command (char *arg, int from_tty)
+{
+  printf_unfiltered (
+     "\"set dcache\" must be followed by the name of a subcommand.\n");
+  help_list (dcache_set_list, "set dcache ", -1, gdb_stdout);
+}
+
+static void
+show_dcache_command (char *args, int from_tty)
+{
+  cmd_show_list (dcache_show_list, from_tty, "");
+}
+
 void
 _initialize_dcache (void)
 {
@@ -656,4 +721,28 @@ Print information on the dcache performa
 With no arguments, this command prints the cache configuration and a\n\
 summary of each line in the cache.  Use \"info dcache <lineno> to dump\"\n\
 the contents of a given line."));
+
+  add_prefix_cmd ("dcache", class_obscure, set_dcache_command, _("\
+Use this command to set number of lines in dcache and line-size."),
+		  &dcache_set_list, "set dcache ", /*allow_unknown*/0, &setlist);
+  add_prefix_cmd ("dcache", class_obscure, show_dcache_command, _("\
+Show dcachesettings."),
+		  &dcache_show_list, "show dcache ", /*allow_unknown*/0, &showlist);
+
+  add_setshow_uinteger_cmd ("line-size", class_obscure,
+			    &dcache_line_size, _("\
+Set dcache line size in bytes (must be power of 2)."), _("\
+Show dcache line size."),
+			    NULL,
+			    set_dcache_line_size,
+			    NULL,
+			    &dcache_set_list, &dcache_show_list);
+  add_setshow_uinteger_cmd ("size", class_obscure,
+			    &dcache_size, _("\
+Set number of dcache lines."), _("\
+Show number of dcache lines."),
+			    NULL,
+			    set_dcache_size,
+			    NULL,
+			    &dcache_set_list, &dcache_show_list);
 }
Index: doc/gdb.texinfo
===================================================================
RCS file: /cvs/src/src/gdb/doc/gdb.texinfo,v
retrieving revision 1.848
diff -u -p -r1.848 gdb.texinfo
--- doc/gdb.texinfo	21 Jul 2011 15:13:29 -0000	1.848
+++ doc/gdb.texinfo	25 Jul 2011 20:43:39 -0000
@@ -9332,6 +9332,26 @@ operation.
 
 If a line number is specified, the contents of that line will be
 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).
+
+@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.
+
+@item show dcache size
+@kindex show dcache size
+Show maximum number of dcache entries.  See also @ref{Caching Remote Data, info dcache}.
+
+@item show dcache line-size
+@kindex show dcache line-size
+Show default size of dcache lines.  See also @ref{Caching Remote Data, info dcache}.
+
 @end table
 
 @node Searching Memory

  reply	other threads:[~2011-07-25 20:49 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-07-23  2:40 Paul Pluzhnikov
2011-07-23 16:57 ` Eli Zaretskii
2011-07-25 15:01 ` Tom Tromey
2011-07-25 18:47   ` Paul Pluzhnikov
2011-07-25 19:22     ` Tom Tromey
2011-07-25 19:32     ` Pedro Alves
2011-07-25 19:33       ` Tom Tromey
2011-07-25 20:49         ` Pedro Alves
2011-07-25 20:22     ` Eli Zaretskii
2011-07-25 21:04       ` Paul Pluzhnikov [this message]
2011-07-26  0:28         ` Pedro Alves
2011-07-26  9:51         ` Eli Zaretskii
2011-07-25 19:26 ` Jan Kratochvil
2011-07-25 20:58   ` Paul Pluzhnikov
2011-07-26  2:55     ` Jan Kratochvil

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=CALoOobPQKQZuvSw9E6RvhCfM7kSPkaaZ9F1DeMA1wiAy5pTU6A@mail.gmail.com \
    --to=ppluzhnikov@google.com \
    --cc=eliz@gnu.org \
    --cc=gdb-patches@sourceware.org \
    --cc=pedro@codesourcery.com \
    --cc=tromey@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox