mirror of
https://github.com/monero-project/monero.git
synced 2025-07-25 17:55:20 -04:00
added unbound to external deps
This commit is contained in:
parent
732493c5cb
commit
9ef094b356
394 changed files with 199264 additions and 0 deletions
343
external/unbound/testcode/checklocks.h
vendored
Normal file
343
external/unbound/testcode/checklocks.h
vendored
Normal file
|
@ -0,0 +1,343 @@
|
|||
/**
|
||||
* testcode/checklocks.h - wrapper on locks that checks access.
|
||||
*
|
||||
* 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 COPYRIGHT
|
||||
* HOLDER 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 TESTCODE_CHECK_LOCKS_H
|
||||
#define TESTCODE_CHECK_LOCKS_H
|
||||
|
||||
/**
|
||||
* \file
|
||||
* Locks that are checked.
|
||||
*
|
||||
* Holds information per lock and per thread.
|
||||
* That information is protected by a mutex (unchecked).
|
||||
*
|
||||
* Checks:
|
||||
* o which func, file, line created the lock.
|
||||
* o contention count, measures amount of contention on the lock.
|
||||
* o the memory region(s) that the lock protects are
|
||||
* memcmp'ed to ascertain no race conditions.
|
||||
* o checks that locks are unlocked properly (before deletion).
|
||||
* keeps which func, file, line that locked it.
|
||||
* o checks deadlocks with timeout so it can print errors for them.
|
||||
*
|
||||
* Limitations:
|
||||
* o Detects unprotected memory access when the lock is locked or freed,
|
||||
* which detects races only if they happen, and only if in protected
|
||||
* memory areas.
|
||||
* o Detects deadlocks by timeout, so approximately, as they happen.
|
||||
* o Does not check order of locking.
|
||||
* o Uses a lot of memory.
|
||||
* o The checks use locks themselves, changing scheduling,
|
||||
* thus changing what races you see.
|
||||
*/
|
||||
|
||||
#ifdef USE_THREAD_DEBUG
|
||||
#ifndef HAVE_PTHREAD
|
||||
/* we need the *timed*lock() routines to use for deadlock detection. */
|
||||
#error "Need pthreads for checked locks"
|
||||
#endif
|
||||
/******************* THREAD DEBUG ************************/
|
||||
#include <pthread.h>
|
||||
|
||||
/** How many threads to allocate for */
|
||||
#define THRDEBUG_MAX_THREADS 32 /* threads */
|
||||
/** do we check locking order */
|
||||
extern int check_locking_order;
|
||||
|
||||
/**
|
||||
* Protection memory area.
|
||||
* It is copied to a holding buffer to compare against later.
|
||||
* Note that it may encompass the lock structure.
|
||||
*/
|
||||
struct protected_area {
|
||||
/** where the memory region starts */
|
||||
void* region;
|
||||
/** size of the region */
|
||||
size_t size;
|
||||
/** backbuffer that holds a copy, of same size. */
|
||||
void* hold;
|
||||
/** next protected area in list */
|
||||
struct protected_area* next;
|
||||
};
|
||||
|
||||
/**
|
||||
* Per thread information for locking debug wrappers.
|
||||
*/
|
||||
struct thr_check {
|
||||
/** thread id */
|
||||
pthread_t id;
|
||||
/** real thread func */
|
||||
void* (*func)(void*);
|
||||
/** func user arg */
|
||||
void* arg;
|
||||
/** number of thread in list structure */
|
||||
int num;
|
||||
/** instance number - how many locks have been created by thread */
|
||||
int locks_created;
|
||||
/** file to write locking order information to */
|
||||
FILE* order_info;
|
||||
/**
|
||||
* List of locks that this thread is holding, double
|
||||
* linked list. The first element is the most recent lock acquired.
|
||||
* So it represents the stack of locks acquired. (of all types).
|
||||
*/
|
||||
struct checked_lock *holding_first, *holding_last;
|
||||
/** if the thread is currently waiting for a lock, which one */
|
||||
struct checked_lock* waiting;
|
||||
};
|
||||
|
||||
/**
|
||||
* One structure for all types of locks.
|
||||
*/
|
||||
struct checked_lock {
|
||||
/** mutex for exclusive access to this structure */
|
||||
pthread_mutex_t lock;
|
||||
/** list of memory regions protected by this checked lock */
|
||||
struct protected_area* prot;
|
||||
/** where was this lock created */
|
||||
const char* create_func, *create_file;
|
||||
/** where was this lock created */
|
||||
int create_line;
|
||||
/** unique instance identifier */
|
||||
int create_thread, create_instance;
|
||||
/** contention count */
|
||||
size_t contention_count;
|
||||
/** number of times locked, ever */
|
||||
size_t history_count;
|
||||
/** hold count (how many threads are holding this lock) */
|
||||
int hold_count;
|
||||
/** how many threads are waiting for this lock */
|
||||
int wait_count;
|
||||
/** who touched it last */
|
||||
const char* holder_func, *holder_file;
|
||||
/** who touched it last */
|
||||
int holder_line;
|
||||
/** who owns the lock now */
|
||||
struct thr_check* holder;
|
||||
/** for rwlocks, the writelock holder */
|
||||
struct thr_check* writeholder;
|
||||
|
||||
/** next lock a thread is holding (less recent) */
|
||||
struct checked_lock* next_held_lock[THRDEBUG_MAX_THREADS];
|
||||
/** prev lock a thread is holding (more recent) */
|
||||
struct checked_lock* prev_held_lock[THRDEBUG_MAX_THREADS];
|
||||
|
||||
/** type of lock */
|
||||
enum check_lock_type {
|
||||
/** basic mutex */
|
||||
check_lock_mutex,
|
||||
/** fast spinlock */
|
||||
check_lock_spinlock,
|
||||
/** rwlock */
|
||||
check_lock_rwlock
|
||||
} type;
|
||||
/** the lock itself, see type to disambiguate the union */
|
||||
union {
|
||||
/** mutex */
|
||||
pthread_mutex_t mutex;
|
||||
/** spinlock */
|
||||
pthread_spinlock_t spinlock;
|
||||
/** rwlock */
|
||||
pthread_rwlock_t rwlock;
|
||||
} u;
|
||||
};
|
||||
|
||||
/**
|
||||
* Additional call for the user to specify what areas are protected
|
||||
* @param lock: the lock that protects the area. It can be inside the area.
|
||||
* The lock must be inited. Call with user lock. (any type).
|
||||
* It demangles the lock itself (struct checked_lock**).
|
||||
* @param area: ptr to mem.
|
||||
* @param size: length of area.
|
||||
* You can call it multiple times with the same lock to give several areas.
|
||||
* Call it when you are done initialising the area, since it will be copied
|
||||
* at this time and protected right away against unauthorised changes until
|
||||
* the next lock() call is done.
|
||||
*/
|
||||
void lock_protect(void* lock, void* area, size_t size);
|
||||
|
||||
/**
|
||||
* Remove protected area from lock.
|
||||
* No need to call this when deleting the lock.
|
||||
* @param lock: the lock, any type, (struct checked_lock**).
|
||||
* @param area: pointer to memory.
|
||||
*/
|
||||
void lock_unprotect(void* lock, void* area);
|
||||
|
||||
/**
|
||||
* Get memory associated with a checked lock
|
||||
* @param lock: the checked lock, any type. (struct checked_lock**).
|
||||
* @return: in bytes, including protected areas.
|
||||
*/
|
||||
size_t lock_get_mem(void* lock);
|
||||
|
||||
/**
|
||||
* Initialise checklock. Sets up internal debug structures.
|
||||
*/
|
||||
void checklock_start(void);
|
||||
|
||||
/**
|
||||
* Cleanup internal debug state.
|
||||
*/
|
||||
void checklock_stop(void);
|
||||
|
||||
/**
|
||||
* Init locks.
|
||||
* @param type: what type of lock this is.
|
||||
* @param lock: ptr to user alloced ptr structure. This is inited.
|
||||
* So an alloc is done and the ptr is stored as result.
|
||||
* @param func: caller function name.
|
||||
* @param file: caller file name.
|
||||
* @param line: caller line number.
|
||||
*/
|
||||
void checklock_init(enum check_lock_type type, struct checked_lock** lock,
|
||||
const char* func, const char* file, int line);
|
||||
|
||||
/**
|
||||
* Destroy locks. Free the structure.
|
||||
* @param type: what type of lock this is.
|
||||
* @param lock: ptr to user alloced structure. This is destroyed.
|
||||
* @param func: caller function name.
|
||||
* @param file: caller file name.
|
||||
* @param line: caller line number.
|
||||
*/
|
||||
void checklock_destroy(enum check_lock_type type, struct checked_lock** lock,
|
||||
const char* func, const char* file, int line);
|
||||
|
||||
/**
|
||||
* Acquire readlock.
|
||||
* @param type: what type of lock this is. Had better be a rwlock.
|
||||
* @param lock: ptr to lock.
|
||||
* @param func: caller function name.
|
||||
* @param file: caller file name.
|
||||
* @param line: caller line number.
|
||||
*/
|
||||
void checklock_rdlock(enum check_lock_type type, struct checked_lock* lock,
|
||||
const char* func, const char* file, int line);
|
||||
|
||||
/**
|
||||
* Acquire writelock.
|
||||
* @param type: what type of lock this is. Had better be a rwlock.
|
||||
* @param lock: ptr to lock.
|
||||
* @param func: caller function name.
|
||||
* @param file: caller file name.
|
||||
* @param line: caller line number.
|
||||
*/
|
||||
void checklock_wrlock(enum check_lock_type type, struct checked_lock* lock,
|
||||
const char* func, const char* file, int line);
|
||||
|
||||
/**
|
||||
* Locks.
|
||||
* @param type: what type of lock this is. Had better be mutex or spinlock.
|
||||
* @param lock: the lock.
|
||||
* @param func: caller function name.
|
||||
* @param file: caller file name.
|
||||
* @param line: caller line number.
|
||||
*/
|
||||
void checklock_lock(enum check_lock_type type, struct checked_lock* lock,
|
||||
const char* func, const char* file, int line);
|
||||
|
||||
/**
|
||||
* Unlocks.
|
||||
* @param type: what type of lock this is.
|
||||
* @param lock: the lock.
|
||||
* @param func: caller function name.
|
||||
* @param file: caller file name.
|
||||
* @param line: caller line number.
|
||||
*/
|
||||
void checklock_unlock(enum check_lock_type type, struct checked_lock* lock,
|
||||
const char* func, const char* file, int line);
|
||||
|
||||
/**
|
||||
* Create thread.
|
||||
* @param thr: Thread id, where to store result.
|
||||
* @param func: thread start function.
|
||||
* @param arg: user argument.
|
||||
*/
|
||||
void checklock_thrcreate(pthread_t* thr, void* (*func)(void*), void* arg);
|
||||
|
||||
/**
|
||||
* Wait for thread to exit. Returns thread return value.
|
||||
* @param thread: thread to wait for.
|
||||
*/
|
||||
void checklock_thrjoin(pthread_t thread);
|
||||
|
||||
/** structures to enable compiler type checking on the locks.
|
||||
* Also the pointer makes it so that the lock can be part of the protected
|
||||
* region without any possible problem (since the ptr will stay the same.)
|
||||
* i.e. there can be contention and readlocks stored in checked_lock, while
|
||||
* the protected area stays the same, even though it contains (ptr to) lock.
|
||||
*/
|
||||
struct checked_lock_rw { struct checked_lock* c_rw; };
|
||||
/** structures to enable compiler type checking on the locks. */
|
||||
struct checked_lock_mutex { struct checked_lock* c_m; };
|
||||
/** structures to enable compiler type checking on the locks. */
|
||||
struct checked_lock_spl { struct checked_lock* c_spl; };
|
||||
|
||||
/** debugging rwlock */
|
||||
typedef struct checked_lock_rw lock_rw_t;
|
||||
#define lock_rw_init(lock) checklock_init(check_lock_rwlock, &((lock)->c_rw), __func__, __FILE__, __LINE__)
|
||||
#define lock_rw_destroy(lock) checklock_destroy(check_lock_rwlock, &((lock)->c_rw), __func__, __FILE__, __LINE__)
|
||||
#define lock_rw_rdlock(lock) checklock_rdlock(check_lock_rwlock, (lock)->c_rw, __func__, __FILE__, __LINE__)
|
||||
#define lock_rw_wrlock(lock) checklock_wrlock(check_lock_rwlock, (lock)->c_rw, __func__, __FILE__, __LINE__)
|
||||
#define lock_rw_unlock(lock) checklock_unlock(check_lock_rwlock, (lock)->c_rw, __func__, __FILE__, __LINE__)
|
||||
|
||||
/** debugging mutex */
|
||||
typedef struct checked_lock_mutex lock_basic_t;
|
||||
#define lock_basic_init(lock) checklock_init(check_lock_mutex, &((lock)->c_m), __func__, __FILE__, __LINE__)
|
||||
#define lock_basic_destroy(lock) checklock_destroy(check_lock_mutex, &((lock)->c_m), __func__, __FILE__, __LINE__)
|
||||
#define lock_basic_lock(lock) checklock_lock(check_lock_mutex, (lock)->c_m, __func__, __FILE__, __LINE__)
|
||||
#define lock_basic_unlock(lock) checklock_unlock(check_lock_mutex, (lock)->c_m, __func__, __FILE__, __LINE__)
|
||||
|
||||
/** debugging spinlock */
|
||||
typedef struct checked_lock_spl lock_quick_t;
|
||||
#define lock_quick_init(lock) checklock_init(check_lock_spinlock, &((lock)->c_spl), __func__, __FILE__, __LINE__)
|
||||
#define lock_quick_destroy(lock) checklock_destroy(check_lock_spinlock, &((lock)->c_spl), __func__, __FILE__, __LINE__)
|
||||
#define lock_quick_lock(lock) checklock_lock(check_lock_spinlock, (lock)->c_spl, __func__, __FILE__, __LINE__)
|
||||
#define lock_quick_unlock(lock) checklock_unlock(check_lock_spinlock, (lock)->c_spl, __func__, __FILE__, __LINE__)
|
||||
|
||||
/** we use the pthread id, our thr_check structure is kept behind the scenes */
|
||||
typedef pthread_t ub_thread_t;
|
||||
#define ub_thread_create(thr, func, arg) checklock_thrcreate(thr, func, arg)
|
||||
#define ub_thread_self() pthread_self()
|
||||
#define ub_thread_join(thread) checklock_thrjoin(thread)
|
||||
|
||||
typedef pthread_key_t ub_thread_key_t;
|
||||
#define ub_thread_key_create(key, f) LOCKRET(pthread_key_create(key, f))
|
||||
#define ub_thread_key_set(key, v) LOCKRET(pthread_setspecific(key, v))
|
||||
#define ub_thread_key_get(key) pthread_getspecific(key)
|
||||
|
||||
#endif /* USE_THREAD_DEBUG */
|
||||
#endif /* TESTCODE_CHECK_LOCKS_H */
|
Loading…
Add table
Add a link
Reference in a new issue