Commit 00dcddaa by Frank Ch. Eigler Committed by Frank Ch. Eigler

ANSI C conversion, libmudflap specialization, recursion limiting.

2004-07-08  Frank Ch. Eigler  <fche@redhat.com>

	ANSI C conversion, libmudflap specialization, recursion limiting.
	* splay-tree.h (splay_tree_{de,}allocate_fn): Remove allocation_data
	argument and indirection function pointers, update callers.
	(splay_tree_s): Add statistics and recursion control fields
	num_keys, max_depth, depth, rebalance_p.
	* splay-tree.c (splay_tree_splay_helper): Track recursion depth.
	Back out of search if it exceeds limit.
	(splay_tree_splay): Manage recursion limiting with rebalancing as
	needed.
	(splay_tree_new): More initialization.
	(splay_tree_rebalance): New function.
	(splay_tree_foreach): Rewrite using nonrecursive logic.
	(splay_tree_xmalloc_allocate, splay_tree_xmalloc_deallocate):
	Remove.  Point indirect calls to mf-runtime.c's routines.
	(splay_tree_compare_ints, splay_tree_compare_pointers): Remove unused
	functions.
	(splay_tree_delete, splay_tree_delete_helper): Ditto.
	* testsuite/heap-scalestress.c: New test based on one from
	Eyal Lebedinsky <eyal@eyal.emu.id.au>:

From-SVN: r84303
parent a32e70c3
2004-07-08 Frank Ch. Eigler <fche@redhat.com>
ANSI C conversion, libmudflap specialization, recursion limiting.
* splay-tree.h (splay_tree_{de,}allocate_fn): Remove allocation_data
argument and indirection function pointers, update callers.
(splay_tree_s): Add statistics and recursion control fields
num_keys, max_depth, depth, rebalance_p.
* splay-tree.c (splay_tree_splay_helper): Track recursion depth.
Back out of search if it exceeds limit.
(splay_tree_splay): Manage recursion limiting with rebalancing as
needed.
(splay_tree_new): More initialization.
(splay_tree_rebalance): New function.
(splay_tree_foreach): Rewrite using nonrecursive logic.
(splay_tree_xmalloc_allocate, splay_tree_xmalloc_deallocate):
Remove. Point indirect calls to mf-runtime.c's routines.
(splay_tree_compare_ints, splay_tree_compare_pointers): Remove unused
functions.
(splay_tree_delete, splay_tree_delete_helper): Ditto.
* testsuite/heap-scalestress.c: New test based on one from
Eyal Lebedinsky <eyal@eyal.emu.id.au>:
2004-07-05 Matthias Klose <doko@debian.org> 2004-07-05 Matthias Klose <doko@debian.org>
* libtool-version: New. * libtool-version: New.
......
/* A splay-tree datatype. /* A splay-tree datatype.
Copyright 1998, 1999, 2000, 2002, 2004 Free Software Foundation, Inc. Copyright 1998, 1999, 2000, 2002, 2004 Free Software Foundation, Inc.
Contributed by Mark Mitchell (mark@markmitchell.com). Contributed by Mark Mitchell (mark@markmitchell.com).
Adapted for libmudflap from libiberty. Adapted for libmudflap from libiberty by Frank Ch. Eigler <fche@redhat.com>.
This file is part of GCC. This file is part of GCC.
...@@ -26,23 +26,16 @@ Boston, MA 02111-1307, USA. */ ...@@ -26,23 +26,16 @@ Boston, MA 02111-1307, USA. */
Algorithms. Harper-Collins, Inc. 1991. Algorithms. Harper-Collins, Inc. 1991.
The major feature of splay trees is that all basic tree operations The major feature of splay trees is that all basic tree operations
are amortized O(log n) time for a tree with n nodes. */ are amortized O(log n) time for a tree with n nodes.
This version has been further modified to periodically rebalance
the entire tree, should degenerate access patterns result in a very
lopsided tree.
*/
#ifndef _SPLAY_TREE_H #ifndef _SPLAY_TREE_H
#define _SPLAY_TREE_H #define _SPLAY_TREE_H
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#define PARAMS(X) X
#define PTR void *
#define ATTRIBUTE_UNUSED __attribute__((__unused__))
#ifndef GTY
#define GTY(X)
#endif
/* Use typedefs for the key and data types to facilitate changing /* Use typedefs for the key and data types to facilitate changing
these types, if necessary. These types should be sufficiently wide these types, if necessary. These types should be sufficiently wide
that any pointer or scalar can be cast to these types, and then that any pointer or scalar can be cast to these types, and then
...@@ -54,83 +47,50 @@ typedef void *splay_tree_value; ...@@ -54,83 +47,50 @@ typedef void *splay_tree_value;
typedef struct splay_tree_node_s *splay_tree_node; typedef struct splay_tree_node_s *splay_tree_node;
/* The type of a function used to iterate over the tree. */ /* The type of a function used to iterate over the tree. */
typedef int (*splay_tree_foreach_fn) PARAMS((splay_tree_node, void*)); typedef int (*splay_tree_foreach_fn) (splay_tree_node, void *);
/* The type of a function used to allocate memory for tree root and
node structures. The first argument is the number of bytes needed;
the second is a data pointer the splay tree functions pass through
to the allocator. This function must never return zero. */
typedef PTR (*splay_tree_allocate_fn) PARAMS((int, void *));
/* The type of a function used to free memory allocated using the
corresponding splay_tree_allocate_fn. The first argument is the
memory to be freed; the latter is a data pointer the splay tree
functions pass through to the freer. */
typedef void (*splay_tree_deallocate_fn) PARAMS((void *, void *));
/* The nodes in the splay tree. */ /* The nodes in the splay tree. */
struct splay_tree_node_s GTY(()) struct splay_tree_node_s
{ {
/* The key. */ /* Data. */
splay_tree_key GTY ((use_param1)) key; splay_tree_key key;
splay_tree_value value;
/* The value. */ /* Children. */
splay_tree_value GTY ((use_param2)) value; splay_tree_node left;
splay_tree_node right;
/* The left and right children, respectively. */
splay_tree_node GTY ((use_params)) left;
splay_tree_node GTY ((use_params)) right;
}; };
/* The splay tree itself. */ /* The splay tree itself. */
struct splay_tree_s GTY(()) struct splay_tree_s
{ {
/* The root of the tree. */ /* The root of the tree. */
splay_tree_node GTY ((use_params)) root; splay_tree_node root;
/* Allocate/free functions, and a data pointer to pass to them. */
splay_tree_allocate_fn allocate;
splay_tree_deallocate_fn deallocate;
PTR GTY((skip)) allocate_data;
/* The last key value for which the tree has been splayed, but not /* The last key value for which the tree has been splayed, but not
since modified. */ since modified. */
splay_tree_key GTY ((use_param1)) last_splayed_key; splay_tree_key last_splayed_key;
int last_splayed_key_p; int last_splayed_key_p;
/* Statistics. */
unsigned num_keys;
/* Traversal recursion control flags. */
unsigned max_depth;
unsigned depth;
unsigned rebalance_p;
}; };
typedef struct splay_tree_s *splay_tree; typedef struct splay_tree_s *splay_tree;
extern splay_tree splay_tree_new PARAMS((void)); extern splay_tree splay_tree_new (void);
extern void splay_tree_delete PARAMS((splay_tree)); extern splay_tree_node splay_tree_insert (splay_tree, splay_tree_key, splay_tree_value);
extern splay_tree_node splay_tree_insert extern void splay_tree_remove (splay_tree, splay_tree_key);
PARAMS((splay_tree, extern splay_tree_node splay_tree_lookup (splay_tree, splay_tree_key);
splay_tree_key, extern splay_tree_node splay_tree_predecessor (splay_tree, splay_tree_key);
splay_tree_value)); extern splay_tree_node splay_tree_successor (splay_tree, splay_tree_key);
extern void splay_tree_remove PARAMS((splay_tree, extern splay_tree_node splay_tree_max (splay_tree);
splay_tree_key)); extern splay_tree_node splay_tree_min (splay_tree);
extern splay_tree_node splay_tree_lookup extern int splay_tree_foreach (splay_tree, splay_tree_foreach_fn, void *);
PARAMS((splay_tree, extern void splay_tree_rebalance (splay_tree sp);
splay_tree_key));
extern splay_tree_node splay_tree_predecessor
PARAMS((splay_tree,
splay_tree_key));
extern splay_tree_node splay_tree_successor
PARAMS((splay_tree,
splay_tree_key));
extern splay_tree_node splay_tree_max
PARAMS((splay_tree));
extern splay_tree_node splay_tree_min
PARAMS((splay_tree));
extern int splay_tree_foreach PARAMS((splay_tree,
splay_tree_foreach_fn,
void*));
extern int splay_tree_compare_ints PARAMS((splay_tree_key,
splay_tree_key));
extern int splay_tree_compare_pointers PARAMS((splay_tree_key,
splay_tree_key));
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* _SPLAY_TREE_H */ #endif /* _SPLAY_TREE_H */
/* zz30
*
* demonstrate a splay-tree depth problem
*/
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#ifndef SCALE
#define SCALE 100000
#endif
struct list
{
struct list *next;
};
int
main ()
{
struct list *head = NULL;
struct list *tail = NULL;
struct list *p;
long n;
int direction;
for (direction = 0; direction < 2; direction++)
{
fprintf (stdout, "allocating\n");
fflush (stdout);
for (n = 0; n < SCALE; ++n)
{
p = malloc (sizeof *p);
if (NULL == p)
{
fprintf (stdout, "malloc failed\n");
break;
}
if (direction == 0)
{ /* add at tail */
p->next = NULL;
if (NULL != tail)
tail->next = p;
else
head = p;
tail = p;
}
else
{ /* add at head */
p->next = head;
if (NULL == tail)
tail = p;
head = p;
}
}
fprintf (stdout, "freeing\n");
fflush (stdout);
while (NULL != head)
{
p = head;
head = head->next;
free (p);
}
}
fprintf (stdout, "done\n");
fflush (stdout);
return (0);
}
/* { dg-output "allocating.*freeing.*allocating.*freeing.*done" } */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment