* How is pthread_self() implemented?
@ 2003-08-31 17:52 Chris Seaton
2003-09-01 4:33 ` Ross Johnson
0 siblings, 1 reply; 5+ messages in thread
From: Chris Seaton @ 2003-08-31 17:52 UTC (permalink / raw)
To: pthreads-win32
I'm writing my own (very lightweight) threading library for Windows and
POSIX threads. There are reasons why I can't use pthreads-win32, but
they aren't important here. I'm currently implementing a ThisThread()
routine. With POSIX threads I simply call pthread_self(), but I'm stuck
for Windows.
Originally I called GetCurrentThread(), but that returns a pseudo
handle, so I call DuplicateHandle(), as this pthreads-win32 library
uses.
However, DuplicateHandle() creates a new handle every time it is called,
so I can't compare them. Basically
ThisThread() != ThisThread()
How does the pthreads-win32 library solve this problem?
--
Chris Seaton
chris@chrisseaton.com
http://www.chrisseaton.com/
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: How is pthread_self() implemented?
2003-08-31 17:52 How is pthread_self() implemented? Chris Seaton
@ 2003-09-01 4:33 ` Ross Johnson
2003-09-01 4:41 ` Will Bryant
0 siblings, 1 reply; 5+ messages in thread
From: Ross Johnson @ 2003-09-01 4:33 UTC (permalink / raw)
To: Chris Seaton; +Cc: pthreads-win32
Chris Seaton wrote:
>I'm writing my own (very lightweight) threading library for Windows and
>POSIX threads. There are reasons why I can't use pthreads-win32, but
>they aren't important here. I'm currently implementing a ThisThread()
>routine. With POSIX threads I simply call pthread_self(), but I'm stuck
>for Windows.
>
>Originally I called GetCurrentThread(), but that returns a pseudo
>handle, so I call DuplicateHandle(), as this pthreads-win32 library
>uses.
>
>However, DuplicateHandle() creates a new handle every time it is called,
>so I can't compare them. Basically
>
>ThisThread() != ThisThread()
>
>How does the pthreads-win32 library solve this problem?
>
>
Pthreads-win32 keeps a POSIX thread struct in which it stores the handle
returned by the original Win32 CreateThread(). The pointer to the POSIX
struct is kept in TLS (TSD) so that other pthread library functions can
refer to that struct.
John Bossom's original design also allows for pre-existing Win32 threads
to use any POSIX routines, and therefore fully interact with POSIX
threads, by creating a one-time-only on-the-fly detached POSIX thread
handle for the Win32 thread. In this case, the library uses
DuplicateHandle(), which is sufficient for our purposes.
This is the logic you'll see in pthread_self.c at the following URL (all
one line):
http://sources.redhat.com/cgi-bin/cvsweb.cgi/pthreads/pthread_self.c?rev=1.2&content-type=text/x-cvsweb-markup&cvsroot=pthreads-win32
Regards.
Ross
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: How is pthread_self() implemented?
2003-09-01 4:33 ` Ross Johnson
@ 2003-09-01 4:41 ` Will Bryant
2003-09-01 7:22 ` Ross Johnson
0 siblings, 1 reply; 5+ messages in thread
From: Will Bryant @ 2003-09-01 4:41 UTC (permalink / raw)
To: pthreads-win32
> John Bossom's original design also allows for pre-existing Win32 threads
> to use any POSIX routines, and therefore fully interact with POSIX
> threads, by creating a one-time-only on-the-fly detached POSIX thread
> handle for the Win32 thread.
So it is safe to use all pthreads-win32 functions from threads not created
using the pthreads interface? I have an application where nearly all of the
code only needs to use standard windows threads, but there are a couple of
condition variables that I'd like to be able to use...
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: How is pthread_self() implemented?
2003-09-01 4:41 ` Will Bryant
@ 2003-09-01 7:22 ` Ross Johnson
2003-09-01 15:49 ` Ross Johnson
0 siblings, 1 reply; 5+ messages in thread
From: Ross Johnson @ 2003-09-01 7:22 UTC (permalink / raw)
To: Will Bryant; +Cc: pthreads-win32
Will Bryant wrote:
>>John Bossom's original design also allows for pre-existing Win32 threads
>>to use any POSIX routines, and therefore fully interact with POSIX
>>threads, by creating a one-time-only on-the-fly detached POSIX thread
>>handle for the Win32 thread.
>>
>>
>
>So it is safe to use all pthreads-win32 functions from threads not created
>using the pthreads interface? I have an application where nearly all of the
>code only needs to use standard windows threads, but there are a couple of
>condition variables that I'd like to be able to use...
>
Note that non-POSIX threads are regarded by pthreads-win32 as detached
and deferred-cancelable initially. However, I don't think there's any
reason a non-POSIX thread can't subsequently change it's cancelability
type. There's no way it can make itself joinable though. Apart from
that, just about everything should work.
In particular, for condition variables I haven't proven the following
but I believe it should all work properly. And since this should work,
then so should POSIX read-write locks. Note that you odn't need to
explicitly call pthread_self() unless you need the POSIX thread handle.
Any routine that needs it internally will cause the POSIX handle to be
created implicitly.
// Global
pthread_t posixGuest[MAX_GUESTS];
pthread_mutex_t CVLock = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t CV = PTHREAD_COND_INITIALIZER;
int champaigneChilled = 0;
int cakeIced = 0;
int chaos = 0;
int mayhem = 0;
long guest = 0;
// Thread A (Win32 or POSIX thread):
// Party guest thread
...
if ((guest = InterLockedIncremement(&guest)) >= MAX_GUESTS)
return(gateCrasher);
posixGuest[guest] = pthread_self(); // Only needed sometimes e.g.
see thread D
// Mingle
pthread_mutex_lock(&CVLock);
pthread_cleanup_push(pthread_mutex_unlock(&CVLock));
while ( ! (champaigneChilled && cakeIced ) ) {
pthread_cond_wait(&CV, &CVLock);
}
pthread_cleanup_pop(1);
toastBirthdaySubject();
eatCake();
...
// Thread B (Win32 or POSIX thread):
// Ice cake thread
...
cakeIced = 1;
pthread_cond_broadcast(&CV);
...
// Thread C (Win32 or POSIX thread):
// Chill champaigne thread
...
champaigeChilled = 1;
pthread_cond_broadcast(&CV);
...
// Thread D (Win32 or POSIX thread):
// Monitor party thread
...
if (chaos && meyhem) {
// Evict our guests
for (i = 0; i < MAX_GUESTS && pthread_kill(posixGuest[i], 0) ==
0; i++)
pthread_cancel(posixGuest[i]);
}
...
Regards.
Ross
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: How is pthread_self() implemented?
2003-09-01 7:22 ` Ross Johnson
@ 2003-09-01 15:49 ` Ross Johnson
0 siblings, 0 replies; 5+ messages in thread
From: Ross Johnson @ 2003-09-01 15:49 UTC (permalink / raw)
To: rpj; +Cc: Will Bryant, pthreads-win32
Ross Johnson wrote:
> Will Bryant wrote:
>
>>> John Bossom's original design also allows for pre-existing Win32
>>> threads
>>> to use any POSIX routines, and therefore fully interact with POSIX
>>> threads, by creating a one-time-only on-the-fly detached POSIX thread
>>> handle for the Win32 thread.
>>>
>>
>>
>> So it is safe to use all pthreads-win32 functions from threads not
>> created
>> using the pthreads interface? I have an application where nearly all
>> of the
>> code only needs to use standard windows threads, but there are a
>> couple of
>> condition variables that I'd like to be able to use...
>>
> Note that non-POSIX threads are regarded by pthreads-win32 as detached
> and deferred-cancelable initially. However, I don't think there's any
> reason a non-POSIX thread can't subsequently change it's cancelability
> type. There's no way it can make itself joinable though. Apart from
> that, just about everything should work.
>
> In particular, for condition variables I haven't proven the following
> but I believe it should all work properly. And since this should work,
> then so should POSIX read-write locks. Note that you odn't need to
> explicitly call pthread_self() unless you need the POSIX thread
> handle. Any routine that needs it internally will cause the POSIX
> handle to be created implicitly.
When I thought about this some more I realised that you won't be able to
cancel an 'implicit' POSIX thread as I've claimed in the code below.
Cancelation in pthreads-win32 depends on establishing a setjmp point (or
a catch clause in the case of the C++/SEH versions of the library). This
is done inside of the POSIX thread startup code and so there won't be
one for 'implicit' POSIX threads.
For now therefore, the library should probably be fixed to initialise
'implicit' POSIX handles with cancelation type PTHREAD_CANCEL_DISABLE,
and prevent threads from changing this value subsequently.
Otherwise, the rest of it should work.
Regards.
Ross
>
> // Global
>
> pthread_t posixGuest[MAX_GUESTS];
> pthread_mutex_t CVLock = PTHREAD_MUTEX_INITIALIZER;
> pthread_cond_t CV = PTHREAD_COND_INITIALIZER;
> int champaigneChilled = 0;
> int cakeIced = 0;
> int chaos = 0;
> int mayhem = 0;
> long guest = 0;
>
> // Thread A (Win32 or POSIX thread):
>
> // Party guest thread
> ...
> if ((guest = InterLockedIncremement(&guest)) >= MAX_GUESTS)
> return(gateCrasher);
> posixGuest[guest] = pthread_self(); // Only needed sometimes
> e.g. see thread D
> // Mingle
> pthread_mutex_lock(&CVLock);
> pthread_cleanup_push(pthread_mutex_unlock(&CVLock));
> while ( ! (champaigneChilled && cakeIced ) ) {
> pthread_cond_wait(&CV, &CVLock);
> }
> pthread_cleanup_pop(1);
>
> toastBirthdaySubject();
> eatCake();
> ...
>
> // Thread B (Win32 or POSIX thread):
>
> // Ice cake thread
> ...
> cakeIced = 1;
> pthread_cond_broadcast(&CV);
> ...
>
> // Thread C (Win32 or POSIX thread):
>
> // Chill champaigne thread
> ...
> champaigeChilled = 1;
> pthread_cond_broadcast(&CV);
> ...
>
> // Thread D (Win32 or POSIX thread):
>
> // Monitor party thread
> ...
> if (chaos && meyhem) {
> // Evict our guests
> for (i = 0; i < MAX_GUESTS && pthread_kill(posixGuest[i], 0) ==
> 0; i++)
> pthread_cancel(posixGuest[i]);
> }
> ...
>
>
> Regards.
> Ross
>
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2003-09-01 15:49 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2003-08-31 17:52 How is pthread_self() implemented? Chris Seaton
2003-09-01 4:33 ` Ross Johnson
2003-09-01 4:41 ` Will Bryant
2003-09-01 7:22 ` Ross Johnson
2003-09-01 15:49 ` Ross Johnson
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).