Skip site navigation (1)Skip section navigation (2)
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>