diff options
author | peter <peter@FreeBSD.org> | 2008-07-12 05:00:28 +0000 |
---|---|---|
committer | peter <peter@FreeBSD.org> | 2008-07-12 05:00:28 +0000 |
commit | ba8f85b49c38af7bc2a9acdef5dcde2de008d25e (patch) | |
tree | ceac31a567976fd5866cb5791b059781f6e045de /lib/isc/pthreads | |
parent | 0f328cea2580ffb8f9e363be671a517787111472 (diff) | |
download | FreeBSD-src-ba8f85b49c38af7bc2a9acdef5dcde2de008d25e.zip FreeBSD-src-ba8f85b49c38af7bc2a9acdef5dcde2de008d25e.tar.gz |
Flatten bind9 vendor work area
Diffstat (limited to 'lib/isc/pthreads')
-rw-r--r-- | lib/isc/pthreads/Makefile.in | 38 | ||||
-rw-r--r-- | lib/isc/pthreads/condition.c | 74 | ||||
-rw-r--r-- | lib/isc/pthreads/include/Makefile.in | 25 | ||||
-rw-r--r-- | lib/isc/pthreads/include/isc/Makefile.in | 37 | ||||
-rw-r--r-- | lib/isc/pthreads/include/isc/condition.h | 65 | ||||
-rw-r--r-- | lib/isc/pthreads/include/isc/mutex.h | 145 | ||||
-rw-r--r-- | lib/isc/pthreads/include/isc/once.h | 50 | ||||
-rw-r--r-- | lib/isc/pthreads/include/isc/thread.h | 60 | ||||
-rw-r--r-- | lib/isc/pthreads/mutex.c | 270 | ||||
-rw-r--r-- | lib/isc/pthreads/thread.c | 76 |
10 files changed, 840 insertions, 0 deletions
diff --git a/lib/isc/pthreads/Makefile.in b/lib/isc/pthreads/Makefile.in new file mode 100644 index 0000000..b9cc906 --- /dev/null +++ b/lib/isc/pthreads/Makefile.in @@ -0,0 +1,38 @@ +# Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") +# Copyright (C) 1998-2001 Internet Software Consortium. +# +# Permission to use, copy, modify, and distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH +# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +# AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, +# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE +# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +# PERFORMANCE OF THIS SOFTWARE. + +# $Id: Makefile.in,v 1.17 2004/03/05 05:11:16 marka Exp $ + +srcdir = @srcdir@ +VPATH = @srcdir@ +top_srcdir = @top_srcdir@ + +CINCLUDES = -I${srcdir}/include \ + -I${srcdir}/../unix/include \ + -I../include \ + -I${srcdir}/../include \ + -I${srcdir}/.. + +CDEFINES = +CWARNINGS = + +OBJS = condition.@O@ mutex.@O@ thread.@O@ + +SRCS = condition.c mutex.c thread.c + +SUBDIRS = include +TARGETS = ${OBJS} + +@BIND9_MAKE_RULES@ diff --git a/lib/isc/pthreads/condition.c b/lib/isc/pthreads/condition.c new file mode 100644 index 0000000..b9c26c6 --- /dev/null +++ b/lib/isc/pthreads/condition.c @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 1998-2001 Internet Software Consortium. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* $Id: condition.c,v 1.32.18.2 2005/04/29 00:17:05 marka Exp $ */ + +/*! \file */ + +#include <config.h> + +#include <errno.h> + +#include <isc/condition.h> +#include <isc/msgs.h> +#include <isc/strerror.h> +#include <isc/string.h> +#include <isc/time.h> +#include <isc/util.h> + +isc_result_t +isc_condition_waituntil(isc_condition_t *c, isc_mutex_t *m, isc_time_t *t) { + int presult; + isc_result_t result; + struct timespec ts; + char strbuf[ISC_STRERRORSIZE]; + + REQUIRE(c != NULL && m != NULL && t != NULL); + + /* + * POSIX defines a timespec's tv_sec as time_t. + */ + result = isc_time_secondsastimet(t, &ts.tv_sec); + if (result != ISC_R_SUCCESS) + return (result); + + /*! + * POSIX defines a timespec's tv_nsec as long. isc_time_nanoseconds + * ensures its return value is < 1 billion, which will fit in a long. + */ + ts.tv_nsec = (long)isc_time_nanoseconds(t); + + do { +#if ISC_MUTEX_PROFILE + presult = pthread_cond_timedwait(c, &m->mutex, &ts); +#else + presult = pthread_cond_timedwait(c, m, &ts); +#endif + if (presult == 0) + return (ISC_R_SUCCESS); + if (presult == ETIMEDOUT) + return (ISC_R_TIMEDOUT); + } while (presult == EINTR); + + isc__strerror(presult, strbuf, sizeof(strbuf)); + UNEXPECTED_ERROR(__FILE__, __LINE__, + "pthread_cond_timedwait() %s %s", + isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL, + ISC_MSG_RETURNED, "returned"), + strbuf); + return (ISC_R_UNEXPECTED); +} diff --git a/lib/isc/pthreads/include/Makefile.in b/lib/isc/pthreads/include/Makefile.in new file mode 100644 index 0000000..b1164b6 --- /dev/null +++ b/lib/isc/pthreads/include/Makefile.in @@ -0,0 +1,25 @@ +# Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") +# Copyright (C) 1998-2001 Internet Software Consortium. +# +# Permission to use, copy, modify, and distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH +# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +# AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, +# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE +# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +# PERFORMANCE OF THIS SOFTWARE. + +# $Id: Makefile.in,v 1.12 2004/03/05 05:11:19 marka Exp $ + +srcdir = @srcdir@ +VPATH = @srcdir@ +top_srcdir = @top_srcdir@ + +SUBDIRS = isc +TARGETS = + +@BIND9_MAKE_RULES@ diff --git a/lib/isc/pthreads/include/isc/Makefile.in b/lib/isc/pthreads/include/isc/Makefile.in new file mode 100644 index 0000000..2e11f6c --- /dev/null +++ b/lib/isc/pthreads/include/isc/Makefile.in @@ -0,0 +1,37 @@ +# Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") +# Copyright (C) 1998-2001 Internet Software Consortium. +# +# Permission to use, copy, modify, and distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH +# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +# AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, +# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE +# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +# PERFORMANCE OF THIS SOFTWARE. + +# $Id: Makefile.in,v 1.14 2004/03/05 05:11:40 marka Exp $ + +srcdir = @srcdir@ +VPATH = @srcdir@ +top_srcdir = @top_srcdir@ + +@BIND9_VERSION@ + +HEADERS = condition.h mutex.h once.h thread.h + +SUBDIRS = +TARGETS = + +@BIND9_MAKE_RULES@ + +installdirs: + $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${includedir}/isc + +install:: installdirs + for i in ${HEADERS}; do \ + ${INSTALL_DATA} $(srcdir)/$$i ${DESTDIR}${includedir}/isc ; \ + done diff --git a/lib/isc/pthreads/include/isc/condition.h b/lib/isc/pthreads/include/isc/condition.h new file mode 100644 index 0000000..f7cea75 --- /dev/null +++ b/lib/isc/pthreads/include/isc/condition.h @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 1998-2001 Internet Software Consortium. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* $Id: condition.h,v 1.22.18.2 2005/04/29 00:17:05 marka Exp $ */ + +#ifndef ISC_CONDITION_H +#define ISC_CONDITION_H 1 + +/*! \file */ + +#include <isc/lang.h> +#include <isc/mutex.h> +#include <isc/result.h> +#include <isc/types.h> + +typedef pthread_cond_t isc_condition_t; + +#define isc_condition_init(cp) \ + ((pthread_cond_init((cp), NULL) == 0) ? \ + ISC_R_SUCCESS : ISC_R_UNEXPECTED) + +#if ISC_MUTEX_PROFILE +#define isc_condition_wait(cp, mp) \ + ((pthread_cond_wait((cp), &((mp)->mutex)) == 0) ? \ + ISC_R_SUCCESS : ISC_R_UNEXPECTED) +#else +#define isc_condition_wait(cp, mp) \ + ((pthread_cond_wait((cp), (mp)) == 0) ? \ + ISC_R_SUCCESS : ISC_R_UNEXPECTED) +#endif + +#define isc_condition_signal(cp) \ + ((pthread_cond_signal((cp)) == 0) ? \ + ISC_R_SUCCESS : ISC_R_UNEXPECTED) + +#define isc_condition_broadcast(cp) \ + ((pthread_cond_broadcast((cp)) == 0) ? \ + ISC_R_SUCCESS : ISC_R_UNEXPECTED) + +#define isc_condition_destroy(cp) \ + ((pthread_cond_destroy((cp)) == 0) ? \ + ISC_R_SUCCESS : ISC_R_UNEXPECTED) + +ISC_LANG_BEGINDECLS + +isc_result_t +isc_condition_waituntil(isc_condition_t *, isc_mutex_t *, isc_time_t *); + +ISC_LANG_ENDDECLS + +#endif /* ISC_CONDITION_H */ diff --git a/lib/isc/pthreads/include/isc/mutex.h b/lib/isc/pthreads/include/isc/mutex.h new file mode 100644 index 0000000..edafaf6 --- /dev/null +++ b/lib/isc/pthreads/include/isc/mutex.h @@ -0,0 +1,145 @@ +/* + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 1998-2002 Internet Software Consortium. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* $Id: mutex.h,v 1.25.18.3 2005/07/12 01:22:33 marka Exp $ */ + +#ifndef ISC_MUTEX_H +#define ISC_MUTEX_H 1 + +/*! \file */ + +#include <pthread.h> +#include <stdio.h> + +#include <isc/lang.h> +#include <isc/result.h> /* for ISC_R_ codes */ + +ISC_LANG_BEGINDECLS + +/*! + * Supply mutex attributes that enable deadlock detection + * (helpful when debugging). This is system dependent and + * currently only supported on NetBSD. + */ +#if ISC_MUTEX_DEBUG && defined(__NetBSD__) && defined(PTHREAD_MUTEX_ERRORCHECK) +extern pthread_mutexattr_t isc__mutex_attrs; +#define ISC__MUTEX_ATTRS &isc__mutex_attrs +#else +#define ISC__MUTEX_ATTRS NULL +#endif + +/* XXX We could do fancier error handling... */ + +/*! + * Define ISC_MUTEX_PROFILE to turn on profiling of mutexes by line. When + * enabled, isc_mutex_stats() can be used to print a table showing the + * number of times each type of mutex was locked and the amount of time + * waiting to obtain the lock. + */ +#ifndef ISC_MUTEX_PROFILE +#define ISC_MUTEX_PROFILE 0 +#endif + +#if ISC_MUTEX_PROFILE +typedef struct isc_mutexstats isc_mutexstats_t; + +typedef struct { + pthread_mutex_t mutex; /*%< The actual mutex. */ + isc_mutexstats_t * stats; /*%< Mutex statistics. */ +} isc_mutex_t; +#else +typedef pthread_mutex_t isc_mutex_t; +#endif + + +#if ISC_MUTEX_PROFILE +#define isc_mutex_init(mp) \ + isc_mutex_init_profile((mp), __FILE__, __LINE__) +#else +#if ISC_MUTEX_DEBUG && defined(PTHREAD_MUTEX_ERRORCHECK) +#define isc_mutex_init(mp) \ + isc_mutex_init_errcheck((mp)) +#else +#define isc_mutex_init(mp) \ + isc__mutex_init((mp), __FILE__, __LINE__) +isc_result_t isc__mutex_init(isc_mutex_t *mp, const char *file, unsigned int line); +#endif +#endif + +#if ISC_MUTEX_PROFILE +#define isc_mutex_lock(mp) \ + isc_mutex_lock_profile((mp), __FILE__, __LINE__) +#else +#define isc_mutex_lock(mp) \ + ((pthread_mutex_lock((mp)) == 0) ? \ + ISC_R_SUCCESS : ISC_R_UNEXPECTED) +#endif + +#if ISC_MUTEX_PROFILE +#define isc_mutex_unlock(mp) \ + isc_mutex_unlock_profile((mp), __FILE__, __LINE__) +#else +#define isc_mutex_unlock(mp) \ + ((pthread_mutex_unlock((mp)) == 0) ? \ + ISC_R_SUCCESS : ISC_R_UNEXPECTED) +#endif + +#if ISC_MUTEX_PROFILE +#define isc_mutex_trylock(mp) \ + ((pthread_mutex_trylock((&(mp)->mutex)) == 0) ? \ + ISC_R_SUCCESS : ISC_R_LOCKBUSY) +#else +#define isc_mutex_trylock(mp) \ + ((pthread_mutex_trylock((mp)) == 0) ? \ + ISC_R_SUCCESS : ISC_R_LOCKBUSY) +#endif + +#if ISC_MUTEX_PROFILE +#define isc_mutex_destroy(mp) \ + ((pthread_mutex_destroy((&(mp)->mutex)) == 0) ? \ + ISC_R_SUCCESS : ISC_R_UNEXPECTED) +#else +#define isc_mutex_destroy(mp) \ + ((pthread_mutex_destroy((mp)) == 0) ? \ + ISC_R_SUCCESS : ISC_R_UNEXPECTED) +#endif + +#if ISC_MUTEX_PROFILE +#define isc_mutex_stats(fp) isc_mutex_statsprofile(fp); +#else +#define isc_mutex_stats(fp) +#endif + +#if ISC_MUTEX_PROFILE + +isc_result_t +isc_mutex_init_profile(isc_mutex_t *mp, const char * _file, int _line); +isc_result_t +isc_mutex_lock_profile(isc_mutex_t *mp, const char * _file, int _line); +isc_result_t +isc_mutex_unlock_profile(isc_mutex_t *mp, const char * _file, int _line); + +void +isc_mutex_statsprofile(FILE *fp); + +isc_result_t +isc_mutex_init_errcheck(isc_mutex_t *mp); + +#endif /* ISC_MUTEX_PROFILE */ + +ISC_LANG_ENDDECLS +#endif /* ISC_MUTEX_H */ diff --git a/lib/isc/pthreads/include/isc/once.h b/lib/isc/pthreads/include/isc/once.h new file mode 100644 index 0000000..7e9f672 --- /dev/null +++ b/lib/isc/pthreads/include/isc/once.h @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 1999-2001 Internet Software Consortium. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* $Id: once.h,v 1.9.18.2 2005/04/29 00:17:06 marka Exp $ */ + +#ifndef ISC_ONCE_H +#define ISC_ONCE_H 1 + +/*! \file */ + +#include <pthread.h> + +#include <isc/platform.h> +#include <isc/result.h> + +typedef pthread_once_t isc_once_t; + +#ifdef ISC_PLATFORM_BRACEPTHREADONCEINIT +/*! + * This accomodates systems that define PTHRAD_ONCE_INIT improperly. + */ +#define ISC_ONCE_INIT { PTHREAD_ONCE_INIT } +#else +/*! + * This is the usual case. + */ +#define ISC_ONCE_INIT PTHREAD_ONCE_INIT +#endif + +/* XXX We could do fancier error handling... */ + +#define isc_once_do(op, f) \ + ((pthread_once((op), (f)) == 0) ? \ + ISC_R_SUCCESS : ISC_R_UNEXPECTED) + +#endif /* ISC_ONCE_H */ diff --git a/lib/isc/pthreads/include/isc/thread.h b/lib/isc/pthreads/include/isc/thread.h new file mode 100644 index 0000000..3262607 --- /dev/null +++ b/lib/isc/pthreads/include/isc/thread.h @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 1998-2001 Internet Software Consortium. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* $Id: thread.h,v 1.20.18.4 2005/09/18 07:58:08 marka Exp $ */ + +#ifndef ISC_THREAD_H +#define ISC_THREAD_H 1 + +/*! \file */ + +#include <pthread.h> + +#include <isc/lang.h> +#include <isc/result.h> + +ISC_LANG_BEGINDECLS + +typedef pthread_t isc_thread_t; +typedef void * isc_threadresult_t; +typedef void * isc_threadarg_t; +typedef isc_threadresult_t (*isc_threadfunc_t)(isc_threadarg_t); +typedef pthread_key_t isc_thread_key_t; + +isc_result_t +isc_thread_create(isc_threadfunc_t, isc_threadarg_t, isc_thread_t *); + +void +isc_thread_setconcurrency(unsigned int level); + +/* XXX We could do fancier error handling... */ + +#define isc_thread_join(t, rp) \ + ((pthread_join((t), (rp)) == 0) ? \ + ISC_R_SUCCESS : ISC_R_UNEXPECTED) + +#define isc_thread_self \ + (unsigned long)pthread_self + +#define isc_thread_key_create pthread_key_create +#define isc_thread_key_getspecific pthread_getspecific +#define isc_thread_key_setspecific pthread_setspecific +#define isc_thread_key_delete pthread_key_delete + +ISC_LANG_ENDDECLS + +#endif /* ISC_THREAD_H */ diff --git a/lib/isc/pthreads/mutex.c b/lib/isc/pthreads/mutex.c new file mode 100644 index 0000000..7716980 --- /dev/null +++ b/lib/isc/pthreads/mutex.c @@ -0,0 +1,270 @@ +/* + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2000-2002 Internet Software Consortium. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* $Id: mutex.c,v 1.8.18.4 2005/07/12 01:22:32 marka Exp $ */ + +/*! \file */ + +#include <config.h> + +#include <stdio.h> +#include <time.h> +#include <sys/time.h> +#include <errno.h> + +#include <isc/mutex.h> +#include <isc/util.h> +#include <isc/strerror.h> + +#if ISC_MUTEX_PROFILE + +/*@{*/ +/*% Operations on timevals; adapted from FreeBSD's sys/time.h */ +#define timevalclear(tvp) ((tvp)->tv_sec = (tvp)->tv_usec = 0) +#define timevaladd(vvp, uvp) \ + do { \ + (vvp)->tv_sec += (uvp)->tv_sec; \ + (vvp)->tv_usec += (uvp)->tv_usec; \ + if ((vvp)->tv_usec >= 1000000) { \ + (vvp)->tv_sec++; \ + (vvp)->tv_usec -= 1000000; \ + } \ + } while (0) +#define timevalsub(vvp, uvp) \ + do { \ + (vvp)->tv_sec -= (uvp)->tv_sec; \ + (vvp)->tv_usec -= (uvp)->tv_usec; \ + if ((vvp)->tv_usec < 0) { \ + (vvp)->tv_sec--; \ + (vvp)->tv_usec += 1000000; \ + } \ + } while (0) + +/*@}*/ + +#define ISC_MUTEX_MAX_LOCKERS 32 + +typedef struct { + const char * file; + int line; + unsigned count; + struct timeval locked_total; + struct timeval wait_total; +} isc_mutexlocker_t; + +struct isc_mutexstats { + const char * file; /*%< File mutex was created in. */ + int line; /*%< Line mutex was created on. */ + unsigned count; + struct timeval lock_t; + struct timeval locked_total; + struct timeval wait_total; + isc_mutexlocker_t * cur_locker; + isc_mutexlocker_t lockers[ISC_MUTEX_MAX_LOCKERS]; +}; + +#define TABLESIZE (8 * 1024) +static isc_mutexstats_t stats[TABLESIZE]; +static isc_boolean_t stats_init = ISC_FALSE; +static pthread_mutex_t statslock = PTHREAD_MUTEX_INITIALIZER; + + +isc_result_t +isc_mutex_init_profile(isc_mutex_t *mp, const char *file, int line) { + int i, err; + + err = pthread_mutex_init(&mp->mutex, NULL); + if (err == ENOMEM) + return (ISC_R_NOMEMORY); + if (err != 0) + return (ISC_R_UNEXPECTED); + + RUNTIME_CHECK(pthread_mutex_lock(&statslock) == 0); + + if (stats_init == ISC_FALSE) { + for (i = 0; i < TABLESIZE; i++) { + stats[i].file = NULL; + } + stats_init = ISC_TRUE; + } + + mp->stats = NULL; + for (i = 0; i < TABLESIZE; i++) { + if (stats[i].file == NULL) { + mp->stats = &stats[i]; + break; + } + } + RUNTIME_CHECK(mp->stats != NULL); + + RUNTIME_CHECK(pthread_mutex_unlock(&statslock) == 0); + + mp->stats->file = file; + mp->stats->line = line; + mp->stats->count = 0; + timevalclear(&mp->stats->locked_total); + timevalclear(&mp->stats->wait_total); + for (i = 0; i < ISC_MUTEX_MAX_LOCKERS; i++) { + mp->stats->lockers[i].file = NULL; + mp->stats->lockers[i].line = 0; + mp->stats->lockers[i].count = 0; + timevalclear(&mp->stats->lockers[i].locked_total); + timevalclear(&mp->stats->lockers[i].wait_total); + } + + return (ISC_R_SUCCESS); +} + +isc_result_t +isc_mutex_lock_profile(isc_mutex_t *mp, const char *file, int line) { + struct timeval prelock_t; + struct timeval postlock_t; + isc_mutexlocker_t *locker = NULL; + int i; + + gettimeofday(&prelock_t, NULL); + + if (pthread_mutex_lock(&mp->mutex) != 0) + return (ISC_R_UNEXPECTED); + + gettimeofday(&postlock_t, NULL); + mp->stats->lock_t = postlock_t; + + timevalsub(&postlock_t, &prelock_t); + + mp->stats->count++; + timevaladd(&mp->stats->wait_total, &postlock_t); + + for (i = 0; i < ISC_MUTEX_MAX_LOCKERS; i++) { + if (mp->stats->lockers[i].file == NULL) { + locker = &mp->stats->lockers[i]; + locker->file = file; + locker->line = line; + break; + } else if (mp->stats->lockers[i].file == file && + mp->stats->lockers[i].line == line) { + locker = &mp->stats->lockers[i]; + break; + } + } + + if (locker != NULL) { + locker->count++; + timevaladd(&locker->wait_total, &postlock_t); + } + + mp->stats->cur_locker = locker; + + return (ISC_R_SUCCESS); +} + +isc_result_t +isc_mutex_unlock_profile(isc_mutex_t *mp, const char *file, int line) { + struct timeval unlock_t; + + UNUSED(file); + UNUSED(line); + + if (mp->stats->cur_locker != NULL) { + gettimeofday(&unlock_t, NULL); + timevalsub(&unlock_t, &mp->stats->lock_t); + timevaladd(&mp->stats->locked_total, &unlock_t); + timevaladd(&mp->stats->cur_locker->locked_total, &unlock_t); + mp->stats->cur_locker = NULL; + } + + return ((pthread_mutex_unlock((&mp->mutex)) == 0) ? \ + ISC_R_SUCCESS : ISC_R_UNEXPECTED); +} + + +void +isc_mutex_statsprofile(FILE *fp) { + isc_mutexlocker_t *locker; + int i, j; + fprintf(fp, "Mutex stats (in us)\n"); + for (i = 0; i < TABLESIZE; i++) { + if (stats[i].file == NULL) + continue; + fprintf(fp, "%-12s %4d: %10u %lu.%06lu %lu.%06lu\n", + stats[i].file, stats[i].line, stats[i].count, + stats[i].locked_total.tv_sec, + stats[i].locked_total.tv_usec, + stats[i].wait_total.tv_sec, + stats[i].wait_total.tv_usec + ); + for (j = 0; j < ISC_MUTEX_MAX_LOCKERS; j++) { + locker = &stats[i].lockers[j]; + if (locker->file == NULL) + continue; + fprintf(fp, " %-11s %4d: %10u %lu.%06lu %lu.%06lu\n", + locker->file, locker->line, locker->count, + locker->locked_total.tv_sec, + locker->locked_total.tv_usec, + locker->wait_total.tv_sec, + locker->wait_total.tv_usec + ); + } + } +} + +#endif /* ISC_MUTEX_PROFILE */ + +#if ISC_MUTEX_DEBUG && defined(PTHREAD_MUTEX_ERRORCHECK) +isc_result_t +isc_mutex_init_errcheck(isc_mutex_t *mp) +{ + pthread_mutexattr_t attr; + int err; + + if (pthread_mutexattr_init(&attr) != 0) + return (ISC_R_UNEXPECTED); + + if (pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK) != 0) + return (ISC_R_UNEXPECTED); + + err = pthread_mutex_init(mp, &attr) != 0) + if (err == ENOMEM) + return (ISC_R_NOMEMORY); + return ((err == 0) ? ISC_R_SUCCESS : ISC_R_UNEXPECTED); +} +#endif + +#if ISC_MUTEX_DEBUG && defined(__NetBSD__) && defined(PTHREAD_MUTEX_ERRORCHECK) +pthread_mutexattr_t isc__mutex_attrs = { + PTHREAD_MUTEX_ERRORCHECK, /* m_type */ + 0 /* m_flags, which appears to be unused. */ +}; +#endif + +isc_result_t +isc__mutex_init(isc_mutex_t *mp, const char *file, unsigned int line) { + char strbuf[ISC_STRERRORSIZE]; + isc_result_t result = ISC_R_SUCCESS; + int err; + + err = pthread_mutex_init(mp, ISC__MUTEX_ATTRS); + if (err == ENOMEM) + return (ISC_R_NOMEMORY); + if (err != 0) { + isc__strerror(errno, strbuf, sizeof(strbuf)); + UNEXPECTED_ERROR(file, line, "isc_mutex_init() failed: %s", + strbuf); + result = ISC_R_UNEXPECTED; + } + return (result); +} diff --git a/lib/isc/pthreads/thread.c b/lib/isc/pthreads/thread.c new file mode 100644 index 0000000..bdbb593 --- /dev/null +++ b/lib/isc/pthreads/thread.c @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2000, 2001, 2003 Internet Software Consortium. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* $Id: thread.c,v 1.12.18.3 2005/04/29 00:17:05 marka Exp $ */ + +/*! \file */ + +#include <config.h> + +#include <isc/thread.h> +#include <isc/util.h> + +#ifndef THREAD_MINSTACKSIZE +#define THREAD_MINSTACKSIZE (64U * 1024) +#endif + +isc_result_t +isc_thread_create(isc_threadfunc_t func, isc_threadarg_t arg, + isc_thread_t *thread) +{ + pthread_attr_t attr; + size_t stacksize; + int ret; + + pthread_attr_init(&attr); + +#if defined(HAVE_PTHREAD_ATTR_GETSTACKSIZE) && \ + defined(HAVE_PTHREAD_ATTR_SETSTACKSIZE) + ret = pthread_attr_getstacksize(&attr, &stacksize); + if (ret != 0) + return (ISC_R_UNEXPECTED); + + if (stacksize < THREAD_MINSTACKSIZE) { + ret = pthread_attr_setstacksize(&attr, THREAD_MINSTACKSIZE); + if (ret != 0) + return (ISC_R_UNEXPECTED); + } +#endif + +#if defined(PTHREAD_SCOPE_SYSTEM) && defined(NEED_PTHREAD_SCOPE_SYSTEM) + ret = pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM); + if (ret != 0) + return (ISC_R_UNEXPECTED); +#endif + + ret = pthread_create(thread, &attr, func, arg); + if (ret != 0) + return (ISC_R_UNEXPECTED); + + pthread_attr_destroy(&attr); + + return (ISC_R_SUCCESS); +} + +void +isc_thread_setconcurrency(unsigned int level) { +#if defined(CALL_PTHREAD_SETCONCURRENCY) + (void)pthread_setconcurrency(level); +#else + UNUSED(level); +#endif +} |