1/* |
2 * Copyright (c) 2003-2006 Marcel Moolenaar |
3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. --- 7 unchanged lines hidden (view full) --- 18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * |
26 * $FreeBSD: head/lib/libkse/arch/ia64/include/pthread_md.h 161802 2006-09-01 06:17:16Z marcel $ |
27 */ 28 29#ifndef _PTHREAD_MD_H_ 30#define _PTHREAD_MD_H_ 31 32#include <sys/kse.h> 33#include <stddef.h> 34#include <ucontext.h> 35 36#define KSE_STACKSIZE 16384 |
37#define DTV_OFFSET offsetof(struct tcb, tcb_tp.tp_dtv) |
38 39#define THR_GETCONTEXT(ucp) _ia64_save_context(&(ucp)->uc_mcontext) 40#define THR_SETCONTEXT(ucp) PANIC("THR_SETCONTEXT() now in use!\n") 41 42#define PER_THREAD 43 44struct kcb; 45struct kse; 46struct pthread; 47struct tcb; |
48 49/* 50 * tp points to one of these. We define the static TLS as an array 51 * of long double to enforce 16-byte alignment of the TLS memory, 52 * struct ia64_tp, struct tcb and also struct kcb. Both static and 53 * dynamic allocation of any of these structures will result in a 54 * valid, well-aligned thread pointer. 55 */ 56struct ia64_tp { |
57 void *tp_dtv; /* dynamic thread vector. */ |
58 uint64_t _reserved_; 59 long double tp_tls[0]; /* static TLS */ 60}; 61 62struct tcb { 63 struct kse_thr_mailbox tcb_tmbx; 64 struct pthread *tcb_thread; 65 struct kcb *tcb_curkcb; 66 long tcb_isfake; 67 struct ia64_tp tcb_tp; 68}; 69 70struct kcb { 71 struct kse_mailbox kcb_kmbx; |
72 struct kse *kcb_kse; |
73 struct tcb *kcb_curtcb; 74 struct tcb kcb_faketcb; |
75}; 76 |
77register struct ia64_tp *_tp __asm("r13"); 78#define IA64_SET_TP(x) __asm __volatile("mov r13 = %0;;" :: "r"(x)) |
79 80#define _tcb ((struct tcb*)((char*)(_tp) - offsetof(struct tcb, tcb_tp))) 81 82/* 83 * The kcb and tcb constructors. 84 */ 85struct tcb *_tcb_ctor(struct pthread *, int); 86void _tcb_dtor(struct tcb *); 87struct kcb *_kcb_ctor(struct kse *kse); 88void _kcb_dtor(struct kcb *); 89 90/* Called from the KSE to set its private data. */ 91static __inline void 92_kcb_set(struct kcb *kcb) 93{ 94 /* There is no thread yet; use the fake tcb. */ |
95 IA64_SET_TP(&kcb->kcb_faketcb.tcb_tp); |
96} 97 98/* 99 * Get the current kcb. 100 * 101 * This can only be called while in a critical region; don't 102 * worry about having the kcb changed out from under us. 103 */ --- 61 unchanged lines hidden (view full) --- 165 166static __inline void 167_tcb_set(struct kcb *kcb, struct tcb *tcb) 168{ 169 if (tcb == NULL) 170 tcb = &kcb->kcb_faketcb; 171 kcb->kcb_curtcb = tcb; 172 tcb->tcb_curkcb = kcb; |
173 IA64_SET_TP(&tcb->tcb_tp); |
174} 175 176static __inline struct tcb * 177_tcb_get(void) 178{ 179 return (_tcb); 180} 181 --- 21 unchanged lines hidden (view full) --- 203int _ia64_save_context(mcontext_t *mc); 204 205static __inline int 206_thread_enter_uts(struct tcb *tcb, struct kcb *kcb) 207{ 208 if (_ia64_save_context(&tcb->tcb_tmbx.tm_context.uc_mcontext) == 0) { 209 /* Make the fake tcb the current thread. */ 210 kcb->kcb_curtcb = &kcb->kcb_faketcb; |
211 IA64_SET_TP(&kcb->kcb_faketcb.tcb_tp); |
212 _ia64_enter_uts(kcb->kcb_kmbx.km_func, &kcb->kcb_kmbx, 213 kcb->kcb_kmbx.km_stack.ss_sp, 214 kcb->kcb_kmbx.km_stack.ss_size); 215 /* We should not reach here. */ 216 return (-1); 217 } 218 return (0); 219} --- 33 unchanged lines hidden --- |