suricata
threads-profile.h
Go to the documentation of this file.
1 /* Copyright (C) 2007-2013 Open Information Security Foundation
2  *
3  * You can copy, redistribute or modify this Program under the terms of
4  * the GNU General Public License version 2 as published by the Free
5  * Software Foundation.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * version 2 along with this program; if not, write to the Free Software
14  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15  * 02110-1301, USA.
16  */
17 
18 /**
19  * \file
20  *
21  * \author Victor Julien <victor@inliniac.net>
22  *
23  * Lock profiling wrappers
24  */
25 
26 #ifndef SURICATA_THREADS_PROFILE_H
27 #define SURICATA_THREADS_PROFILE_H
28 
29 // UtilCpuGetTicks
30 #include "util-cpu.h"
31 
32 #define PROFILING_MAX_LOCKS 64
33 
34 /* profiling */
35 
36 enum {
39  LOCK_RWW, /**< rwlock, writer */
40  LOCK_RWR, /**< rwlock, reader */
41 };
42 
43 typedef struct ProfilingLock_ {
44  char *file;
45  char *func;
46  int line;
47  int type;
48  uint32_t cont;
49  uint64_t ticks;
51 
52 extern thread_local ProfilingLock locks[PROFILING_MAX_LOCKS];
53 extern thread_local int locks_idx;
54 extern thread_local int record_locks;
55 
56 extern thread_local uint64_t mutex_lock_contention;
57 extern thread_local uint64_t mutex_lock_wait_ticks;
58 extern thread_local uint64_t mutex_lock_cnt;
59 
60 /* mutex */
61 
62 //printf("%16s(%s:%d): (thread:%"PRIuMAX") locked mutex %p ret %" PRId32 "\n", __FUNCTION__, __FILE__, __LINE__, (uintmax_t)pthread_self(), mut, retl);
63 #define SCMutexLock_profile(mut) ({ \
64  mutex_lock_cnt++; \
65  int retl = 0; \
66  int cont = 0; \
67  uint64_t mutex_lock_start = UtilCpuGetTicks(); \
68  if (pthread_mutex_trylock((mut)) != 0) { \
69  mutex_lock_contention++; \
70  cont = 1; \
71  retl = pthread_mutex_lock(mut); \
72  } \
73  uint64_t mutex_lock_end = UtilCpuGetTicks(); \
74  mutex_lock_wait_ticks += (uint64_t)(mutex_lock_end - mutex_lock_start); \
75  \
76  if (locks_idx < PROFILING_MAX_LOCKS && record_locks) { \
77  locks[locks_idx].file = (char *)__FILE__; \
78  locks[locks_idx].func = (char *)__func__; \
79  locks[locks_idx].line = (int)__LINE__; \
80  locks[locks_idx].type = LOCK_MUTEX; \
81  locks[locks_idx].cont = cont; \
82  locks[locks_idx].ticks = (uint64_t)(mutex_lock_end - mutex_lock_start); \
83  locks_idx++; \
84  } \
85  retl; \
86 })
87 
88 #define SCMutex pthread_mutex_t
89 #define SCMutexAttr pthread_mutexattr_t
90 #define SCMutexInit(mut, mutattr ) pthread_mutex_init(mut, mutattr)
91 #define SCMutexLock(mut) SCMutexLock_profile(mut)
92 #define SCMutexTrylock(mut) pthread_mutex_trylock(mut)
93 #define SCMutexIsLocked(mut) (SCMutexTrylock(mut) == EBUSY)
94 #define SCMutexUnlock(mut) pthread_mutex_unlock(mut)
95 #define SCMutexDestroy pthread_mutex_destroy
96 #define SCMUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
97 
98 /* conditions */
99 
100 #define SCCondT pthread_cond_t
101 #define SCCondInit pthread_cond_init
102 #define SCCondSignal pthread_cond_signal
103 #define SCCondDestroy pthread_cond_destroy
104 #define SCCondWait(cond, mut) pthread_cond_wait(cond, mut)
105 
106 /* spinlocks */
107 
108 extern thread_local uint64_t spin_lock_contention;
109 extern thread_local uint64_t spin_lock_wait_ticks;
110 extern thread_local uint64_t spin_lock_cnt;
111 
112 //printf("%16s(%s:%d): (thread:%"PRIuMAX") locked mutex %p ret %" PRId32 "\n", __FUNCTION__, __FILE__, __LINE__, (uintmax_t)pthread_self(), mut, retl);
113 #define SCSpinLock_profile(spin) ({ \
114  spin_lock_cnt++; \
115  int retl = 0; \
116  int cont = 0; \
117  uint64_t spin_lock_start = UtilCpuGetTicks(); \
118  if (pthread_spin_trylock((spin)) != 0) { \
119  spin_lock_contention++; \
120  cont = 1; \
121  retl = pthread_spin_lock((spin)); \
122  } \
123  uint64_t spin_lock_end = UtilCpuGetTicks(); \
124  spin_lock_wait_ticks += (uint64_t)(spin_lock_end - spin_lock_start); \
125  \
126  if (locks_idx < PROFILING_MAX_LOCKS && record_locks) { \
127  locks[locks_idx].file = (char *)__FILE__; \
128  locks[locks_idx].func = (char *)__func__; \
129  locks[locks_idx].line = (int)__LINE__; \
130  locks[locks_idx].type = LOCK_SPIN; \
131  locks[locks_idx].cont = cont; \
132  locks[locks_idx].ticks = (uint64_t)(spin_lock_end - spin_lock_start); \
133  locks_idx++; \
134  } \
135  retl; \
136 })
137 
138 #define SCSpinlock pthread_spinlock_t
139 #define SCSpinLock(mut) SCSpinLock_profile(mut)
140 #define SCSpinTrylock(spin) pthread_spin_trylock(spin)
141 #define SCSpinUnlock(spin) pthread_spin_unlock(spin)
142 #define SCSpinInit(spin, spin_attr) pthread_spin_init(spin, spin_attr)
143 #define SCSpinDestroy(spin) pthread_spin_destroy(spin)
144 
145 /* rwlocks */
146 
147 extern thread_local uint64_t rww_lock_contention;
148 extern thread_local uint64_t rww_lock_wait_ticks;
149 extern thread_local uint64_t rww_lock_cnt;
150 
151 #define SCRWLockWRLock_profile(mut) ({ \
152  rww_lock_cnt++; \
153  int retl = 0; \
154  int cont = 0; \
155  uint64_t rww_lock_start = UtilCpuGetTicks(); \
156  if (pthread_rwlock_trywrlock((mut)) != 0) { \
157  rww_lock_contention++; \
158  cont = 1; \
159  retl = pthread_rwlock_wrlock(mut); \
160  } \
161  uint64_t rww_lock_end = UtilCpuGetTicks(); \
162  rww_lock_wait_ticks += (uint64_t)(rww_lock_end - rww_lock_start); \
163  \
164  if (locks_idx < PROFILING_MAX_LOCKS && record_locks) { \
165  locks[locks_idx].file = (char *)__FILE__; \
166  locks[locks_idx].func = (char *)__func__; \
167  locks[locks_idx].line = (int)__LINE__; \
168  locks[locks_idx].type = LOCK_RWW; \
169  locks[locks_idx].cont = cont; \
170  locks[locks_idx].ticks = (uint64_t)(rww_lock_end - rww_lock_start); \
171  locks_idx++; \
172  } \
173  retl; \
174 })
175 
176 extern thread_local uint64_t rwr_lock_contention;
177 extern thread_local uint64_t rwr_lock_wait_ticks;
178 extern thread_local uint64_t rwr_lock_cnt;
179 
180 #define SCRWLockRDLock_profile(mut) ({ \
181  rwr_lock_cnt++; \
182  int retl = 0; \
183  int cont = 0; \
184  uint64_t rwr_lock_start = UtilCpuGetTicks(); \
185  if (pthread_rwlock_tryrdlock((mut)) != 0) { \
186  rwr_lock_contention++; \
187  cont = 1; \
188  retl = pthread_rwlock_rdlock(mut); \
189  } \
190  uint64_t rwr_lock_end = UtilCpuGetTicks(); \
191  rwr_lock_wait_ticks += (uint64_t)(rwr_lock_end - rwr_lock_start); \
192  \
193  if (locks_idx < PROFILING_MAX_LOCKS && record_locks) { \
194  locks[locks_idx].file = (char *)__FILE__; \
195  locks[locks_idx].func = (char *)__func__; \
196  locks[locks_idx].line = (int)__LINE__; \
197  locks[locks_idx].type = LOCK_RWR; \
198  locks[locks_idx].cont = cont; \
199  locks[locks_idx].ticks = (uint64_t)(rwr_lock_end - rwr_lock_start); \
200  locks_idx++; \
201  } \
202  retl; \
203 })
204 
205 #define SCRWLock pthread_rwlock_t
206 #define SCRWLockInit(rwl, rwlattr ) pthread_rwlock_init(rwl, rwlattr)
207 #define SCRWLockWRLock(mut) SCRWLockWRLock_profile(mut)
208 #define SCRWLockRDLock(mut) SCRWLockRDLock_profile(mut)
209 #define SCRWLockTryWRLock(rwl) pthread_rwlock_trywrlock(rwl)
210 #define SCRWLockTryRDLock(rwl) pthread_rwlock_tryrdlock(rwl)
211 #define SCRWLockUnlock(rwl) pthread_rwlock_unlock(rwl)
212 #define SCRWLockDestroy pthread_rwlock_destroy
213 
214 /* ctrl mutex */
215 #define SCCtrlMutex pthread_mutex_t
216 #define SCCtrlMutexAttr pthread_mutexattr_t
217 #define SCCtrlMutexInit(mut, mutattr ) pthread_mutex_init(mut, mutattr)
218 #define SCCtrlMutexLock(mut) pthread_mutex_lock(mut)
219 #define SCCtrlMutexTrylock(mut) pthread_mutex_trylock(mut)
220 #define SCCtrlMutexUnlock(mut) pthread_mutex_unlock(mut)
221 #define SCCtrlMutexDestroy pthread_mutex_destroy
222 
223 /* ctrl conditions */
224 #define SCCtrlCondT pthread_cond_t
225 #define SCCtrlCondInit pthread_cond_init
226 #define SCCtrlCondSignal pthread_cond_signal
227 #define SCCtrlCondTimedwait pthread_cond_timedwait
228 #define SCCtrlCondWait pthread_cond_wait
229 #define SCCtrlCondDestroy pthread_cond_destroy
230 
231 #endif
spin_lock_cnt
thread_local uint64_t spin_lock_cnt
record_locks
thread_local int record_locks
LOCK_RWR
@ LOCK_RWR
Definition: threads-profile.h:40
LOCK_RWW
@ LOCK_RWW
Definition: threads-profile.h:39
ProfilingLock_::cont
uint32_t cont
Definition: threads-profile.h:48
rwr_lock_cnt
thread_local uint64_t rwr_lock_cnt
ProfilingLock_::func
char * func
Definition: threads-profile.h:45
locks
thread_local ProfilingLock locks[PROFILING_MAX_LOCKS]
rww_lock_contention
thread_local uint64_t rww_lock_contention
ProfilingLock_::file
char * file
Definition: threads-profile.h:44
rwr_lock_contention
thread_local uint64_t rwr_lock_contention
spin_lock_wait_ticks
thread_local uint64_t spin_lock_wait_ticks
LOCK_SPIN
@ LOCK_SPIN
Definition: threads-profile.h:38
ProfilingLock_
Definition: threads-profile.h:43
ProfilingLock_::ticks
uint64_t ticks
Definition: threads-profile.h:49
util-cpu.h
rww_lock_cnt
thread_local uint64_t rww_lock_cnt
mutex_lock_contention
thread_local uint64_t mutex_lock_contention
spin_lock_contention
thread_local uint64_t spin_lock_contention
locks_idx
thread_local int locks_idx
ProfilingLock
struct ProfilingLock_ ProfilingLock
rww_lock_wait_ticks
thread_local uint64_t rww_lock_wait_ticks
PROFILING_MAX_LOCKS
#define PROFILING_MAX_LOCKS
Definition: threads-profile.h:32
rwr_lock_wait_ticks
thread_local uint64_t rwr_lock_wait_ticks
LOCK_MUTEX
@ LOCK_MUTEX
Definition: threads-profile.h:37
ProfilingLock_::type
int type
Definition: threads-profile.h:47
mutex_lock_wait_ticks
thread_local uint64_t mutex_lock_wait_ticks
mutex_lock_cnt
thread_local uint64_t mutex_lock_cnt
ProfilingLock_::line
int line
Definition: threads-profile.h:46