thread.inc 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497
  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. {*****************************************************************************
  14. Threadvar initialization
  15. *****************************************************************************}
  16. procedure InitThread(stklen:SizeUInt);
  17. begin
  18. SysResetFPU;
  19. { ExceptAddrStack and ExceptObjectStack are threadvars }
  20. { so every thread has its on exception handling capabilities }
  21. SysInitExceptions;
  22. { Open all stdio fds again }
  23. SysInitStdio;
  24. InOutRes:=0;
  25. // ErrNo:=0;
  26. { Stack checking }
  27. StackLength:= CheckInitialStkLen(stkLen);
  28. StackBottom:=Sptr - StackLength;
  29. ThreadID := CurrentTM.GetCurrentThreadID();
  30. end;
  31. {*****************************************************************************
  32. Overloaded functions
  33. *****************************************************************************}
  34. function BeginThread(ThreadFunction : tthreadfunc) : TThreadID;
  35. var
  36. dummy : TThreadID;
  37. begin
  38. BeginThread:=BeginThread(nil,DefaultStackSize,ThreadFunction,nil,0,dummy);
  39. end;
  40. function BeginThread(ThreadFunction : tthreadfunc;p : pointer) : TThreadID;
  41. var
  42. dummy : TThreadID;
  43. begin
  44. BeginThread:=BeginThread(nil,DefaultStackSize,ThreadFunction,p,0,dummy);
  45. end;
  46. function BeginThread(ThreadFunction : tthreadfunc;p : pointer;var ThreadId : TThreadID) : TThreadID;
  47. begin
  48. BeginThread:=BeginThread(nil,DefaultStackSize,ThreadFunction,p,0,ThreadId);
  49. end;
  50. function BeginThread(ThreadFunction : tthreadfunc;p : pointer;
  51. var ThreadId : TThreadID; const stacksize: SizeUInt) : TThreadID;
  52. begin
  53. BeginThread:=BeginThread(nil,stacksize,ThreadFunction,p,0,ThreadId);
  54. end;
  55. procedure EndThread;
  56. begin
  57. EndThread(0);
  58. end;
  59. function BeginThread(sa : Pointer;stacksize : SizeUInt; ThreadFunction : tthreadfunc;p : pointer;creationFlags : dword; var ThreadId : TThreadID) : TThreadID;
  60. begin
  61. Result:=CurrentTM.BeginThread(sa,stacksize,threadfunction,P,creationflags,ThreadID);
  62. end;
  63. procedure EndThread(ExitCode : DWord);
  64. begin
  65. { Make sure that all output is written to the redirected file }
  66. Flush(Output);
  67. Flush(ErrOutput);
  68. Flush(StdOut);
  69. Flush(StdErr);
  70. CurrentTM.EndThread(ExitCode);
  71. end;
  72. function SuspendThread (threadHandle : TThreadID) : dword;
  73. begin
  74. Result:=CurrentTM.SuspendThread(ThreadHandle);
  75. end;
  76. function ResumeThread (threadHandle : TThreadID) : dword;
  77. begin
  78. Result:=CurrentTM.ResumeThread(ThreadHandle);
  79. end;
  80. procedure ThreadSwitch;
  81. begin
  82. CurrentTM.ThreadSwitch;
  83. end;
  84. function KillThread (threadHandle : TThreadID) : dword;
  85. begin
  86. Result:=CurrentTM.KillThread(ThreadHandle);
  87. end;
  88. function WaitForThreadTerminate (threadHandle : TThreadID; TimeoutMs : longint) : dword;
  89. begin
  90. Result:=CurrentTM.WaitForThreadTerminate(ThreadHandle,TimeOutMS);
  91. end;
  92. function ThreadSetPriority (threadHandle : TThreadID; Prio: longint): boolean;
  93. begin
  94. Result:=CurrentTM.ThreadSetPriority(ThreadHandle,Prio);
  95. end;
  96. function ThreadGetPriority (threadHandle : TThreadID): longint;
  97. begin
  98. Result:=CurrentTM.ThreadGetPriority(ThreadHandle);
  99. end;
  100. function GetCurrentThreadId : TThreadID;
  101. begin
  102. Result:=CurrentTM.GetCurrentThreadID();
  103. end;
  104. procedure InitCriticalSection(var cs : TRTLCriticalSection);
  105. begin
  106. CurrentTM.InitCriticalSection(cs);
  107. end;
  108. procedure DoneCriticalsection(var cs : TRTLCriticalSection);
  109. begin
  110. CurrentTM.DoneCriticalSection(cs);
  111. end;
  112. procedure EnterCriticalsection(var cs : TRTLCriticalSection);
  113. begin
  114. CurrentTM.EnterCriticalSection(cs);
  115. end;
  116. procedure LeaveCriticalsection(var cs : TRTLCriticalSection);
  117. begin
  118. CurrentTM.LeaveCriticalSection(cs);
  119. end;
  120. Function GetThreadManager(Var TM : TThreadManager) : Boolean;
  121. begin
  122. TM:=CurrentTM;
  123. Result:=True;
  124. end;
  125. Function SetThreadManager(Const NewTM : TThreadManager; Var OldTM : TThreadManager) : Boolean;
  126. begin
  127. GetThreadManager(OldTM);
  128. Result:=SetThreadManager(NewTM);
  129. end;
  130. Function SetThreadManager(Const NewTM : TThreadManager) : Boolean;
  131. begin
  132. Result:=True;
  133. If Assigned(CurrentTM.DoneManager) then
  134. Result:=CurrentTM.DoneManager();
  135. If Result then
  136. begin
  137. CurrentTM:=NewTM;
  138. If Assigned(CurrentTM.InitManager) then
  139. Result:=CurrentTM.InitManager();
  140. end;
  141. end;
  142. function BasicEventCreate(EventAttributes : Pointer; AManualReset,InitialState : Boolean;const Name : ansistring):pEventState;
  143. begin
  144. result:=currenttm.BasicEventCreate(EventAttributes,AManualReset,InitialState, Name);
  145. end;
  146. procedure basiceventdestroy(state:peventstate);
  147. begin
  148. currenttm.basiceventdestroy(state);
  149. end;
  150. procedure basiceventResetEvent(state:peventstate);
  151. begin
  152. currenttm.basiceventResetEvent(state);
  153. end;
  154. procedure basiceventSetEvent(state:peventstate);
  155. begin
  156. currenttm.basiceventSetEvent(state);
  157. end;
  158. function basiceventWaitFor(Timeout : Cardinal;state:peventstate) : longint;
  159. begin
  160. result:=currenttm.basiceventWaitFor(Timeout,state);
  161. end;
  162. function RTLEventCreate :PRTLEvent;
  163. begin
  164. result:=currenttm.rtleventcreate();
  165. end;
  166. procedure RTLeventdestroy(state:pRTLEvent);
  167. begin
  168. currenttm.rtleventdestroy(state);
  169. end;
  170. procedure RTLeventSetEvent(state:pRTLEvent);
  171. begin
  172. currenttm.rtleventsetEvent(state);
  173. end;
  174. procedure RTLeventResetEvent(state:pRTLEvent);
  175. begin
  176. currenttm.rtleventResetEvent(state);
  177. end;
  178. procedure RTLeventStartWait(state:pRTLEvent);
  179. begin
  180. currenttm.rtleventStartWait(state);
  181. end;
  182. procedure RTLeventWaitFor(state:pRTLEvent);
  183. begin
  184. currenttm.rtleventWaitFor(state);
  185. end;
  186. procedure RTLeventWaitFor(state:pRTLEvent;timeout : longint);
  187. begin
  188. currenttm.rtleventWaitForTimeout(state,timeout);
  189. end;
  190. procedure RTLeventsync(m:trtlmethod;p:tprocedure);
  191. begin
  192. currenttm.rtleventsync(m,p);
  193. end;
  194. { ---------------------------------------------------------------------
  195. ThreadManager which gives run-time error. Use if no thread support.
  196. ---------------------------------------------------------------------}
  197. {$ifndef DISABLE_NO_THREAD_MANAGER}
  198. { resourcestrings are not supported by the system unit,
  199. they are in the objpas unit and not available for fpc/tp modes }
  200. const
  201. SNoThreads = 'This binary has no thread support compiled in.';
  202. SRecompileWithThreads = 'Recompile the application with a thread-driver in the program uses clause before other units using thread.';
  203. Procedure NoThreadError;
  204. begin
  205. If IsConsole then
  206. begin
  207. Writeln(StdErr,SNoThreads);
  208. Writeln(StdErr,SRecompileWithThreads);
  209. end;
  210. RunError(232)
  211. end;
  212. function NoBeginThread(sa : Pointer;stacksize : PtrUInt;
  213. ThreadFunction : tthreadfunc;p : pointer;
  214. creationFlags : dword; var ThreadId : TThreadID) : TThreadID;
  215. begin
  216. NoThreadError;
  217. end;
  218. procedure NoEndThread(ExitCode : DWord);
  219. begin
  220. NoThreadError;
  221. end;
  222. function NoThreadHandler (threadHandle : TThreadID) : dword;
  223. begin
  224. NoThreadError;
  225. end;
  226. procedure NoThreadSwitch; {give time to other threads}
  227. begin
  228. NoThreadError;
  229. end;
  230. function NoWaitForThreadTerminate (threadHandle : TThreadID; TimeoutMs : longint) : dword; {0=no timeout}
  231. begin
  232. NoThreadError;
  233. end;
  234. function NoThreadSetPriority (threadHandle : TThreadID; Prio: longint): boolean; {-15..+15, 0=normal}
  235. begin
  236. NoThreadError;
  237. end;
  238. function NoThreadGetPriority (threadHandle : TThreadID): longint;
  239. begin
  240. NoThreadError;
  241. end;
  242. function NoGetCurrentThreadId : TThreadID;
  243. begin
  244. if IsMultiThread then
  245. NoThreadError
  246. else
  247. ThreadingAlreadyUsed:=true;
  248. result:=ThreadID;
  249. end;
  250. procedure NoCriticalSection(var CS);
  251. begin
  252. if IsMultiThread then
  253. NoThreadError
  254. else
  255. ThreadingAlreadyUsed:=true;
  256. end;
  257. procedure NoInitThreadvar(var offset : dword;size : dword);
  258. begin
  259. NoThreadError;
  260. end;
  261. function NoRelocateThreadvar(offset : dword) : pointer;
  262. begin
  263. NoThreadError;
  264. end;
  265. procedure NoAllocateThreadVars;
  266. begin
  267. NoThreadError;
  268. end;
  269. procedure NoReleaseThreadVars;
  270. begin
  271. NoThreadError;
  272. end;
  273. function noBasicEventCreate(EventAttributes : Pointer; AManualReset,InitialState : Boolean;const Name : ansistring):pEventState;
  274. begin
  275. NoThreadError;
  276. end;
  277. procedure nobasiceventdestroy(state:peventstate);
  278. begin
  279. NoThreadError;
  280. end;
  281. procedure nobasiceventResetEvent(state:peventstate);
  282. begin
  283. NoThreadError;
  284. end;
  285. procedure nobasiceventSetEvent(state:peventstate);
  286. begin
  287. NoThreadError;
  288. end;
  289. function nobasiceventWaitFor(Timeout : Cardinal;state:peventstate) : longint;
  290. begin
  291. NoThreadError;
  292. end;
  293. function NORTLEventCreate :PRTLEvent;
  294. begin
  295. if IsMultiThread then
  296. NoThreadError
  297. else
  298. ThreadingAlreadyUsed:=true
  299. end;
  300. procedure NORTLeventdestroy(state:pRTLEvent);
  301. begin
  302. if IsMultiThread then
  303. NoThreadError
  304. else
  305. ThreadingAlreadyUsed:=true
  306. end;
  307. procedure NORTLeventSetEvent(state:pRTLEvent);
  308. begin
  309. NoThreadError;
  310. end;
  311. procedure NORTLeventStartWait(state:pRTLEvent);
  312. begin
  313. NoThreadError;
  314. end;
  315. procedure NORTLeventWaitFor(state:pRTLEvent);
  316. begin
  317. NoThreadError;
  318. end;
  319. procedure NORTLeventWaitForTimeout(state:pRTLEvent;timeout : longint);
  320. begin
  321. NoThreadError;
  322. end;
  323. procedure NORTLeventsync(m:trtlmethod;p:tprocedure);
  324. begin
  325. NoThreadError;
  326. end;
  327. Var
  328. NoThreadManager : TThreadManager;
  329. Procedure SetNoThreadManager;
  330. begin
  331. With NoThreadManager do
  332. begin
  333. InitManager :=Nil;
  334. DoneManager :=Nil;
  335. BeginThread :=@NoBeginThread;
  336. EndThread :=@NoEndThread;
  337. SuspendThread :=@NoThreadHandler;
  338. ResumeThread :=@NoThreadHandler;
  339. KillThread :=@NoThreadHandler;
  340. ThreadSwitch :=@NoThreadSwitch;
  341. WaitForThreadTerminate :=@NoWaitForThreadTerminate;
  342. ThreadSetPriority :=@NoThreadSetPriority;
  343. ThreadGetPriority :=@NoThreadGetPriority;
  344. GetCurrentThreadId :=@NoGetCurrentThreadId;
  345. InitCriticalSection :=@NoCriticalSection;
  346. DoneCriticalSection :=@NoCriticalSection;
  347. EnterCriticalSection :=@NoCriticalSection;
  348. LeaveCriticalSection :=@NoCriticalSection;
  349. InitThreadVar :=@NoInitThreadVar;
  350. RelocateThreadVar :=@NoRelocateThreadVar;
  351. AllocateThreadVars :=@NoAllocateThreadVars;
  352. ReleaseThreadVars :=@NoReleaseThreadVars;
  353. BasicEventCreate :=@NoBasicEventCreate;
  354. basiceventdestroy :=@Nobasiceventdestroy;
  355. basiceventResetEvent :=@NobasiceventResetEvent;
  356. basiceventSetEvent :=@NobasiceventSetEvent;
  357. basiceventWaitFor :=@NobasiceventWaitFor;
  358. rtlEventCreate :=@NortlEventCreate;
  359. rtleventdestroy :=@Nortleventdestroy;
  360. rtleventSetEvent :=@NortleventSetEvent;
  361. rtleventStartWait :=@NortleventStartWait;
  362. rtleventWaitFor :=@NortleventWaitFor;
  363. rtleventsync :=@Nortleventsync;
  364. rtleventwaitfortimeout :=@NortleventWaitForTimeout;
  365. end;
  366. SetThreadManager(NoThreadManager);
  367. end;
  368. {$endif DISABLE_NO_THREAD_MANAGER}