Author: stefan2
Date: Sun Sep 15 16:11:45 2013
New Revision: 1523450

URL: http://svn.apache.org/r1523450
Log:
Improve scalability of fs_open()and similar functions currently limited
by the common_pool_lock.  Acquire the vtable only once per backend.

* subversion/libsvn_fs/fs-loader.c
  (fs_type_defn): add vtable pointer to backend description
  (base_defn,
   fsx_defn,
   fsfs_defn): init vtable to NULL
  (get_library_vtable_direct): backend descriptions are modifiable now;
                               fetch vtable only once per backend
  (svn_fs_print_modules): update caller

Modified:
    subversion/trunk/subversion/libsvn_fs/fs-loader.c

Modified: subversion/trunk/subversion/libsvn_fs/fs-loader.c
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs/fs-loader.c?rev=1523450&r1=1523449&r2=1523450&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_fs/fs-loader.c (original)
+++ subversion/trunk/subversion/libsvn_fs/fs-loader.c Sun Sep 15 16:11:45 2013
@@ -24,6 +24,7 @@
 
 #include <string.h>
 #include <apr.h>
+#include <apr_atomic.h>
 #include <apr_hash.h>
 #include <apr_md5.h>
 #include <apr_thread_mutex.h>
@@ -70,6 +71,7 @@ struct fs_type_defn {
   const char *fs_type;
   const char *fsap_name;
   fs_init_func_t initfunc;
+  fs_library_vtable_t *vtable;
   struct fs_type_defn *next;
 };
 
@@ -81,6 +83,7 @@ static struct fs_type_defn base_defn =
 #else
     NULL,
 #endif
+    NULL,
     NULL /* End of static list: this needs to be reset to NULL if the
             common_pool used when setting it has been cleared. */
   };
@@ -93,6 +96,7 @@ static struct fs_type_defn fsx_defn =
 #else
     NULL,
 #endif
+    NULL,
     &base_defn
   };
 
@@ -104,6 +108,7 @@ static struct fs_type_defn fsfs_defn =
 #else
     NULL,
 #endif
+    NULL,
     &fsx_defn
   };
 
@@ -159,13 +164,20 @@ load_module(fs_init_func_t *initfunc, co
 /* Fetch a library vtable by a pointer into the library definitions array. */
 static svn_error_t *
 get_library_vtable_direct(fs_library_vtable_t **vtable,
-                          const struct fs_type_defn *fst,
+                          struct fs_type_defn *fst,
                           apr_pool_t *pool)
 {
   fs_init_func_t initfunc = NULL;
   const svn_version_t *my_version = svn_fs_version();
   const svn_version_t *fs_version;
 
+  /* most times, we get lucky */
+  *vtable = apr_atomic_casptr((volatile void **)&fst->vtable, NULL, NULL);
+  if (*vtable)
+    return SVN_NO_ERROR;
+
+  /* o.k. the first access needs to actually load the module, find the
+     vtable and check for version compatibility. */
   initfunc = fst->initfunc;
   if (! initfunc)
     SVN_ERR(load_module(&initfunc, fst->fsap_name, pool));
@@ -202,6 +214,10 @@ get_library_vtable_direct(fs_library_vta
                              my_version->patch, my_version->tag,
                              fs_version->major, fs_version->minor,
                              fs_version->patch, fs_version->tag);
+
+  /* the vtable will not change.  Remember it */
+  apr_atomic_casptr((volatile void **)&fst->vtable, *vtable, NULL);
+
   return SVN_NO_ERROR;
 }
 
@@ -1625,7 +1641,7 @@ svn_error_t *
 svn_fs_print_modules(svn_stringbuf_t *output,
                      apr_pool_t *pool)
 {
-  const struct fs_type_defn *defn = fs_modules;
+  struct fs_type_defn *defn = fs_modules;
   fs_library_vtable_t *vtable;
   apr_pool_t *iterpool = svn_pool_create(pool);
 


Reply via email to