thread.inc 18 KB

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