Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 12 Nov 2001 17:32:12 +1100 (EST)
From:      Bruce Evans <bde@zeta.org.au>
To:        Peter Wemm <peter@wemm.org>
Cc:        Robert Watson <rwatson@FreeBSD.ORG>, <freebsd-arch@FreeBSD.ORG>
Subject:   Re: cur{thread/proc}, or not. 
Message-ID:  <20011112165530.B34657-100000@delplex.bde.org>
In-Reply-To: <20011111191735.00D053807@overcee.netplex.com.au>

next in thread | previous in thread | raw e-mail | index | archive | help
On Sun, 11 Nov 2001, Peter Wemm wrote:

> 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

> My gripe is that on i386, it creates a LOT of work for the compiler.

That's just an implementation detail for one arch.  I did strongly object
to the implementation, but...

> 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:

> [235 lines of bletcherous code deleted]

The corresponding code for RELENG_4 is:

Source:
---
void
kthread_exit(int ecode)
{
	proc_reparent(curproc, initproc);
	exit1(curproc, W_EXITCODE(ecode, 0));
}
---

Preprocssor output (!SMP case):
---
void
kthread_exit(int ecode)
{
	proc_reparent(curproc, initproc);
	exit1(curproc, (( ecode ) << 8 | (  0 )) );
}
---

Preprocssor output (SMP case):
---
void
kthread_exit(int ecode)
{
	proc_reparent(((  struct proc * )_global_curproc_nv())  , initproc);
	exit1(((  struct proc * )_global_curproc_nv())  , (( ecode ) << 8 | (  0 )) );
}
---

The preprocssor output didn't even need editing to look this nice.
_global_curproc_nv() is an inline function, so the compiler has more work
to do in the SMP case than might appear.  This function is:

	static __inline int _global_curproc_nv(void) { \
		int val; \
		__asm("movl %%fs:gd_curproc",%0" : "=r" (val)); \
		return (val); \
	} \

which is only about 10 times smaller than the corresponding code in
-current (it has one case instead of 4, and has a much simpler reference
to gd_curproc).

The size of the output in -current can be reduced by a factor of about
2 by copying curproc to a local variable.

> 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?

Better yet, compile a 2.1 or 2.2 kernel under 2.1 or 2.2 and get about 25%
more speed (mostly from not having pessimizations in gcc).

> Count me in the 'curproc considered harmful' camp.  (or curthread).

Count me ouside of it.

> 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.

Passing the pointer down through 20 subroutines (some of which don't
even use it except to pass it along) may add up to much.

Bruce


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?20011112165530.B34657-100000>