pthread_md.h revision 144518
1144518Sdavidxu/*- 2144518Sdavidxu * Copyright (C) 2003 David Xu <davidxu@freebsd.org> 3144518Sdavidxu * Copyright (c) 2001 Daniel Eischen <deischen@freebsd.org> 4144518Sdavidxu * All rights reserved. 5144518Sdavidxu * 6144518Sdavidxu * Redistribution and use in source and binary forms, with or without 7144518Sdavidxu * modification, are permitted provided that the following conditions 8144518Sdavidxu * are met: 9144518Sdavidxu * 1. Redistributions of source code must retain the above copyright 10144518Sdavidxu * notice, this list of conditions and the following disclaimer. 11144518Sdavidxu * 2. Neither the name of the author nor the names of its contributors 12144518Sdavidxu * may be used to endorse or promote products derived from this software 13144518Sdavidxu * without specific prior written permission. 14144518Sdavidxu * 15144518Sdavidxu * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16144518Sdavidxu * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17144518Sdavidxu * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18144518Sdavidxu * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19144518Sdavidxu * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20144518Sdavidxu * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21144518Sdavidxu * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22144518Sdavidxu * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23144518Sdavidxu * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24144518Sdavidxu * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25144518Sdavidxu * SUCH DAMAGE. 26144518Sdavidxu * 27144518Sdavidxu * $FreeBSD: head/lib/libthr/arch/amd64/include/pthread_md.h 144518 2005-04-02 01:20:00Z davidxu $ 28144518Sdavidxu */ 29144518Sdavidxu 30144518Sdavidxu/* 31144518Sdavidxu * Machine-dependent thread prototypes/definitions. 32144518Sdavidxu */ 33144518Sdavidxu#ifndef _PTHREAD_MD_H_ 34144518Sdavidxu#define _PTHREAD_MD_H_ 35144518Sdavidxu 36144518Sdavidxu#include <stddef.h> 37144518Sdavidxu#include <sys/types.h> 38144518Sdavidxu#include <machine/sysarch.h> 39144518Sdavidxu#include <ucontext.h> 40144518Sdavidxu 41144518Sdavidxu#define DTV_OFFSET offsetof(struct tcb, tcb_dtv) 42144518Sdavidxu 43144518Sdavidxu/* 44144518Sdavidxu * Variant II tcb, first two members are required by rtld, 45144518Sdavidxu * %fs points to the structure. 46144518Sdavidxu */ 47144518Sdavidxustruct tcb { 48144518Sdavidxu struct tcb *tcb_self; /* required by rtld */ 49144518Sdavidxu void *tcb_dtv; /* required by rtld */ 50144518Sdavidxu struct pthread *tcb_thread; 51144518Sdavidxu void *tcb_spare[1]; 52144518Sdavidxu}; 53144518Sdavidxu 54144518Sdavidxu/* 55144518Sdavidxu * Evaluates to the byte offset of the per-tcb variable name. 56144518Sdavidxu */ 57144518Sdavidxu#define __tcb_offset(name) __offsetof(struct tcb, name) 58144518Sdavidxu 59144518Sdavidxu/* 60144518Sdavidxu * Evaluates to the type of the per-tcb variable name. 61144518Sdavidxu */ 62144518Sdavidxu#define __tcb_type(name) __typeof(((struct tcb *)0)->name) 63144518Sdavidxu 64144518Sdavidxu/* 65144518Sdavidxu * Evaluates to the value of the per-tcb variable name. 66144518Sdavidxu */ 67144518Sdavidxu#define TCB_GET64(name) ({ \ 68144518Sdavidxu __tcb_type(name) __result; \ 69144518Sdavidxu \ 70144518Sdavidxu u_long __i; \ 71144518Sdavidxu __asm __volatile("movq %%fs:%1, %0" \ 72144518Sdavidxu : "=r" (__i) \ 73144518Sdavidxu : "m" (*(u_long *)(__tcb_offset(name)))); \ 74144518Sdavidxu __result = (__tcb_type(name))__i; \ 75144518Sdavidxu \ 76144518Sdavidxu __result; \ 77144518Sdavidxu}) 78144518Sdavidxu 79144518Sdavidxustruct tcb *_tcb_ctor(struct pthread *, int); 80144518Sdavidxuvoid _tcb_dtor(struct tcb *tcb); 81144518Sdavidxu 82144518Sdavidxustatic __inline void 83144518Sdavidxu_tcb_set(struct tcb *tcb) 84144518Sdavidxu{ 85144518Sdavidxu amd64_set_fsbase(tcb); 86144518Sdavidxu} 87144518Sdavidxu 88144518Sdavidxustatic __inline struct tcb * 89144518Sdavidxu_tcb_get(void) 90144518Sdavidxu{ 91144518Sdavidxu return (TCB_GET64(tcb_self)); 92144518Sdavidxu} 93144518Sdavidxu 94144518Sdavidxuextern struct pthread *_thr_initial; 95144518Sdavidxu 96144518Sdavidxustatic __inline struct pthread * 97144518Sdavidxu_get_curthread(void) 98144518Sdavidxu{ 99144518Sdavidxu if (_thr_initial) 100144518Sdavidxu return (TCB_GET64(tcb_thread)); 101144518Sdavidxu return (NULL); 102144518Sdavidxu} 103144518Sdavidxu#endif 104