You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by rj...@apache.org on 2015/01/04 10:55:05 UTC

svn commit: r1649306 - in /tomcat/jk/trunk: native/common/jk_ajp_common.c native/common/jk_global.h native/common/jk_lb_worker.c xdocs/miscellaneous/changelog.xml

Author: rjung
Date: Sun Jan  4 09:55:05 2015
New Revision: 1649306

URL: http://svn.apache.org/r1649306
Log:
BZ 44454: Improve busy counter by using atomics.

Atomics are used on Windows, when building with
gcc and when APR is available. Not used e.g.
for NSAPI on Solaris when building with Sun Studio
compiler.

Some problems still remain: theoretically the counter
can get skewed when doing a web server restart
(although some testing with Apache on Solaris
didn't actually show this problem).

Modified:
    tomcat/jk/trunk/native/common/jk_ajp_common.c
    tomcat/jk/trunk/native/common/jk_global.h
    tomcat/jk/trunk/native/common/jk_lb_worker.c
    tomcat/jk/trunk/xdocs/miscellaneous/changelog.xml

Modified: tomcat/jk/trunk/native/common/jk_ajp_common.c
URL: http://svn.apache.org/viewvc/tomcat/jk/trunk/native/common/jk_ajp_common.c?rev=1649306&r1=1649305&r2=1649306&view=diff
==============================================================================
--- tomcat/jk/trunk/native/common/jk_ajp_common.c (original)
+++ tomcat/jk/trunk/native/common/jk_ajp_common.c Sun Jan  4 09:55:05 2015
@@ -2397,8 +2397,7 @@ static void ajp_update_stats(jk_endpoint
 {
     aw->s->readed += e->rd;
     aw->s->transferred += e->wr;
-    if (aw->s->busy)
-        aw->s->busy--;
+    JK_ATOMIC_DECREMENT(&(aw->s->busy));
     if (rc == JK_TRUE) {
         aw->s->state = JK_AJP_STATE_OK;
     }
@@ -2464,6 +2463,7 @@ static int JK_METHOD ajp_service(jk_endp
     int rc = JK_UNSET;
     char *msg = "";
     int retry_interval;
+    int busy;
 
     JK_TRACE_ENTER(l);
 
@@ -2561,11 +2561,11 @@ static int JK_METHOD ajp_service(jk_endp
         jk_log(l, JK_LOG_DEBUG, "processing %s with %d retries",
                aw->name, aw->retries);
     }
-    aw->s->busy++;
+    busy = JK_ATOMIC_INCREMENT(&(aw->s->busy));
     if (aw->s->state == JK_AJP_STATE_ERROR)
         aw->s->state = JK_AJP_STATE_PROBE;
-    if (aw->s->busy > aw->s->max_busy)
-        aw->s->max_busy = aw->s->busy;
+    if (busy > aw->s->max_busy)
+        aw->s->max_busy = busy;
     retry_interval = p->worker->retry_interval;
     for (i = 0; i < aw->retries; i++) {
         /* Reset reply message buffer for each retry

Modified: tomcat/jk/trunk/native/common/jk_global.h
URL: http://svn.apache.org/viewvc/tomcat/jk/trunk/native/common/jk_global.h?rev=1649306&r1=1649305&r2=1649306&view=diff
==============================================================================
--- tomcat/jk/trunk/native/common/jk_global.h (original)
+++ tomcat/jk/trunk/native/common/jk_global.h Sun Jan  4 09:55:05 2015
@@ -65,6 +65,7 @@
 #ifdef HAVE_APR
 #include "apr_lib.h"
 #include "apr_strings.h"
+#include "apr_atomic.h"
 #endif
 
 #include <stdio.h>
@@ -413,6 +414,36 @@ typedef int jk_sock_t;
 #define strcasecmp(a,b) apr_strnatcasecmp(a,b)
 #endif
 
+/* Atomics */
+#if defined(WIN32)
+#define JK_ATOMIC_INCREMENT(x) InterlockedIncrement(x)
+#define JK_ATOMIC_DECREMENT(x) \
+    do {\
+        if (InterlockedDecrement(x) < 0) InterlockedIncrement(x);\
+    } while (0)
+#elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1))
+#define JK_ATOMIC_INCREMENT(x) __sync_add_and_fetch(x, 1)
+#define JK_ATOMIC_DECREMENT(x) \
+    do {\
+        if (__sync_sub_and_fetch(x, 1) < 0) __sync_add_and_fetch(x, 1);\
+    } while (0)
+#elif defined(HAVE_APR)
+#define JK_ATOMIC_INCREMENT(x) ((int)apr_atomic_inc32((volatile apr_uint32_t *)x) + 1)
+#define JK_ATOMIC_DECREMENT(x) \
+    do {\
+        /* apr_atomic_add32 returns the *old* value */\
+        apr_uint32_t y;\
+        y = apr_atomic_add32((volatile apr_uint32_t *)x, -1);\
+        if (y == 0 || y > INT_MAX) apr_atomic_inc32((volatile apr_uint32_t *)x);\
+    } while (0)
+#else
+#define JK_ATOMIC_INCREMENT(x) (++(*x))
+#define JK_ATOMIC_DECREMENT(x) \
+    do {\
+        if (--(*x) < 0) (++(*x));\
+    } while (0)
+#endif
+
 /* IPV6 support */
 #if defined(HAVE_APR)
 #define JK_HAVE_IPV6            APR_HAVE_IPV6

Modified: tomcat/jk/trunk/native/common/jk_lb_worker.c
URL: http://svn.apache.org/viewvc/tomcat/jk/trunk/native/common/jk_lb_worker.c?rev=1649306&r1=1649305&r2=1649306&view=diff
==============================================================================
--- tomcat/jk/trunk/native/common/jk_lb_worker.c (original)
+++ tomcat/jk/trunk/native/common/jk_lb_worker.c Sun Jan  4 09:55:05 2015
@@ -1310,6 +1310,7 @@ static int JK_METHOD service(jk_endpoint
                 int service_stat = JK_UNSET;
                 jk_uint64_t rd = 0;
                 jk_uint64_t wr = 0;
+                int busy;
                 /* Reset endpoint read and write sizes for
                  * this request.
                  */
@@ -1319,10 +1320,10 @@ static int JK_METHOD service(jk_endpoint
                     jk_shm_lock();
 
                 /* Increment the number of workers serving request */
-                p->worker->s->busy++;
-                rec->s->busy++;
-                if (p->worker->s->busy > p->worker->s->max_busy)
-                    p->worker->s->max_busy = p->worker->s->busy;
+                busy = JK_ATOMIC_INCREMENT(&(rec->s->busy));
+                busy = JK_ATOMIC_INCREMENT(&(p->worker->s->busy));
+                if (busy > p->worker->s->max_busy)
+                    p->worker->s->max_busy = busy;
                 if (p->worker->lbmethod == JK_LB_METHOD_REQUESTS ||
                     p->worker->lbmethod == JK_LB_METHOD_BUSYNESS ||
                     (!sessionid &&
@@ -1419,10 +1420,8 @@ static int JK_METHOD service(jk_endpoint
                  * Check if the busy was reset to zero by graceful
                  * restart of the server.
                  */
-                if (p->worker->s->busy)
-                    p->worker->s->busy--;
-                if (rec->s->busy)
-                    rec->s->busy--;
+                JK_ATOMIC_DECREMENT(&(p->worker->s->busy));
+                JK_ATOMIC_DECREMENT(&(rec->s->busy));
                 if (service_stat == JK_TRUE) {
                     /*
                      * Successful request.

Modified: tomcat/jk/trunk/xdocs/miscellaneous/changelog.xml
URL: http://svn.apache.org/viewvc/tomcat/jk/trunk/xdocs/miscellaneous/changelog.xml?rev=1649306&r1=1649305&r2=1649306&view=diff
==============================================================================
--- tomcat/jk/trunk/xdocs/miscellaneous/changelog.xml (original)
+++ tomcat/jk/trunk/xdocs/miscellaneous/changelog.xml Sun Jan  4 09:55:05 2015
@@ -168,6 +168,9 @@
         <bug>44454</bug>: LB: Add warning to docs about problems with
         "busyness" load balancing method. (rjung)
       </update>
+      <fix>
+        <bug>44454</bug>: Improve busy counter by using atomics. (rjung)
+      </fix>
     </changelog>
   </subsection>
 </section>



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org