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