thread.inc 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682
  1. {
  2. This file is part of the Free Pascal Run time library.
  3. Copyright (c) 2000 by the Free Pascal development team
  4. OS independent thread functions/overloads
  5. See the File COPYING.FPC, included in this distribution,
  6. for details about the copyright.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10. **********************************************************************}
  11. Var
  12. CurrentTM : TThreadManager;
  13. {$ifndef THREADVAR_RELOCATED_ALREADY_DEFINED}
  14. fpc_threadvar_relocate_proc : TRelocateThreadVarHandler; public name 'FPC_THREADVAR_RELOCATE';
  15. {$endif THREADVAR_RELOCATED_ALREADY_DEFINED}
  16. {$ifndef HAS_GETCPUCOUNT}
  17. function GetCPUCount: LongWord;
  18. begin
  19. Result := 1;
  20. end;
  21. {$endif}
  22. {*****************************************************************************
  23. Threadvar initialization
  24. *****************************************************************************}
  25. procedure InitThread(stklen:SizeUInt);
  26. begin
  27. {$ifndef FPUNONE}
  28. SysInitFPU;
  29. { the call to SysResetFPU should not be needed here, but SysInitFPU is not properly implemented for all CPUs yet }
  30. SysResetFPU;
  31. {$endif}
  32. {$ifndef HAS_MEMORYMANAGER}
  33. {$ifndef FPC_NO_DEFAULT_HEAP}
  34. { initialize this thread's heap }
  35. InitHeapThread;
  36. {$endif ndef FPC_NO_DEFAULT_HEAP}
  37. {$else HAS_MEMORYMANAGER}
  38. if MemoryManager.InitThread <> nil then
  39. MemoryManager.InitThread();
  40. {$endif HAS_MEMORYMANAGER}
  41. {$ifdef FPC_HAS_FEATURE_WIDESTRINGS}
  42. if assigned(widestringmanager.ThreadInitProc) then
  43. widestringmanager.ThreadInitProc;
  44. {$endif FPC_HAS_FEATURE_WIDESTRINGS}
  45. {$ifdef FPC_HAS_FEATURE_EXCEPTIONS}
  46. { ExceptAddrStack and ExceptObjectStack are threadvars }
  47. { so every thread has its on exception handling capabilities }
  48. SysInitExceptions;
  49. {$endif FPC_HAS_FEATURE_EXCEPTIONS}
  50. {$ifdef FPC_HAS_FEATURE_CONSOLEIO}
  51. {$ifndef EMBEDDED}
  52. { Open all stdio fds again }
  53. SysInitStdio;
  54. InOutRes:=0;
  55. // ErrNo:=0;
  56. {$endif EMBEDDED}
  57. {$endif FPC_HAS_FEATURE_CONSOLEIO}
  58. {$ifdef FPC_HAS_FEATURE_STACKCHECK}
  59. { Stack checking }
  60. StackLength:= CheckInitialStkLen(stkLen);
  61. StackBottom:=Sptr - StackLength;
  62. {$endif FPC_HAS_FEATURE_STACKCHECK}
  63. ThreadID := CurrentTM.GetCurrentThreadID();
  64. end;
  65. procedure DoneThread;
  66. begin
  67. {$ifdef FPC_HAS_FEATURE_WIDESTRINGS}
  68. if assigned(widestringmanager.ThreadFiniProc) then
  69. widestringmanager.ThreadFiniProc;
  70. {$endif FPC_HAS_FEATURE_WIDESTRINGS}
  71. {$ifndef HAS_MEMORYMANAGER}
  72. {$ifndef FPC_NO_DEFAULT_HEAP}
  73. FinalizeHeap;
  74. {$endif ndef FPC_NO_DEFAULT_HEAP}
  75. {$endif HAS_MEMORYMANAGER}
  76. if MemoryManager.DoneThread <> nil then
  77. MemoryManager.DoneThread();
  78. {$ifdef FPC_HAS_FEATURE_CONSOLEIO}
  79. { Open all stdio fds again }
  80. SysFlushStdio;
  81. {$endif FPC_HAS_FEATURE_CONSOLEIO}
  82. { Support platforms where threadvar memory is managed outside of the RTL:
  83. reset ThreadID and allow ReleaseThreadVars to be unassigned }
  84. ThreadID := TThreadID(0);
  85. if assigned(CurrentTM.ReleaseThreadVars) then
  86. CurrentTM.ReleaseThreadVars;
  87. end;
  88. procedure InitThread;
  89. begin
  90. { we should find a reasonable value here }
  91. InitThread($1000000);
  92. end;
  93. {*****************************************************************************
  94. Overloaded functions
  95. *****************************************************************************}
  96. function BeginThread(ThreadFunction : tthreadfunc) : TThreadID;
  97. var
  98. dummy : TThreadID;
  99. begin
  100. BeginThread:=BeginThread(nil,DefaultStackSize,ThreadFunction,nil,0,dummy);
  101. end;
  102. function BeginThread(ThreadFunction : tthreadfunc;p : pointer) : TThreadID;
  103. var
  104. dummy : TThreadID;
  105. begin
  106. BeginThread:=BeginThread(nil,DefaultStackSize,ThreadFunction,p,0,dummy);
  107. end;
  108. function BeginThread(ThreadFunction : tthreadfunc;p : pointer;var ThreadId : TThreadID) : TThreadID;
  109. begin
  110. BeginThread:=BeginThread(nil,DefaultStackSize,ThreadFunction,p,0,ThreadId);
  111. end;
  112. function BeginThread(ThreadFunction : tthreadfunc;p : pointer;
  113. var ThreadId : TThreadID; const stacksize: SizeUInt) : TThreadID;
  114. begin
  115. BeginThread:=BeginThread(nil,stacksize,ThreadFunction,p,0,ThreadId);
  116. end;
  117. procedure EndThread;
  118. begin
  119. EndThread(0);
  120. end;
  121. function BeginThread(sa : Pointer;stacksize : SizeUInt; ThreadFunction : tthreadfunc;p : pointer;creationFlags : dword; var ThreadId : TThreadID) : TThreadID;
  122. begin
  123. Result:=CurrentTM.BeginThread(sa,stacksize,threadfunction,P,creationflags,ThreadID);
  124. end;
  125. procedure FlushThread;
  126. begin
  127. {$ifdef FPC_HAS_FEATURE_CONSOLEIO}
  128. SysFlushStdio;
  129. {$endif FPC_HAS_FEATURE_CONSOLEIO}
  130. end;
  131. procedure EndThread(ExitCode : DWord);
  132. begin
  133. CurrentTM.EndThread(ExitCode);
  134. end;
  135. function SuspendThread (threadHandle : TThreadID) : dword;
  136. begin
  137. Result:=CurrentTM.SuspendThread(ThreadHandle);
  138. end;
  139. function ResumeThread (threadHandle : TThreadID) : dword;
  140. begin
  141. Result:=CurrentTM.ResumeThread(ThreadHandle);
  142. end;
  143. function CloseThread (threadHandle : TThreadID):dword;
  144. begin
  145. result:=CurrentTM.CloseThread(ThreadHandle);
  146. end;
  147. procedure ThreadSwitch;
  148. begin
  149. CurrentTM.ThreadSwitch;
  150. end;
  151. function KillThread (threadHandle : TThreadID) : dword;
  152. begin
  153. Result:=CurrentTM.KillThread(ThreadHandle);
  154. end;
  155. function WaitForThreadTerminate (threadHandle : TThreadID; TimeoutMs : longint) : dword;
  156. begin
  157. Result:=CurrentTM.WaitForThreadTerminate(ThreadHandle,TimeOutMS);
  158. end;
  159. function ThreadSetPriority (threadHandle : TThreadID; Prio: longint): boolean;
  160. begin
  161. Result:=CurrentTM.ThreadSetPriority(ThreadHandle,Prio);
  162. end;
  163. function ThreadGetPriority (threadHandle : TThreadID): longint;
  164. begin
  165. Result:=CurrentTM.ThreadGetPriority(ThreadHandle);
  166. end;
  167. function GetCurrentThreadId : TThreadID;
  168. begin
  169. Result:=CurrentTM.GetCurrentThreadID();
  170. end;
  171. procedure SetThreadDebugName(threadHandle: TThreadID; const ThreadName: AnsiString);
  172. begin
  173. CurrentTM.SetThreadDebugNameA(threadHandle, ThreadName);
  174. end;
  175. {$ifdef FPC_HAS_FEATURE_UNICODESTRINGS}
  176. procedure SetThreadDebugName(threadHandle: TThreadID; const ThreadName: UnicodeString);
  177. begin
  178. CurrentTM.SetThreadDebugNameU(threadHandle, ThreadName);
  179. end;
  180. {$endif FPC_HAS_FEATURE_UNICODESTRINGS}
  181. procedure InitCriticalSection(out cs : TRTLCriticalSection);
  182. begin
  183. CurrentTM.InitCriticalSection(cs);
  184. end;
  185. procedure DoneCriticalSection(var cs : TRTLCriticalSection);
  186. begin
  187. CurrentTM.DoneCriticalSection(cs);
  188. end;
  189. procedure EnterCriticalSection(var cs : TRTLCriticalSection);
  190. begin
  191. CurrentTM.EnterCriticalSection(cs);
  192. end;
  193. function TryEnterCriticalSection(var cs : TRTLCriticalSection):longint;
  194. begin
  195. result:=CurrentTM.TryEnterCriticalSection(cs);
  196. end;
  197. procedure LeaveCriticalSection(var cs : TRTLCriticalSection);
  198. begin
  199. CurrentTM.LeaveCriticalSection(cs);
  200. end;
  201. Function GetThreadManager(Out TM : TThreadManager) : Boolean;
  202. begin
  203. TM:=CurrentTM;
  204. Result:=True;
  205. end;
  206. Function SetThreadManager(Const NewTM : TThreadManager; Out OldTM : TThreadManager) : Boolean;
  207. begin
  208. GetThreadManager(OldTM);
  209. Result:=SetThreadManager(NewTM);
  210. end;
  211. Function SetThreadManager(Const NewTM : TThreadManager) : Boolean;
  212. begin
  213. Result:=True;
  214. If Assigned(CurrentTM.DoneManager) then
  215. Result:=CurrentTM.DoneManager();
  216. If Result then
  217. begin
  218. CurrentTM:=NewTM;
  219. If Assigned(CurrentTM.InitManager) then
  220. Result:=CurrentTM.InitManager();
  221. end;
  222. end;
  223. function BasicEventCreate(EventAttributes : Pointer; AManualReset,InitialState : Boolean;const Name : ansistring):pEventState;
  224. begin
  225. result:=currenttm.BasicEventCreate(EventAttributes,AManualReset,InitialState, Name);
  226. end;
  227. procedure BasicEventDestroy(state:peventstate);
  228. begin
  229. currenttm.BasicEventDestroy(state);
  230. end;
  231. procedure BasicEventResetEvent(state:peventstate);
  232. begin
  233. currenttm.BasicEventResetEvent(state);
  234. end;
  235. procedure BasicEventSetEvent(state:peventstate);
  236. begin
  237. currenttm.BasicEventSetEvent(state);
  238. end;
  239. function BasicEventWaitFor(Timeout : Cardinal;state:peventstate;FUseComWait : Boolean=False) : longint;
  240. begin
  241. result:=currenttm.BasicEventWaitFor(Timeout,state,FUseComWait);
  242. end;
  243. function RTLEventCreate :PRTLEvent;
  244. begin
  245. result:=currenttm.RTLEventCreate();
  246. end;
  247. procedure RTLeventDestroy(state:pRTLEvent);
  248. begin
  249. currenttm.RTLEventDestroy(state);
  250. end;
  251. procedure RTLeventSetEvent(state:pRTLEvent);
  252. begin
  253. currenttm.RTLEventSetEvent(state);
  254. end;
  255. procedure RTLeventResetEvent(state:pRTLEvent);
  256. begin
  257. currenttm.RTLEventResetEvent(state);
  258. end;
  259. procedure RTLeventWaitFor(state:pRTLEvent);
  260. begin
  261. currenttm.RTLEventWaitFor(state);
  262. end;
  263. procedure RTLeventWaitFor(state:pRTLEvent;timeout : longint);
  264. begin
  265. currenttm.RTLEventWaitForTimeout(state,timeout);
  266. end;
  267. { ---------------------------------------------------------------------
  268. lazy thread initialization support
  269. ---------------------------------------------------------------------}
  270. type
  271. PLazyInitThreadingProcInfo = ^TLazyInitThreadingProcInfo;
  272. TLazyInitThreadingProcInfo = Record
  273. Next : PLazyInitThreadingProcInfo;
  274. Proc : TProcedure;
  275. End;
  276. const
  277. LazyInitThreadingProcList: PLazyInitThreadingProcInfo = nil;
  278. procedure FinalizeLazyInitThreading;
  279. var
  280. p: PLazyInitThreadingProcInfo;
  281. begin
  282. while assigned(LazyInitThreadingProcList) do
  283. begin
  284. p:=LazyInitThreadingProcList^.Next;
  285. Dispose(LazyInitThreadingProcList);
  286. LazyInitThreadingProcList:=p;
  287. end;
  288. end;
  289. procedure RegisterLazyInitThreadingProc(const proc: TProcedure);
  290. var
  291. p: PLazyInitThreadingProcInfo;
  292. begin
  293. if IsMultiThread then
  294. begin
  295. { multithreading is already enabled - execute directly }
  296. proc();
  297. end
  298. else
  299. begin
  300. if not assigned(LazyInitThreadingProcList) then
  301. AddExitProc(@FinalizeLazyInitThreading);
  302. new(p);
  303. p^.Next:=LazyInitThreadingProcList;
  304. p^.Proc:=proc;
  305. LazyInitThreadingProcList:=p;
  306. end;
  307. end;
  308. procedure LazyInitThreading;
  309. var
  310. p: PLazyInitThreadingProcInfo;
  311. begin
  312. p:=LazyInitThreadingProcList;
  313. while assigned(p) do
  314. begin
  315. p^.Proc();
  316. p:=p^.Next;
  317. end;
  318. end;
  319. { ---------------------------------------------------------------------
  320. ThreadManager which gives run-time error. Use if no thread support.
  321. ---------------------------------------------------------------------}
  322. {$ifndef DISABLE_NO_THREAD_MANAGER}
  323. { resourcestrings are not supported by the system unit,
  324. they are in the objpas unit and not available for fpc/tp modes }
  325. const
  326. SNoThreads = 'This binary has no thread support compiled in.';
  327. SRecompileWithThreads = 'Recompile the application with a thread-driver in the program uses clause before other units using thread.';
  328. Procedure NoThreadError;
  329. begin
  330. {$ifndef EMBEDDED}
  331. {$ifdef FPC_HAS_FEATURE_CONSOLEIO}
  332. {$ifndef FPC_SYSTEM_NO_VERBOSE_THREADERROR}
  333. If IsConsole then
  334. begin
  335. Writeln(StdErr,SNoThreads);
  336. Writeln(StdErr,SRecompileWithThreads);
  337. end;
  338. {$endif FPC_SYSTEM_NO_VERBOSE_THREADERROR}
  339. {$endif FPC_HAS_FEATURE_CONSOLEIO}
  340. {$endif EMBEDDED}
  341. RunError(232)
  342. end;
  343. function NoBeginThread(sa : Pointer;stacksize : PtrUInt;
  344. ThreadFunction : tthreadfunc;p : pointer;
  345. creationFlags : dword; var ThreadId : TThreadID) : TThreadID;
  346. begin
  347. NoThreadError;
  348. result:=tthreadid(-1);
  349. end;
  350. procedure NoEndThread(ExitCode : DWord);
  351. begin
  352. NoThreadError;
  353. end;
  354. function NoThreadHandler (threadHandle : TThreadID) : dword;
  355. begin
  356. NoThreadError;
  357. result:=dword(-1);
  358. end;
  359. function NoWaitForThreadTerminate (threadHandle : TThreadID; TimeoutMs : longint) : dword; {0=no timeout}
  360. begin
  361. NoThreadError;
  362. result:=dword(-1);
  363. end;
  364. function NoThreadSetPriority (threadHandle : TThreadID; Prio: longint): boolean; {-15..+15, 0=normal}
  365. begin
  366. NoThreadError;
  367. result:=false;
  368. end;
  369. function NoThreadGetPriority (threadHandle : TThreadID): longint;
  370. begin
  371. NoThreadError;
  372. result:=-1;
  373. end;
  374. function NoGetCurrentThreadId : TThreadID;
  375. begin
  376. if IsMultiThread then
  377. NoThreadError
  378. else
  379. ThreadingAlreadyUsed:=true;
  380. result:=TThreadID(1);
  381. end;
  382. procedure NoSetThreadDebugNameA(threadHandle: TThreadID; const ThreadName: AnsiString);
  383. begin
  384. NoThreadError;
  385. end;
  386. {$ifdef FPC_HAS_FEATURE_UNICODESTRINGS}
  387. procedure NoSetThreadDebugNameU(threadHandle: TThreadID; const ThreadName: UnicodeString);
  388. begin
  389. NoThreadError;
  390. end;
  391. {$endif FPC_HAS_FEATURE_UNICODESTRINGS}
  392. procedure NoCriticalSection(var CS);
  393. begin
  394. if IsMultiThread then
  395. NoThreadError
  396. else
  397. ThreadingAlreadyUsed:=true;
  398. end;
  399. function NoTryEnterCriticalSection(var CS):longint;
  400. begin
  401. if IsMultiThread then
  402. NoThreadError
  403. else
  404. ThreadingAlreadyUsed:=true;
  405. Result:=-1;
  406. end;
  407. procedure NoInitThreadvar(var offset : {$ifdef cpu16}word{$else}dword{$endif};size : dword);
  408. begin
  409. NoThreadError;
  410. end;
  411. function NoRelocateThreadvar(offset : {$ifdef cpu16}word{$else}dword{$endif}) : pointer;
  412. begin
  413. NoThreadError;
  414. result:=nil;
  415. end;
  416. function NoBasicEventCreate(EventAttributes : Pointer; AManualReset,InitialState : Boolean;const Name : ansistring):pEventState;
  417. begin
  418. if IsMultiThread then
  419. NoThreadError
  420. else
  421. ThreadingAlreadyUsed:=true;
  422. result:=nil;
  423. end;
  424. procedure NoBasicEvent(state:peventstate);
  425. begin
  426. if IsMultiThread then
  427. NoThreadError
  428. else
  429. ThreadingAlreadyUsed:=true;
  430. end;
  431. function NoBasicEventWaitFor(Timeout : Cardinal;state:peventstate;FUseComWait : Boolean=False) : longint;
  432. begin
  433. if IsMultiThread then
  434. NoThreadError
  435. else
  436. ThreadingAlreadyUsed:=true;
  437. result:=-1;
  438. end;
  439. function NoRTLEventCreate :PRTLEvent;
  440. begin
  441. if IsMultiThread then
  442. NoThreadError
  443. else
  444. ThreadingAlreadyUsed:=true;
  445. result:=nil;
  446. end;
  447. procedure NoRTLEvent(state:pRTLEvent);
  448. begin
  449. if IsMultiThread then
  450. NoThreadError
  451. else
  452. ThreadingAlreadyUsed:=true
  453. end;
  454. procedure NoRTLEventWaitForTimeout(state:pRTLEvent;timeout : longint);
  455. begin
  456. if IsMultiThread then
  457. NoThreadError
  458. else
  459. ThreadingAlreadyUsed:=true;
  460. end;
  461. const
  462. NoThreadManager : TThreadManager = (
  463. InitManager : Nil;
  464. DoneManager : Nil;
  465. {$ifdef EMBEDDED}
  466. { while this is pretty hacky, it reduces the size of typical embedded programs
  467. and works fine on arm and avr }
  468. BeginThread : @NoBeginThread;
  469. EndThread : TEndThreadHandler(@NoThreadError);
  470. SuspendThread : TThreadHandler(@NoThreadError);
  471. ResumeThread : TThreadHandler(@NoThreadError);
  472. KillThread : TThreadHandler(@NoThreadError);
  473. CloseThread : TThreadHandler(@NoThreadError);
  474. ThreadSwitch : TThreadSwitchHandler(@NoThreadError);
  475. WaitForThreadTerminate : TWaitForThreadTerminateHandler(@NoThreadError);
  476. ThreadSetPriority : TThreadSetPriorityHandler(@NoThreadError);
  477. ThreadGetPriority : TThreadGetPriorityHandler(@NoThreadError);
  478. GetCurrentThreadId : @NoGetCurrentThreadId;
  479. SetThreadDebugNameA : TThreadSetThreadDebugNameHandlerA(@NoThreadError);
  480. {$ifdef FPC_HAS_FEATURE_UNICODESTRINGS}
  481. SetThreadDebugNameU : TThreadSetThreadDebugNameHandlerU(@NoThreadError);
  482. {$endif FPC_HAS_FEATURE_UNICODESTRINGS}
  483. InitCriticalSection : TCriticalSectionHandler(@NoThreadError);
  484. DoneCriticalSection : TCriticalSectionHandler(@NoThreadError);
  485. EnterCriticalSection : TCriticalSectionHandler(@NoThreadError);
  486. TryEnterCriticalSection: TCriticalSectionHandlerTryEnter(@NoThreadError);
  487. LeaveCriticalSection : TCriticalSectionHandler(@NoThreadError);
  488. InitThreadVar : TInitThreadVarHandler(@NoThreadError);
  489. RelocateThreadVar : TRelocateThreadVarHandler(@NoThreadError);
  490. AllocateThreadVars : @NoThreadError;
  491. ReleaseThreadVars : @NoThreadError;
  492. BasicEventCreate : TBasicEventCreateHandler(@NoThreadError);
  493. BasicEventdestroy : TBasicEventHandler(@NoThreadError);
  494. BasicEventResetEvent : TBasicEventHandler(@NoThreadError);
  495. BasicEventSetEvent : TBasicEventHandler(@NoThreadError);
  496. BasicEventWaitFor : TBasicEventWaitForHandler(@NoThreadError);
  497. RTLEventCreate : TRTLCreateEventHandler(@NoThreadError);
  498. RTLEventdestroy : TRTLEventHandler(@NoThreadError);
  499. RTLEventSetEvent : TRTLEventHandler(@NoThreadError);
  500. RTLEventResetEvent : TRTLEventHandler(@NoThreadError);
  501. RTLEventWaitFor : TRTLEventHandler(@NoThreadError);
  502. RTLEventwaitfortimeout : TRTLEventHandlerTimeout(@NoThreadError);
  503. {$else EMBEDDED}
  504. BeginThread : @NoBeginThread;
  505. EndThread : @NoEndThread;
  506. SuspendThread : @NoThreadHandler;
  507. ResumeThread : @NoThreadHandler;
  508. KillThread : @NoThreadHandler;
  509. CloseThread : @NoThreadHandler;
  510. ThreadSwitch : @NoThreadError;
  511. WaitForThreadTerminate : @NoWaitForThreadTerminate;
  512. ThreadSetPriority : @NoThreadSetPriority;
  513. ThreadGetPriority : @NoThreadGetPriority;
  514. GetCurrentThreadId : @NoGetCurrentThreadId;
  515. SetThreadDebugNameA : @NoSetThreadDebugNameA;
  516. {$ifdef FPC_HAS_FEATURE_UNICODESTRINGS}
  517. SetThreadDebugNameU : @NoSetThreadDebugNameU;
  518. {$endif FPC_HAS_FEATURE_UNICODESTRINGS}
  519. InitCriticalSection : @NoCriticalSection;
  520. DoneCriticalSection : @NoCriticalSection;
  521. EnterCriticalSection : @NoCriticalSection;
  522. TryEnterCriticalSection: @NoTryEnterCriticalSection;
  523. LeaveCriticalSection : @NoCriticalSection;
  524. InitThreadVar : @NoInitThreadVar;
  525. RelocateThreadVar : @NoRelocateThreadVar;
  526. AllocateThreadVars : @NoThreadError;
  527. ReleaseThreadVars : @NoThreadError;
  528. BasicEventCreate : @NoBasicEventCreate;
  529. BasicEventDestroy : @NoBasicEvent;
  530. BasicEventResetEvent : @NoBasicEvent;
  531. BasicEventSetEvent : @NoBasicEvent;
  532. BasicEventWaitFor : @NoBasiceventWaitFor;
  533. RTLEventCreate : @NoRTLEventCreate;
  534. RTLEventDestroy : @NoRTLevent;
  535. RTLEventSetEvent : @NoRTLevent;
  536. RTLEventResetEvent : @NoRTLEvent;
  537. RTLEventWaitFor : @NoRTLEvent;
  538. RTLEventWaitforTimeout : @NoRTLEventWaitForTimeout;
  539. {$endif EMBEDDED}
  540. );
  541. Procedure SetNoThreadManager;
  542. begin
  543. SetThreadManager(NoThreadManager);
  544. end;
  545. Procedure InitSystemThreads; public name '_FPC_InitSystemThreads';
  546. begin
  547. { This should be changed to a real value during
  548. thread driver initialization if appropriate. }
  549. ThreadID := TThreadID(1);
  550. SetNoThreadManager;
  551. end;
  552. {$endif DISABLE_NO_THREAD_MANAGER}