1 /* $OpenBSD: rthread.h,v 1.39 2012/05/03 09:07:17 pirofti Exp $ */ 2 /* 3 * Copyright (c) 2004,2005 Ted Unangst <tedu@openbsd.org> 4 * All Rights Reserved. 5 * 6 * Permission to use, copy, modify, and distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 */ 18 /* 19 * Private data structures that back up the typedefs in pthread.h. 20 * Since only the thread library cares about their size or arrangement, 21 * it should be possible to switch libraries without relinking. 22 * 23 * Do not reorder _spinlock_lock_t and sem_t variables in the structs. 24 * This is due to alignment requirements of certain arches like hppa. 25 * The current requirement is 16 bytes. 26 */ 27 28 #include <sys/queue.h> 29 #include <semaphore.h> 30 #include <machine/spinlock.h> 31 #include <machine/tcb.h> /* for TLS_VARIANT */ 32 33 #ifdef __LP64__ 34 #define RTHREAD_STACK_SIZE_DEF (512 * 1024) 35 #else 36 #define RTHREAD_STACK_SIZE_DEF (256 * 1024) 37 #endif 38 39 struct stack { 40 SLIST_ENTRY(stack) link; /* link for free default stacks */ 41 void *sp; /* machine stack pointer */ 42 void *base; /* bottom of allocated area */ 43 size_t guardsize; /* size of PROT_NONE zone or */ 44 /* ==1 if application alloced */ 45 size_t len; /* total size of allocated stack */ 46 }; 47 48 struct sem { 49 _spinlock_lock_t lock; 50 volatile int waitcount; 51 volatile int value; 52 int pad; 53 }; 54 55 TAILQ_HEAD(pthread_queue, pthread); 56 57 struct pthread_mutex { 58 _spinlock_lock_t lock; 59 struct pthread_queue lockers; 60 int type; 61 pthread_t owner; 62 int count; 63 int prioceiling; 64 }; 65 66 struct pthread_mutex_attr { 67 int ma_type; 68 int ma_protocol; 69 int ma_prioceiling; 70 }; 71 72 struct pthread_cond { 73 _spinlock_lock_t lock; 74 struct pthread_queue waiters; 75 struct pthread_mutex *mutex; 76 clockid_t clock; 77 }; 78 79 struct pthread_cond_attr { 80 clockid_t ca_clock; 81 }; 82 83 struct pthread_rwlock { 84 _spinlock_lock_t lock; 85 pthread_t owner; 86 struct pthread_queue writers; 87 int readers; 88 }; 89 90 struct pthread_rwlockattr { 91 int pshared; 92 }; 93 94 struct pthread_attr { 95 void *stack_addr; 96 size_t stack_size; 97 size_t guard_size; 98 int detach_state; 99 int contention_scope; 100 int sched_policy; 101 struct sched_param sched_param; 102 int sched_inherit; 103 }; 104 105 #define PTHREAD_MIN_PRIORITY 0 106 #define PTHREAD_MAX_PRIORITY 31 107 108 struct rthread_key { 109 int used; 110 void (*destructor)(void *); 111 }; 112 113 struct rthread_storage { 114 int keyid; 115 struct rthread_storage *next; 116 void *data; 117 }; 118 119 struct rthread_cleanup_fn { 120 void (*fn)(void *); 121 void *arg; 122 struct rthread_cleanup_fn *next; 123 }; 124 125 struct pthread_barrier { 126 pthread_mutex_t mutex; 127 pthread_cond_t cond; 128 int threshold; 129 int sofar; 130 int generation; 131 }; 132 133 struct pthread_barrierattr { 134 int pshared; 135 }; 136 137 struct pthread_spinlock { 138 _spinlock_lock_t lock; 139 pthread_t owner; 140 }; 141 142 struct pthread { 143 struct sem donesem; 144 #if TLS_VARIANT == 1 145 int *errno_ptr; 146 #endif 147 pid_t tid; 148 unsigned int flags; 149 _spinlock_lock_t flags_lock; 150 void *retval; 151 void *(*fn)(void *); 152 void *arg; 153 char name[32]; 154 struct stack *stack; 155 LIST_ENTRY(pthread) threads; 156 TAILQ_ENTRY(pthread) waiting; 157 pthread_cond_t blocking_cond; 158 int sched_policy; 159 struct pthread_attr attr; 160 struct sched_param sched_param; 161 struct rthread_storage *local_storage; 162 struct rthread_cleanup_fn *cleanup_fns; 163 int myerrno; 164 165 /* currently in a cancel point? */ 166 int cancel_point; 167 168 /* cancel received in a delayed cancel block? */ 169 int delayed_cancel; 170 }; 171 #define THREAD_DONE 0x001 172 #define THREAD_DETACHED 0x002 173 #define THREAD_CANCELED 0x004 174 #define THREAD_CANCEL_ENABLE 0x008 175 #define THREAD_CANCEL_DEFERRED 0x010 176 #define THREAD_CANCEL_DELAY 0x020 177 #define THREAD_DYING 0x040 178 179 #define IS_CANCELED(thread) \ 180 (((thread)->flags & (THREAD_CANCELED|THREAD_DYING)) == THREAD_CANCELED) 181 182 183 extern int _threads_ready; 184 extern size_t _thread_pagesize; 185 extern LIST_HEAD(listhead, pthread) _thread_list; 186 extern struct pthread _initial_thread; 187 extern _spinlock_lock_t _thread_lock; 188 extern struct pthread_attr _rthread_attr_default; 189 190 #define ROUND_TO_PAGE(size) \ 191 (((size) + (_thread_pagesize - 1)) & ~(_thread_pagesize - 1)) 192 193 void _spinlock(_spinlock_lock_t *); 194 void _spinunlock(_spinlock_lock_t *); 195 int _sem_wait(sem_t, int, const struct timespec *, int *); 196 int _sem_post(sem_t); 197 198 int _rthread_init(void); 199 void _rthread_setflag(pthread_t, int); 200 void _rthread_clearflag(pthread_t, int); 201 struct stack *_rthread_alloc_stack(pthread_t); 202 void _rthread_free_stack(struct stack *); 203 void _rthread_tls_destructors(pthread_t); 204 void _rthread_debug(int, const char *, ...) 205 __attribute__((__format__ (printf, 2, 3))); 206 void _rthread_debug_init(void); 207 #if defined(__ELF__) && defined(PIC) 208 void _rthread_dl_lock(int what); 209 void _rthread_bind_lock(int); 210 #endif 211 212 /* rthread_cancel.c */ 213 void _enter_cancel(pthread_t); 214 void _leave_cancel(pthread_t); 215 void _enter_delayed_cancel(pthread_t); 216 void _leave_delayed_cancel(pthread_t, int); 217 218 void _thread_dump_info(void); 219 220 int _atomic_lock(register volatile _spinlock_lock_t *); 221 222 /* syscalls */ 223 int getthrid(void); 224 void __threxit(pid_t *); 225 int __thrsleep(const volatile void *, clockid_t, const struct timespec *, 226 void *, const int *); 227 int __thrwakeup(const volatile void *, int n); 228 int __thrsigdivert(sigset_t, siginfo_t *, const struct timespec *); 229 int sched_yield(void); 230 int _thread_sys_sigaction(int, const struct sigaction *, 231 struct sigaction *); 232