]> source.dussan.org Git - rspamd.git/commitdiff
* Improve locking by using asm 'pause' command
authorVsevolod Stakhov <vsevolod@rambler-co.ru>
Wed, 17 Jun 2009 16:31:42 +0000 (20:31 +0400)
committerVsevolod Stakhov <vsevolod@rambler-co.ru>
Wed, 17 Jun 2009 16:31:42 +0000 (20:31 +0400)
* Try to fix read locking in rwlock

CMakeLists.txt
config.h.in
src/mem_pool.c

index 754b2200a75b68285cfc0cc1df7852ea266edd02..67611982796b7f3603d0c3f5fb9bbba883bb6f2f 100644 (file)
@@ -34,6 +34,7 @@ OPTION(ENABLE_GPERF_TOOLS  "Enable google perftools [default: OFF]"
 INCLUDE(CheckIncludeFiles)
 INCLUDE(CheckFunctionExists)
 INCLUDE(CheckSymbolExists)
+INCLUDE(CheckCSourceCompiles)
 INCLUDE(CheckLibraryExists)
 INCLUDE(FindPkgConfig)
 
@@ -229,6 +230,12 @@ CHECK_SYMBOL_EXISTS(_SC_NPROCESSORS_ONLN unistd.h HAVE_SC_NPROCESSORS_ONLN)
 CHECK_SYMBOL_EXISTS(CLOCK_PROCESS_CPUTIME_ID time.h HAVE_CLOCK_PROCESS_CPUTIME_ID)
 CHECK_SYMBOL_EXISTS(CLOCK_VIRTUAL time.h HAVE_CLOCK_VIRTUAL)
 
+CHECK_C_SOURCE_COMPILES ("#include <sys/types.h>
+                          int main (int argc, char **argv) {
+                                                       __asm __volatile(\"pause\");
+                                                       return 0;
+                                                 }" HAVE_ASM_PAUSE)
+
 IF(NOT HAVE_COMPATIBLE_QUEUE_H)
        INCLUDE_DIRECTORIES(compat)
 ENDIF(NOT HAVE_COMPATIBLE_QUEUE_H)
index 61bbc6068fe573bf5e7a43a971e43f2d7f2c76d8..12593da611a729356664d6f46445b45b07c615ed 100644 (file)
 
 #cmakedefine WITH_GPERF_TOOLS    1
 
+#cmakedefine HAVE_ASM_PAUSE      1
+
 #define RVERSION          "${RSPAMD_VERSION}"
 #define RSPAMD_MASTER_SITE_URL "${RSPAMD_MASTER_SITE_URL}"
 
index e034ea65227fedab51cd9f5c4fbb486d66d51e88..e8be6a95c2a9e65fbaec94afbd063d34a14bbcf5 100644 (file)
@@ -343,17 +343,17 @@ __mutex_spin (memory_pool_mutex_t *mutex)
                /* Spin again */
                g_atomic_int_set (&mutex->spin, MUTEX_SPIN_COUNT);
        }
-#ifdef HAVE_NANOSLEEP
+#ifdef HAVE_ASM_PAUSE
+       __asm __volatile("pause");
+#elif defined(HAVE_SCHED_YIELD)
+       (void)sched_yield ();
+#elif defined(HAVE_NANOSLEEP)
        struct timespec ts;
        ts.tv_sec = 0;
        ts.tv_nsec = MUTEX_SLEEP_TIME;
        /* Spin */
        while (nanosleep (&ts, &ts) == -1 && errno == EINTR);
-#endif
-#ifdef HAVE_SCHED_YIELD
-       (void)sched_yield ();
-#endif
-#if !defined(HAVE_NANOSLEEP) && !defined(HAVE_SCHED_YIELD)
+#else
 #      error No methods to spin are defined
 #endif
        return 1;
@@ -552,7 +552,9 @@ memory_pool_wlock_rwlock (memory_pool_rwlock_t *lock)
 void 
 memory_pool_runlock_rwlock (memory_pool_rwlock_t *lock)
 {
-       memory_pool_unlock_mutex (lock->__r_lock);
+       if (g_atomic_int_get (&lock->__r_lock->lock)) {
+               (void)g_atomic_int_dec_and_test (&lock->__r_lock->lock);
+       }
 }
 
 void