Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 8 Aug 2014 14:22:01 +0300
From:      Konstantin Belousov <kostikbel@gmail.com>
To:        "Ivan A. Kosarev" <ivan@ivan-labs.com>
Cc:        freebsd-current@freebsd.org
Subject:   Re: libthr and main thread stack size
Message-ID:  <20140808112201.GC93733@kib.kiev.ua>
In-Reply-To: <53E48B38.9010607@ivan-labs.com>
References:  <53E36E84.4060806@ivan-labs.com> <20140808052807.GB93733@kib.kiev.ua> <53E48B38.9010607@ivan-labs.com>

next in thread | previous in thread | raw e-mail | index | archive | help

--S7dBYt2qcX9qS6Ih
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable

On Fri, Aug 08, 2014 at 12:32:56PM +0400, Ivan A. Kosarev wrote:
>=20
> On 08/08/2014 09:28 AM, Konstantin Belousov wrote:
> > On Thu, Aug 07, 2014 at 04:18:12PM +0400, Ivan A. Kosarev wrote:
> >> Hello,
> >>
> >> According to libthr's thr_init.c (the 9.2 version) init_main_thread()
> >> allocates s.c. "red zone" below the main stack in order to protect oth=
er
> >> stacks. The size of the main stack is determined by the
> >> _thr_stack_initial variable that is declared extern though it doesn't
> >> seem it can be changed. The value of the variable is set to 4M on 64-b=
it
> >> platforms which is obviously not sufficient for the most of real progr=
ams.
> >>
> >> Can anyone please confirm that there is no way to increase the stack
> >> size for the main thread and thus any program linked against libthr has
> >> only a few megabytes of stack memory for its main thread--whatever the
> >> system stack size (ulimit -s) is set to?
> > Yes, there is no way to change the main thread stack clamping.
> > Could you provide a reasonable use case for the 4MB stack ?
>=20
> Traversing trees with recursive functions or on-stack grammar parsers?
>=20
> >
> > Anyway, I somewhat sympathize to the idea to stop clamping the main
> > thread stack, and to not reuse it for other threads stack carving.
> > This also means that non-main threads stack allocator should stop
> > tracking the explicit location for the stacks and rely on vm mmap(2)
> > base selection instead.
>=20
> Yes, that would solve the problem.
>=20
> > I do not know the motivations why the current scheme of stacks allocati=
on
> > was chosen.  The changes do not look too involved.
In fact, I can resonably explain the current behaviour. The motivation
seems to come from desire to interpret the RLIMIT_STACK as the global
limit to the stack usage by all threads. From this PoV, it becomes clean
why the other thread stacks are carved from the main stack.

Of course, it does not quite work this way, because there is no check
that we did not overflowed from the main stack area.

>=20
> Thanks a lot.
>=20

Below is the patch which adds environment variable LIBPTHREAD_BIGSTACK_MAIN.
Setting it to any value results in the main thread stack left as is, and
other threads allocate stack below the area of RLIMIT_STACK.  Try it.
I do not want to set this behaviour as default.

diff --git a/lib/libthr/thread/thr_init.c b/lib/libthr/thread/thr_init.c
index 937d83f..9bf0e29 100644
--- a/lib/libthr/thread/thr_init.c
+++ b/lib/libthr/thread/thr_init.c
@@ -37,6 +37,7 @@
 #include <sys/types.h>
 #include <sys/signalvar.h>
 #include <sys/ioctl.h>
+#include <sys/resource.h>
 #include <sys/sysctl.h>
 #include <sys/ttycom.h>
 #include <sys/mman.h>
@@ -441,6 +442,7 @@ init_main_thread(struct pthread *thread)
 static void
 init_private(void)
 {
+	struct rlimit rlim;
 	size_t len;
 	int mib[2];
 	char *env;
@@ -471,6 +473,12 @@ init_private(void)
 		len =3D sizeof (_usrstack);
 		if (sysctl(mib, 2, &_usrstack, &len, NULL, 0) =3D=3D -1)
 			PANIC("Cannot get kern.usrstack from sysctl");
+		env =3D getenv("LIBPTHREAD_BIGSTACK_MAIN");
+		if (env !=3D NULL) {
+			if (getrlimit(RLIMIT_STACK, &rlim) =3D=3D -1)
+				PANIC("Cannot get stack rlimit");
+			_thr_stack_initial =3D rlim.rlim_cur;
+		}
 		len =3D sizeof(_thr_is_smp);
 		sysctlbyname("kern.smp.cpus", &_thr_is_smp, &len, NULL, 0);
 		_thr_is_smp =3D (_thr_is_smp > 1);
diff --git a/lib/libthr/thread/thr_stack.c b/lib/libthr/thread/thr_stack.c
index 15a9c82..e5d149e 100644
--- a/lib/libthr/thread/thr_stack.c
+++ b/lib/libthr/thread/thr_stack.c
@@ -246,7 +246,10 @@ _thr_stack_alloc(struct pthread_attr *attr)
 		THREAD_LIST_UNLOCK(curthread);
 	}
 	else {
-		/* Allocate a stack from usrstack. */
+		/*
+		 * Allocate a stack from or below usrstack, depending
+		 * on the LIBPTHREAD_BIGSTACK_MAIN env variable.
+		 */
 		if (last_stack =3D=3D NULL)
 			last_stack =3D _usrstack - _thr_stack_initial -
 			    _thr_guard_default;
@@ -268,7 +271,7 @@ _thr_stack_alloc(struct pthread_attr *attr)
=20
 		/* Map the stack and guard page together, and split guard
 		   page from allocated space: */
-		if ((stackaddr =3D mmap(stackaddr, stacksize+guardsize,
+		if ((stackaddr =3D mmap(stackaddr, stacksize + guardsize,
 		     _rtld_get_stack_prot(), MAP_STACK,
 		     -1, 0)) !=3D MAP_FAILED &&
 		    (guardsize =3D=3D 0 ||

--S7dBYt2qcX9qS6Ih
Content-Type: application/pgp-signature

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2

iQIcBAEBAgAGBQJT5LLYAAoJEJDCuSvBvK1BYLEP/2FBbRhmS3++NiwcdGMeTSNR
Y5wwAqMg0jP1uOaqUyoB4ee0LfizdGm1ihEz32LABPk8jPMzEdTHeUnoeqxWDN1G
/goxKuZK+VjI9DfaqSLxKOob5/GlgCbZY0cqiKnriXsf2i5sQJN6EIN4YBzoxX2M
VMj06wRVQvaLnNRAu3qmGh2IeZcJs2neiBfi6iuv3OU4tIF/Uh9c3h0DBNzkSvvB
2ad3gHU8JHPvX4+L5qy4hFsPAoqEA9HeGViXmugSgIIPaVN5H4yiebX51QvJb5Cu
KpTll/8pBB1WwQ5YROgrRBgf2pZDSXQPGtIg7GVjJd9yLqfrOPJouwyfQj6WlFH0
rgbj3q9MZMdX6HZwfZ7cWr+aS2uHujwA6fMDLPP47qz8ulfxOR3Mk03ly2WrI20d
aW71MfQ9Zq2YNsQ2M/cWrt2YzcF6twdmSw5iRKYRVlbjmQiGLeNlBxbB2xoUvyQL
FO5jWXkD3xjPch1TS7c91w60JSiD3/NDiw1zgRcnSePnD9roZXnkbPIm77Z0g9Fs
cdmVw8vxTkw6gglrm2hINbGOCQuX2vYhGS7DL4E1Q1+/M8Oel+CS1BLaoIOJFZwZ
i2+RdZBEbpJoHzZIlx/NKslXyoh98ZMiOndW0Ya5HGxy+1QHRyEeY0OUzoXK/8Qk
jovMXS+iJ6kM/KCE62zo
=89Ms
-----END PGP SIGNATURE-----

--S7dBYt2qcX9qS6Ih--



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