Ver Fonte

Use futex instead of pthread_mutex on Linux

z3APA3A há 7 anos atrás
pai
commit
930d9823ea
3 ficheiros alterados com 52 adições e 1 exclusões
  1. 33 0
      src/common.c
  2. 2 0
      src/sockmap.c
  3. 17 1
      src/structures.h

+ 33 - 0
src/common.c

@@ -34,6 +34,35 @@ int havelog = 0;
 
 unsigned char **stringtable = NULL;
 
+#ifdef WITH_LINUX_FUTEX
+int sys_futex(void *addr1, int op, int val1, struct timespec *timeout, void *addr2, int val3)
+{
+	return syscall(SYS_futex, addr1, op, val1, timeout, addr2, val3);
+}
+int mutex_lock(int *val)
+{
+	int c;
+	if ((c = __sync_val_compare_and_swap(val, 0, 1)) != 0)
+		do {
+			if(c == 2 || __sync_val_compare_and_swap(val, 1, 2) != 0)
+				sys_futex(val, FUTEX_WAIT_PRIVATE, 2, NULL, NULL, 0);
+		} while ((c = __sync_val_compare_and_swap(val, 0, 2)) != 0);
+	
+	return 0;
+}
+
+int mutex_unlock(int *val)
+{
+	if(__sync_fetch_and_sub (val, 1) != 1){
+		*val = 0;
+		sys_futex(val, FUTEX_WAKE_PRIVATE, 1, NULL, NULL, 0);
+	}
+	
+	
+	return 0;
+}
+#endif
+
 int myinet_ntop(int af, void *src, char *dst, socklen_t size){
 #ifndef NOIPV6
  if(af != AF_INET6){
@@ -546,6 +575,10 @@ int dobuf2(struct clientparam * param, unsigned char * buf, const unsigned char
 				 sprintf((char *)buf+i, "%hu", ntohs(*SAPORT(&param->req)));
 				 i += (int)strlen((char *)buf+i);
 				 break;
+				case 'L':
+				 sprintf((char *)buf+i, "%"PRINTF_INT64_MODIFIER"u", param->cycles);
+				 i += (int)strlen((char *)buf+i);
+				 break;
 				case 'I':
 				 sprintf((char *)buf+i, "%"PRINTF_INT64_MODIFIER"u", param->statssrv64);
 				 i += (int)strlen((char *)buf+i);

+ 2 - 0
src/sockmap.c

@@ -107,6 +107,7 @@ int splicemap(struct clientparam * param, int timeo){
 
  while((!stop || (inclipipe && param->remsock != INVALID_SOCKET) || (insrvpipe && param->clisock != INVALID_SOCKET)) && !conf.timetoexit){
 
+    param->cycles++;
 #ifdef NOIPV6
     sasize = sizeof(struct sockaddr_in);
 #else
@@ -367,6 +368,7 @@ int sockmap(struct clientparam * param, int timeo){
 
 
  while (!stop&&!conf.timetoexit){
+	param->cycles++;
 #ifdef NOIPV6
 	sasize = sizeof(struct sockaddr_in);
 #else

+ 17 - 1
src/structures.h

@@ -34,6 +34,21 @@ extern "C" {
 #define SASIZETYPE socklen_t
 #define SOCKET int
 #define INVALID_SOCKET  (-1)
+#ifdef WITH_LINUX_FUTEX
+#define _GNU_SOURCE
+#include <unistd.h>
+#include <sys/syscall.h>
+#include <linux/kernel.h>
+#include <linux/futex.h>
+#define pthread_mutex_t int
+#define pthread_mutex_init(x, y) (*(x)=0)
+#define pthread_mutex_destroy(x) (*(x)=0)
+#define pthread_mutex_lock(x) mutex_lock(x)
+#define pthread_mutex_unlock(x) mutex_unlock(x)
+int mutex_lock(int *val);
+int mutex_unlock(int *val);
+#else
+#endif
 #else
 #include <winsock2.h>
 #include <Ws2tcpip.h>
@@ -477,7 +492,8 @@ struct clientparam {
 	REDIRTYPE redirtype;
 
 	uint64_t	waitclient64,
-			waitserver64;
+			waitserver64,
+			cycles;
 
 	int	redirected,
 		operation,