]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
Locks
authorWouter Wijngaards <wouter@nlnetlabs.nl>
Tue, 20 Feb 2007 11:45:45 +0000 (11:45 +0000)
committerWouter Wijngaards <wouter@nlnetlabs.nl>
Tue, 20 Feb 2007 11:45:45 +0000 (11:45 +0000)
git-svn-id: file:///svn/unbound/trunk@129 be551aaa-1e26-0410-a405-d3ace91eadb9

configure.ac
doc/Changelog
util/locks.c [new file with mode: 0644]
util/locks.h [new file with mode: 0644]

index 5540c9d05751adff055b14da958fe1e761c6e495..89fc0fe5c435610abd67e3ca8c44e6a73ecea412 100644 (file)
@@ -361,6 +361,7 @@ if test x_$withval != x_no; then
                LIBS="$PTHREAD_LIBS $LIBS"
                CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
                CC="$PTHREAD_CC"
+               AC_CHECK_TYPES(pthread_spinlock_t,,,[#include <pthread.h>])
                ])
 fi
 
index 03a3c9c6d79f90385758c696a8bd853ee1d69be5..2000bd224140772638d2a8125823aaacf7c82cbb 100644 (file)
@@ -1,3 +1,6 @@
+20 February 2007: Wouter
+       - Added locks code and pthread spinlock detection.
+
 19 February 2007: Wouter
        - Created 0.0 svn tag.
        - added acx_pthread.m4 autoconf check for pthreads from 
diff --git a/util/locks.c b/util/locks.c
new file mode 100644 (file)
index 0000000..1dbdedd
--- /dev/null
@@ -0,0 +1,44 @@
+/**
+ * util/locks.c - unbound locking primitives
+ *
+ * Copyright (c) 2007, NLnet Labs. All rights reserved.
+ * 
+ * This software is open source.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 
+ * Neither the name of the NLNET LABS nor the names of its contributors may
+ * be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * \file
+ * Implementation of locking and threading support.
+ * A place for locking debug code since most locking functions are macros.
+ */
+
+#include "config.h"
+#include "util/locks.h"
+
diff --git a/util/locks.h b/util/locks.h
new file mode 100644 (file)
index 0000000..eab783b
--- /dev/null
@@ -0,0 +1,181 @@
+/**
+ * util/locks.h - unbound locking primitives
+ *
+ * Copyright (c) 2007, NLnet Labs. All rights reserved.
+ * 
+ * This software is open source.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 
+ * Neither the name of the NLNET LABS nor the names of its contributors may
+ * be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef UTIL_LOCKS_H
+#define UTIL_LOCKS_H
+
+/**
+ * \file
+ * Locking primitives.
+ * If pthreads is available, these are used.
+ * If no locking exists, they do nothing.
+ *
+ * The idea is to have different sorts of locks for different tasks.
+ * This allows the locking code to be ported more easily.
+ *
+ * Types of locks that are supported.
+ *   o lock_rw: lock that has many readers and one writer (to a data entry).
+ *   o lock_basic: simple mutex. Blocking, one person has access only.
+ *     This lock is meant for non performance sensitive uses.
+ *   o lock_quick: speed lock. For performance sensitive locking of critical
+ *     sections. Could be implemented by a mutex or a spinlock.
+ * 
+ * Also thread creation and deletion functions are defined here.
+ */
+
+#include "util/log.h"
+
+/**
+ * The following macro is used to check the return value of the
+ * pthread calls. They return 0 on success and an errno on error.
+ * The errno is logged to the logfile with a descriptive comment.
+ */
+#define LOCKRET(func) do {\
+       int err;                \
+       if( (err=(func)) != 0)          \
+               log_err("%s at %d could not " #func ": %s", \
+               __FILE__, __LINE__, strerror(err));     \
+       } while(0) 
+
+#ifdef HAVE_PTHREAD
+#include <pthread.h>
+
+/** we use the pthread rwlock */
+typedef pthread_rwlock_t lock_rw_t;
+/** small front for pthread init func, NULL is default attrs. */
+#define lock_rw_init(lock) LOCKRET(pthread_rwlock_init(lock, NULL))
+/** free up the lock. must be unlocked. */
+#define lock_rw_destroy(lock) LOCKRET(pthread_rwlock_destroy(lock))
+/** acquire a read lock */
+#define lock_rw_rdlock(lock) LOCKRET(pthread_rwlock_rdlock(lock))
+/** acquire a write lock */
+#define lock_rw_wrlock(lock) LOCKRET(pthread_rwlock_wrlock(lock))
+/** unlock previously acquired read or write lock */
+#define lock_rw_unlock(lock) LOCKRET(pthread_rwlock_unlock(lock))
+
+/** use pthread mutex for basic lock */
+typedef pthread_mutex_t lock_basic_t;
+/** small front for pthread init func, NULL is default attrs. */
+#define lock_basic_init(lock) LOCKRET(pthread_mutex_init(lock, NULL))
+/** free up the lock. must be unlocked. */
+#define lock_basic_destroy(lock) LOCKRET(pthread_mutex_destroy(lock))
+/** acquire lock. This may block indefinetely. */
+#define lock_basic_lock(lock) LOCKRET(pthread_mutex_lock(lock))
+/** unlock acquired lock. */
+#define lock_basic_unlock(lock) LOCKRET(pthread_mutex_unlock(lock))
+
+#ifdef HAVE_PTHREAD_SPINLOCK_T
+/** in case spinlocks are not supported, use a mutex. */
+typedef pthread_mutex_t lock_quick_t;
+/** small front for pthread init func, NULL is default attrs. */
+#define lock_quick_init(lock) LOCKRET(pthread_mutex_init(lock, NULL))
+/** free up the lock. must be unlocked. */
+#define lock_quick_destroy(lock) LOCKRET(pthread_mutex_destroy(lock))
+/** acquire lock. may block. */
+#define lock_quick_lock(lock) LOCKRET(pthread_mutex_lock(lock))
+/** unlock acquired lock. */
+#define lock_quick_unlock(lock) LOCKRET(pthread_mutex_unlock(lock))
+
+#else /* HAVE_PTHREAD_SPINLOCK_T */
+/** use pthread spinlock for the quick lock */
+typedef pthread_spinlock_t lock_quick_t;
+/** 
+ * allocate process private since this is available whether
+ * Thread Process-Shared Synchronization is supported or not.
+ * This means only threads inside this process may access the lock.
+ * (not threads from another process that shares memory).
+ * spinlocks are not supported on all pthread platforms. 
+ */
+#define lock_quick_init(lock) LOCKRET(pthread_spin_init(lock, PTHREAD_PROCESS_PRIVATE))
+/** free up the lock. must be unlocked. */
+#define lock_quick_destroy(lock) LOCKRET(pthread_spin_destroy(lock))
+/** acquire lock. This may block indefinetely, and will spin. */
+#define lock_quick_lock(lock) LOCKRET(pthread_spin_lock(lock))
+/** unlock acquired lock. */
+#define lock_quick_unlock(lock) LOCKRET(pthread_spin_unlock(lock))
+
+#endif /* HAVE SPINLOCK */
+
+/** Thread creation */
+typedef pthread_t ub_thread_t;
+/** Pass where to store tread_t in thr. Use default NULL attributes. */
+#define ub_thread_create(thr, func, arg) LOCKRET(pthread_create(thr, NULL, func, arg))
+
+#else /* HAVE_PTHREAD */
+
+/** In case there is no pthread support, define locks to do nothing */
+typedef int lock_rw_t;
+/** does nothing */
+#define lock_rw_init(lock) /* nop */
+/** does nothing */
+#define lock_rw_destroy(lock) /* nop */
+/** does nothing */
+#define lock_rw_rdlock(lock) /* nop */
+/** does nothing */
+#define lock_rw_wrlock(lock) /* nop */
+/** does nothing */
+#define lock_rw_unlock(lock) /* nop */
+
+/** define locks to do nothing */
+typedef int lock_basic_t;
+/** does nothing */
+#define lock_basic_init(lock) /* nop */
+/** does nothing */
+#define lock_basic_destroy(lock) /* nop */
+/** does nothing */
+#define lock_basic_lock(lock) /* nop */
+/** does nothing */
+#define lock_basic_unlock(lock) /* nop */
+
+/** define locks to do nothing */
+typedef int lock_quick_t;
+/** does nothing */
+#define lock_quick_init(lock) /* nop */
+/** does nothing */
+#define lock_quick_destroy(lock) /* nop */
+/** does nothing */
+#define lock_quick_lock(lock) /* nop */
+/** does nothing */
+#define lock_quick_unlock(lock) /* nop */
+
+/** Thread creation, threads do not exist */
+typedef int ub_thread_t;
+/** ub_thread_create gives an error, it should not be called. */
+#define ub_thread_create(thr, func, arg) \
+       fatal_exit("%s %d called thread create, but no thread support "  \
+               "has been compiled in.",  __FILE__, __LINE__)
+
+#endif /* HAVE_PTHREAD */
+#endif /* UTIL_LOCKS_H */