MAJOR: ssl: Change default locks on ssl session cache.

Prevously pthread process shared lock were used by default,
if USE_SYSCALL_FUTEX is not specified.

This patch implements an OS independant kind of lock:
An active spinlock is usedf if USE_SYSCALL_FUTEX is not specified.

The old behavior is still available if USE_PTHREAD_PSHARED=1.
diff --git a/src/shctx.c b/src/shctx.c
index 86e6056..f33b7ca 100644
--- a/src/shctx.c
+++ b/src/shctx.c
@@ -13,6 +13,9 @@
 
 #include <sys/mman.h>
 #ifndef USE_PRIVATE_CACHE
+#ifdef USE_PTHREAD_PSHARED
+#include <pthread.h>
+#else
 #ifdef USE_SYSCALL_FUTEX
 #include <unistd.h>
 #ifndef u32
@@ -20,9 +23,8 @@
 #endif
 #include <linux/futex.h>
 #include <sys/syscall.h>
-#else /* USE_SYSCALL_FUTEX */
-#include <pthread.h>
-#endif /* USE_SYSCALL_FUTEX */
+#endif
+#endif
 #endif
 #include <arpa/inet.h>
 #include "ebmbtree.h"
@@ -60,10 +62,10 @@
 
 struct shared_context {
 #ifndef USE_PRIVATE_CACHE
-#ifdef USE_SYSCALL_FUTEX
-	unsigned int waiters;
-#else /* USE_SYSCALL_FUTEX */
+#ifdef USE_PTHREAD_PSHARED
 	pthread_mutex_t mutex;
+#else
+	unsigned int waiters;
 #endif
 #endif
 	struct shsess_packet_hdr upd;
@@ -75,17 +77,63 @@
 
 /* Static shared context */
 static struct shared_context *shctx = NULL;
-#ifndef USE_PRIVATE_CACHE
-static int use_shared_mem = 0;
-#endif
 
 /* Lock functions */
-#ifdef USE_PRIVATE_CACHE
+
+#if defined (USE_PRIVATE_CACHE)
+
 #define shared_context_lock()
 #define shared_context_unlock()
 
+#elif defined (USE_PTHREAD_PSHARED)
+static int use_shared_mem = 0;
+
+#define shared_context_lock()   if (use_shared_mem) pthread_mutex_lock(&shctx->mutex)
+#define shared_context_unlock() if (use_shared_mem) pthread_mutex_unlock(&shctx->mutex)
+
 #else
+static int use_shared_mem = 0;
+
 #ifdef USE_SYSCALL_FUTEX
+static inline void _shared_context_wait4lock(unsigned int *count, unsigned int *uaddr, int value)
+{
+	syscall(SYS_futex, uaddr, FUTEX_WAIT, value, NULL, 0, 0);
+}
+
+static inline void _shared_context_awakelocker(unsigned int *uaddr)
+{
+	syscall(SYS_futex, uaddr, FUTEX_WAKE, 1, NULL, 0, 0);
+}
+
+#else /* internal spin lock */
+
+#if defined (__i486__) || defined (__i586__) || defined (__i686__) || defined (__x86_64__)
+static inline void relax()
+{
+	__asm volatile("rep;nop\n" ::: "memory");
+}
+#else /* if no x86_64 or i586 arch: use less optimized but generic asm */
+static inline void relax()
+{
+	__asm volatile("" ::: "memory");
+}
+#endif
+
+static inline void _shared_context_wait4lock(unsigned int *count, unsigned int *uaddr, int value)
+{
+        int i;
+
+        for (i = 0; i < *count; i++) {
+                relax();
+                relax();
+        }
+        *count = *count << 1;
+}
+
+#define _shared_context_awakelocker(a)
+
+#endif
+
 #if defined (__i486__) || defined (__i586__) || defined (__i686__) || defined (__x86_64__)
 static inline unsigned int xchg(unsigned int *ptr, unsigned int x)
 {
@@ -139,6 +187,7 @@
 static inline void _shared_context_lock(void)
 {
 	unsigned int x;
+	unsigned int count = 4;
 
 	x = cmpxchg(&shctx->waiters, 0, 1);
 	if (x) {
@@ -146,7 +195,7 @@
 			x = xchg(&shctx->waiters, 2);
 
 		while (x) {
-			syscall(SYS_futex, &shctx->waiters, FUTEX_WAIT, 2, NULL, 0, 0);
+			_shared_context_wait4lock(&count, &shctx->waiters, 2);
 			x = xchg(&shctx->waiters, 2);
 		}
 	}
@@ -156,7 +205,7 @@
 {
 	if (atomic_dec(&shctx->waiters)) {
 		shctx->waiters = 0;
-		syscall(SYS_futex, &shctx->waiters, FUTEX_WAKE, 1, NULL, 0, 0);
+		_shared_context_awakelocker(&shctx->waiters);
 	}
 }
 
@@ -164,13 +213,6 @@
 
 #define shared_context_unlock() if (use_shared_mem) _shared_context_unlock()
 
-#else /* USE_SYSCALL_FUTEX */
-
-#define shared_context_lock()   if (use_shared_mem) pthread_mutex_lock(&shctx->mutex)
-
-#define shared_context_unlock() if (use_shared_mem) pthread_mutex_unlock(&shctx->mutex)
-
-#endif
 #endif
 
 /* List Macros */
@@ -508,9 +550,9 @@
 {
 	int i;
 #ifndef USE_PRIVATE_CACHE
-#ifndef USE_SYSCALL_FUTEX
+#ifdef USE_PTHREAD_PSHARED
 	pthread_mutexattr_t attr;
-#endif /* USE_SYSCALL_FUTEX */
+#endif
 #endif
 	struct shared_block *prev,*cur;
 	int maptype = MAP_PRIVATE;
@@ -537,9 +579,7 @@
 
 #ifndef USE_PRIVATE_CACHE
 	if (maptype == MAP_SHARED) {
-#ifdef USE_SYSCALL_FUTEX
-		shctx->waiters = 0;
-#else
+#ifdef USE_PTHREAD_PSHARED
 		if (pthread_mutexattr_init(&attr)) {
 			munmap(shctx, sizeof(struct shared_context)+(size*sizeof(struct shared_block)));
 			shctx = NULL;
@@ -559,6 +599,8 @@
 			shctx = NULL;
 			return SHCTX_E_INIT_LOCK;
 		}
+#else
+		shctx->waiters = 0;
 #endif
 		use_shared_mem = 1;
 	}