[fpc-devel] OO rewrite - technical questions
Hans-Peter Diettrich
DrDiettrich1 at aol.com
Wed Jul 21 16:23:18 CEST 2010
Michael Schnell schrieb:
>> Since it turned out that loading segment registers is very time
>> consuming on newer (i486+) processors, the memory management was
>> changed from segmented (16 bit) into paged (32 bit flat). Segment
>> registers never should be changed by an application,
> Not really, The OS needs to set the segment registers, anyway, when
> returning to a preempted thread or process,
Of course the *entire* CPU state is kept in an stored machine state
record. My concern was about the ban of using more than one segment
selector (DS=CS=ES=SS), related to one set of segment descriptor tables.
The thread specific FS/GS selector most probably selects a tiny
segment, with small related tables, that do not affect performance a
lot. And since the segment registers are only changed on process/thread
switches, the resulting overhead is kept to the absolute minimum.
> otherwise it needs to be
> clearly documented that the user program is not supposed to use them at
> all.
Apart from that, I've heard that segment registers have no special
effect in 64 bit mode at all? How can these registers ever be used, in
64 bit code? Safe bet: don't touch them ever, use only as documented
(for FS/GS).
> Assigning some value - e.g.the pointer to the threadvar area - to
> e.g. GS would not harm performance-wise.
When an OS does not provide an API to create segments (in a 32 bit flat
model), there exist no values (segment selectors) that can be loaded
into a segment register at all, by application code.
Otherwise it *would* harm performance-wise, to load another segment
selector into a segment register, due to the associated overhead in the
MMU (address translation logic, from virtual into physical addresses).
In a non-segmented environment (64 bit mode?) the segment registers have
no special meaning, and consequently no such related overhead.
>> it should be left to the OS process/thread scheduler and thread-API
>> calls.
> If a register is not predefined by the OS (such as GS on WIN32), I think
> the ABI should inform the ASM programmer about how to use it. Simply
> stating "all other registers need to be preserved by the callee" would
> suffice and answer the original question about if the compiler would
> need to safe GS in case an "external" function might trash it.
Of course this would be nice, but till then it's simply wise to not use
such undocumented registers at all, neither in compiler created code,
nor in ASM.
> Moreover of course the ABI should clearly state how an ASM function is
> supposed to create threadvars, anyway.
IMO the OS provides means to allocate an thread-local memory block
(Thread Local Storage), whose content *can* be used for threadvars. It's
not up to the API or ABI to bother with the "record" layout of that TLS
memory block, that's all application/compiler specific. A threadvar
simply is a member of that record, and the API specified register
contains the (direct or indirect) address of the TLS.
IMO also no physical/logical separation exists, between application
(main thread) and other thread memory, everything exists in the overall
process memory. It's up to the compiler/coder, to prevent unsynchronized
access to memory locations that could be updated concurrently by
multiple threads.
BTW, the definition of "threadvar" is not a very practical one. In
practice it should be possible to assign threadvars to *specific*
threads, otherwise *every* thread has to allocate an TLS containing
*all* the threadvars of the entire application. Furthermore it would be
sufficient to have all "threadvars" in the specific TThread-derived
classes, eliminating the need for any additional TLS.
DoDi
More information about the fpc-devel
mailing list