Web lists-archives.com

Re: [Mingw-users] GCC-4.9.3 is now our current release

Hello Ralph!

Nice bit of archaeology!

On Fri, Mar 18, 2016 at 7:35 AM, ralph engels <ralphengels@xxxxxxxxx> wrote:
> Hard finding much info about why they decided to use a struct,
> but i managed to dig up a really old thread on google about it.
>> Originally pthread_t was defined as a pointer (to the opaque pthread_t_
>> struct) and later it was changed to a struct containing the original
>> pointer plus a sequence counter. This is allowed under both the original
>> POSIX Threads Standard and the current Single Unix Specification.

According to my understanding, this is true (at least for POSIX).  I believe
that POSIX only requires that pthread_t be an "opaque handle," i.e., you
can't assume anything about what it is (other than that it has value

So, pthreads-win32 is POSIX compliant.  However, from recollection, the
winpthreads guys say that there is a lot of pthreads code "in the wild"
that tacitly assumes that pthread_t is a scalar.  So, even though
pthreads-win32 is POSIX compliant, it breaks a lot of real-world code
(with gcc's std::thread implementation being one minor, easily-fixable
example).  Their view (from recollection) is that a scalar pthread_t is
the de facto standard, even if not technically required by POSIX, so
making pthread_t be a scalar was one of their motivations for writing

(Personally I don't care.  I hardly ever use pthreads, and my interest
was in std::thread on windows.)

>> When pthread_t is a simple pointer to a struct some very difficult to
>> debug problems arise from the process of freeing and later allocing
>> thread structs because new pthread_t handles can acquire the identity of
>> previously detached threads.

I had speculated something along these lines.  As I understand what they're
saying, if pthread_t is a pointer to some sort of thread struct, then,
by chance,
the memory for a thread that is detached, has exited, and has been deallocated
could get reused for a new thread, so that for two pthread_t's, t1 and t2

   t1 (old, detached, exited, and deallocated)  == t1 (new, live thread)

which could presumably break something.  Making pthread_t a struct that
contains the pointer and also some sort of uniqueness counter would fix
this (barring wrap-around of the uniqueness counter).

>> The change to a struct was made, along with
>> some changes to their internal managment, in order to guarantee (for
>> practical applications) that the pthread_t handle will be unique over the
>> life of the running process.
>> Where application code attempts to compare one pthread_t against another
>> directly, a compiler error will be emitted because structs can't be
>> compared at that level.

Indeed as happens when compiling gcc's std::thread implementation against

>> This should signal a potentially serious problem
>> in the code design, which would go undetected if pthread_t was a scalar.
>> The POSIX Threading API provides a function named pthread_equal() to
>> compare pthread_t thread handles.
>> Other pthreads implementations, such as Sun's, use an int as the handle
>> but do guarantee uniqueness within the process scope.

Sounds good.

I wonder how winpthreads does it.  Does it use some sort of unique integer
handle (that is guaranteed to stay unique even when detached threads exit)?
Or do they use a pointer to a thread struct that might not be unique in the
presence of dead threads?

>> Win32 scalar typed
>> thread handles also guarantee uniqueness in system scope.

I understand threads to be part of a single process, so I wouldn't
care whether thread handles are unique cross-process (but perhaps
the windows os or some microsoft apps rely on system-wide uniqueness
of thread handles for some reason).

>> It wasn't clear
>> how well the internal management of these handles would scale as the
>> number of threads and the fragmentation of the sequence numbering
>> increased for applications where thousands or millions of threads are
>> created and detached over time. The current management of threads within
>> pthreads-win32 using structs for pthread_t, and reusing without ever
>> freeing them, reduces the management time overheads to a constant, which
>> could be important given that pthreads-win32 threads are built on top of
>> Win32 threads and will therefore include that management overhead on top
>> of their own. The cost is that the memory resources used for thread
>> handles will remain at the peak level until the process exits.

I didn't know this.  In practice, it shouldn't be a problem.  It's not exactly
a leak, because the dead thread handles get reused for new threads.

>> While it may be inconvenient for developers to be forced away from making
>> assumptions about the internals of pthread_t,

And as I understand it, the winpthreads guys elected not to impose this
inconvenience on their users.

>> the advantage for the
>> future development of pthread-win32, as well as those applications that
>> use it and other pthread implementations, is that the library is free to
>> change pthread_t internals and management as better methods arise.
> so it seems the .p pointer is actually correct as pr the description p
> is the original pointer from back before they changed it.
> I think i can close the book on it now :) but was nice to have
> confirmation before we start rolling it out.
> Thanks for your help.

Thanks for finding this very nice description of what's going on with
pthreads-win32, and why they made their particular design decisions.

> Regards Ralph Engels

Happy Mulit-Threaded Hacking!

K. Frank

Transform Data into Opportunity.
Accelerate data analysis in your applications with
Intel Data Analytics Acceleration Library.
Click to learn more.
MinGW-users mailing list

This list observes the Etiquette found at 
We ask that you be polite and do the same.  Disregard for the list etiquette may cause your account to be moderated.

You may change your MinGW Account Options or unsubscribe at:
Also: mailto:mingw-users-request@xxxxxxxxxxxxxxxxxxxxx?subject=unsubscribe