thread.inc 19 KB

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