As I wrote in a previous post, Delphi string, dynamic array and memory manager don't like multi-core CPU.

My proposal is to add a threadlocalvar keyword, to be used instead of var in your code, to mark some variables to be used in only the current thread. Then the compiler and RTL won't have to use the LOCK instruction, and the application will be MUCH faster in multi-thread environment.

I made this proposal in both the Embarcadero forum and in the FreePascal forum.

So what about using a threadlocalvar new reserved word, in a threadvar way, which could define the variable (string, dynamic array) to be accessed by the current thread only, and won't have any LOCK call?

My guess is that any server thread uses mostly such local variables (e.g. for string concatenation of XML or HTML stream), and don't need the thread safe approach most of the time.

It could lead into confusion some Delphi users/beginners... perhaps it's worth noting that the threadvar itself does exist for years (since Delphi 1 I guess), but is used only by those how need this feature. If you need it, you use it. Otherwise you ignore it, and your application will be slower in some cases, but wil work. For some CPU intensive applications, like multi-thread servers, it should be a great improvement to have such a threadlocalvar at hand.

Note 1: the threadvar implements one variable instance per thread, and the threadlocalvar should implements one variable instance for the current thread only.

Note 2: any threadlocalvar could be assigned to a normal var, when a multi-thread safe variable is needed (e.g. for communication between threads): in this case, it will be a direct write, not a copy on write. Copy on write would be enabled between threadlocalvar, of course, for better performance.

Note 3: it's up to the programmer to take care of the multi-thread approach, but writing threadlocalvar (so many characters to type!) will prevent for doing it without knowing it.

This could be something like that:

function TServer.ComputePage: string; threadlocalvar tmp: string; // differs from var tmp: string i: integer; // i is defined as threadlocalvar, but is the same as normal var begin for i := 0 to high(ListStr) do // ListStr[] is a dynamic array tmp := tmp+ListStr[i]+#13#10; // very fast computation, without LOCK result := tmp; // copy from local heap to global heap end;

To implement this at the compiler and RTL level, we could use reference count <=-2 for these variables (-1=const, -2=ref 0, -3=ref 1..).

The RTL (i.e. system.pas unit) should be modified as such, for example for handling a threadlocalvar string reference counting add:

function _LStrAddRef(var str): Pointer; var P: PStrRec; begin if Integer(str)<>0 then begin P := Pointer(Integer(str) - sizeof(StrRec)); if P.refcnt >= 0 then InterlockedIncrement(P.refcnt) else // slow multi-thread safe reference count if P.refcnt < -1 then // -1 for const dec(P.refcnt); // -2,-3... for threadlocalvar end; Result := Pointer(str); end;

And a local threadheap should be implemented for such threadlocalvar, with threadlocalgetmem() and such functions.

Another possibility should be do add a "threadlocal" attribute for types, to be used for local variables and properties:

TServer = class public ListStr: threadlocal array of string; ...

In this case, the method above should begin with:

function TServer.ComputePage: string; var tmp: threadlocal string; // differs from var tmp: string ....

But this threadlocal attribute syntax sounds a bit not "pascalish", whereas the threadlocalvar does (it sounds like the treadvar feature) ... another idea?