Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 12 Nov 2001 04:39:25 -0800
From:      Peter Wemm <peter@wemm.org>
To:        Matthew Dillon <dillon@apollo.backplane.com>
Cc:        Bruce Evans <bde@zeta.org.au>, Robert Watson <rwatson@FreeBSD.ORG>, freebsd-arch@FreeBSD.ORG
Subject:   Re: cur{thread/proc}, or not. 
Message-ID:  <20011112123925.6A89E380A@overcee.netplex.com.au>
In-Reply-To: <200111121009.fACA9SI75024@apollo.backplane.com> 

next in thread | previous in thread | raw e-mail | index | archive | help
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




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20011112123925.6A89E380A>