1 /* $MirOS: src/lib/libc/include/thread_private.h,v 1.4 2010/09/12 15:51:03 tg Exp $ */ 2 /* $OpenBSD: thread_private.h,v 1.16 2004/06/07 21:11:23 marc Exp $ */ 3 4 /* needs <sys/time.h> for some functions */ 5 6 /* PUBLIC DOMAIN: No Rights Reserved. Marco S Hyman <marc@snafu.org> */ 7 8 #ifndef _THREAD_PRIVATE_H_ 9 #define _THREAD_PRIVATE_H_ 10 11 /* 12 * This file defines the thread library interface to libc. Thread 13 * libraries must implement the functions described here for proper 14 * inter-operation with libc. libc contains weak versions of the 15 * described functions for operation in a non-threaded environment. 16 */ 17 18 /* 19 * This variable is 0 until a second thread is created. 20 */ 21 extern int __isthreaded; 22 23 /* 24 * Weak symbols are used in libc so that the thread library can 25 * efficiently wrap libc functions. 26 * 27 * Use WEAK_NAME(n) to get a libc-private name for n (_weak_n), 28 * WEAK_ALIAS(n) to generate the weak symbol n pointing to _weak_n, 29 * WEAK_PROTOTYPE(n) to generate a prototype for _weak_n (based on n). 30 */ 31 #define WEAK_NAME(name) __CONCAT(_weak_,name) 32 #define WEAK_ALIAS(name) __weak_alias(name, WEAK_NAME(name)) 33 #ifdef __GNUC__ 34 #define WEAK_PROTOTYPE(name) __typeof__(name) WEAK_NAME(name) 35 #else 36 #define WEAK_PROTOTYPE(name) /* typeof() only in gcc */ 37 #endif 38 39 /* 40 * helper macro to make unique names in the thread namespace 41 */ 42 #define __THREAD_NAME(name) __CONCAT(_thread_tagname_,name) 43 44 /* 45 * helper functions that exist as (weak) null functions in libc and 46 * (strong) functions in the thread library. These functions: 47 * 48 * _thread_tag_lock: 49 * lock the mutex associated with the given tag. If the given 50 * tag is NULL a tag is first allocated. 51 * 52 * _thread_tag_unlock: 53 * unlock the mutex associated with the given tag. If the given 54 * tag is NULL a tag is first allocated. 55 * 56 * _thread_tag_storage: 57 * return a pointer to per thread instance of data associated 58 * with the given tag. If the given tag is NULL a tag is first 59 * allocated. 60 */ 61 void _thread_tag_lock(void **); 62 void _thread_tag_unlock(void **); 63 void *_thread_tag_storage(void **, void *, size_t, void *); 64 65 /* 66 * Macros used in libc to access thread mutex, keys, and per thread storage. 67 * _THREAD_PRIVATE_KEY and _THREAD_PRIVATE_MUTEX are different macros for 68 * historical reasons. They do the same thing, define a static variable 69 * keyed by 'name' that identifies a mutex and a key to identify per thread 70 * data. 71 */ 72 #define _THREAD_PRIVATE_KEY(name) \ 73 static void *__THREAD_NAME(name) 74 #define _THREAD_PRIVATE_MUTEX(name) \ 75 static void *__THREAD_NAME(name) 76 #define _THREAD_PRIVATE_MUTEX_LOCK(name) \ 77 _thread_tag_lock(&(__THREAD_NAME(name))) 78 #define _THREAD_PRIVATE_MUTEX_UNLOCK(name) \ 79 _thread_tag_unlock(&(__THREAD_NAME(name))) 80 #define _THREAD_PRIVATE(keyname, storage, error) \ 81 _thread_tag_storage(&(__THREAD_NAME(keyname)), &(storage), \ 82 sizeof (storage), error) 83 /* 84 * Resolver code is special cased in that it uses global keys. 85 */ 86 extern void *__THREAD_NAME(_res); 87 extern void *__THREAD_NAME(_res_ext); 88 extern void *__THREAD_NAME(serv_mutex); 89 90 /* 91 * File descriptor locking definitions. 92 */ 93 #define FD_READ 0x1 94 #define FD_WRITE 0x2 95 #define FD_RDWR (FD_READ | FD_WRITE) 96 97 #ifdef _SYS_TIME_H_ 98 int _thread_fd_lock(int, int, struct timespec *); 99 #endif 100 void _thread_fd_unlock(int, int); 101 102 /* 103 * Macros are used in libc code for historical (debug) reasons. 104 * Define them here. 105 */ 106 #define _FD_LOCK(_fd,_type,_ts) _thread_fd_lock(_fd, _type, _ts) 107 #define _FD_UNLOCK(_fd,_type) _thread_fd_unlock(_fd, _type) 108 109 110 /* 111 * malloc lock/unlock prototypes and definitions 112 */ 113 void _thread_malloc_init(void); 114 void _thread_malloc_lock(void); 115 void _thread_malloc_unlock(void); 116 117 #define _MALLOC_LOCK() do { \ 118 if (__isthreaded) \ 119 _thread_malloc_lock(); \ 120 } while (0) 121 #define _MALLOC_UNLOCK() do { \ 122 if (__isthreaded) \ 123 _thread_malloc_unlock();\ 124 } while (0) 125 #define _MALLOC_LOCK_INIT() do { \ 126 if (__isthreaded) \ 127 _thread_malloc_init();\ 128 } while (0) 129 130 #define _ARC4_LOCK() /* nothing; for now */ 131 #define _ARC4_UNLOCK() /* nothing; for now */ 132 133 /* copied from pthread_private.h with a twist */ 134 #ifdef _LIBC_IN_ABORT 135 int _thread_sys_sigprocmask(int, const void *, void *); 136 #endif 137 138 #endif /* _THREAD_PRIVATE_H_ */ 139