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 SCMutexUnlock(mut) pthread_mutex_unlock(mut)
94 #define SCMutexDestroy pthread_mutex_destroy
95 #define SCMUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
96 
97 /* conditions */
98 
99 #define SCCondT pthread_cond_t
100 #define SCCondInit pthread_cond_init
101 #define SCCondSignal pthread_cond_signal
102 #define SCCondDestroy pthread_cond_destroy
103 #define SCCondWait(cond, mut) pthread_cond_wait(cond, mut)
104 
105 /* spinlocks */
106 
107 extern thread_local uint64_t spin_lock_contention;
108 extern thread_local uint64_t spin_lock_wait_ticks;
109 extern thread_local uint64_t spin_lock_cnt;
110 
111 //printf("%16s(%s:%d): (thread:%"PRIuMAX") locked mutex %p ret %" PRId32 "\n", __FUNCTION__, __FILE__, __LINE__, (uintmax_t)pthread_self(), mut, retl);
112 #define SCSpinLock_profile(spin) ({ \
113  spin_lock_cnt++; \
114  int retl = 0; \
115  int cont = 0; \
116  uint64_t spin_lock_start = UtilCpuGetTicks(); \
117  if (pthread_spin_trylock((spin)) != 0) { \
118  spin_lock_contention++; \
119  cont = 1; \
120  retl = pthread_spin_lock((spin)); \
121  } \
122  uint64_t spin_lock_end = UtilCpuGetTicks(); \
123  spin_lock_wait_ticks += (uint64_t)(spin_lock_end - spin_lock_start); \
124  \
125  if (locks_idx < PROFILING_MAX_LOCKS && record_locks) { \
126  locks[locks_idx].file = (char *)__FILE__; \
127  locks[locks_idx].func = (char *)__func__; \
128  locks[locks_idx].line = (int)__LINE__; \
129  locks[locks_idx].type = LOCK_SPIN; \
130  locks[locks_idx].cont = cont; \
131  locks[locks_idx].ticks = (uint64_t)(spin_lock_end - spin_lock_start); \
132  locks_idx++; \
133  } \
134  retl; \
135 })
136 
137 #define SCSpinlock pthread_spinlock_t
138 #define SCSpinLock(mut) SCSpinLock_profile(mut)
139 #define SCSpinTrylock(spin) pthread_spin_trylock(spin)
140 #define SCSpinUnlock(spin) pthread_spin_unlock(spin)
141 #define SCSpinInit(spin, spin_attr) pthread_spin_init(spin, spin_attr)
142 #define SCSpinDestroy(spin) pthread_spin_destroy(spin)
143 
144 /* rwlocks */
145 
146 extern thread_local uint64_t rww_lock_contention;
147 extern thread_local uint64_t rww_lock_wait_ticks;
148 extern thread_local uint64_t rww_lock_cnt;
149 
150 #define SCRWLockWRLock_profile(mut) ({ \
151  rww_lock_cnt++; \
152  int retl = 0; \
153  int cont = 0; \
154  uint64_t rww_lock_start = UtilCpuGetTicks(); \
155  if (pthread_rwlock_trywrlock((mut)) != 0) { \
156  rww_lock_contention++; \
157  cont = 1; \
158  retl = pthread_rwlock_wrlock(mut); \
159  } \
160  uint64_t rww_lock_end = UtilCpuGetTicks(); \
161  rww_lock_wait_ticks += (uint64_t)(rww_lock_end - rww_lock_start); \
162  \
163  if (locks_idx < PROFILING_MAX_LOCKS && record_locks) { \
164  locks[locks_idx].file = (char *)__FILE__; \
165  locks[locks_idx].func = (char *)__func__; \
166  locks[locks_idx].line = (int)__LINE__; \
167  locks[locks_idx].type = LOCK_RWW; \
168  locks[locks_idx].cont = cont; \
169  locks[locks_idx].ticks = (uint64_t)(rww_lock_end - rww_lock_start); \
170  locks_idx++; \
171  } \
172  retl; \
173 })
174 
175 extern thread_local uint64_t rwr_lock_contention;
176 extern thread_local uint64_t rwr_lock_wait_ticks;
177 extern thread_local uint64_t rwr_lock_cnt;
178 
179 #define SCRWLockRDLock_profile(mut) ({ \
180  rwr_lock_cnt++; \
181  int retl = 0; \
182  int cont = 0; \
183  uint64_t rwr_lock_start = UtilCpuGetTicks(); \
184  if (pthread_rwlock_tryrdlock((mut)) != 0) { \
185  rwr_lock_contention++; \
186  cont = 1; \
187  retl = pthread_rwlock_rdlock(mut); \
188  } \
189  uint64_t rwr_lock_end = UtilCpuGetTicks(); \
190  rwr_lock_wait_ticks += (uint64_t)(rwr_lock_end - rwr_lock_start); \
191  \
192  if (locks_idx < PROFILING_MAX_LOCKS && record_locks) { \
193  locks[locks_idx].file = (char *)__FILE__; \
194  locks[locks_idx].func = (char *)__func__; \
195  locks[locks_idx].line = (int)__LINE__; \
196  locks[locks_idx].type = LOCK_RWR; \
197  locks[locks_idx].cont = cont; \
198  locks[locks_idx].ticks = (uint64_t)(rwr_lock_end - rwr_lock_start); \
199  locks_idx++; \
200  } \
201  retl; \
202 })
203 
204 #define SCRWLock pthread_rwlock_t
205 #define SCRWLockInit(rwl, rwlattr ) pthread_rwlock_init(rwl, rwlattr)
206 #define SCRWLockWRLock(mut) SCRWLockWRLock_profile(mut)
207 #define SCRWLockRDLock(mut) SCRWLockRDLock_profile(mut)
208 #define SCRWLockTryWRLock(rwl) pthread_rwlock_trywrlock(rwl)
209 #define SCRWLockTryRDLock(rwl) pthread_rwlock_tryrdlock(rwl)
210 #define SCRWLockUnlock(rwl) pthread_rwlock_unlock(rwl)
211 #define SCRWLockDestroy pthread_rwlock_destroy
212 
213 /* ctrl mutex */
214 #define SCCtrlMutex pthread_mutex_t
215 #define SCCtrlMutexAttr pthread_mutexattr_t
216 #define SCCtrlMutexInit(mut, mutattr ) pthread_mutex_init(mut, mutattr)
217 #define SCCtrlMutexLock(mut) pthread_mutex_lock(mut)
218 #define SCCtrlMutexTrylock(mut) pthread_mutex_trylock(mut)
219 #define SCCtrlMutexUnlock(mut) pthread_mutex_unlock(mut)
220 #define SCCtrlMutexDestroy pthread_mutex_destroy
221 
222 /* ctrl conditions */
223 #define SCCtrlCondT pthread_cond_t
224 #define SCCtrlCondInit pthread_cond_init
225 #define SCCtrlCondSignal pthread_cond_signal
226 #define SCCtrlCondTimedwait pthread_cond_timedwait
227 #define SCCtrlCondWait pthread_cond_wait
228 #define SCCtrlCondDestroy pthread_cond_destroy
229 
230 #endif
spin_lock_cnt
thread_local uint64_t spin_lock_cnt
record_locks
thread_local int record_locks
ProfilingLock_::cont
uint32_t cont
Definition: threads-profile.h:48
rwr_lock_cnt
thread_local uint64_t rwr_lock_cnt
LOCK_RWR
@ LOCK_RWR
Definition: threads-profile.h:40
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
LOCK_MUTEX
@ LOCK_MUTEX
Definition: threads-profile.h:37
rwr_lock_contention
thread_local uint64_t rwr_lock_contention
spin_lock_wait_ticks
thread_local uint64_t spin_lock_wait_ticks
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
LOCK_RWW
@ LOCK_RWW
Definition: threads-profile.h:39
rwr_lock_wait_ticks
thread_local uint64_t rwr_lock_wait_ticks
ProfilingLock_::type
int type
Definition: threads-profile.h:47
mutex_lock_wait_ticks
thread_local uint64_t mutex_lock_wait_ticks
LOCK_SPIN
@ LOCK_SPIN
Definition: threads-profile.h:38
mutex_lock_cnt
thread_local uint64_t mutex_lock_cnt
ProfilingLock_::line
int line
Definition: threads-profile.h:46