thread.inc 19 KB

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