xref: /freebsd/lib/libthr/arch/amd64/include/pthread_md.h (revision 5e53a4f90f82c4345f277dd87cc9292f26e04a29)
1a091d823SDavid Xu /*-
2*5e53a4f9SPedro F. Giffuni  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3*5e53a4f9SPedro F. Giffuni  *
4a091d823SDavid Xu  * Copyright (C) 2003 David Xu <davidxu@freebsd.org>
5a091d823SDavid Xu  * Copyright (c) 2001 Daniel Eischen <deischen@freebsd.org>
6a091d823SDavid Xu  * All rights reserved.
7a091d823SDavid Xu  *
8a091d823SDavid Xu  * Redistribution and use in source and binary forms, with or without
9a091d823SDavid Xu  * modification, are permitted provided that the following conditions
10a091d823SDavid Xu  * are met:
11a091d823SDavid Xu  * 1. Redistributions of source code must retain the above copyright
12a091d823SDavid Xu  *    notice, this list of conditions and the following disclaimer.
13a091d823SDavid Xu  * 2. Neither the name of the author nor the names of its contributors
14a091d823SDavid Xu  *    may be used to endorse or promote products derived from this software
15a091d823SDavid Xu  *    without specific prior written permission.
16a091d823SDavid Xu  *
17a091d823SDavid Xu  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18a091d823SDavid Xu  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19a091d823SDavid Xu  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20a091d823SDavid Xu  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21a091d823SDavid Xu  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22a091d823SDavid Xu  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23a091d823SDavid Xu  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24a091d823SDavid Xu  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25a091d823SDavid Xu  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26a091d823SDavid Xu  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27a091d823SDavid Xu  * SUCH DAMAGE.
28a091d823SDavid Xu  *
29a091d823SDavid Xu  * $FreeBSD$
30a091d823SDavid Xu  */
31a091d823SDavid Xu 
32a091d823SDavid Xu /*
33a091d823SDavid Xu  * Machine-dependent thread prototypes/definitions.
34a091d823SDavid Xu  */
35a091d823SDavid Xu #ifndef _PTHREAD_MD_H_
36a091d823SDavid Xu #define	_PTHREAD_MD_H_
37a091d823SDavid Xu 
38a091d823SDavid Xu #include <stddef.h>
39a091d823SDavid Xu #include <sys/types.h>
40a091d823SDavid Xu #include <machine/sysarch.h>
41d99f6dacSDavid Xu 
42d99f6dacSDavid Xu #define	CPU_SPINWAIT		__asm __volatile("pause")
43a091d823SDavid Xu 
44a091d823SDavid Xu #define	DTV_OFFSET		offsetof(struct tcb, tcb_dtv)
45a091d823SDavid Xu 
46a091d823SDavid Xu /*
47a091d823SDavid Xu  * Variant II tcb, first two members are required by rtld,
48a091d823SDavid Xu  * %fs points to the structure.
49a091d823SDavid Xu  */
50a091d823SDavid Xu struct tcb {
51a091d823SDavid Xu 	struct tcb		*tcb_self;	/* required by rtld */
52a091d823SDavid Xu 	void			*tcb_dtv;	/* required by rtld */
53a091d823SDavid Xu 	struct pthread		*tcb_thread;
54a091d823SDavid Xu 	void			*tcb_spare[1];
55a091d823SDavid Xu };
56a091d823SDavid Xu 
57a091d823SDavid Xu /*
58a091d823SDavid Xu  * Evaluates to the byte offset of the per-tcb variable name.
59a091d823SDavid Xu  */
60a091d823SDavid Xu #define	__tcb_offset(name)	__offsetof(struct tcb, name)
61a091d823SDavid Xu 
62a091d823SDavid Xu /*
63a091d823SDavid Xu  * Evaluates to the type of the per-tcb variable name.
64a091d823SDavid Xu  */
65a091d823SDavid Xu #define	__tcb_type(name)	__typeof(((struct tcb *)0)->name)
66a091d823SDavid Xu 
67a091d823SDavid Xu /*
68a091d823SDavid Xu  * Evaluates to the value of the per-tcb variable name.
69a091d823SDavid Xu  */
70a091d823SDavid Xu #define	TCB_GET64(name) ({					\
71a091d823SDavid Xu 	__tcb_type(name) __result;				\
72a091d823SDavid Xu 								\
73a091d823SDavid Xu 	u_long __i;						\
74a091d823SDavid Xu 	__asm __volatile("movq %%fs:%1, %0"			\
75a091d823SDavid Xu 	    : "=r" (__i)					\
76b34d83a7SDimitry Andric 	    : "m" (*(volatile u_long *)(__tcb_offset(name))));  \
77a091d823SDavid Xu 	__result = (__tcb_type(name))__i;			\
78a091d823SDavid Xu 								\
79a091d823SDavid Xu 	__result;						\
80a091d823SDavid Xu })
81a091d823SDavid Xu 
82a091d823SDavid Xu static __inline void
83a091d823SDavid Xu _tcb_set(struct tcb *tcb)
84a091d823SDavid Xu {
85a091d823SDavid Xu 	amd64_set_fsbase(tcb);
86a091d823SDavid Xu }
87a091d823SDavid Xu 
88a091d823SDavid Xu static __inline struct tcb *
89a091d823SDavid Xu _tcb_get(void)
90a091d823SDavid Xu {
91a091d823SDavid Xu 	return (TCB_GET64(tcb_self));
92a091d823SDavid Xu }
93a091d823SDavid Xu 
94a091d823SDavid Xu static __inline struct pthread *
95a091d823SDavid Xu _get_curthread(void)
96a091d823SDavid Xu {
97a091d823SDavid Xu 	return (TCB_GET64(tcb_thread));
98a091d823SDavid Xu }
99d6e0eb0aSDavid Xu 
100d6e0eb0aSDavid Xu #define	HAS__UMTX_OP_ERR	1
101d6e0eb0aSDavid Xu 
102a091d823SDavid Xu #endif
103