Michael Schnell schrieb:
What makes you think that this is different from x86?
With X86/32 Linux, the "application"address of a threadvar
Please distinguish: Segmented or Flat address?
Only FS and GS can add an non-zero offset, to the *offset* given in the
instruction. The sum of both is the flat "address" (effectively another
offset), that can be stored in a pointer variable. In 32/64 bit flat
memory models all pointers are "near", i.e. they don't include an
segment selector, and a zero-based segment is implied (DS...).
in the ASM
instruction is the same for all threads. The ASM instruction is done
with a "GS:" prefix, thus instead of the DS sector, (that is used
without the prefix), GS is used as a selector. Now the 16 bit selector
reads an entry in an OS-provided table and same is added to the address
given in the instruction. The OS provides a different table for each
thread and thus the resulting memory address is different, even though
the GS selector value itself is the same for each thread.
Thus GS provides an thread specific segment offset, to an block (record)
of threadvars.
With X86/32 Windows, the "application"address of a thread var in the ASM
instruction is the same for all threads, as well. The access is done
reading a structure that exists for each thread, using the "FS:" prefix
in the ASM instruction (this results in using the appropriate thread's
structure, as - like with Linux - the OS provides a different selecting
table for each thread and thus the resulting memory address is
different, even though the FS selector value itself is the same for each
thread.
Here FS provides the thread specific segment offset.
Now the threadvar is accessed using this pointer and the
standard DS selector. One indirection more than is Linux, slightly less
efficient.
I.e. the intermediate result is a pointer to an block (record) of
threadvars.
With NIOS (and supposedly similar with ARM), there is no "selector"
hardware. Instead, one of the 32 registers (R26, called GP ("General
Pointer") ) is used to address normal static and global variables. Now
another register (R23) is used to address threadvars. Within a running
application the value of R26 is always the same, while the value of R23
is different for each thread (of course all registers are preemption-safe).
Here a register provides the offset to the block of threadvars.
Regarding pointers this yields:
With X86/32 Linux, with C you can define a pointer type "__thread int
i*". So this pointer knows that is handles a threadvar and thus the
compiler can generate code accessing the threadvar via GS even when a
pointer is used (I did not test yet whether this really works).
Kind of a near pointer, with the thread segement (offset) implied.
With
Pascal this is not possible (AFAIK). So using a pointer, a value is
always accessed via DS. AFAIK, when calculating the pointer value it's
technically not possible to "rebase" the address from GS to DS, as the
selector tables can't be read from user space. Catch 22.
You only have to determine the flat address, before storing it in the
pointer variable - @MyThreadvar?
With X86/32 Windows, The threadvar is finally accessed via DS anyway. So
no problem here. If you save the address of a threadvar in a global
variable, a different thread will be able to access the threadvar of the
thread that saved the pointer. I should test if FP really gives thread
specific address-values for pointers to threadvars in Windows but not in
Linux. (IMHO different behavior would be erroneous.)
With NIOS (and supposedly similar with ARM), the pointer value for a
threadvar will be calculated adding the offset to R23 creating a normal
memory address. So no problem here. If you save the address of a
threadvar in a global variable, a different thread will 'be able to
access the threadvar of the thread that saved the pointer.
The only question is, whether you want the (absolute, flat) address of
the threadvar of an *specific* thread, or the address of the threadvar
in the *current* thread. Since the current thread can change, the offset
of the threadvar record will change accordingly, and must be determined
by the appropriate means (via segment or other address register).
DoDi
_______________________________________________
fpc-devel maillist - fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel