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

_______________________________________________
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel

Reply via email to