1 /*	$NetBSD: mutex.h,v 1.4 2014/12/10 04:38:00 christos Exp $	*/
2 
3 /*
4  * Copyright (C) 2004, 2005, 2007  Internet Systems Consortium, Inc. ("ISC")
5  * Copyright (C) 1998-2002  Internet Software Consortium.
6  *
7  * Permission to use, copy, modify, and/or distribute this software for any
8  * purpose with or without fee is hereby granted, provided that the above
9  * copyright notice and this permission notice appear in all copies.
10  *
11  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
12  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
13  * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
14  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
15  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
16  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17  * PERFORMANCE OF THIS SOFTWARE.
18  */
19 
20 /* Id: mutex.h,v 1.30 2007/06/19 23:47:18 tbox Exp  */
21 
22 #ifndef ISC_MUTEX_H
23 #define ISC_MUTEX_H 1
24 
25 /*! \file */
26 
27 #include <pthread.h>
28 #include <stdio.h>
29 
30 #include <isc/lang.h>
31 #include <isc/result.h>		/* for ISC_R_ codes */
32 
33 ISC_LANG_BEGINDECLS
34 
35 /*!
36  * Supply mutex attributes that enable deadlock detection
37  * (helpful when debugging).  This is system dependent and
38  * currently only supported on NetBSD.
39  */
40 #if ISC_MUTEX_DEBUG && defined(__NetBSD__) && defined(PTHREAD_MUTEX_ERRORCHECK)
41 extern pthread_mutexattr_t isc__mutex_attrs;
42 #define ISC__MUTEX_ATTRS &isc__mutex_attrs
43 #else
44 #define ISC__MUTEX_ATTRS NULL
45 #endif
46 
47 /* XXX We could do fancier error handling... */
48 
49 /*!
50  * Define ISC_MUTEX_PROFILE to turn on profiling of mutexes by line.  When
51  * enabled, isc_mutex_stats() can be used to print a table showing the
52  * number of times each type of mutex was locked and the amount of time
53  * waiting to obtain the lock.
54  */
55 #ifndef ISC_MUTEX_PROFILE
56 #define ISC_MUTEX_PROFILE 0
57 #endif
58 
59 #if ISC_MUTEX_PROFILE
60 typedef struct isc_mutexstats isc_mutexstats_t;
61 
62 typedef struct {
63 	pthread_mutex_t		mutex;	/*%< The actual mutex. */
64 	isc_mutexstats_t *	stats;	/*%< Mutex statistics. */
65 } isc_mutex_t;
66 #else
67 typedef pthread_mutex_t	isc_mutex_t;
68 #endif
69 
70 
71 #if ISC_MUTEX_PROFILE
72 #define isc_mutex_init(mp) \
73 	isc_mutex_init_profile((mp), __FILE__, __LINE__)
74 #else
75 #if ISC_MUTEX_DEBUG && defined(PTHREAD_MUTEX_ERRORCHECK)
76 #define isc_mutex_init(mp) \
77         isc_mutex_init_errcheck((mp))
78 #else
79 #define isc_mutex_init(mp) \
80 	isc__mutex_init((mp), __FILE__, __LINE__)
81 isc_result_t isc__mutex_init(isc_mutex_t *mp, const char *file, unsigned int line);
82 #endif
83 #endif
84 
85 #if ISC_MUTEX_PROFILE
86 #define isc_mutex_lock(mp) \
87 	isc_mutex_lock_profile((mp), __FILE__, __LINE__)
88 #else
89 #define isc_mutex_lock(mp) \
90 	((pthread_mutex_lock((mp)) == 0) ? \
91 	 ISC_R_SUCCESS : ISC_R_UNEXPECTED)
92 #endif
93 
94 #if ISC_MUTEX_PROFILE
95 #define isc_mutex_unlock(mp) \
96 	isc_mutex_unlock_profile((mp), __FILE__, __LINE__)
97 #else
98 #define isc_mutex_unlock(mp) \
99 	((pthread_mutex_unlock((mp)) == 0) ? \
100 	 ISC_R_SUCCESS : ISC_R_UNEXPECTED)
101 #endif
102 
103 #if ISC_MUTEX_PROFILE
104 #define isc_mutex_trylock(mp) \
105 	((pthread_mutex_trylock((&(mp)->mutex)) == 0) ? \
106 	 ISC_R_SUCCESS : ISC_R_LOCKBUSY)
107 #else
108 #define isc_mutex_trylock(mp) \
109 	((pthread_mutex_trylock((mp)) == 0) ? \
110 	 ISC_R_SUCCESS : ISC_R_LOCKBUSY)
111 #endif
112 
113 #if ISC_MUTEX_PROFILE
114 #define isc_mutex_destroy(mp) \
115 	((pthread_mutex_destroy((&(mp)->mutex)) == 0) ? \
116 	 ISC_R_SUCCESS : ISC_R_UNEXPECTED)
117 #else
118 #define isc_mutex_destroy(mp) \
119 	((pthread_mutex_destroy((mp)) == 0) ? \
120 	 ISC_R_SUCCESS : ISC_R_UNEXPECTED)
121 #endif
122 
123 #if ISC_MUTEX_PROFILE
124 #define isc_mutex_stats(fp) isc_mutex_statsprofile(fp);
125 #else
126 #define isc_mutex_stats(fp)
127 #endif
128 
129 #if ISC_MUTEX_PROFILE
130 
131 isc_result_t
132 isc_mutex_init_profile(isc_mutex_t *mp, const char * _file, int _line);
133 isc_result_t
134 isc_mutex_lock_profile(isc_mutex_t *mp, const char * _file, int _line);
135 isc_result_t
136 isc_mutex_unlock_profile(isc_mutex_t *mp, const char * _file, int _line);
137 
138 void
139 isc_mutex_statsprofile(FILE *fp);
140 
141 isc_result_t
142 isc_mutex_init_errcheck(isc_mutex_t *mp);
143 
144 #endif /* ISC_MUTEX_PROFILE */
145 
146 ISC_LANG_ENDDECLS
147 #endif /* ISC_MUTEX_H */
148