[fpc-devel] OO rewrite - technical questions
Hans-Peter Diettrich
DrDiettrich1 at aol.com
Sat Jul 24 04:55:54 CEST 2010
Michael Schnell schrieb:
>> Do you mean segment or general-purpose register(s)?
> This depends on the arch. X86 does not really have general-purpose
> registers, while NIOS, ARM MIPS (and supposedly X86/64) has almost only
> general-purpose registers.
M68K has distinct address and data registers, x86 has segment and data
registers, not to mention other special registers (flags...) in every
architecture.
>> How is that different from WinAPI?
> The whole discussion here is that X86/32-WinAPI in fact uses a segment
> register for this purpose but it's nowhere decently documented.
> Moreover (bus not a problem) I understand that gnu C on X86/32 Linux
> uses a segment register as a pointer to the threadvar area, while the
> non-documented WinAPI uses a segment register as a pointer to a
> thread-dedicated structure that again contains a pointer to the
> threadvar area.
I see no difference here. IMO the segment register is used implicitly in
thread API calls, with no further use by application code. Every thread
has one "slot" reserved in the OS-maintained data structure, where it
can store one private value. In the "Using Thread Local Storage" entry
in the MSDN library this value is the handle of a memory block, created
with LocalAlloc. It could be the handle of an local heap as well,
created with HeapCreate, when special handling of threadvars shall be
implemented in the RTL. No special segment register seems to be involved
in the subsequent use of that allocated memory (flat memory model).
>> When we consider threads created in a DLL/.so, too, then the platform
>> has to establish such conventions, for the entire app<->library ABI.
> Not really.
I found the Windows conventions in "Register Usage" in the MSDN Library,
telling which registers are considered (non-)volatile.
> The main executable can create a thread and a function
> called in the thread can internally declare and use a static threadvar.
> So the ABI needs to document how the (ASM) function is supposed to
> access the threadvar it internally defines. As it needs to use a
> register for this, the ABI needs to define that the alee is to use
> exactly this register and (supposedly) that the callee is not supposed
> to modify it when it returns.
Application code can use any non-volatile register for (thread...)
communication purposes. When an application and a shared library shall
work together, they must use the same convention about the use of such
registers.
>> How else should it be done, in a practical way? Registers are not a
>> solution, since:
>> Assume you have 10 units, each of which declares only one threadvar -
>> then you would have to reserve 10 registers for these threadvars,
>> application-wide!
> Sorry but here you are decently wrong.
>
> With most archs all static variables (such as globals and threadvars)
> always are accessed relative to a register. With X86/32 globals and
> statics are allocated relative to DS,
Here the segment register is somewhat irrelevant, since each maps to the
entire 4 GB process address space. All 32 bit "pointers" simply are
offsets into that address space, like in any other unsegmented
architecture. The only difference may be access rights (CS: executable,
read-only).
> with X86/32-Linux, threadvars are allocated relative to FS.
FS and GS may be used for special (OS, SEH and TLS) management, they are
useless in application code.
> The archs i know, that don't have segment
> registers use "address"- or "general purpose" registers for this. So we
> have two "basic data pointers": one for the normal static vars and one
> for the threadvars. Both are safe regarding preemption. The basic
> pointer for normal static vars is initialized at the program start and
> never changed within the application, the pointer to the threadvars is
> initialized when a thread starts and - because it is preemption save
> just like any other register - its never changed when this thread is
> running.
On Windows such base-pointers should reside in non-volatile registers,
otherwise no difference in their use. As long as the base values are
immutable, the equivalent absolute addresses can be used instead (in
contrast to PIC).
> Moreover the point with threadvars is that threads that use the same
> code see different values in the same threadvar. These threads of course
> can't use different registers to access them as the run the same code.
Consider a threadvar as a field of a related thread object (instance).
DoDi
More information about the fpc-devel
mailing list