thread.inc 19 KB

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