Add __builtin_expect in many places.
[kopensolaris-gnu/glibc.git] / iconv / gconv_dl.c
index 7d327ed..d07f84e 100644 (file)
@@ -1,5 +1,5 @@
 /* Handle loading/unloading of shared object for transformation.
 /* Handle loading/unloading of shared object for transformation.
-   Copyright (C) 1997, 1998, 1999 Free Software Foundation, Inc.
+   Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
 
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
 
@@ -18,6 +18,7 @@
    write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
    Boston, MA 02111-1307, USA.  */
 
    write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
    Boston, MA 02111-1307, USA.  */
 
+#include <assert.h>
 #include <dlfcn.h>
 #include <inttypes.h>
 #include <search.h>
 #include <dlfcn.h>
 #include <inttypes.h>
 #include <search.h>
 
 #include <gconv_int.h>
 
 
 #include <gconv_int.h>
 
+
+#ifdef DEBUG
+/* For debugging purposes.  */
+static void print_all (void);
+#endif
+
+
 /* This is a tuning parameter.  If a transformation module is not used
    anymore it gets not immediately unloaded.  Instead we wait a certain
    number of load attempts for further modules.  If none of the
 /* This is a tuning parameter.  If a transformation module is not used
    anymore it gets not immediately unloaded.  Instead we wait a certain
    number of load attempts for further modules.  If none of the
@@ -50,7 +58,7 @@ known_compare (const void *p1, const void *p2)
   const struct __gconv_loaded_object *s2 =
     (const struct __gconv_loaded_object *) p2;
 
   const struct __gconv_loaded_object *s2 =
     (const struct __gconv_loaded_object *) p2;
 
-  return (intptr_t) s1->handle - (intptr_t) s2->handle;
+  return strcmp (s1->name, s2->name);
 }
 
 /* Open the gconv database if necessary.  A non-negative return value
 }
 
 /* Open the gconv database if necessary.  A non-negative return value
@@ -83,7 +91,8 @@ __gconv_find_shlib (const char *name)
          found->counter = -TRIES_BEFORE_UNLOAD - 1;
          found->handle = NULL;
 
          found->counter = -TRIES_BEFORE_UNLOAD - 1;
          found->handle = NULL;
 
-         if (__tsearch (found, &loaded, known_compare) == NULL)
+         if (__builtin_expect (__tsearch (found, &loaded, known_compare)
+                               == NULL, 0))
            {
              /* Something went wrong while inserting the entry.  */
              free (found);
            {
              /* Something went wrong while inserting the entry.  */
              free (found);
@@ -147,9 +156,12 @@ do_release_shlib (const void *nodep, VISIT value, int level)
     return;
 
   if (obj == release_handle)
     return;
 
   if (obj == release_handle)
-    /* This is the object we want to unload.  Now set the release
-       counter to zero.  */
-    obj->counter = 0;
+    {
+      /* This is the object we want to unload.  Now decrement the
+        reference counter.  */
+      assert (obj->counter > 0);
+      --obj->counter;
+    }
   else if (obj->counter <= 0)
     {
       if (--obj->counter < -TRIES_BEFORE_UNLOAD && obj->handle != NULL)
   else if (obj->counter <= 0)
     {
       if (--obj->counter < -TRIES_BEFORE_UNLOAD && obj->handle != NULL)
@@ -198,3 +210,24 @@ free_mem (void)
   __tdestroy (loaded, do_release_all);
 }
 text_set_element (__libc_subfreeres, free_mem);
   __tdestroy (loaded, do_release_all);
 }
 text_set_element (__libc_subfreeres, free_mem);
+
+
+#ifdef DEBUG
+static void
+do_print (const void *nodep, VISIT value, int level)
+{
+  struct __gconv_loaded_object *obj = *(struct __gconv_loaded_object **) nodep;
+
+  printf ("%10s: \"%s\", %d\n",
+         value == leaf ? "leaf" :
+         value == preorder ? "preorder" :
+         value == postorder ? "postorder" : "endorder",
+         obj->name, obj->counter);
+}
+
+static void
+print_all (void)
+{
+  __twalk (loaded, do_print);
+}
+#endif