Patchwork [RFA,2/2] Remove free_splay_tree cleanup

login
register
mail settings
Submitter Tom Tromey
Date Oct. 9, 2017, 2:43 a.m.
Message ID <20171009024300.8346-3-tom@tromey.com>
Download mbox | patch
Permalink /patch/23401/
State New
Headers show

Comments

Tom Tromey - Oct. 9, 2017, 2:43 a.m.
One spot in gdb uses a cleanup to free a splay tree.  This patch
introduces a unique_ptr specialization for this case.

gdb/ChangeLog
2017-10-08  Tom Tromey  <tom@tromey.com>

	* mi/mi-main.c (free_splay_tree): Remove.
	(list_available_thread_groups): Use splay_tree_up.
	* common/gdb_splay_tree.h: New file.
---
 gdb/ChangeLog               |  6 ++++++
 gdb/common/gdb_splay_tree.h | 38 ++++++++++++++++++++++++++++++++++++++
 gdb/mi/mi-main.c            | 24 ++++++++----------------
 3 files changed, 52 insertions(+), 16 deletions(-)
 create mode 100644 gdb/common/gdb_splay_tree.h
Simon Marchi - Oct. 9, 2017, 2:10 p.m.
On 2017-10-08 10:43 PM, Tom Tromey wrote:
> One spot in gdb uses a cleanup to free a splay tree.  This patch
> introduces a unique_ptr specialization for this case.
> 
> gdb/ChangeLog
> 2017-10-08  Tom Tromey  <tom@tromey.com>
> 
> 	* mi/mi-main.c (free_splay_tree): Remove.
> 	(list_available_thread_groups): Use splay_tree_up.
> 	* common/gdb_splay_tree.h: New file.
> ---
>  gdb/ChangeLog               |  6 ++++++
>  gdb/common/gdb_splay_tree.h | 38 ++++++++++++++++++++++++++++++++++++++
>  gdb/mi/mi-main.c            | 24 ++++++++----------------
>  3 files changed, 52 insertions(+), 16 deletions(-)
>  create mode 100644 gdb/common/gdb_splay_tree.h
> 
> diff --git a/gdb/common/gdb_splay_tree.h b/gdb/common/gdb_splay_tree.h
> new file mode 100644
> index 0000000000..b0dca2115c
> --- /dev/null
> +++ b/gdb/common/gdb_splay_tree.h
> @@ -0,0 +1,38 @@
> +/* GDB wrapper for splay trees.
> +
> +   Copyright (C) 2017 Free Software Foundation, Inc.
> +
> +   This file is part of GDB.
> +
> +   This program is free software; you can redistribute it and/or modify
> +   it under the terms of the GNU General Public License as published by
> +   the Free Software Foundation; either version 3 of the License, or
> +   (at your option) any later version.
> +
> +   This program is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> +   GNU General Public License for more details.
> +
> +   You should have received a copy of the GNU General Public License
> +   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
> +
> +#ifndef GDB_SPLAY_TREE_H
> +#define GDB_SPLAY_TREE_H
> +
> +#include "splay-tree.h"
> +
> +struct gdb_splay_tree_deleter
> +{
> +  void operator() (splay_tree tree) const
> +  {
> +    splay_tree_delete (tree);
> +  }
> +};

Instead of adding the gdb_ prefix, what about putting it in the gdb namespace (gdb::splay_tree_deleter)?

> +
> +/* A unique pointer to a splay tree.  */
> +
> +typedef std::unique_ptr<splay_tree_s, gdb_splay_tree_deleter>
> +    gdb_splay_tree_up;
> +
> +#endif /* ! GDB_SPLAY_TREE_H */
> diff --git a/gdb/mi/mi-main.c b/gdb/mi/mi-main.c
> index 98fff4f1b5..b9d3cba931 100644
> --- a/gdb/mi/mi-main.c
> +++ b/gdb/mi/mi-main.c
> @@ -46,7 +46,7 @@
>  #include "valprint.h"
>  #include "inferior.h"
>  #include "osdata.h"
> -#include "splay-tree.h"
> +#include "common/gdb_splay_tree.h"
>  #include "tracepoint.h"
>  #include "ctf.h"
>  #include "ada-lang.h"
> @@ -720,13 +720,6 @@ splay_tree_int_comparator (splay_tree_key xa, splay_tree_key xb)
>  }
>  
>  static void
> -free_splay_tree (void *xt)
> -{
> -  splay_tree t = (splay_tree) xt;
> -  splay_tree_delete (t);
> -}
> -
> -static void
>  list_available_thread_groups (const std::set<int> &ids, int recurse)
>  {
>    struct osdata *data;
> @@ -739,7 +732,7 @@ list_available_thread_groups (const std::set<int> &ids, int recurse)
>       The vector contains information about all threads for the given pid.
>       This is assigned an initial value to avoid "may be used uninitialized"
>       warning from gcc.  */
> -  splay_tree tree = NULL;
> +  gdb_splay_tree_up tree;
>  
>    /* get_osdata will throw if it cannot return data.  */
>    data = get_osdata ("processes");
> @@ -750,10 +743,9 @@ list_available_thread_groups (const std::set<int> &ids, int recurse)
>        struct osdata *threads = get_osdata ("threads");
>  
>        make_cleanup_osdata_free (threads);
> -      tree = splay_tree_new (splay_tree_int_comparator,
> -			     NULL,
> -			     free_vector_of_osdata_items);
> -      make_cleanup (free_splay_tree, tree);
> +      tree.reset (splay_tree_new (splay_tree_int_comparator,
> +				  NULL,
> +				  free_vector_of_osdata_items));
>  
>        for (ix_items = 0;
>  	   VEC_iterate (osdata_item_s, threads->items,
> @@ -764,11 +756,11 @@ list_available_thread_groups (const std::set<int> &ids, int recurse)
>  	  int pid_i = strtoul (pid, NULL, 0);
>  	  VEC (osdata_item_s) *vec = 0;
>  
> -	  splay_tree_node n = splay_tree_lookup (tree, pid_i);
> +	  splay_tree_node n = splay_tree_lookup (tree.get (), pid_i);
>  	  if (!n)
>  	    {
>  	      VEC_safe_push (osdata_item_s, vec, item);
> -	      splay_tree_insert (tree, pid_i, (splay_tree_value)vec);
> +	      splay_tree_insert (tree.get (), pid_i, (splay_tree_value)vec);
>  	    }
>  	  else
>  	    {
> @@ -812,7 +804,7 @@ list_available_thread_groups (const std::set<int> &ids, int recurse)
>  
>        if (recurse)
>  	{
> -	  splay_tree_node n = splay_tree_lookup (tree, pid_i);
> +	  splay_tree_node n = splay_tree_lookup (tree.get (), pid_i);
>  	  if (n)
>  	    {
>  	      VEC (osdata_item_s) *children = (VEC (osdata_item_s) *) n->value;
> 

Out of curiosity, is there still a reason to use splay_tree instead of std::map?

Simon
Tom Tromey - Oct. 9, 2017, 5:58 p.m.
>>>>> "Simon" == Simon Marchi <simark@simark.ca> writes:

>> +struct gdb_splay_tree_deleter
>> +{
>> +  void operator() (splay_tree tree) const
>> +  {
>> +    splay_tree_delete (tree);
>> +  }
>> +};

Simon> Instead of adding the gdb_ prefix, what about putting it in the gdb
Simon> namespace (gdb::splay_tree_deleter)?

I can make the change, but I was just copying all the other deleters
that exist.

You may want to go change all of those as well.

Simon> Out of curiosity, is there still a reason to use splay_tree
Simon> instead of std::map?

I don't know.

Tom
Simon Marchi - Oct. 9, 2017, 8:51 p.m.
On 2017-10-09 01:58 PM, Tom Tromey wrote:
>>>>>> "Simon" == Simon Marchi <simark@simark.ca> writes:
> 
>>> +struct gdb_splay_tree_deleter
>>> +{
>>> +  void operator() (splay_tree tree) const
>>> +  {
>>> +    splay_tree_delete (tree);
>>> +  }
>>> +};
> 
> Simon> Instead of adding the gdb_ prefix, what about putting it in the gdb
> Simon> namespace (gdb::splay_tree_deleter)?
> 
> I can make the change, but I was just copying all the other deleters
> that exist.
> 
> You may want to go change all of those as well.

There's gdb::xfree_deleter already.  But I have no strong feelings, the patch
is good as-is or with this changed.

Thanks,

Simon

Patch

diff --git a/gdb/common/gdb_splay_tree.h b/gdb/common/gdb_splay_tree.h
new file mode 100644
index 0000000000..b0dca2115c
--- /dev/null
+++ b/gdb/common/gdb_splay_tree.h
@@ -0,0 +1,38 @@ 
+/* GDB wrapper for splay trees.
+
+   Copyright (C) 2017 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#ifndef GDB_SPLAY_TREE_H
+#define GDB_SPLAY_TREE_H
+
+#include "splay-tree.h"
+
+struct gdb_splay_tree_deleter
+{
+  void operator() (splay_tree tree) const
+  {
+    splay_tree_delete (tree);
+  }
+};
+
+/* A unique pointer to a splay tree.  */
+
+typedef std::unique_ptr<splay_tree_s, gdb_splay_tree_deleter>
+    gdb_splay_tree_up;
+
+#endif /* ! GDB_SPLAY_TREE_H */
diff --git a/gdb/mi/mi-main.c b/gdb/mi/mi-main.c
index 98fff4f1b5..b9d3cba931 100644
--- a/gdb/mi/mi-main.c
+++ b/gdb/mi/mi-main.c
@@ -46,7 +46,7 @@ 
 #include "valprint.h"
 #include "inferior.h"
 #include "osdata.h"
-#include "splay-tree.h"
+#include "common/gdb_splay_tree.h"
 #include "tracepoint.h"
 #include "ctf.h"
 #include "ada-lang.h"
@@ -720,13 +720,6 @@  splay_tree_int_comparator (splay_tree_key xa, splay_tree_key xb)
 }
 
 static void
-free_splay_tree (void *xt)
-{
-  splay_tree t = (splay_tree) xt;
-  splay_tree_delete (t);
-}
-
-static void
 list_available_thread_groups (const std::set<int> &ids, int recurse)
 {
   struct osdata *data;
@@ -739,7 +732,7 @@  list_available_thread_groups (const std::set<int> &ids, int recurse)
      The vector contains information about all threads for the given pid.
      This is assigned an initial value to avoid "may be used uninitialized"
      warning from gcc.  */
-  splay_tree tree = NULL;
+  gdb_splay_tree_up tree;
 
   /* get_osdata will throw if it cannot return data.  */
   data = get_osdata ("processes");
@@ -750,10 +743,9 @@  list_available_thread_groups (const std::set<int> &ids, int recurse)
       struct osdata *threads = get_osdata ("threads");
 
       make_cleanup_osdata_free (threads);
-      tree = splay_tree_new (splay_tree_int_comparator,
-			     NULL,
-			     free_vector_of_osdata_items);
-      make_cleanup (free_splay_tree, tree);
+      tree.reset (splay_tree_new (splay_tree_int_comparator,
+				  NULL,
+				  free_vector_of_osdata_items));
 
       for (ix_items = 0;
 	   VEC_iterate (osdata_item_s, threads->items,
@@ -764,11 +756,11 @@  list_available_thread_groups (const std::set<int> &ids, int recurse)
 	  int pid_i = strtoul (pid, NULL, 0);
 	  VEC (osdata_item_s) *vec = 0;
 
-	  splay_tree_node n = splay_tree_lookup (tree, pid_i);
+	  splay_tree_node n = splay_tree_lookup (tree.get (), pid_i);
 	  if (!n)
 	    {
 	      VEC_safe_push (osdata_item_s, vec, item);
-	      splay_tree_insert (tree, pid_i, (splay_tree_value)vec);
+	      splay_tree_insert (tree.get (), pid_i, (splay_tree_value)vec);
 	    }
 	  else
 	    {
@@ -812,7 +804,7 @@  list_available_thread_groups (const std::set<int> &ids, int recurse)
 
       if (recurse)
 	{
-	  splay_tree_node n = splay_tree_lookup (tree, pid_i);
+	  splay_tree_node n = splay_tree_lookup (tree.get (), pid_i);
 	  if (n)
 	    {
 	      VEC (osdata_item_s) *children = (VEC (osdata_item_s) *) n->value;