apr_atomic_xchgptr() and friends are not available on APR 0.9. (This is causing a buildbot build failure.)
-Hyrum On Tue, May 17, 2011 at 11:27 AM, <stef...@apache.org> wrote: > Author: stefan2 > Date: Tue May 17 11:27:25 2011 > New Revision: 1104160 > > URL: http://svn.apache.org/viewvc?rev=1104160&view=rev > Log: > Speed up UTF8 conversion, especially if APR_HAS_THREADS. > Provide global > > * subversion/libsvn_subr/utf.c > (SVN_UTF_NTOU_XLATE_HANDLE, SVN_UTF_UTON_XLATE_HANDLE): > make them identifiable by address > (xlat_ntou_static_handle, xlat_uton_static_handle): > introduce global translation map pointers as 1st level cache > (get_xlate_handle_node): match standard xlat types by address; > try global map pointers first before falling back to the hash > (put_xlate_handle_node): match standard xlat types by address; > push old global maps to hash > > Modified: > subversion/trunk/subversion/libsvn_subr/utf.c > > Modified: subversion/trunk/subversion/libsvn_subr/utf.c > URL: > http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_subr/utf.c?rev=1104160&r1=1104159&r2=1104160&view=diff > ============================================================================== > --- subversion/trunk/subversion/libsvn_subr/utf.c (original) > +++ subversion/trunk/subversion/libsvn_subr/utf.c Tue May 17 11:27:25 2011 > @@ -29,6 +29,7 @@ > #include <apr_strings.h> > #include <apr_lib.h> > #include <apr_xlate.h> > +#include <apr_atomic.h> > > #include "svn_string.h" > #include "svn_error.h" > @@ -42,9 +43,13 @@ > > > > -#define SVN_UTF_NTOU_XLATE_HANDLE "svn-utf-ntou-xlate-handle" > -#define SVN_UTF_UTON_XLATE_HANDLE "svn-utf-uton-xlate-handle" > -#define SVN_APR_UTF8_CHARSET "UTF-8" > +/* Use these static strings to maximize performance on standard conversions. > + * Any strings on other locations are still valid, however. > + */ > +static const char *SVN_UTF_NTOU_XLATE_HANDLE = "svn-utf-ntou-xlate-handle"; > +static const char *SVN_UTF_UTON_XLATE_HANDLE = "svn-utf-uton-xlate-handle"; > + > +static const char *SVN_APR_UTF8_CHARSET = "UTF-8"; > > #if APR_HAS_THREADS > static apr_thread_mutex_t *xlate_handle_mutex = NULL; > @@ -79,6 +84,13 @@ typedef struct xlate_handle_node_t { > memory leak. */ > static apr_hash_t *xlate_handle_hash = NULL; > > +/* "1st level cache" to standard conversion maps. We may access these > + * using atomic xchange ops, i.e. without further thread synchronization. > + * If the respective item is NULL, fallback to hash lookup. > + */ > +static volatile void *xlat_ntou_static_handle = NULL; > +static volatile void *xlat_uton_static_handle = NULL; > + > /* Clean up the xlate handle cache. */ > static apr_status_t > xlate_cleanup(void *arg) > @@ -91,6 +103,10 @@ xlate_cleanup(void *arg) > #endif > xlate_handle_hash = NULL; > > + /* ensure no stale objects get accessed */ > + xlat_ntou_static_handle = NULL; > + xlat_uton_static_handle = NULL; > + > return APR_SUCCESS; > } > > @@ -183,6 +199,19 @@ get_xlate_handle_node(xlate_handle_node_ > { > if (xlate_handle_hash) > { > + /* 1st level: global, static items */ > + if (userdata_key == SVN_UTF_NTOU_XLATE_HANDLE) > + old_node = apr_atomic_xchgptr(&xlat_ntou_static_handle, NULL); > + else if (userdata_key == SVN_UTF_UTON_XLATE_HANDLE) > + old_node = apr_atomic_xchgptr(&xlat_uton_static_handle, NULL); > + > + if (old_node && old_node->valid) > + { > + *ret = old_node; > + return SVN_NO_ERROR; > + } > + > + /* 2nd level: hash lookup */ > #if APR_HAS_THREADS > apr_err = apr_thread_mutex_lock(xlate_handle_mutex); > if (apr_err != APR_SUCCESS) > @@ -321,9 +350,20 @@ put_xlate_handle_node(xlate_handle_node_ > assert(node->next == NULL); > if (!userdata_key) > return; > + > + /* push previous global node to the hash */ > if (xlate_handle_hash) > { > xlate_handle_node_t **node_p; > + > + /* 1st level: global, static items */ > + if (userdata_key == SVN_UTF_NTOU_XLATE_HANDLE) > + node = apr_atomic_xchgptr(&xlat_ntou_static_handle, node); > + else if (userdata_key == SVN_UTF_UTON_XLATE_HANDLE) > + node = apr_atomic_xchgptr(&xlat_uton_static_handle, node); > + if (node == NULL) > + return; > + > #if APR_HAS_THREADS > if (apr_thread_mutex_lock(xlate_handle_mutex) != APR_SUCCESS) > SVN_ERR_MALFUNCTION_NO_RETURN(); > > >