Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 2 Jul 1998 00:44:59 +0000 (GMT)
From:      Terry Lambert <tlambert@primenet.com>
To:        jabley@clear.co.nz (Joe Abley)
Cc:        freebsd-hackers@FreeBSD.ORG
Subject:   Re: pthreads
Message-ID:  <199807020045.RAA00880@usr07.primenet.com>
In-Reply-To: <Pine.BSF.3.96.980702080311.2083A-100000@buddha.clear.net.nz> from "Joe Abley" at Jul 2, 98 08:09:39 am

next in thread | previous in thread | raw e-mail | index | archive | help
> Does anybody know the background of posix thread support in FreeBSD? I
> can't seem to find any docs on the background anywhere...

John Birrell did a lot of hacking on Chris Provenzo's code.

Someone else (I forget; sorry) did hacking to mostly bring the
return codes up to the Draft 4 standard.

Jeremy Allison and I hacked various bits here and there to fix
ommissions here and there.

John Birrell rewrote lots of it in -current, with an eye toward
bringing the code up to the Draft 10 standard (the ratified standard),
and he and John Dyson did a lot of work to support a kernel
implementation, also in -current, using rfork() and some rather
complicated stack management.

John Dyson did a number of patches for CPU affinity and a number of
other things, which were necessary to make a kernel implementation
useful at all (so far as I know, these were distributed from his
FreeBSD home directory, so they have sonce been removed from
circulation.  8-(.  Someone correct me if they snagged a copy before
that happened and are willing to share).

That's basically the abridged history of pthreads.


> I'm interested in a couple of issues.
> 
> 1. On Solaris, to compile a pthreaded program, I stick a
> 
>   #define _REENTRANT
>   #include <pthread.h>
> 
> at the top of the source files, and link with -lpthread. With FreeBSD the
> linking phase is more involved, since I need to exclude the standard C
> libraries and link with libc_r instead.

The libc_r will be linked before the default libc.  You do *not* need
to exclude the standard libc.

For FreeBSD, you can:

	#define _THREADSAFE
	#include <pthread.h>

This basically #define's errno to make it per-thread, and little else.

This step is not necessary under -current, which unconditionally
defines errno (the source of the "undefined: __error" complaints).

If you add:

	CFLAGS+= -pthread

All the library mumbo-jumbo will be done for you.


> Why was the decision made to support pthreads in this manner?

The difference is the name: "libpthread.a" vs. "libc_r.a".


> What benefits does this have over the Solaris way of doing things?

None (except in the new order of things in -current, you don't need
a "#define _THREADSAFE", and sun still needs "_REENTRANT").


> 2. Should I really be using the 2.2.6-RELEASE libc_r pthread support, or
> should I be looking at Chris Provenzano's pmpthreads?

The 2.2.6-RELEASE libc_r pthread support is Draft 4.  There are a few
known bugs (mostly to do with signals -- a singla is delivered to the
running thread if it hasn't masked it.  You are supposed to mask the
signals in all threads except the one you designate a handler for the
signal in question.  This is POSIX behaviour).


The "Draft 4" nature of the code means that you can't statically
initialize mutexes, and that the "attr" argument to "pthread_create"
is the address of the address of the attr, instead of just the address;
there are other subtle differences that are explained in the
O'Reilly book in gory detail.

Effectively, you can test for a Draft 4 using the manifest constant
PTHREAD_MUTEX_INITIALIZER to enable the code to run on both Draft 10
(standard) and Draft 4 systems (such as FreeBSD and SGI) like so:

#ifdef PTHREAD_MUTEX_INITIALIZER
                /*
                 * This is a draft 10 or standard pthreads implementation
                 */
                if ( pthread_create( &listener_tid, attr, (void *) daemon,
                    (void *) port ) != 0 ) {
                        exit( 1 );
                }
#else   /* !PTHREAD_MUTEX_INITIALIZER*/
                /*
                 * This is a draft 4 or earlier pthreads implementation
                 */
                if ( pthread_create( &listener_tid, &attr, (void *) daemon,
                    (void *) port ) != 0 ) {
                        exit( 1 );
                }
#endif  /* !PTHREAD_MUTEX_INITIALIZER*/


You should also be aware that if you are using g++ with exceptions, in
order to get per thread exception stacks, you will need to use the
ports g++ 2.8.1, which was patched by Jeremy.


If you are attempting to use STL in combination with pthreads, well...
don't use the GNU STL code, it's broken!  Use the Moscow Center for
SPARC computing code.  There are Draft 4 issues with the mutex
initialization which are pretty easy to hack around using static
constructors.



> I'm by no means any kind of expert on posix threads; I've just been
> working on some code which compiled but refused to run properly on
> FreeBSD. Moving the code to Solaris (and removing all the nice BSD
> networking code which Sun have seen fit not to support on Solaris), it
> compiled and worked fine, no problems.
> 
> I'm not asking for help with my code... Just some pointers on the history
> of pthread support in FreeBSD.

Hopefully this will answer your questions enough to get you running.


					Terry Lambert
					terry@lambert.org
---
Any opinions in this posting are my own and not those of my present
or previous employers.

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-hackers" in the body of the message



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