Both Microsoft and windows compilers support thread local storage.  *If*
you guys go with the threading model and *if* it does not introduce any
serious portability issues with gcc (big ifs, and I'm not familiar with
gcc), than IMO TLS is really the way to go.  I don't think any
reorganization of postgres's static variables is necessary.  TLS is
implemented in the win32 API, not the C Libs, so by giving up the syntax
sugar you can make direct calls and keep compiler independence in win32.

Microsoft syntax is __desclspec(thread) and Borland syntax is simply
__thread.  All TLS variables *must* be static (or implicitly static
through extern, i.e. no 'auto' variables) and their addresses can not be
assumed to be constant.  

Taking addresses of TLS variables should be considered illegal, as well
as pointers to TLS variables.  Another gotcha is that DLLs that have
__thread variables will GPF if loaded with LoadLibrary (they should be
static linked).  Of course, pg does not use dlls, but it's worth noting.

Merlin

Thu, 25 Sep 2003 15:48:43 -0400
"Merlin Moncure" <merlin.moncure@rcsonline.com>
Re: [HACKERS] Threads vs Processes 
Actually you can use a DLL with LoadLibrary as long as you do the following.

When a process uses load-time linking with this DLL, the entry-point
function is sufficient to manage the thread local storage. Problems can
occur with a process that uses run-time linking because the entry-point
function is not called for threads that exist before the LoadLibrary
function is called, so TLS memory is not allocated for these threads. The
following example solves this problem by checking the value returned by the
TlsGetValue function and allocating memory if the value indicates that the
TLS slot for this thread is not set.

LPVOID lpvData; 
 
// Retrieve a data pointer for the current thread.
 
lpvData = TlsGetValue(dwTlsIndex); 
 
// If NULL, allocate memory for this thread.
 
if (lpvData == NULL) 
{ 
    lpvData = (LPVOID) LocalAlloc(LPTR, 256); 
    if (lpvData != NULL) 
        TlsSetValue(dwTlsIndex, lpvData); 
}

Unless gcc has extension as Borland and Microsoft do you will have to
utilize the API and not the compiler/linker customizations that make access
variables declared as __declspec(thread) or __thread under Borland.

Keith

-----Original Message-----
From: pgsql-hackers-owner@postgresql.org
[mailto:pgsql-hackers-owner@postgresql.org] On Behalf Of Merlin Moncure
Sent: Thursday, September 25, 2003 2:49 PM
To: Tom Lane
Cc: pgsql-hackers@postgresql.org; pgsql-hackers-win32@postgresql.org; Bruce
Momjian; Shridhar Daithankar; Claudio Natoli
Subject: Re: [HACKERS] Threads vs Processes 


Both Microsoft and windows compilers support thread local storage.  *If* you
guys go with the threading model and *if* it does not introduce any serious
portability issues with gcc (big ifs, and I'm not familiar with gcc), than
IMO TLS is really the way to go.  I don't think any reorganization of
postgres's static variables is necessary.  TLS is implemented in the win32
API, not the C Libs, so by giving up the syntax sugar you can make direct
calls and keep compiler independence in win32.

Microsoft syntax is __desclspec(thread) and Borland syntax is simply
__thread.  All TLS variables *must* be static (or implicitly static through
extern, i.e. no 'auto' variables) and their addresses can not be assumed to
be constant.  

Taking addresses of TLS variables should be considered illegal, as well as
pointers to TLS variables.  Another gotcha is that DLLs that have __thread
variables will GPF if loaded with LoadLibrary (they should be static
linked).  Of course, pg does not use dlls, but it's worth noting.

Merlin

---------------------------(end of broadcast)---------------------------
TIP 5: Have you checked our extensive FAQ?

               http://www.postgresql.org/docs/faqs/FAQ.html


Thu, 25 Sep 2003 15:03:57 -0500
"Keith Bottner" <kbottner@comcast.net>
Re: [HACKERS] Threads vs Processes 
"Merlin Moncure" <merlin.moncure@rcsonline.com> writes:
> All TLS variables *must* be static (or implicitly static
> through extern, i.e. no 'auto' variables)

I assume you mean static as in not-auto, rather than static as in
not-global.  Otherwise we have a problem here.

> and their addresses can not be
> assumed to be constant.

Surely the addresses can be assumed constant within a thread.  Otherwise
we have a problem here too.

> Taking addresses of TLS variables should be considered illegal,

Sorry, no can accept that restriction.

			regards, tom lane

Thu, 25 Sep 2003 19:15:00 -0400
Tom Lane <tgl@sss.pgh.pa.us>
Re: [HACKERS] Threads vs Processes 
Tom Lane wrote:
> I assume you mean static as in not-auto, rather than static as in
> not-global.  Otherwise we have a problem here.
[...]
> Surely the addresses can be assumed constant within a thread.  Otherwise
> we have a problem here too.
[...]
>>Taking addresses of TLS variables should be considered illegal,
> Sorry, no can accept that restriction.
> 

I think you are okay on all 3 fronts,
from http://gcc.gnu.org/onlinedocs/gcc/Thread-Local.html#Thread-Local :

"The __thread specifier may be used alone, with the extern or static 
specifiers, but with no other storage class specifier. When used with 
extern or static, __thread must appear immediately after the other 
storage class specifier."

and

"When the address-of operator is applied to a thread-local variable, it 
is evaluated at run-time and returns the address of the current thread's 
instance of that variable. An address so obtained may be used by any 
thread. When a thread terminates, any pointers to thread-local variables 
in that thread become invalid."

Also see "ISO/IEC 9899:1999 Edits for Thread-Local Storage" :
http://gcc.gnu.org/onlinedocs/gcc/C99-Thread-Local-Edits.html#C99%20Thread-Local%20Edits

and ELF Handling For Thread-Local Storage,
http://people.redhat.com/drepper/tls.pdf may be of interest.

Cheers,
Kurt.



Fri, 26 Sep 2003 15:52:11 +1200
Kurt at DBC <kurtw@dbc.co.nz>
Re: [HACKERS] Threads vs Processes