1 /* 2 * Copyright (c) 2003 Matt Dillon <dillon@backplane.com> 3 * Copyright (c) 2008 The DragonFly Project. 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 * 27 * Machine independant code should not directly include this file. 28 * 29 * $DragonFly: src/sys/platform/pc64/include/thread.h,v 1.3 2008/08/29 17:07:17 dillon Exp $ 30 */ 31 32 #ifndef _MACHINE_THREAD_H_ 33 #define _MACHINE_THREAD_H_ 34 35 #ifndef _MACHINE_SEGMENTS_H_ 36 #include <machine/segments.h> 37 #endif 38 39 struct md_thread { 40 unsigned int mtd_cpl; 41 union savefpu *mtd_savefpu; 42 struct savetls mtd_savetls; 43 }; 44 45 #ifdef _KERNEL 46 47 #define td_cpl td_mach.mtd_cpl 48 #define td_tls td_mach.mtd_savetls 49 #define td_savefpu td_mach.mtd_savefpu 50 51 /* 52 * mycpu() retrieves the base of the current cpu's globaldata structure. 53 * Note that it is *NOT* volatile, meaning that the value may be cached by 54 * GCC. We have to force a dummy memory reference so gcc does not cache 55 * the gd pointer across a procedure call (which might block and cause us 56 * to wakeup on a different cpu). 57 * 58 * Also note that in DragonFly a thread can be preempted, but it cannot 59 * move to another cpu preemptively so the 'gd' pointer is good until you 60 * block. 61 */ 62 63 struct globaldata; 64 65 extern int __mycpu__dummy; 66 67 static __inline 68 struct globaldata * 69 _get_mycpu(void) 70 { 71 struct globaldata *gd; 72 73 __asm ("movq %%gs:globaldata,%0" : "=r" (gd) : "m"(__mycpu__dummy)); 74 return(gd); 75 } 76 77 #define mycpu _get_mycpu() 78 79 #ifdef SMP 80 #define mycpuid (_get_mycpu()->gd_cpuid) 81 #else 82 #define mycpuid 0 83 #endif 84 85 /* 86 * note: curthread is never NULL, but curproc can be. Also note that 87 * in DragonFly, the current pcb is stored in the thread structure. 88 */ 89 #define curthread mycpu->gd_curthread 90 #define curproc curthread->td_proc 91 92 #endif /* _KERNEL */ 93 94 #endif /* !_MACHINE_THREAD_H_ */ 95