InitThread in memory manager is not called when new thread is created
## Summary
When thread is started (for example using `BeginThread`), `InitThread` routine of memory manager is not called; however `DoneThread` routine is always called (and even is not ifdef'ed in `thread.inc`).
## System Information
<!-- The more information are provided the easier it is to replicate the bug -->
- **Operating system:** Linux (Ubuntu 24.04, kernel 6.8.0-35-generic (64-bit))
- **Processor architecture:** x86-64
- **Compiler version:** trunk
- **Device:** Computer
## Steps to reproduce
Simplest route: copy cmem module and add `CInitThread` and `CDoneThread` routines to it that only write messages to stdout, like so:
```pascal
// cmem body...
procedure CInitThread;
begin
WriteLn('!!! Init thread');
end;
procedure CDoneThread;
begin
WriteLn('!!! Done thread');
end;
Const
CMemoryManager : TMemoryManager =
(
NeedLock : false;
GetMem : @CGetmem;
FreeMem : @CFreeMem;
FreememSize : @CFreememSize;
AllocMem : @CAllocMem;
ReallocMem : @CReAllocMem;
MemSize : @CMemSize;
InitThread : @CInitThread;
DoneThread : @CDoneThread;
RelocateHeap : nil;
GetHeapStatus : @CGetHeapStatus;
GetFPCHeapStatus: @CGetFPCHeapStatus;
);
```
In general - just create memory manager that handles `InitThread` (it will not be called)
## Example Project
Example project using modified cmem unit (called `cmemmod`):
```pascal
program test;
{$Mode Delphi}
uses
cmemmod,
{$IfDef Unix}
cthreads,
{$EndIf}
SysUtils;
function ProcTask(AData: Pointer): PtrInt;
begin
WriteLn('In task!');
Result := 0;
end;
var ThreadId: TThreadId;
begin
WriteLn('Starting thread');
ThreadId := BeginThread(@ProcTask, nil);
WriteLn('Waiting');
WaitForThreadTerminate(ThreadId, -1);
WriteLn('Done');
end.
```
## What is the current bug behavior?
Code outputs this:
```txt
Starting thread
Waiting
In task!
!!! Done thread
Done
```
## What is the expected (correct) behavior?
It should call `InitThread` in memory manager and therefore print `!!! Init thread`:
```pascal
Starting thread
Waiting
!!! Init thread <-- this line could be before "Waiting", it does not matter; it just must be before "In task!"
In task!
!!! Done thread
Done
```
## Possible fixes
In `thread.inc` in `procedure InitThread(stklen: SizeUInt)` there is a condition:
```pascal
{$ifndef HAS_MEMORYMANAGER}
{$ifndef FPC_NO_DEFAULT_HEAP}
{ initialize this thread's heap }
InitHeapThread;
{$endif ndef FPC_NO_DEFAULT_HEAP}
{$else HAS_MEMORYMANAGER}
if MemoryManager.InitThread <> nil then
MemoryManager.InitThread();
{$endif HAS_MEMORYMANAGER}
```
`HAS_MEMORYMANAGER` is disabled in `heap.inc`, therefore memory manager never gets a chance to get `InitThread` call.
However in `DoneThread` in `thread.inc`, call to `DoneThread` of memory manager is not ifdef'ed and is always called:
```pascal
{$ifndef HAS_MEMORYMANAGER}
{$ifndef FPC_NO_DEFAULT_HEAP}
FinalizeHeap;
{$endif ndef FPC_NO_DEFAULT_HEAP}
{$endif HAS_MEMORYMANAGER}
if MemoryManager.DoneThread <> nil then
MemoryManager.DoneThread();
```
## Attachments
[cmemmod.pas](/uploads/3ab2bcce3ee9a8492aaad27e1319f986/cmemmod.pas)
[test.pas](/uploads/7a23f884302af9e2574bf6e7de376012/test.pas)
issue