[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.


More information about the fpc-devel mailing list