[fpc-devel] threadvar implementation

"Vinzent Höfler" JeLlyFish.software at gmx.net
Wed Aug 4 21:40:59 CEST 2010

Von: Michael Schnell <mschnell at lumino.de>:

> As Pascal (other than C) does not provide a means to define that a 
> pointer type is a pointer to a threadvar rather than to a normal var, 
> Pascal alway uses DS to access any variable.

JFTR, plain vanilla C (i.e. ISO C99) does not even have a notion of a "thread variable", because it doesn't have threads. So I don't know what C you're referring to here.

> > - test yourself. It may be possible to get that address also with an 
> > LEA instruction (untested). 
> I did the test.

No need to. The segment value is not used by LEA. It calculates the "effective address" which basically means the offset.

>    lea eax, FS:[$34] resulst in EAX = $34, even though FS is $3B and
>    mov eax, FS:[$34] results in correctly loading ax from memory and
>    mov eax,[eax] with eax = $34 correctly results in an access violation
> in fact I did not suppose that
>    lea eax, FS:[$34] would compile at all but it does
>    the code of lea eax, FS:[$34]  is 64 8D 05 34 00 00 00, using the DS 
> prefix "64" while

I'm sure you meant "FS prefix". DS doesn't have one AFAIR.

>    the code of lea eax, $34]        is     8D 05 34 00 00 00
> I don't see what lea eax, FS:[$34] in fact is supposed to do.

Loading the effective address. Any decent assembler could "optimize" that code into a "mov eax, 34h".

> to read a normal var it needs to do
>    mov eax, normvar; (this is implicitely DS based)
> to get the pointer to a normal var it needs to do
>   lea eax, normalvar; (this is implicitely DS based)
>   to read a threadvar, it needs to do
>   mov eax, FS:(threadmanagementblock+thrfeafvarblockoffset); (this 
> results in the DS-based address of the threadvar block)
>   mov eax, [eax+threadvar]

Or do that beforehand and "simply" store the pointer to the threadvar. This must be done anyway, because via pointer is the only way to reference a threadvar.

That means that:

threadvar x : Integer;

var       y : ^Integer;

should result in a proper initialization of "x" by the compiler when a thread is started and references would implicitly change like this:

x := 1;  => x^ := 1;
y := @x; => y  := x;

In that way, there is not even the notion of a "pointer to a threadvar" needed, because the compiler can handle that transparently like another reference type.

Actually, I was under the impression that the compiler does exactly such a transformation already.


GMX DSL: Internet-, Telefon- und Handy-Flat ab 19,99 EUR/mtl.  
Bis zu 150 EUR Startguthaben inklusive! http://portal.gmx.net/de/go/dsl

More information about the fpc-devel mailing list