Date: Sun, 11 Nov 2001 11:17:34 -0800 From: Peter Wemm <peter@wemm.org> To: Robert Watson <rwatson@FreeBSD.ORG> Cc: freebsd-arch@FreeBSD.ORG Subject: Re: cur{thread/proc}, or not. Message-ID: <20011111191735.00D053807@overcee.netplex.com.au> In-Reply-To: <Pine.NEB.3.96L.1011111101234.11566A-100000@fledge.watson.org>
next in thread | previous in thread | raw e-mail | index | archive | help
Robert Watson wrote: > It seems to me that unless a very strong argument exists against using > curproc/curthread (and I don't preclude one existing), using them would > actually be an improvement, as it would assert that this class of > 'borrowing' couldn't exist, simplifying the kernel, not to mention > squeezing a bit more stuff out of the stack (which, at ten levels deep, > actually begins to add up on 64-bit machines). I believe that there are > many places where the 'p' passed in is implicitly assumed to be the > current process, and that making that reliance explicit would be an > improvement, rather than a problem. My gripe is that on i386, it creates a LOT of work for the compiler. Consider this small function in kern_kthread.c: void kthread_exit(int ecode) { sx_xlock(&proctree_lock); PROC_LOCK(curproc); proc_reparent(curproc, initproc); PROC_UNLOCK(curproc); sx_xunlock(&proctree_lock); exit1(curthread, W_EXITCODE(ecode, 0)); } Have a look at http://people.freebsd.org/~peter/macros.c where I've cpp'ed it and indented it for readability. Anyway, kthread_exit() turns into this for the compiler to choke on: void kthread_exit(int ecode) { _sx_xlock((&proctree_lock), 0, 0); do { do { if (!atomic_cmpset_ptr(&(((((&((({ __typeof(((struct globaldata *) 0)->gd_curthread) __result; if (sizeof(__result) == 1) { u_char __b; __asm volatile ("movb %%fs:%1,%0":"=r" (__b):"m"(*(u_char *) (((size_t) (&((struct globaldata *) 0)->gd_curthread))))); __result = *(__typeof(((struct globaldata *) 0)->gd_curthread) *) & __b; } else if (sizeof(__result) == 2) { u_short __w; __asm volatile ("movw %%fs:%1,%0":"=r" (__w):"m"(*(u_short *) (((size_t) (&((struct globaldata *) 0)->gd_curthread))))); __result = *(__typeof(((struct globaldata *) 0)->gd_curthread) *) & __w; } else if (sizeof(__result) == 4) { u_int __i; __asm volatile ("movl %%fs:%1,%0":"=r" (__i):"m"(*(u_int *) (((size_t) (&((struct globaldata *) 0)->gd_curthread))))); __result = *(__typeof(((struct globaldata *) 0)->gd_curthread) *) & __i; } else { __result = *({ __typeof(((struct globaldata *) 0)->gd_curthread) * __p; __asm volatile ("movl %%fs:%1,%0; addl %2,%0":"=r" (__p):"m"(*(struct globaldata *) (((size_t) (&((struct globaldata *) 0)->gd_prvspace)))), "i"(((size_t) (&((struct globaldata *) 0)->gd_curthread)))); __p; }); } __result; })->td_proc))->p_mtx)))))->mtx_lock, (void *)0x00000004, ((({ __typeof(((struct globaldata *) 0)->gd_curthread) __result; if (sizeof(__result) == 1) { u_char __b; __asm volatile ("movb %%fs:%1,%0":"=r" (__b):"m"(*(u_char *) (((size_t) (&((struct globaldata *) 0)->gd_curthread))))); __result = *(__typeof(((struct globaldata *) 0)->gd_curthread) *) & __b; } else if (sizeof(__result) == 2) { u_short __w; __asm volatile ("movw %%fs:%1,%0":"=r" (__w):"m"(*(u_short *) (((size_t) (&((struct globaldata *) 0)->gd_curthread))))); __result = *(__typeof(((struct globaldata *) 0)->gd_curthread) *) & __w; } else if (sizeof(__result) == 4) { u_int __i; __asm volatile ("movl %%fs:%1,%0":"=r" (__i):"m"(*(u_int *) (((size_t) (&((struct globaldata *) 0)->gd_curthread))))); __result = *(__typeof(((struct globaldata *) 0)->gd_curthread) *) & __i; } else { __result = *({ __typeof(((struct globaldata *) 0)->gd_curthread) * __p; __asm volatile ("movl %%fs:%1,%0; addl %2,%0":"=r" (__p):"m"(*(struct globaldata *) (((size_t) (&((struct globaldata *) 0)->gd_prvspace)))), "i"(((size_t) (&((struct globaldata *) 0)->gd_curthread)))); __p; }); } __result; }))))) _mtx_lock_sleep(((((&((({ __typeof(((struct globaldata *) 0)->gd_curthread) __result; if (sizeof(__result) == 1) { u_char __b; __asm volatile ("movb %%fs:%1,%0":"=r" (__b):"m"(*(u_char *) (((size_t) (&((struct globaldata *) 0)->gd_curthread))))); __result = *(__typeof(((struct globaldata *) 0)->gd_curthread) *) & __b; } else if (sizeof(__result) == 2) { u_short __w; __asm volatile ("movw %%fs:%1,%0":"=r" (__w):"m"(*(u_short *) (((size_t) (&((struct globaldata *) 0)->gd_curthread))))); __result = *(__typeof(((struct globaldata *) 0)->gd_curthread) *) & __w; } else if (sizeof(__result) == 4) { u_int __i; __asm volatile ("movl %%fs:%1,%0":"=r" (__i):"m"(*(u_int *) (((size_t) (&((struct globaldata *) 0)->gd_curthread))))); __result = *(__typeof(((struct globaldata *) 0)->gd_curthread) *) & __i; } else { __result = *({ __typeof(((struct globaldata *) 0)->gd_curthread) * __p; __asm volatile ("movl %%fs:%1,%0; addl %2,%0":"=r" (__p):"m"(*(struct globaldata *) (((size_t) (&((struct globaldata *) 0)->gd_prvspace)))), "i"(((size_t) (&((struct globaldata *) 0)->gd_curthread)))); __p; }); } __result; })->td_proc))->p_mtx)))), (((0))), ((0)), ((0))); } while (0); do { if ((((((0))) & 0x00000002) == 0 && (((&(((&((({ __typeof(((struct globaldata *) 0)->gd_curthread) __result; if (sizeof(__result) == 1) { u_char __b; __asm volatile ("movb %%fs:%1,%0":"=r" (__b):"m"(*(u_char *) (((size_t) (&((struct globaldata *) 0)->gd_curthread))))); __result = *(__typeof(((struct globaldata *) 0)->gd_curthread) *) & __b; } else if (sizeof(__result) == 2) { u_short __w; __asm volatile ("movw %%fs:%1,%0":"=r" (__w):"m"(*(u_short *) (((size_t) (&((struct globaldata *) 0)->gd_curthread))))); __result = *(__typeof(((struct globaldata *) 0)->gd_curthread) *) & __w; } else if (sizeof(__result) == 4) { u_int __i; __asm volatile ("movl %%fs:%1,%0":"=r" (__i):"m"(*(u_int *) (((size_t) (&((struct globaldata *) 0)->gd_curthread))))); __result = *(__typeof(((struct globaldata *) 0)->gd_curthread) *) & __i; } else { __result = *({ __typeof(((struct globaldata *) 0)->gd_curthread) * __p; __asm volatile ("movl %%fs:%1,%0; addl %2,%0":"=r" (__p):"m"(*(struct globaldata *) (((size_t) (&((struct globaldata *) 0)->gd_prvspace)))), "i"(((size_t) (&((struct globaldata *) 0)->gd_curthread)))); __p; }); } __result; })->td_proc))->p_mtx)))->mtx_object))->lo_flags & 0x00040000) == 0)); } while (0); } while (0); proc_reparent((({ __typeof(((struct globaldata *) 0)->gd_curthread) __result; if (sizeof(__result) == 1) { u_char __b; __asm volatile ("movb %%fs:%1,%0":"=r" (__b):"m"(*(u_char *) (((size_t) (&((struct globaldata *) 0)->gd_curthread))))); __result = *(__typeof(((struct globaldata *) 0)->gd_curthread) *) & __b; } else if (sizeof(__result) == 2) { u_short __w; __asm volatile ("movw %%fs:%1,%0":"=r" (__w):"m"(*(u_short *) (((size_t) (&((struct globaldata *) 0)->gd_curthread))))); __result = *(__typeof(((struct globaldata *) 0)->gd_curthread) *) & __w; } else if (sizeof(__result) == 4) { u_int __i; __asm volatile ("movl %%fs:%1,%0":"=r" (__i):"m"(*(u_int *) (((size_t) (&((struct globaldata *) 0)->gd_curthread))))); __result = *(__typeof(((struct globaldata *) 0)->gd_curthread) *) & __i; } else { __result = *({ __typeof(((struct globaldata *) 0)->gd_curthread) * __p; __asm volatile ("movl %%fs:%1,%0; addl %2,%0":"=r" (__p):"m"(*(struct globaldata *) (((size_t) (&((struct globaldata *) 0)->gd_prvspace)))), "i"(((size_t) (&((struct globaldata *) 0)->gd_curthread)))); __p; }); } __result; })->td_proc), initproc); do { do { if (((((((0)))) & 0x00000002) == 0 && (((&(((&((({ __typeof(((struct globaldata *) 0)->gd_curthread) __result; if (sizeof(__result) == 1) { u_char __b; __asm volatile ("movb %%fs:%1,%0":"=r" (__b):"m"(*(u_char *) (((size_t) (&((struct globaldata *) 0)->gd_curthread))))); __result = *(__typeof(((struct globaldata *) 0)->gd_curthread) *) & __b; } else if (sizeof(__result) == 2) { u_short __w; __asm volatile ("movw %%fs:%1,%0":"=r" (__w):"m"(*(u_short *) (((size_t) (&((struct globaldata *) 0)->gd_curthread))))); __result = *(__typeof(((struct globaldata *) 0)->gd_curthread) *) & __w; } else if (sizeof(__result) == 4) { u_int __i; __asm volatile ("movl %%fs:%1,%0":"=r" (__i):"m"(*(u_int *) (((size_t) (&((struct globaldata *) 0)->gd_curthread))))); __result = *(__typeof(((struct globaldata *) 0)->gd_curthread) *) & __i; } else { __result = *({ __typeof(((struct globaldata *) 0)->gd_curthread) * __p; __asm volatile ("movl %%fs:%1,%0; addl %2,%0":"=r" (__p):"m"(*(struct globaldata *) (((size_t) (&((struct globaldata *) 0)->gd_prvspace)))), "i"(((size_t) (&((struct globaldata *) 0)->gd_curthread)))); __p; }); } __result; })->td_proc))->p_mtx)))->mtx_object))->lo_flags & 0x00040000) == 0)); } while (0); do { if (!atomic_cmpset_ptr(&(((((&((({ __typeof(((struct globaldata *) 0)->gd_curthread) __result; if (sizeof(__result) == 1) { u_char __b; __asm volatile ("movb %%fs:%1,%0":"=r" (__b):"m"(*(u_char *) (((size_t) (&((struct globaldata *) 0)->gd_curthread))))); __result = *(__typeof(((struct globaldata *) 0)->gd_curthread) *) & __b; } else if (sizeof(__result) == 2) { u_short __w; __asm volatile ("movw %%fs:%1,%0":"=r" (__w):"m"(*(u_short *) (((size_t) (&((struct globaldata *) 0)->gd_curthread))))); __result = *(__typeof(((struct globaldata *) 0)->gd_curthread) *) & __w; } else if (sizeof(__result) == 4) { u_int __i; __asm volatile ("movl %%fs:%1,%0":"=r" (__i):"m"(*(u_int *) (((size_t) (&((struct globaldata *) 0)->gd_curthread))))); __result = *(__typeof(((struct globaldata *) 0)->gd_curthread) *) & __i; } else { __result = *({ __typeof(((struct globaldata *) 0)->gd_curthread) * __p; __asm volatile ("movl %%fs:%1,%0; addl %2,%0":"=r" (__p):"m"(*(struct globaldata *) (((size_t) (&((struct globaldata *) 0)->gd_prvspace)))), "i"(((size_t) (&((struct globaldata *) 0)->gd_curthread)))); __p; }); } __result; })->td_proc))->p_mtx)))))->mtx_lock, ((({ __typeof(((struct globaldata *) 0)->gd_curthread) __result; if (sizeof(__result) == 1) { u_char __b; __asm volatile ("movb %%fs:%1,%0":"=r" (__b):"m"(*(u_char *) (((size_t) (&((struct globaldata *) 0)->gd_curthread))))); __result = *(__typeof(((struct globaldata *) 0)->gd_curthread) *) & __b; } else if (sizeof(__result) == 2) { u_short __w; __asm volatile ("movw %%fs:%1,%0":"=r" (__w):"m"(*(u_short *) (((size_t) (&((struct globaldata *) 0)->gd_curthread))))); __result = *(__typeof(((struct globaldata *) 0)->gd_curthread) *) & __w; } else if (sizeof(__result) == 4) { u_int __i; __asm volatile ("movl %%fs:%1,%0":"=r" (__i):"m"(*(u_int *) (((size_t) (&((struct globaldata *) 0)->gd_curthread))))); __result = *(__typeof(((struct globaldata *) 0)->gd_curthread) *) & __i; } else { __result = *({ __typeof(((struct globaldata *) 0)->gd_curthread) * __p; __asm volatile ("movl %%fs:%1,%0; addl %2,%0":"=r" (__p):"m"(*(struct globaldata *) (((size_t) (&((struct globaldata *) 0)->gd_prvspace)))), "i"(((size_t) (&((struct globaldata *) 0)->gd_curthread)))); __p; }); } __result; }))), (void *)0x00000004)) _mtx_unlock_sleep(((((&((({ __typeof(((struct globaldata *) 0)->gd_curthread) __result; if (sizeof(__result) == 1) { u_char __b; __asm volatile ("movb %%fs:%1,%0":"=r" (__b):"m"(*(u_char *) (((size_t) (&((struct globaldata *) 0)->gd_curthread))))); __result = *(__typeof(((struct globaldata *) 0)->gd_curthread) *) & __b; } else if (sizeof(__result) == 2) { u_short __w; __asm volatile ("movw %%fs:%1,%0":"=r" (__w):"m"(*(u_short *) (((size_t) (&((struct globaldata *) 0)->gd_curthread))))); __result = *(__typeof(((struct globaldata *) 0)->gd_curthread) *) & __w; } else if (sizeof(__result) == 4) { u_int __i; __asm volatile ("movl %%fs:%1,%0":"=r" (__i):"m"(*(u_int *) (((size_t) (&((struct globaldata *) 0)->gd_curthread))))); __result = *(__typeof(((struct globaldata *) 0)->gd_curthread) *) & __i; } else { __result = *({ __typeof(((struct globaldata *) 0)->gd_curthread) * __p; __asm volatile ("movl %%fs:%1,%0; addl %2,%0":"=r" (__p):"m"(*(struct globaldata *) (((size_t) (&((struct globaldata *) 0)->gd_prvspace)))), "i"(((size_t) (&((struct globaldata *) 0)->gd_curthread)))); __p; }); } __result; })->td_proc))->p_mtx)))), (((0))), ((0)), ((0))); } while (0); } while (0); _sx_xunlock((&proctree_lock), 0, 0); exit1(({ __typeof(((struct globaldata *) 0)->gd_curthread) __result; if (sizeof(__result) == 1) { u_char __b; __asm volatile ("movb %%fs:%1,%0":"=r" (__b):"m"(*(u_char *) (((size_t) (&((struct globaldata *) 0)->gd_curthread))))); __result = *(__typeof(((struct globaldata *) 0)->gd_curthread) *) & __b; } else if (sizeof(__result) == 2) { u_short __w; __asm volatile ("movw %%fs:%1,%0":"=r" (__w):"m"(*(u_short *) (((size_t) (&((struct globaldata *) 0)->gd_curthread))))); __result = *(__typeof(((struct globaldata *) 0)->gd_curthread) *) & __w; } else if (sizeof(__result) == 4) { u_int __i; __asm volatile ("movl %%fs:%1,%0":"=r" (__i):"m"(*(u_int *) (((size_t) (&((struct globaldata *) 0)->gd_curthread))))); __result = *(__typeof(((struct globaldata *) 0)->gd_curthread) *) & __i; } else { __result = *({ __typeof(((struct globaldata *) 0)->gd_curthread) * __p; __asm volatile ("movl %%fs:%1,%0; addl %2,%0":"=r" (__p):"m"(*(struct globaldata *) (((size_t) (&((struct globaldata *) 0)->gd_prvspace)))), "i"(((size_t) (&((struct globaldata *) 0)->gd_curthread)))); __p; }); } __result; }), ((ecode) << 8 | (0))); } Ever wonder why the kernel gets slower and slower to compile? Ever compiled a 2.1 or 2.2 kernel on a modern machine and been shocked away by the speed? Count me in the 'curproc considered harmful' camp. (or curthread). Yes, this doesn't end up as a lot of code in the end, but the compiler still has to digest it and the optimizer has got to do a sh!tload of work to eliminate massive quantities of unused code. Just imagine what happens without -O. Regarding 64 bit machines, all of our 64 bit platforms use register passing, some with fixed size register frames. On those, the difference of saving one argument isn't going to add up to much, if anything. And it would still require an intermediate frame to hold the calculated value of curproc/curthread where its used. 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?20011111191735.00D053807>