From 31dbf5249c74bc884a4f1c6fbb3f13ae58d67022 Mon Sep 17 00:00:00 2001 From: cvs2svn Date: Fri, 26 Mar 1999 18:24:02 +0000 Subject: This commit was manufactured by cvs2git to create tag 'OPENBSD_2_5_BASE'. --- src/lib/libc/include/namespace.h | 18 ++++ src/lib/libc/include/thread_private.h | 179 ++++++++++++++++++++++++++++++++++ 2 files changed, 197 insertions(+) create mode 100644 src/lib/libc/include/namespace.h create mode 100644 src/lib/libc/include/thread_private.h (limited to 'src/lib/libc/include') diff --git a/src/lib/libc/include/namespace.h b/src/lib/libc/include/namespace.h new file mode 100644 index 0000000000..4a51f15ddf --- /dev/null +++ b/src/lib/libc/include/namespace.h @@ -0,0 +1,18 @@ +/* $OpenBSD: namespace.h,v 1.2 1996/08/19 08:28:08 tholo Exp $ */ + +#define catclose _catclose +#define catgets _catgets +#define catopen _catopen +#define err _err +#define errx _errx +#define strtoq _strtoq +#define strtouq _strtouq +#define sys_errlist _sys_errlist +#define sys_nerr _sys_nerr +#define sys_siglist _sys_siglist +#define verr _verr +#define verrx _verrx +#define vwarn _vwarn +#define vwarnx _vwarnx +#define warn _warn +#define warnx _warnx diff --git a/src/lib/libc/include/thread_private.h b/src/lib/libc/include/thread_private.h new file mode 100644 index 0000000000..0027468269 --- /dev/null +++ b/src/lib/libc/include/thread_private.h @@ -0,0 +1,179 @@ +/* + * + * Support for thread-safety in libc and libc_r common code using macros + * to declare thread-safe data structures. + * + * $OpenBSD: thread_private.h,v 1.2 1999/01/06 05:19:32 d Exp $ + */ + +#ifndef _THREAD_PRIVATE_H_ +#define _THREAD_PRIVATE_H_ + +/* + * Parts of this file are + * Copyright (c) 1998 John Birrell . + * All rights reserved. + * + * $Id: thread_private.h,v 1.2 1999/01/06 05:19:32 d Exp $ + * $OpenBSD: thread_private.h,v 1.2 1999/01/06 05:19:32 d Exp $ + */ + +/* + * This global flag is non-zero when a process has created one + * or more threads. It is used to avoid calling locking functions + * when they are not required. In libc, this is always assumed + * to be zero. + */ + +extern volatile int __isthreaded; + +#ifdef _THREAD_SAFE + +#include +#include "pthread_private.h" + +/* + * File lock contention is difficult to diagnose without knowing + * where locks were set. Allow a debug library to be built which + * records the source file and line number of each lock call. + */ +#ifdef _FLOCK_DEBUG +#define _FLOCKFILE(x) _flockfile_debug(x, __FILE__, __LINE__) +#else +#define _FLOCKFILE(x) flockfile(x) +#endif + +/* + * These macros help in making persistent storage thread-specific. + * Libc makes extensive use of private static data structures + * that hold state across function invocation, and these macros + * are no-ops when _THREAD_SAFE is not defined. + * In a thread-safe library, the static variables are used only for + * initialising the per-thread instances of the state variables. + */ + +/* + * Give names to the private variables used to hold per-thread + * data structures. + */ +#ifdef __STDC__ +#define __THREAD_MUTEXP_NAME(name) _thread_mutexp_inst__ ## name +#define __THREAD_MUTEX_NAME(name) _thread_mutex_inst__ ## name +#define __THREAD_KEY_NAME(name) _thread_key_inst__ ## name +#else +#define __THREAD_MUTEXP_NAME(name) _thread_mutexp_inst__/**/name +#define __THREAD_MUTEX_NAME(name) _thread_mutex_inst__/**/name +#define __THREAD_KEY_NAME(name) _thread_key_inst__/**/name +#endif + +/* + * Mutex declare, lock and unlock macros. + */ +#define _THREAD_PRIVATE_MUTEX(name) \ + static struct pthread_mutex __THREAD_MUTEXP_NAME(name) = \ + PTHREAD_MUTEX_STATIC_INITIALIZER; \ + static pthread_mutex_t __THREAD_MUTEX_NAME(name) = \ + &__THREAD_MUTEXP_NAME(name); + +#define _THREAD_PRIVATE_MUTEX_LOCK(name) \ + pthread_mutex_lock(&__THREAD_MUTEX_NAME(name)) + +#define _THREAD_PRIVATE_MUTEX_UNLOCK(name) \ + pthread_mutex_unlock(&__THREAD_MUTEX_NAME(name)) + +/* + * A mutexed data structure used to hold the persistent state's key. + */ +struct _thread_private_key_struct { + struct pthread_mutex lockd; + pthread_mutex_t lock; + int init; + pthread_key_t key; +}; + +/* + * Declaration of a per-thread state key. + */ +#define _THREAD_PRIVATE_KEY(name) \ + static volatile struct _thread_private_key_struct \ + __THREAD_KEY_NAME(name) = { \ + PTHREAD_MUTEX_STATIC_INITIALIZER, \ + &__THREAD_KEY_NAME(name).lockd, \ + 0 \ + }; + +/* + * Initialisation of storage space for a per-thread state variable. + * A pointer to a per-thread *copy* of the _initv parameter is returned. + * It calls malloc the first time and the space is automatically free'd + * when the thread dies. If you need something a bit more complicated + * than free() you will need to roll-your-own. + */ +#define _THREAD_PRIVATE(keyname, _initv, _errv) \ + ({ \ + struct _thread_private_key_struct * __k = \ + &__THREAD_KEY_NAME(keyname); \ + void* __p; \ + extern void free __P((void*)); \ + extern void* malloc __P((size_t)); \ + \ + if (!__isthreaded) { \ + /* non-threaded behaviour */ \ + __p = &(_initv); \ + goto _ok; \ + } \ + \ + /* create key for first thread */ \ + pthread_mutex_lock(&__k->lock); \ + if (__k->init == 0) { \ + if (pthread_key_create(&__k->key, free)) { \ + pthread_mutex_unlock(&__k->lock); \ + goto _err; \ + } \ + __k->init = 1; \ + } \ + pthread_mutex_unlock(&__k->lock); \ + \ + if ((__p = pthread_getspecific(__k->key)) == NULL) { \ + /* alloc space on 1st call in this thread */ \ + if ((__p = malloc(sizeof(_initv))) == NULL) \ + goto _err; \ + if (pthread_setspecific(__k->key, __p) != 0) { \ + free(__p); \ + goto _err; \ + } \ + /* initialise with _initv */ \ + memcpy(__p, &_initv, sizeof(_initv)); \ + } \ + goto _ok; \ + _err: \ + __p = (_errv); \ + _ok: \ + __p; \ + }) + +/* + * Macros for locking and unlocking FILEs. These test if the + * process is threaded to avoid locking when not required. + */ +#define FLOCKFILE(fp) if (__isthreaded) _FLOCKFILE(fp) +#define FUNLOCKFILE(fp) if (__isthreaded) funlockfile(fp) + +#else /* !_THREAD_SAFE */ + +/* + * Do-nothing macros for single-threaded case. + */ +#define _FD_LOCK(f,o,p) (0) +#define _FD_UNLOCK(f,o) /* nothing */ +#define _THREAD_PRIVATE_KEY(_key) /* nothing */ +#define _THREAD_PRIVATE(keyname, _initv, _errv) (&(_initv)) +#define _THREAD_PRIVATE_MUTEX(_name) /* nothing */ +#define _THREAD_PRIVATE_MUTEX_LOCK(_name) /* nothing */ +#define _THREAD_PRIVATE_MUTEX_UNLOCK(_name) /* nothing */ +#define FLOCKFILE(fp) /* nothing */ +#define FUNLOCKFILE(fp) /* nothing */ + +#endif /* !_THREAD_SAFE */ + +#endif _THREAD_PRIVATE_H_ -- cgit v1.2.3-55-g6feb