From owner-freebsd-arch Mon Nov 12 4:39:47 2001 Delivered-To: freebsd-arch@freebsd.org Received: from peter3.wemm.org (c1315225-a.plstn1.sfba.home.com [24.14.150.180]) by hub.freebsd.org (Postfix) with ESMTP id B07DF37B41A; Mon, 12 Nov 2001 04:39:25 -0800 (PST) Received: from overcee.netplex.com.au (overcee.wemm.org [10.0.0.3]) by peter3.wemm.org (8.11.0/8.11.0) with ESMTP id fACCdPM13118; Mon, 12 Nov 2001 04:39:25 -0800 (PST) (envelope-from peter@wemm.org) Received: from wemm.org (localhost [127.0.0.1]) by overcee.netplex.com.au (Postfix) with ESMTP id 6A89E380A; Mon, 12 Nov 2001 04:39:25 -0800 (PST) (envelope-from peter@wemm.org) X-Mailer: exmh version 2.5 07/13/2001 with nmh-1.0.4 To: Matthew Dillon Cc: Bruce Evans , Robert Watson , freebsd-arch@FreeBSD.ORG Subject: Re: cur{thread/proc}, or not. In-Reply-To: <200111121009.fACA9SI75024@apollo.backplane.com> Date: Mon, 12 Nov 2001 04:39:25 -0800 From: Peter Wemm Message-Id: <20011112123925.6A89E380A@overcee.netplex.com.au> Sender: owner-freebsd-arch@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.ORG Matthew Dillon wrote: > :> Have a look at http://people.freebsd.org/~peter/macros.c where I've cpp'e d > :> it and indented it for readability. Anyway, kthread_exit() turns into > :> this for the compiler to choke on: > : > :> [235 lines of bletcherous code deleted] > > It's a mess, but the code produced isn't too bad. It's much better > now that the mutexes are calling real procedures. Mutexes only call procedures if debugging options are on. If you compile without INVARIANTS, KTR, or WITNESS, then you get the maximum inline versions. Regarding __globaldata() .. That's almost how an intermediate version of globals.h did it on the i386, about rev 1.16. We always have the option to go back to something like later on if preemption turns out to be a wash. Your inline function doesn't work though.. %fs isn't a general purpose register.. You can't store a pointer in the register itself. You have to use an indirect memory reference to fetch the pointer. ie: struct globaldata *gd; __asm("movl %%fs,%0" : "=r" (gd)); return(gd); must be more like this: __asm("movl %%fs:0,%0" : "=r" (gd)); ie: read memory location 0 from the %fs segment. Note that the RELENG_4 macros call inlines: #define GLOBAL_FUNC(name) \ static __inline void *_global_ptr_##name(void) { \ void *val; \ __asm __volatile("movl $gd_" #name ",%0;" \ "addl %%fs:globaldata,%0" : "=r" (val)); \ return (val); \ } \ static __inline void *_global_ptr_##name##_nv(void) { \ void *val; \ __asm("movl $gd_" #name ",%0;" \ "addl %%fs:globaldata,%0" : "=r" (val)); \ return (val); \ } \ static __inline int _global_##name(void) { \ int val; \ __asm __volatile("movl %%fs:gd_" #name ",%0" : "=r" (val)); \ return (val); \ } \ static __inline int _global_##name##_nv(void) { \ int val; \ __asm("movl %%fs:gd_" #name ",%0" : "=r" (val)); \ return (val); \ } \ static __inline void _global_##name##_set(int val) { \ __asm __volatile("movl %0,%%fs:gd_" #name : : "r" (val)); \ } \ static __inline void _global_##name##_set_nv(int val) { \ __asm("movl %0,%%fs:gd_" #name : : "r" (val)); \ } ... GLOBAL_FUNC(curproc) GLOBAL_FUNC(astpending) GLOBAL_FUNC(curpcb) GLOBAL_FUNC(npxproc) GLOBAL_FUNC(common_tss) GLOBAL_FUNC(switchtime) GLOBAL_FUNC(switchticks) ... Bruce neglected to show the spammage from this in his cut/paste. Here's what it really looks like in RELENG_4, and remember that this is *without* mutexes and atomic support, etc, and after I have cleaned it up so that hopefully the mail system wont shred it: static __inline void *_global_ptr_curproc (void) { void *val; __asm volatile ("movl $gd_" "curproc" ",%0;" "addl %%fs:globaldata,%0" : "=r" (val)); return (val); } static __inline void *_global_ptr_curproc_nv(void) { void *val; __asm("movl $gd_" "curproc" ",%0;" "addl %%fs:globaldata,%0" : "=r" (val)); return (val); } static __inline int _global_curproc (void) { int val; __asm volatile ("movl %%fs:gd_" "curproc" ",%0" : "=r" (val)); return (val); } static __inline int _global_curproc_nv(void) { int val; __asm("movl %%fs:gd_" "curproc" ",%0" : "=r" (val)); return (val); } static __inline void _global_curproc_set(int val) { __asm volatile ("movl %0,%%fs:gd_" "curproc" : : "r" (val)); } static __inline void _global_curproc_set_nv(int val) { __asm("movl %0,%%fs:gd_" "curproc" : : "r" (val)); } static __inline void *_global_ptr_astpending (void) { void *val; __asm volatile ("movl $gd_" "astpending" ",%0;" "addl %%fs:globaldata,%0" : "=r" (val)); return (val); } static __inline void *_global_ptr_astpending_nv(void) { void *val; __asm("movl $gd_" "astpending" ",%0;" "addl %%fs:globaldata,%0" : "=r" (val)); return (val); } static __inline int _global_astpending (void) { int val; __asm volatile ("movl %%fs:gd_" "astpending" ",%0" : "=r" (val)); return (val); } static __inline int _global_astpending_nv(void) { int val; __asm("movl %%fs:gd_" "astpending" ",%0" : "=r" (val)); return (val); } static __inline void _global_astpending_set(int val) { __asm volatile ("movl %0,%%fs:gd_" "astpending" : : "r" (val)); } static __inline void _global_astpending_set_nv(int val) { __asm("movl %0,%%fs:gd_" "astpending" : : "r" (val)); } static __inline void *_global_ptr_curpcb (void) { void *val; __asm volatile ("movl $gd_" "curpcb" ",%0;" "addl %%fs:globaldata,%0" : "=r" (val)); return (val); } static __inline void *_global_ptr_curpcb_nv(void) { void *val; __asm("movl $gd_" "curpcb" ",%0;" "addl %%fs:globaldata,%0" : "=r" (val)); return (val); } static __inline int _global_curpcb (void) { int val; __asm volatile ("movl %%fs:gd_" "curpcb" ",%0" : "=r" (val)); return (val); } static __inline int _global_curpcb_nv(void) { int val; __asm("movl %%fs:gd_" "curpcb" ",%0" : "=r" (val)); return (val); } static __inline void _global_curpcb_set(int val) { __asm volatile ("movl %0,%%fs:gd_" "curpcb" : : "r" (val)); } static __inline void _global_curpcb_set_nv(int val) { __asm("movl %0,%%fs:gd_" "curpcb" : : "r" (val)); } static __inline void *_global_ptr_npxproc (void) { void *val; __asm volatile ("movl $gd_" "npxproc" ",%0;" "addl %%fs:globaldata,%0" : "=r" (val)); return (val); } static __inline void *_global_ptr_npxproc_nv(void) { void *val; __asm("movl $gd_" "npxproc" ",%0;" "addl %%fs:globaldata,%0" : "=r" (val)); return (val); } static __inline int _global_npxproc (void) { int val; __asm volatile ("movl %%fs:gd_" "npxproc" ",%0" : "=r" (val)); return (val); } static __inline int _global_npxproc_nv(void) { int val; __asm("movl %%fs:gd_" "npxproc" ",%0" : "=r" (val)); return (val); } static __inline void _global_npxproc_set(int val) { __asm volatile ("movl %0,%%fs:gd_" "npxproc" : : "r" (val)); } static __inline void _global_npxproc_set_nv(int val) { __asm("movl %0,%%fs:gd_" "npxproc" : : "r" (val)); } static __inline void *_global_ptr_common_tss (void) { void *val; __asm volatile ("movl $gd_" "common_tss" ",%0;" "addl %%fs:globaldata,%0" : "=r" (val)); return (val); } static __inline void *_global_ptr_common_tss_nv(void) { void *val; __asm("movl $gd_" "common_tss" ",%0;" "addl %%fs:globaldata,%0" : "=r" (val)); return (val); } static __inline int _global_common_tss (void) { int val; __asm volatile ("movl %%fs:gd_" "common_tss" ",%0" : "=r" (val)); return (val); } static __inline int _global_common_tss_nv(void) { int val; __asm("movl %%fs:gd_" "common_tss" ",%0" : "=r" (val)); return (val); } static __inline void _global_common_tss_set(int val) { __asm volatile ("movl %0,%%fs:gd_" "common_tss" : : "r" (val)); } static __inline void _global_common_tss_set_nv(int val) { __asm("movl %0,%%fs:gd_" "common_tss" : : "r" (val)); } static __inline void *_global_ptr_switchtime (void) { void *val; __asm volatile ("movl $gd_" "switchtime" ",%0;" "addl %%fs:globaldata,%0" : "=r" (val)); return (val); } static __inline void *_global_ptr_switchtime_nv(void) { void *val; __asm("movl $gd_" "switchtime" ",%0;" "addl %%fs:globaldata,%0" : "=r" (val)); return (val); } static __inline int _global_switchtime (void) { int val; __asm volatile ("movl %%fs:gd_" "switchtime" ",%0" : "=r" (val)); return (val); } static __inline int _global_switchtime_nv(void) { int val; __asm("movl %%fs:gd_" "switchtime" ",%0" : "=r" (val)); return (val); } static __inline void _global_switchtime_set(int val) { __asm volatile ("movl %0,%%fs:gd_" "switchtime" : : "r" (val)); } static __inline void _global_switchtime_set_nv(int val) { __asm("movl %0,%%fs:gd_" "switchtime" : : "r" (val)); } static __inline void *_global_ptr_switchticks (void) { void *val; __asm volatile ("movl $gd_" "switchticks" ",%0;" "addl %%fs:globaldata,%0" : "=r" (val)); return (val); } static __inline void *_global_ptr_switchticks_nv(void) { void *val; __asm("movl $gd_" "switchticks" ",%0;" "addl %%fs:globaldata,%0" : "=r" (val)); return (val); } static __inline int _global_switchticks (void) { int val; __asm volatile ("movl %%fs:gd_" "switchticks" ",%0" : "=r" (val)); return (val); } static __inline int _global_switchticks_nv(void) { int val; __asm("movl %%fs:gd_" "switchticks" ",%0" : "=r" (val)); return (val); } static __inline void _global_switchticks_set(int val) { __asm volatile ("movl %0,%%fs:gd_" "switchticks" : : "r" (val)); } static __inline void _global_switchticks_set_nv(int val) { __asm("movl %0,%%fs:gd_" "switchticks" : : "r" (val)); } static __inline void *_global_ptr_common_tssd (void) { void *val; __asm volatile ("movl $gd_" "common_tssd" ",%0;" "addl %%fs:globaldata,%0" : "=r" (val)); return (val); } static __inline void *_global_ptr_common_tssd_nv(void) { void *val; __asm("movl $gd_" "common_tssd" ",%0;" "addl %%fs:globaldata,%0" : "=r" (val)); return (val); } static __inline int _global_common_tssd (void) { int val; __asm volatile ("movl %%fs:gd_" "common_tssd" ",%0" : "=r" (val)); return (val); } static __inline int _global_common_tssd_nv(void) { int val; __asm("movl %%fs:gd_" "common_tssd" ",%0" : "=r" (val)); return (val); } static __inline void _global_common_tssd_set(int val) { __asm volatile ("movl %0,%%fs:gd_" "common_tssd" : : "r" (val)); } static __inline void _global_common_tssd_set_nv(int val) { __asm("movl %0,%%fs:gd_" "common_tssd" : : "r" (val)); } static __inline void *_global_ptr_tss_gdt (void) { void *val; __asm volatile ("movl $gd_" "tss_gdt" ",%0;" "addl %%fs:globaldata,%0" : "=r" (val)); return (val); } static __inline void *_global_ptr_tss_gdt_nv(void) { void *val; __asm("movl $gd_" "tss_gdt" ",%0;" "addl %%fs:globaldata,%0" : "=r" (val)); return (val); } static __inline int _global_tss_gdt (void) { int val; __asm volatile ("movl %%fs:gd_" "tss_gdt" ",%0" : "=r" (val)); return (val); } static __inline int _global_tss_gdt_nv(void) { int val; __asm("movl %%fs:gd_" "tss_gdt" ",%0" : "=r" (val)); return (val); } static __inline void _global_tss_gdt_set(int val) { __asm volatile ("movl %0,%%fs:gd_" "tss_gdt" : : "r" (val)); } static __inline void _global_tss_gdt_set_nv(int val) { __asm("movl %0,%%fs:gd_" "tss_gdt" : : "r" (val)); } static __inline void *_global_ptr_cpuid (void) { void *val; __asm volatile ("movl $gd_" "cpuid" ",%0;" "addl %%fs:globaldata,%0" : "=r" (val)); return (val); } static __inline void *_global_ptr_cpuid_nv(void) { void *val; __asm("movl $gd_" "cpuid" ",%0;" "addl %%fs:globaldata,%0" : "=r" (val)); return (val); } static __inline int _global_cpuid (void) { int val; __asm volatile ("movl %%fs:gd_" "cpuid" ",%0" : "=r" (val)); return (val); } static __inline int _global_cpuid_nv(void) { int val; __asm("movl %%fs:gd_" "cpuid" ",%0" : "=r" (val)); return (val); } static __inline void _global_cpuid_set(int val) { __asm volatile ("movl %0,%%fs:gd_" "cpuid" : : "r" (val)); } static __inline void _global_cpuid_set_nv(int val) { __asm("movl %0,%%fs:gd_" "cpuid" : : "r" (val)); } static __inline void *_global_ptr_other_cpus (void) { void *val; __asm volatile ("movl $gd_" "other_cpus" ",%0;" "addl %%fs:globaldata,%0" : "=r" (val)); return (val); } static __inline void *_global_ptr_other_cpus_nv(void) { void *val; __asm("movl $gd_" "other_cpus" ",%0;" "addl %%fs:globaldata,%0" : "=r" (val)); return (val); } static __inline int _global_other_cpus (void) { int val; __asm volatile ("movl %%fs:gd_" "other_cpus" ",%0" : "=r" (val)); return (val); } static __inline int _global_other_cpus_nv(void) { int val; __asm("movl %%fs:gd_" "other_cpus" ",%0" : "=r" (val)); return (val); } static __inline void _global_other_cpus_set(int val) { __asm volatile ("movl %0,%%fs:gd_" "other_cpus" : : "r" (val)); } static __inline void _global_other_cpus_set_nv(int val) { __asm("movl %0,%%fs:gd_" "other_cpus" : : "r" (val)); } static __inline void *_global_ptr_inside_intr (void) { void *val; __asm volatile ("movl $gd_" "inside_intr" ",%0;" "addl %%fs:globaldata,%0" : "=r" (val)); return (val); } static __inline void *_global_ptr_inside_intr_nv(void) { void *val; __asm("movl $gd_" "inside_intr" ",%0;" "addl %%fs:globaldata,%0" : "=r" (val)); return (val); } static __inline int _global_inside_intr (void) { int val; __asm volatile ("movl %%fs:gd_" "inside_intr" ",%0" : "=r" (val)); return (val); } static __inline int _global_inside_intr_nv(void) { int val; __asm("movl %%fs:gd_" "inside_intr" ",%0" : "=r" (val)); return (val); } static __inline void _global_inside_intr_set(int val) { __asm volatile ("movl %0,%%fs:gd_" "inside_intr" : : "r" (val)); } static __inline void _global_inside_intr_set_nv(int val) { __asm("movl %0,%%fs:gd_" "inside_intr" : : "r" (val)); } static __inline void *_global_ptr_prv_CMAP1 (void) { void *val; __asm volatile ("movl $gd_" "prv_CMAP1" ",%0;" "addl %%fs:globaldata,%0" : "=r" (val)); return (val); } static __inline void *_global_ptr_prv_CMAP1_nv(void) { void *val; __asm("movl $gd_" "prv_CMAP1" ",%0;" "addl %%fs:globaldata,%0" : "=r" (val)); return (val); } static __inline int _global_prv_CMAP1 (void) { int val; __asm volatile ("movl %%fs:gd_" "prv_CMAP1" ",%0" : "=r" (val)); return (val); } static __inline int _global_prv_CMAP1_nv(void) { int val; __asm("movl %%fs:gd_" "prv_CMAP1" ",%0" : "=r" (val)); return (val); } static __inline void _global_prv_CMAP1_set(int val) { __asm volatile ("movl %0,%%fs:gd_" "prv_CMAP1" : : "r" (val)); } static __inline void _global_prv_CMAP1_set_nv(int val) { __asm("movl %0,%%fs:gd_" "prv_CMAP1" : : "r" (val)); } static __inline void *_global_ptr_prv_CMAP2 (void) { void *val; __asm volatile ("movl $gd_" "prv_CMAP2" ",%0;" "addl %%fs:globaldata,%0" : "=r" (val)); return (val); } static __inline void *_global_ptr_prv_CMAP2_nv(void) { void *val; __asm("movl $gd_" "prv_CMAP2" ",%0;" "addl %%fs:globaldata,%0" : "=r" (val)); return (val); } static __inline int _global_prv_CMAP2 (void) { int val; __asm volatile ("movl %%fs:gd_" "prv_CMAP2" ",%0" : "=r" (val)); return (val); } static __inline int _global_prv_CMAP2_nv(void) { int val; __asm("movl %%fs:gd_" "prv_CMAP2" ",%0" : "=r" (val)); return (val); } static __inline void _global_prv_CMAP2_set(int val) { __asm volatile ("movl %0,%%fs:gd_" "prv_CMAP2" : : "r" (val)); } static __inline void _global_prv_CMAP2_set_nv(int val) { __asm("movl %0,%%fs:gd_" "prv_CMAP2" : : "r" (val)); } static __inline void *_global_ptr_prv_CMAP3 (void) { void *val; __asm volatile ("movl $gd_" "prv_CMAP3" ",%0;" "addl %%fs:globaldata,%0" : "=r" (val)); return (val); } static __inline void *_global_ptr_prv_CMAP3_nv(void) { void *val; __asm("movl $gd_" "prv_CMAP3" ",%0;" "addl %%fs:globaldata,%0" : "=r" (val)); return (val); } static __inline int _global_prv_CMAP3 (void) { int val; __asm volatile ("movl %%fs:gd_" "prv_CMAP3" ",%0" : "=r" (val)); return (val); } static __inline int _global_prv_CMAP3_nv(void) { int val; __asm("movl %%fs:gd_" "prv_CMAP3" ",%0" : "=r" (val)); return (val); } static __inline void _global_prv_CMAP3_set(int val) { __asm volatile ("movl %0,%%fs:gd_" "prv_CMAP3" : : "r" (val)); } static __inline void _global_prv_CMAP3_set_nv(int val) { __asm("movl %0,%%fs:gd_" "prv_CMAP3" : : "r" (val)); } static __inline void *_global_ptr_prv_PMAP1 (void) { void *val; __asm volatile ("movl $gd_" "prv_PMAP1" ",%0;" "addl %%fs:globaldata,%0" : "=r" (val)); return (val); } static __inline void *_global_ptr_prv_PMAP1_nv(void) { void *val; __asm("movl $gd_" "prv_PMAP1" ",%0;" "addl %%fs:globaldata,%0" : "=r" (val)); return (val); } static __inline int _global_prv_PMAP1 (void) { int val; __asm volatile ("movl %%fs:gd_" "prv_PMAP1" ",%0" : "=r" (val)); return (val); } static __inline int _global_prv_PMAP1_nv(void) { int val; __asm("movl %%fs:gd_" "prv_PMAP1" ",%0" : "=r" (val)); return (val); } static __inline void _global_prv_PMAP1_set(int val) { __asm volatile ("movl %0,%%fs:gd_" "prv_PMAP1" : : "r" (val)); } static __inline void _global_prv_PMAP1_set_nv(int val) { __asm("movl %0,%%fs:gd_" "prv_PMAP1" : : "r" (val)); } static __inline void *_global_ptr_prv_CADDR1 (void) { void *val; __asm volatile ("movl $gd_" "prv_CADDR1" ",%0;" "addl %%fs:globaldata,%0" : "=r" (val)); return (val); } static __inline void *_global_ptr_prv_CADDR1_nv(void) { void *val; __asm("movl $gd_" "prv_CADDR1" ",%0;" "addl %%fs:globaldata,%0" : "=r" (val)); return (val); } static __inline int _global_prv_CADDR1 (void) { int val; __asm volatile ("movl %%fs:gd_" "prv_CADDR1" ",%0" : "=r" (val)); return (val); } static __inline int _global_prv_CADDR1_nv(void) { int val; __asm("movl %%fs:gd_" "prv_CADDR1" ",%0" : "=r" (val)); return (val); } static __inline void _global_prv_CADDR1_set(int val) { __asm volatile ("movl %0,%%fs:gd_" "prv_CADDR1" : : "r" (val)); } static __inline void _global_prv_CADDR1_set_nv(int val) { __asm("movl %0,%%fs:gd_" "prv_CADDR1" : : "r" (val)); } static __inline void *_global_ptr_prv_CADDR2 (void) { void *val; __asm volatile ("movl $gd_" "prv_CADDR2" ",%0;" "addl %%fs:globaldata,%0" : "=r" (val)); return (val); } static __inline void *_global_ptr_prv_CADDR2_nv(void) { void *val; __asm("movl $gd_" "prv_CADDR2" ",%0;" "addl %%fs:globaldata,%0" : "=r" (val)); return (val); } static __inline int _global_prv_CADDR2 (void) { int val; __asm volatile ("movl %%fs:gd_" "prv_CADDR2" ",%0" : "=r" (val)); return (val); } static __inline int _global_prv_CADDR2_nv(void) { int val; __asm("movl %%fs:gd_" "prv_CADDR2" ",%0" : "=r" (val)); return (val); } static __inline void _global_prv_CADDR2_set(int val) { __asm volatile ("movl %0,%%fs:gd_" "prv_CADDR2" : : "r" (val)); } static __inline void _global_prv_CADDR2_set_nv(int val) { __asm("movl %0,%%fs:gd_" "prv_CADDR2" : : "r" (val)); } static __inline void *_global_ptr_prv_CADDR3 (void) { void *val; __asm volatile ("movl $gd_" "prv_CADDR3" ",%0;" "addl %%fs:globaldata,%0" : "=r" (val)); return (val); } static __inline void *_global_ptr_prv_CADDR3_nv(void) { void *val; __asm("movl $gd_" "prv_CADDR3" ",%0;" "addl %%fs:globaldata,%0" : "=r" (val)); return (val); } static __inline int _global_prv_CADDR3 (void) { int val; __asm volatile ("movl %%fs:gd_" "prv_CADDR3" ",%0" : "=r" (val)); return (val); } static __inline int _global_prv_CADDR3_nv(void) { int val; __asm("movl %%fs:gd_" "prv_CADDR3" ",%0" : "=r" (val)); return (val); } static __inline void _global_prv_CADDR3_set(int val) { __asm volatile ("movl %0,%%fs:gd_" "prv_CADDR3" : : "r" (val)); } static __inline void _global_prv_CADDR3_set_nv(int val) { __asm("movl %0,%%fs:gd_" "prv_CADDR3" : : "r" (val)); } static __inline void *_global_ptr_prv_PADDR1 (void) { void *val; __asm volatile ("movl $gd_" "prv_PADDR1" ",%0;" "addl %%fs:globaldata,%0" : "=r" (val)); return (val); } static __inline void *_global_ptr_prv_PADDR1_nv(void) { void *val; __asm("movl $gd_" "prv_PADDR1" ",%0;" "addl %%fs:globaldata,%0" : "=r" (val)); return (val); } static __inline int _global_prv_PADDR1 (void) { int val; __asm volatile ("movl %%fs:gd_" "prv_PADDR1" ",%0" : "=r" (val)); return (val); } static __inline int _global_prv_PADDR1_nv(void) { int val; __asm("movl %%fs:gd_" "prv_PADDR1" ",%0" : "=r" (val)); return (val); } static __inline void _global_prv_PADDR1_set(int val) { __asm volatile ("movl %0,%%fs:gd_" "prv_PADDR1" : : "r" (val)); } static __inline void _global_prv_PADDR1_set_nv(int val) { __asm("movl %0,%%fs:gd_" "prv_PADDR1" : : "r" (val)); } void kproc_start(udata) const void *udata; { const struct kproc_desc *kp = udata; int error; error = kthread_create((void (*)(void *))kp->func, 0 , kp->global_procpp, kp->arg0); if (error) panic("kproc_start: %s: error %d", kp->arg0, error); } int kthread_create(void (*func)(void *), void *arg, struct proc **newpp, const char *fmt, ...) { int error; va_list ap; struct proc *p2; if (!proc0.p_stats ) { panic("kthread_create called too soon"); } error = fork1(&proc0, (1<<5) | (1<<2) | (1<<4) , &p2); if (error) return error; if (newpp != 0 ) *newpp = p2; p2->p_flag |= 0x00004 | 0x00200 ; p2->p_procsig->ps_flag |= 0x0001 ; { if (( p2 )->p_lock++ == 0 && (( p2 )->p_flag & 0x00004 ) == 0) faultin( p2 ); } ; (( ap ) = (va_list)__builtin_next_arg( fmt )) ; vsnprintf(p2->p_comm, sizeof(p2->p_comm), fmt, ap); ; cpu_set_fork_handler(p2, func, arg); return 0; } void kthread_exit(int ecode) { proc_reparent((( struct proc * )_global_curproc_nv()) , initproc); exit1((( struct proc * )_global_curproc_nv()) , (( ecode ) << 8 | ( 0 )) ); } int suspend_kproc(struct proc *p, int timo) { if ((p->p_flag & 0x00200 ) == 0) return (22 ); ( p->p_siglist ).__bits[((( 17 ) - 1) >> 5) ] |= (1 << ((( 17 ) - 1) & 31)) ; return tsleep((caddr_t)&p->p_siglist, 40 , "suspkp", timo); } int resume_kproc(struct proc *p) { if ((p->p_flag & 0x00200 ) == 0) return (22 ); ( p->p_siglist ).__bits[((( 17 ) - 1) >> 5) ] &= ~(1 << ((( 17 ) - 1) & 31)) ; wakeup((caddr_t)&p->p_siglist); return (0); } void kproc_suspend_loop(struct proc *p) { while ((( p->p_siglist ).__bits[((( 17 ) - 1) >> 5) ] & (1 << ((( 17 ) - 1) & 31)) ) ) { wakeup((caddr_t)&p->p_siglist); tsleep((caddr_t)&p->p_siglist, 40 , "kpsusp", 0); } } And dont forget the extra support code required for this: #include "assym.s" #ifdef SMP /* * Define layout of per-cpu address space. * This is "constructed" in locore.s on the BSP and in mp_machdep.c * for each AP. DO NOT REORDER THESE WITHOUT UPDATING THE REST! */ .globl _SMP_prvspace, _lapic .set _SMP_prvspace,(MPPTDI << PDRSHIFT) .set _lapic,_SMP_prvspace + (NPTEPG-1) * PAGE_SIZE .globl gd_idlestack,gd_idlestack_top .set gd_idlestack,PS_IDLESTACK .set gd_idlestack_top,PS_IDLESTACK_TOP #endif /* * Define layout of the global data. On SMP this lives in * the per-cpu address space, otherwise it's in the data segment. */ .globl globaldata #ifndef SMP .data ALIGN_DATA globaldata: .space GD_SIZEOF /* in data segment */ #else .set globaldata,0 #endif .globl gd_curproc, gd_curpcb, gd_npxproc, gd_astpending .globl gd_common_tss, gd_switchtime, gd_switchticks .set gd_curproc,globaldata + GD_CURPROC .set gd_astpending,globaldata + GD_ASTPENDING .set gd_curpcb,globaldata + GD_CURPCB .set gd_npxproc,globaldata + GD_NPXPROC .set gd_common_tss,globaldata + GD_COMMON_TSS .set gd_switchtime,globaldata + GD_SWITCHTIME .set gd_switchticks,globaldata + GD_SWITCHTICKS .globl gd_common_tssd, gd_tss_gdt .set gd_common_tssd,globaldata + GD_COMMON_TSSD .set gd_tss_gdt,globaldata + GD_TSS_GDT #ifdef USER_LDT .globl gd_currentldt .set gd_currentldt,globaldata + GD_CURRENTLDT #endif #ifndef SMP .globl _curproc, _curpcb, _npxproc, _astpending .globl _common_tss, _switchtime, _switchticks .set _curproc,globaldata + GD_CURPROC .set _astpending,globaldata + GD_ASTPENDING .set _curpcb,globaldata + GD_CURPCB .set _npxproc,globaldata + GD_NPXPROC .set _common_tss,globaldata + GD_COMMON_TSS .set _switchtime,globaldata + GD_SWITCHTIME .set _switchticks,globaldata + GD_SWITCHTICKS .globl _common_tssd, _tss_gdt .set _common_tssd,globaldata + GD_COMMON_TSSD .set _tss_gdt,globaldata + GD_TSS_GDT #ifdef USER_LDT .globl _currentldt .set _currentldt,globaldata + GD_CURRENTLDT #endif #endif #ifdef SMP /* * The BSP version of these get setup in locore.s and pmap.c, while * the AP versions are setup in mp_machdep.c. */ .globl gd_cpuid, gd_cpu_lockid, gd_other_cpus .globl gd_ss_eflags, gd_inside_intr .globl gd_prv_CMAP1, gd_prv_CMAP2, gd_prv_CMAP3, gd_prv_PMAP1 .globl gd_prv_CADDR1, gd_prv_CADDR2, gd_prv_CADDR3, gd_prv_PADDR1 .set gd_cpuid,globaldata + GD_CPUID .set gd_cpu_lockid,globaldata + GD_CPU_LOCKID .set gd_other_cpus,globaldata + GD_OTHER_CPUS .set gd_ss_eflags,globaldata + GD_SS_EFLAGS .set gd_inside_intr,globaldata + GD_INSIDE_INTR .set gd_prv_CMAP1,globaldata + GD_PRV_CMAP1 .set gd_prv_CMAP2,globaldata + GD_PRV_CMAP2 .set gd_prv_CMAP3,globaldata + GD_PRV_CMAP3 .set gd_prv_PMAP1,globaldata + GD_PRV_PMAP1 .set gd_prv_CADDR1,globaldata + GD_PRV_CADDR1 .set gd_prv_CADDR2,globaldata + GD_PRV_CADDR2 .set gd_prv_CADDR3,globaldata + GD_PRV_CADDR3 .set gd_prv_PADDR1,globaldata + GD_PRV_PADDR1 #endif The globals.s code has to be in exact sync with the C headers. And we push a whole bunch of stuff into the kernel namelist as well: # nm /kernel | sort | more 00000000 A globaldata 00000004 A gd_curproc 00000008 A gd_npxproc 0000000c A gd_curpcb 00000010 A gd_switchtime 00000018 A gd_common_tss 00000080 A gd_switchticks 00000084 A gd_common_tssd 0000008c A gd_tss_gdt 00000090 A gd_cpuid 00000094 A gd_cpu_lockid 00000098 A gd_other_cpus 0000009c A gd_inside_intr 000000a0 A gd_ss_eflags 000000a4 A gd_prv_CMAP1 000000a8 A gd_prv_CMAP2 000000ac A gd_prv_CMAP3 000000b0 A gd_prv_PMAP1 000000b4 A gd_prv_CADDR1 000000b8 A gd_prv_CADDR2 000000bc A gd_prv_CADDR3 000000c0 A gd_prv_PADDR1 000000c4 A gd_astpending 00005000 A gd_idlestack 00008000 A gd_idlestack_top 9fc00000 A PTmap 9fe7f000 A PTD 9fe7f9fc A PTDpde 9fe7fffc A APTDpde a0000000 A kernbase a011ffb0 T btext a0120019 t begin a0120064 T sigcode a0120084 t _osigcode a01200ac t _esigcode a01200ac t recover_bootinfo a01200b9 t newboot a01200fb t got_bi_size a012010c t got_common_bi_size a012010f t olddiskboot a0120120 t identify_cpu [....] Anyway, we have plenty of time to come back to this if it turns out that we dont need the complexity. We have *lots* of optimization choices. But we should not start restricting our options yet. Cheers, -Peter -- Peter Wemm - peter@FreeBSD.org; peter@yahoo-inc.com; peter@netplex.com.au "All of this is for nothing if we don't go to the stars" - JMS/B5 To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-arch" in the body of the message