thread.inc 19 KB

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