xref: /minix3/external/bsd/bind/dist/lib/isc/pthreads/mutex.c (revision 00b67f09dd46474d133c95011a48590a8e8f94c7)
1*00b67f09SDavid van Moolenbroek /*	$NetBSD: mutex.c,v 1.6 2015/07/08 17:28:59 christos Exp $	*/
2*00b67f09SDavid van Moolenbroek 
3*00b67f09SDavid van Moolenbroek /*
4*00b67f09SDavid van Moolenbroek  * Copyright (C) 2004, 2005, 2007, 2008, 2011, 2012, 2014, 2015  Internet Systems Consortium, Inc. ("ISC")
5*00b67f09SDavid van Moolenbroek  * Copyright (C) 2000-2002  Internet Software Consortium.
6*00b67f09SDavid van Moolenbroek  *
7*00b67f09SDavid van Moolenbroek  * Permission to use, copy, modify, and/or distribute this software for any
8*00b67f09SDavid van Moolenbroek  * purpose with or without fee is hereby granted, provided that the above
9*00b67f09SDavid van Moolenbroek  * copyright notice and this permission notice appear in all copies.
10*00b67f09SDavid van Moolenbroek  *
11*00b67f09SDavid van Moolenbroek  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
12*00b67f09SDavid van Moolenbroek  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
13*00b67f09SDavid van Moolenbroek  * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
14*00b67f09SDavid van Moolenbroek  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
15*00b67f09SDavid van Moolenbroek  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
16*00b67f09SDavid van Moolenbroek  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17*00b67f09SDavid van Moolenbroek  * PERFORMANCE OF THIS SOFTWARE.
18*00b67f09SDavid van Moolenbroek  */
19*00b67f09SDavid van Moolenbroek 
20*00b67f09SDavid van Moolenbroek /* Id: mutex.c,v 1.18 2011/01/04 23:47:14 tbox Exp  */
21*00b67f09SDavid van Moolenbroek 
22*00b67f09SDavid van Moolenbroek /*! \file */
23*00b67f09SDavid van Moolenbroek 
24*00b67f09SDavid van Moolenbroek #include <config.h>
25*00b67f09SDavid van Moolenbroek 
26*00b67f09SDavid van Moolenbroek #include <stdio.h>
27*00b67f09SDavid van Moolenbroek #include <time.h>
28*00b67f09SDavid van Moolenbroek #include <sys/time.h>
29*00b67f09SDavid van Moolenbroek #include <errno.h>
30*00b67f09SDavid van Moolenbroek 
31*00b67f09SDavid van Moolenbroek #include <isc/mutex.h>
32*00b67f09SDavid van Moolenbroek #include <isc/util.h>
33*00b67f09SDavid van Moolenbroek #include <isc/strerror.h>
34*00b67f09SDavid van Moolenbroek 
35*00b67f09SDavid van Moolenbroek #if ISC_MUTEX_PROFILE
36*00b67f09SDavid van Moolenbroek 
37*00b67f09SDavid van Moolenbroek /*@{*/
38*00b67f09SDavid van Moolenbroek /*% Operations on timevals; adapted from FreeBSD's sys/time.h */
39*00b67f09SDavid van Moolenbroek #define timevalclear(tvp)      ((tvp)->tv_sec = (tvp)->tv_usec = 0)
40*00b67f09SDavid van Moolenbroek #define timevaladd(vvp, uvp)                                            \
41*00b67f09SDavid van Moolenbroek 	do {                                                            \
42*00b67f09SDavid van Moolenbroek 		(vvp)->tv_sec += (uvp)->tv_sec;                         \
43*00b67f09SDavid van Moolenbroek 		(vvp)->tv_usec += (uvp)->tv_usec;                       \
44*00b67f09SDavid van Moolenbroek 		if ((vvp)->tv_usec >= 1000000) {                        \
45*00b67f09SDavid van Moolenbroek 			(vvp)->tv_sec++;                                \
46*00b67f09SDavid van Moolenbroek 			(vvp)->tv_usec -= 1000000;                      \
47*00b67f09SDavid van Moolenbroek 		}                                                       \
48*00b67f09SDavid van Moolenbroek 	} while (/*CONSTCOND*/0)
49*00b67f09SDavid van Moolenbroek #define timevalsub(vvp, uvp)                                            \
50*00b67f09SDavid van Moolenbroek 	do {                                                            \
51*00b67f09SDavid van Moolenbroek 		(vvp)->tv_sec -= (uvp)->tv_sec;                         \
52*00b67f09SDavid van Moolenbroek 		(vvp)->tv_usec -= (uvp)->tv_usec;                       \
53*00b67f09SDavid van Moolenbroek 		if ((vvp)->tv_usec < 0) {                               \
54*00b67f09SDavid van Moolenbroek 			(vvp)->tv_sec--;                                \
55*00b67f09SDavid van Moolenbroek 			(vvp)->tv_usec += 1000000;                      \
56*00b67f09SDavid van Moolenbroek 		}                                                       \
57*00b67f09SDavid van Moolenbroek 	} while (/*CONSTCOND*/0)
58*00b67f09SDavid van Moolenbroek 
59*00b67f09SDavid van Moolenbroek /*@}*/
60*00b67f09SDavid van Moolenbroek 
61*00b67f09SDavid van Moolenbroek #define ISC_MUTEX_MAX_LOCKERS 32
62*00b67f09SDavid van Moolenbroek 
63*00b67f09SDavid van Moolenbroek typedef struct {
64*00b67f09SDavid van Moolenbroek 	const char *		file;
65*00b67f09SDavid van Moolenbroek 	int			line;
66*00b67f09SDavid van Moolenbroek 	unsigned		count;
67*00b67f09SDavid van Moolenbroek 	struct timeval		locked_total;
68*00b67f09SDavid van Moolenbroek 	struct timeval		wait_total;
69*00b67f09SDavid van Moolenbroek } isc_mutexlocker_t;
70*00b67f09SDavid van Moolenbroek 
71*00b67f09SDavid van Moolenbroek struct isc_mutexstats {
72*00b67f09SDavid van Moolenbroek 	const char *		file;	/*%< File mutex was created in. */
73*00b67f09SDavid van Moolenbroek 	int 			line;	/*%< Line mutex was created on. */
74*00b67f09SDavid van Moolenbroek 	unsigned		count;
75*00b67f09SDavid van Moolenbroek 	struct timeval		lock_t;
76*00b67f09SDavid van Moolenbroek 	struct timeval		locked_total;
77*00b67f09SDavid van Moolenbroek 	struct timeval		wait_total;
78*00b67f09SDavid van Moolenbroek 	isc_mutexlocker_t *	cur_locker;
79*00b67f09SDavid van Moolenbroek 	isc_mutexlocker_t	lockers[ISC_MUTEX_MAX_LOCKERS];
80*00b67f09SDavid van Moolenbroek };
81*00b67f09SDavid van Moolenbroek 
82*00b67f09SDavid van Moolenbroek #ifndef ISC_MUTEX_PROFTABLESIZE
83*00b67f09SDavid van Moolenbroek #define ISC_MUTEX_PROFTABLESIZE (1024 * 1024)
84*00b67f09SDavid van Moolenbroek #endif
85*00b67f09SDavid van Moolenbroek static isc_mutexstats_t stats[ISC_MUTEX_PROFTABLESIZE];
86*00b67f09SDavid van Moolenbroek static int stats_next = 0;
87*00b67f09SDavid van Moolenbroek static isc_boolean_t stats_init = ISC_FALSE;
88*00b67f09SDavid van Moolenbroek static pthread_mutex_t statslock = PTHREAD_MUTEX_INITIALIZER;
89*00b67f09SDavid van Moolenbroek 
90*00b67f09SDavid van Moolenbroek 
91*00b67f09SDavid van Moolenbroek isc_result_t
isc_mutex_init_profile(isc_mutex_t * mp,const char * file,int line)92*00b67f09SDavid van Moolenbroek isc_mutex_init_profile(isc_mutex_t *mp, const char *file, int line) {
93*00b67f09SDavid van Moolenbroek 	int i, err;
94*00b67f09SDavid van Moolenbroek 
95*00b67f09SDavid van Moolenbroek 	err = pthread_mutex_init(&mp->mutex, NULL);
96*00b67f09SDavid van Moolenbroek 	if (err == ENOMEM)
97*00b67f09SDavid van Moolenbroek 		return (ISC_R_NOMEMORY);
98*00b67f09SDavid van Moolenbroek 	if (err != 0)
99*00b67f09SDavid van Moolenbroek 		return (ISC_R_UNEXPECTED);
100*00b67f09SDavid van Moolenbroek 
101*00b67f09SDavid van Moolenbroek 	RUNTIME_CHECK(pthread_mutex_lock(&statslock) == 0);
102*00b67f09SDavid van Moolenbroek 
103*00b67f09SDavid van Moolenbroek 	if (stats_init == ISC_FALSE)
104*00b67f09SDavid van Moolenbroek 		stats_init = ISC_TRUE;
105*00b67f09SDavid van Moolenbroek 
106*00b67f09SDavid van Moolenbroek 	/*
107*00b67f09SDavid van Moolenbroek 	 * If all statistics entries have been used, give up and trigger an
108*00b67f09SDavid van Moolenbroek 	 * assertion failure.  There would be no other way to deal with this
109*00b67f09SDavid van Moolenbroek 	 * because we'd like to keep record of all locks for the purpose of
110*00b67f09SDavid van Moolenbroek 	 * debugging and the number of necessary locks is unpredictable.
111*00b67f09SDavid van Moolenbroek 	 * If this failure is triggered while debugging, named should be
112*00b67f09SDavid van Moolenbroek 	 * rebuilt with an increased ISC_MUTEX_PROFTABLESIZE.
113*00b67f09SDavid van Moolenbroek 	 */
114*00b67f09SDavid van Moolenbroek 	RUNTIME_CHECK(stats_next < ISC_MUTEX_PROFTABLESIZE);
115*00b67f09SDavid van Moolenbroek 	mp->stats = &stats[stats_next++];
116*00b67f09SDavid van Moolenbroek 
117*00b67f09SDavid van Moolenbroek 	RUNTIME_CHECK(pthread_mutex_unlock(&statslock) == 0);
118*00b67f09SDavid van Moolenbroek 
119*00b67f09SDavid van Moolenbroek 	mp->stats->file = file;
120*00b67f09SDavid van Moolenbroek 	mp->stats->line = line;
121*00b67f09SDavid van Moolenbroek 	mp->stats->count = 0;
122*00b67f09SDavid van Moolenbroek 	timevalclear(&mp->stats->locked_total);
123*00b67f09SDavid van Moolenbroek 	timevalclear(&mp->stats->wait_total);
124*00b67f09SDavid van Moolenbroek 	for (i = 0; i < ISC_MUTEX_MAX_LOCKERS; i++) {
125*00b67f09SDavid van Moolenbroek 		mp->stats->lockers[i].file = NULL;
126*00b67f09SDavid van Moolenbroek 		mp->stats->lockers[i].line = 0;
127*00b67f09SDavid van Moolenbroek 		mp->stats->lockers[i].count = 0;
128*00b67f09SDavid van Moolenbroek 		timevalclear(&mp->stats->lockers[i].locked_total);
129*00b67f09SDavid van Moolenbroek 		timevalclear(&mp->stats->lockers[i].wait_total);
130*00b67f09SDavid van Moolenbroek 	}
131*00b67f09SDavid van Moolenbroek 
132*00b67f09SDavid van Moolenbroek 	return (ISC_R_SUCCESS);
133*00b67f09SDavid van Moolenbroek }
134*00b67f09SDavid van Moolenbroek 
135*00b67f09SDavid van Moolenbroek isc_result_t
isc_mutex_lock_profile(isc_mutex_t * mp,const char * file,int line)136*00b67f09SDavid van Moolenbroek isc_mutex_lock_profile(isc_mutex_t *mp, const char *file, int line) {
137*00b67f09SDavid van Moolenbroek 	struct timeval prelock_t;
138*00b67f09SDavid van Moolenbroek 	struct timeval postlock_t;
139*00b67f09SDavid van Moolenbroek 	isc_mutexlocker_t *locker = NULL;
140*00b67f09SDavid van Moolenbroek 	int i;
141*00b67f09SDavid van Moolenbroek 
142*00b67f09SDavid van Moolenbroek 	gettimeofday(&prelock_t, NULL);
143*00b67f09SDavid van Moolenbroek 
144*00b67f09SDavid van Moolenbroek 	if (pthread_mutex_lock(&mp->mutex) != 0)
145*00b67f09SDavid van Moolenbroek 		return (ISC_R_UNEXPECTED);
146*00b67f09SDavid van Moolenbroek 
147*00b67f09SDavid van Moolenbroek 	gettimeofday(&postlock_t, NULL);
148*00b67f09SDavid van Moolenbroek 	mp->stats->lock_t = postlock_t;
149*00b67f09SDavid van Moolenbroek 
150*00b67f09SDavid van Moolenbroek 	timevalsub(&postlock_t, &prelock_t);
151*00b67f09SDavid van Moolenbroek 
152*00b67f09SDavid van Moolenbroek 	mp->stats->count++;
153*00b67f09SDavid van Moolenbroek 	timevaladd(&mp->stats->wait_total, &postlock_t);
154*00b67f09SDavid van Moolenbroek 
155*00b67f09SDavid van Moolenbroek 	for (i = 0; i < ISC_MUTEX_MAX_LOCKERS; i++) {
156*00b67f09SDavid van Moolenbroek 		if (mp->stats->lockers[i].file == NULL) {
157*00b67f09SDavid van Moolenbroek 			locker = &mp->stats->lockers[i];
158*00b67f09SDavid van Moolenbroek 			locker->file = file;
159*00b67f09SDavid van Moolenbroek 			locker->line = line;
160*00b67f09SDavid van Moolenbroek 			break;
161*00b67f09SDavid van Moolenbroek 		} else if (mp->stats->lockers[i].file == file &&
162*00b67f09SDavid van Moolenbroek 			   mp->stats->lockers[i].line == line) {
163*00b67f09SDavid van Moolenbroek 			locker = &mp->stats->lockers[i];
164*00b67f09SDavid van Moolenbroek 			break;
165*00b67f09SDavid van Moolenbroek 		}
166*00b67f09SDavid van Moolenbroek 	}
167*00b67f09SDavid van Moolenbroek 
168*00b67f09SDavid van Moolenbroek 	if (locker != NULL) {
169*00b67f09SDavid van Moolenbroek 		locker->count++;
170*00b67f09SDavid van Moolenbroek 		timevaladd(&locker->wait_total, &postlock_t);
171*00b67f09SDavid van Moolenbroek 	}
172*00b67f09SDavid van Moolenbroek 
173*00b67f09SDavid van Moolenbroek 	mp->stats->cur_locker = locker;
174*00b67f09SDavid van Moolenbroek 
175*00b67f09SDavid van Moolenbroek 	return (ISC_R_SUCCESS);
176*00b67f09SDavid van Moolenbroek }
177*00b67f09SDavid van Moolenbroek 
178*00b67f09SDavid van Moolenbroek isc_result_t
isc_mutex_unlock_profile(isc_mutex_t * mp,const char * file,int line)179*00b67f09SDavid van Moolenbroek isc_mutex_unlock_profile(isc_mutex_t *mp, const char *file, int line) {
180*00b67f09SDavid van Moolenbroek 	struct timeval unlock_t;
181*00b67f09SDavid van Moolenbroek 
182*00b67f09SDavid van Moolenbroek 	UNUSED(file);
183*00b67f09SDavid van Moolenbroek 	UNUSED(line);
184*00b67f09SDavid van Moolenbroek 
185*00b67f09SDavid van Moolenbroek 	if (mp->stats->cur_locker != NULL) {
186*00b67f09SDavid van Moolenbroek 		gettimeofday(&unlock_t, NULL);
187*00b67f09SDavid van Moolenbroek 		timevalsub(&unlock_t, &mp->stats->lock_t);
188*00b67f09SDavid van Moolenbroek 		timevaladd(&mp->stats->locked_total, &unlock_t);
189*00b67f09SDavid van Moolenbroek 		timevaladd(&mp->stats->cur_locker->locked_total, &unlock_t);
190*00b67f09SDavid van Moolenbroek 		mp->stats->cur_locker = NULL;
191*00b67f09SDavid van Moolenbroek 	}
192*00b67f09SDavid van Moolenbroek 
193*00b67f09SDavid van Moolenbroek 	return ((pthread_mutex_unlock((&mp->mutex)) == 0) ? \
194*00b67f09SDavid van Moolenbroek 		ISC_R_SUCCESS : ISC_R_UNEXPECTED);
195*00b67f09SDavid van Moolenbroek }
196*00b67f09SDavid van Moolenbroek 
197*00b67f09SDavid van Moolenbroek 
198*00b67f09SDavid van Moolenbroek void
isc_mutex_statsprofile(FILE * fp)199*00b67f09SDavid van Moolenbroek isc_mutex_statsprofile(FILE *fp) {
200*00b67f09SDavid van Moolenbroek 	isc_mutexlocker_t *locker;
201*00b67f09SDavid van Moolenbroek 	int i, j;
202*00b67f09SDavid van Moolenbroek 
203*00b67f09SDavid van Moolenbroek 	fprintf(fp, "Mutex stats (in us)\n");
204*00b67f09SDavid van Moolenbroek 	for (i = 0; i < stats_next; i++) {
205*00b67f09SDavid van Moolenbroek 		fprintf(fp, "%-12s %4d: %10u  %lu.%06lu %lu.%06lu %5d\n",
206*00b67f09SDavid van Moolenbroek 			stats[i].file, stats[i].line, stats[i].count,
207*00b67f09SDavid van Moolenbroek 			stats[i].locked_total.tv_sec,
208*00b67f09SDavid van Moolenbroek 			stats[i].locked_total.tv_usec,
209*00b67f09SDavid van Moolenbroek 			stats[i].wait_total.tv_sec,
210*00b67f09SDavid van Moolenbroek 			stats[i].wait_total.tv_usec,
211*00b67f09SDavid van Moolenbroek 			i);
212*00b67f09SDavid van Moolenbroek 		for (j = 0; j < ISC_MUTEX_MAX_LOCKERS; j++) {
213*00b67f09SDavid van Moolenbroek 			locker = &stats[i].lockers[j];
214*00b67f09SDavid van Moolenbroek 			if (locker->file == NULL)
215*00b67f09SDavid van Moolenbroek 				continue;
216*00b67f09SDavid van Moolenbroek 			fprintf(fp, " %-11s %4d: %10u  %lu.%06lu %lu.%06lu %5d\n",
217*00b67f09SDavid van Moolenbroek 				locker->file, locker->line, locker->count,
218*00b67f09SDavid van Moolenbroek 				locker->locked_total.tv_sec,
219*00b67f09SDavid van Moolenbroek 				locker->locked_total.tv_usec,
220*00b67f09SDavid van Moolenbroek 				locker->wait_total.tv_sec,
221*00b67f09SDavid van Moolenbroek 				locker->wait_total.tv_usec,
222*00b67f09SDavid van Moolenbroek 				i);
223*00b67f09SDavid van Moolenbroek 		}
224*00b67f09SDavid van Moolenbroek 	}
225*00b67f09SDavid van Moolenbroek }
226*00b67f09SDavid van Moolenbroek 
227*00b67f09SDavid van Moolenbroek #endif /* ISC_MUTEX_PROFILE */
228*00b67f09SDavid van Moolenbroek 
229*00b67f09SDavid van Moolenbroek #if ISC_MUTEX_DEBUG && defined(PTHREAD_MUTEX_ERRORCHECK)
230*00b67f09SDavid van Moolenbroek isc_result_t
isc_mutex_init_errcheck(isc_mutex_t * mp)231*00b67f09SDavid van Moolenbroek isc_mutex_init_errcheck(isc_mutex_t *mp)
232*00b67f09SDavid van Moolenbroek {
233*00b67f09SDavid van Moolenbroek 	pthread_mutexattr_t attr;
234*00b67f09SDavid van Moolenbroek 	int err, errd;
235*00b67f09SDavid van Moolenbroek 
236*00b67f09SDavid van Moolenbroek 	if (pthread_mutexattr_init(&attr) != 0)
237*00b67f09SDavid van Moolenbroek 		return (ISC_R_UNEXPECTED);
238*00b67f09SDavid van Moolenbroek 
239*00b67f09SDavid van Moolenbroek 	if (pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK) != 0) {
240*00b67f09SDavid van Moolenbroek 		errd = pthread_mutexattr_destroy(&attr);
241*00b67f09SDavid van Moolenbroek 		RUNTIME_CHECK(errd == 0);
242*00b67f09SDavid van Moolenbroek 		return (ISC_R_UNEXPECTED);
243*00b67f09SDavid van Moolenbroek 	}
244*00b67f09SDavid van Moolenbroek 
245*00b67f09SDavid van Moolenbroek 	err = pthread_mutex_init(mp, &attr) != 0)
246*00b67f09SDavid van Moolenbroek 	errd = pthread_mutexattr_destroy(&attr);
247*00b67f09SDavid van Moolenbroek 	RUNTIME_CHECK(errd == 0);
248*00b67f09SDavid van Moolenbroek 	if (err == ENOMEM)
249*00b67f09SDavid van Moolenbroek 		return (ISC_R_NOMEMORY);
250*00b67f09SDavid van Moolenbroek 	return ((err == 0) ? ISC_R_SUCCESS : ISC_R_UNEXPECTED);
251*00b67f09SDavid van Moolenbroek }
252*00b67f09SDavid van Moolenbroek #endif
253*00b67f09SDavid van Moolenbroek 
254*00b67f09SDavid van Moolenbroek #if ISC_MUTEX_DEBUG && defined(__NetBSD__) && defined(PTHREAD_MUTEX_ERRORCHECK)
255*00b67f09SDavid van Moolenbroek pthread_mutexattr_t isc__mutex_attrs = {
256*00b67f09SDavid van Moolenbroek 	PTHREAD_MUTEX_ERRORCHECK,	/* m_type */
257*00b67f09SDavid van Moolenbroek 	0				/* m_flags, which appears to be unused. */
258*00b67f09SDavid van Moolenbroek };
259*00b67f09SDavid van Moolenbroek #endif
260*00b67f09SDavid van Moolenbroek 
261*00b67f09SDavid van Moolenbroek #if !(ISC_MUTEX_DEBUG && defined(PTHREAD_MUTEX_ERRORCHECK)) && !ISC_MUTEX_PROFILE
262*00b67f09SDavid van Moolenbroek isc_result_t
isc__mutex_init(isc_mutex_t * mp,const char * file,unsigned int line)263*00b67f09SDavid van Moolenbroek isc__mutex_init(isc_mutex_t *mp, const char *file, unsigned int line) {
264*00b67f09SDavid van Moolenbroek 	char strbuf[ISC_STRERRORSIZE];
265*00b67f09SDavid van Moolenbroek 	isc_result_t result = ISC_R_SUCCESS;
266*00b67f09SDavid van Moolenbroek 	int err;
267*00b67f09SDavid van Moolenbroek #ifdef HAVE_PTHREAD_MUTEX_ADAPTIVE_NP
268*00b67f09SDavid van Moolenbroek 	pthread_mutexattr_t attr;
269*00b67f09SDavid van Moolenbroek 	int errd;
270*00b67f09SDavid van Moolenbroek 
271*00b67f09SDavid van Moolenbroek 	if (pthread_mutexattr_init(&attr) != 0)
272*00b67f09SDavid van Moolenbroek 		return (ISC_R_UNEXPECTED);
273*00b67f09SDavid van Moolenbroek 	if (pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ADAPTIVE_NP) != 0) {
274*00b67f09SDavid van Moolenbroek 		errd = pthread_mutexattr_destroy(&attr);
275*00b67f09SDavid van Moolenbroek 		RUNTIME_CHECK(errd == 0);
276*00b67f09SDavid van Moolenbroek 		return (ISC_R_UNEXPECTED);
277*00b67f09SDavid van Moolenbroek 	}
278*00b67f09SDavid van Moolenbroek 	err = pthread_mutex_init(mp, &attr);
279*00b67f09SDavid van Moolenbroek 	errd = pthread_mutexattr_destroy(&attr);
280*00b67f09SDavid van Moolenbroek 	RUNTIME_CHECK(errd == 0);
281*00b67f09SDavid van Moolenbroek #else /* HAVE_PTHREAD_MUTEX_ADAPTIVE_NP */
282*00b67f09SDavid van Moolenbroek 	err = pthread_mutex_init(mp, ISC__MUTEX_ATTRS);
283*00b67f09SDavid van Moolenbroek #endif /* HAVE_PTHREAD_MUTEX_ADAPTIVE_NP */
284*00b67f09SDavid van Moolenbroek 
285*00b67f09SDavid van Moolenbroek 	if (err == ENOMEM)
286*00b67f09SDavid van Moolenbroek 		return (ISC_R_NOMEMORY);
287*00b67f09SDavid van Moolenbroek 	if (err != 0) {
288*00b67f09SDavid van Moolenbroek 		isc__strerror(err, strbuf, sizeof(strbuf));
289*00b67f09SDavid van Moolenbroek 		UNEXPECTED_ERROR(file, line, "isc_mutex_init() failed: %s",
290*00b67f09SDavid van Moolenbroek 				 strbuf);
291*00b67f09SDavid van Moolenbroek 		result = ISC_R_UNEXPECTED;
292*00b67f09SDavid van Moolenbroek 	}
293*00b67f09SDavid van Moolenbroek 	return (result);
294*00b67f09SDavid van Moolenbroek }
295*00b67f09SDavid van Moolenbroek #endif
296