From a5e23d8a52d6bd711cca1dcd995392037273578b Mon Sep 17 00:00:00 2001 From: Cerghit Ionel Date: Thu, 27 Aug 2015 16:31:51 +0300 Subject: [PATCH 1/2] lock_ops.h: added support for debugging locks with the flag DBG_LOCK set(from menuconfig for example), with each lock will be stored information regarding the place from where the lock was aquired (file, function, line) --- fastlock.h | 50 ++++++++++++++++++++++++++++++++++++++++++++++---- futex_lock.h | 47 ++++++++++++++++++++++++++++++++++++++++++++--- lock_ops.h | 39 ++++++++++++++++++++++++--------------- net/net_tcp.c | 2 +- version.h | 7 ++++++- 5 files changed, 121 insertions(+), 24 deletions(-) diff --git a/fastlock.h b/fastlock.h index 49e6d8329c3..212c685f3fb 100644 --- a/fastlock.h +++ b/fastlock.h @@ -55,10 +55,23 @@ #endif /*! The actual lock */ +#ifndef DBG_LOCK typedef volatile int fl_lock_t; +#else +typedef struct fl_lock_t_{ + volatile int lock; + char* file; + char* func; + unsigned long line; +} fl_lock_t; +#endif /*! Initialize a lock, zero is unlocked. */ -#define init_lock( l ) (l)=0 +#ifndef DBG_LOCK + #define init_lock( l ) (l)=0 +#else + #define init_lock( l ) (l).lock = 0 +#endif @@ -68,7 +81,11 @@ typedef volatile int fl_lock_t; * \return 1 if the lock is held by someone else, 0 otherwise * \see get_lock */ +#ifndef DBG_LOCK inline static int tsl(fl_lock_t* lock) +#else +inline static int tsl(volatile int* lock) +#endif { int val; @@ -167,8 +184,15 @@ inline static int tsl(fl_lock_t* lock) * \param lock the lock that should be set * \see tsl */ +#ifndef DBG_LOCK inline static void get_lock(fl_lock_t* lock) { +#else +inline static void get_lock(fl_lock_t* lock_struct, const char* file, const char* func, unsigned int line) +{ + volatile int *lock = &lock_struct->lock; +#endif + #ifdef ADAPTIVE_WAIT int i=ADAPTIVE_WAIT_LOOPS; #endif @@ -182,6 +206,13 @@ inline static void get_lock(fl_lock_t* lock) sched_yield(); #endif } + +#ifdef DBG_LOCK + lock_struct->file = (char*)file; + lock_struct->func = (char*)func; + lock_struct->line = line; +#endif + } @@ -189,8 +220,18 @@ inline static void get_lock(fl_lock_t* lock) * Release a lock * \param lock the lock that should be released */ +#ifndef DBG_LOCK inline static void release_lock(fl_lock_t* lock) { +#else +inline static void release_lock(fl_lock_t* lock_struct) +{ + volatile int *lock = &lock_struct->lock; + lock_struct->file = 0; + lock_struct->func = 0; + lock_struct->line = 0; +#endif + #if defined(__CPU_i386) || defined(__CPU_x86_64) /* char val; val=0; */ @@ -200,9 +241,9 @@ inline static void release_lock(fl_lock_t* lock) ); #elif defined(__CPU_sparc64) || defined(__CPU_sparc) asm volatile( -#ifndef NOSMP - "membar #LoadStore | #StoreStore \n\t" /*is this really needed?*/ -#endif + #ifndef NOSMP + "membar #LoadStore | #StoreStore \n\t" /*is this really needed?*/ + #endif "stb %%g0, [%0] \n\t" : /*no output*/ : "r" (lock) @@ -245,6 +286,7 @@ inline static void release_lock(fl_lock_t* lock) #else #error "unknown architecture" #endif + } diff --git a/futex_lock.h b/futex_lock.h index 352946b120d..6de19f2c4ea 100644 --- a/futex_lock.h +++ b/futex_lock.h @@ -45,7 +45,16 @@ #include /*! The actual lock */ +#ifndef DBG_LOCK typedef volatile int fx_lock_t; +#else +typedef struct fx_lock_t_{ + volatile int lock; + char* file; + char* func; + unsigned long line; +} fx_lock_t; +#endif /* * Possible Lock values: @@ -55,8 +64,11 @@ typedef volatile int fx_lock_t; */ /*! Initialize a lock, zero is unlocked. */ -#define init_lock( l ) (l)=0 - +#ifndef DBG_LOCK + #define init_lock( l ) (l)=0 +#else + #define init_lock( l ) (l).lock = 0 +#endif /* * Wait on a futex * param lock - futex to wait on @@ -90,7 +102,11 @@ typedef volatile int fx_lock_t; * param val is the value to write to the lock * returns previous value of lock */ +#ifndef DBG_LOCK inline static int _atomic_xchg(fx_lock_t* lock, int val) +#else +inline static int _atomic_xchg(volatile int *lock, int val) +#endif { #if defined(__CPU_i386) || defined(__CPU_x86_64) @@ -195,8 +211,15 @@ inline static int _atomic_xchg(fx_lock_t* lock, int val) * Get a lock. * \param lock the lock that should be gotten */ +#ifndef DBG_LOCK inline static void get_lock(fx_lock_t* lock) { +#else +inline static void get_lock(fx_lock_t* lock_struct, const char* file, const char* func, unsigned int line) +{ + volatile int *lock = &lock_struct->lock; +#endif + int c; #ifdef ADAPTIVE_WAIT register int i = ADAPTIVE_WAIT_LOOPS; @@ -225,16 +248,34 @@ inline static void get_lock(fx_lock_t* lock) c = atomic_xchg(lock, 2); } } + +#ifdef DBG_LOCK + lock_struct->file = (char*)file; + lock_struct->func = (char*)func; + lock_struct->line = line; +#endif + } /*! \brief * Release a lock * \param lock the lock that should be released */ +#ifndef DBG_LOCK inline static void release_lock(fx_lock_t* lock) { - int c; +#else +inline static void release_lock(fx_lock_t* lock_struct) +{ + volatile int *lock = &lock_struct->lock; +#endif + int c; +#ifdef DBG_LOCK + lock_struct->file = NULL; + lock_struct->func = NULL; + lock_struct->line = 0; +#endif c = atomic_xchg(lock, 0); //Only do wakekup if others are waiting on the lock (value of 2) diff --git a/lock_ops.h b/lock_ops.h index bc30de7bb98..30494a140dd 100644 --- a/lock_ops.h +++ b/lock_ops.h @@ -66,17 +66,18 @@ #ifdef FAST_LOCK -#ifdef USE_FUTEX -#include "futex_lock.h" + #ifdef USE_FUTEX + #include "futex_lock.h" -typedef fx_lock_t gen_lock_t; + typedef fx_lock_t gen_lock_t; -#elif defined FAST_LOCK -#include "fastlock.h" + #elif defined FAST_LOCK -typedef fl_lock_t gen_lock_t; + #include "fastlock.h" -#endif + typedef fl_lock_t gen_lock_t; + + #endif #define lock_destroy(lock) /* do nothing */ @@ -86,9 +87,14 @@ inline static gen_lock_t* lock_init(gen_lock_t* lock) return lock; } -#define lock_get(lock) get_lock(lock) #define lock_release(lock) release_lock(lock) +#ifndef DBG_LOCK + #define lock_get(lock) get_lock(lock) +#else + #define lock_get(lock) get_lock(lock, __FILE__, __FUNCTION__, __LINE__) +#endif + #elif defined USE_PTHREAD_MUTEX #include @@ -102,11 +108,10 @@ inline static gen_lock_t* lock_init(gen_lock_t* lock) else return 0; } + #define lock_get(lock) pthread_mutex_lock(lock) #define lock_release(lock) pthread_mutex_unlock(lock) - - #elif defined USE_POSIX_SEM #include @@ -116,6 +121,7 @@ typedef sem_t gen_lock_t; inline static gen_lock_t* lock_init(gen_lock_t* lock) { + if (sem_init(lock, 1, 1)<0) return 0; return lock; } @@ -123,7 +129,6 @@ inline static gen_lock_t* lock_init(gen_lock_t* lock) #define lock_get(lock) sem_wait(lock) #define lock_release(lock) sem_post(lock) - #elif defined USE_SYSV_SEM #include #include @@ -150,9 +155,6 @@ extern int uid; /* from main.c */ typedef int gen_lock_t; - - - inline static gen_lock_t* lock_init(gen_lock_t* lock) { union semun su; @@ -170,13 +172,15 @@ inline static gen_lock_t* lock_init(gen_lock_t* lock) /* init error*/ return 0; } + return lock; + } +//TODO if is init inline static void lock_destroy(gen_lock_t* lock) { union semun su; - su.val = 0; semctl(*lock, 0, IPC_RMID, su); } @@ -198,6 +202,7 @@ inline static void lock_get(gen_lock_t* lock) LM_CRIT("%s (%d)\n", strerror(errno), errno); } } + } inline static void lock_release(gen_lock_t* lock) @@ -208,6 +213,7 @@ inline static void lock_release(gen_lock_t* lock) sop.sem_op=1; /* up */ sop.sem_flg=0; tryagain: + if (semop(*lock, &sop, 1)==-1){ if (errno==EINTR){ /* very improbable*/ @@ -313,6 +319,8 @@ inline static void lock_set_get(gen_lock_set_t* s, int n) LM_CRIT("%s (%d)\n", strerror(errno), errno); } } + +s } inline static void lock_set_release(gen_lock_set_t* s, int n) @@ -331,6 +339,7 @@ inline static void lock_set_release(gen_lock_set_t* s, int n) LM_CRIT("%s (%d)\n", strerror(errno), errno); } } + } #else #error "no lock set method selected" diff --git a/net/net_tcp.c b/net/net_tcp.c index 712d3530f35..988220cbac4 100644 --- a/net/net_tcp.c +++ b/net/net_tcp.c @@ -837,7 +837,7 @@ static struct tcp_connection* tcpconn_new(int sock, union sockaddr_union* su, error: if (c) { - if (c->write_lock) lock_destroy(&c->write_lock); + lock_destroy(&c->write_lock); shm_free(c); } return 0; diff --git a/version.h b/version.h index 8666dcfd728..f8b3c735650 100644 --- a/version.h +++ b/version.h @@ -159,6 +159,11 @@ #define USE_SYSV_SEM_STR "" #endif +#ifdef DBG_LOCK +#define DBG_LOCK_STR ", DBG_LOCK" +#else +#define DBG_LOCK_STR "" +#endif #ifdef NOSMP #define NOSMP_STR "-NOSMP" @@ -173,7 +178,7 @@ SHM_MMAP_STR PKG_MALLOC_STR VQ_MALLOC_STR F_MALLOC_STR \ HP_MALLOC_STR USE_SHM_MEM_STR DBG_QM_MALLOC_STR DBG_F_MALLOC_STR \ DEBUG_DMALLOC_STR QM_JOIN_FREE_STR FAST_LOCK_STR NOSMP_STR \ - USE_PTHREAD_MUTEX_STR USE_POSIX_SEM_STR USE_SYSV_SEM_STR + USE_PTHREAD_MUTEX_STR USE_POSIX_SEM_STR USE_SYSV_SEM_STR DBG_LOCK_STR #endif From 0d939a2827144cb19b8b374b741224eb9e4b630a Mon Sep 17 00:00:00 2001 From: Cerghit Ionel Date: Fri, 28 Aug 2015 11:09:04 +0300 Subject: [PATCH 2/2] lock_ops.h: fixed typo for SYSV semaphores --- lock_ops.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/lock_ops.h b/lock_ops.h index 30494a140dd..1071531ab99 100644 --- a/lock_ops.h +++ b/lock_ops.h @@ -319,8 +319,6 @@ inline static void lock_set_get(gen_lock_set_t* s, int n) LM_CRIT("%s (%d)\n", strerror(errno), errno); } } - -s } inline static void lock_set_release(gen_lock_set_t* s, int n)