Adriaan van Os wrote:
The threadvarlists of all compilation units are collected when compiling a main program or library (similar to how the initialisation routines of all used units are collected, I guess GPC also already contains some mechanism for this).
Actually, it doesn't. It used to do until several years ago. But since this method wasn't supported by all linkers (GNU ld does, sure, but e.g., IIRC the SGI linker didn't), so unit initialization wouldn't work there, we switched to calling initializers explicitly (automatically, of course) from the main program.
When the first thread is started (via BeginThread(), we don't detect if someone uses pthread_create or so), the thread manager walks the threadvartable and the referenced lists and fills in all indexes. This thread manager is fully pluggable, so everyone is free to use his own (e.g. if you implement some user space fibers or so).
Yes, this is something I'd like to see as well.
So this might be an option. (But again, first I'd like to see which variables are actually affected and thus how big the effects would actually be. InOutRes might well be the worst, because most-often used one, but not the only one, of course.)
These are the threadvars in FPC's system unit:
ThreadVar ThreadID : TThreadID; { Standard In- and Output } ErrOutput, Output, Input, StdOut, StdErr : Text; InOutRes : Word; { Stack checking } StackBottom : Pointer; StackLength : SizeUInt;
I guess we'd get a similar list in GPC. However, as I've said before, I'm skeptical about Input etc. Do we really want a per-thread Input, each with its own buffer (which means, if several of them are acutally used, it becomes hard to foretell in which one each sequence of input bytes ends up)? Similar for Output. For StdErr, one could argue that it shouldn't buffer at all (which GPC's in fact doesn't, and so does stderr in C by default AFAIK).
There's a few more in TP-compatibility units (like doserror in the Dos unit and some crt things)
Well, for CRT, just making the internal state per-thread wouldn't really help much AFAICS. E.g., if each threads has its own screen buffer, and updates the real screen from it, this would probably result in chaos. IOW, as there's only one physical screen (unless multi-headed), I think one probably needs some common data across threads. Or you leave it up to the user -- as, e.g., ncurses recommends doing all curses I/O within one thread.
Since our RTL is under a slightly modified LGPL (allows static linking as long as you make the modifications to the FPC-RTL-licensed code available), license-wise I don't think there is any problem for you to reuse things. If there is, we could dual-license it under the regular LGPL as well I suppose (the main reason for the static linking exception is that some OS'es, like Dos, simply do not support dynamic linking, and support for creating dynamic libraries was not available for all OS'es in our compiler from the start either).
BTW, standard LGPL allows static linking as well. You just have to distribute object files of the non-free parts, so users can relink. But I suppose for some reason that's not desired?
Frank