thread.inc 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544
  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:cardinal);
  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:=stklen;
  28. StackBottom:=Sptr - StackLength;
  29. ThreadID := CurrentTM.GetCurrentThreadID();
  30. end;
  31. {*****************************************************************************
  32. Overloaded functions
  33. *****************************************************************************}
  34. {$ifndef CPU64}
  35. {$ifndef unix}
  36. {$endif unix}
  37. {$endif CPU64}
  38. function BeginThread(ThreadFunction : tthreadfunc) : DWord;
  39. var
  40. dummy : TThreadID;
  41. begin
  42. BeginThread:=BeginThread(nil,DefaultStackSize,ThreadFunction,nil,0,dummy);
  43. end;
  44. function BeginThread(ThreadFunction : tthreadfunc;p : pointer) : DWord;
  45. var
  46. dummy : TThreadID;
  47. begin
  48. BeginThread:=BeginThread(nil,DefaultStackSize,ThreadFunction,p,0,dummy);
  49. end;
  50. function BeginThread(ThreadFunction : tthreadfunc;p : pointer;var ThreadId : TThreadID) : DWord;
  51. begin
  52. BeginThread:=BeginThread(nil,DefaultStackSize,ThreadFunction,p,0,ThreadId);
  53. end;
  54. {$ifndef CPU64}
  55. {$ifndef unix}
  56. {$endif unix}
  57. {$endif CPU64}
  58. procedure EndThread;
  59. begin
  60. EndThread(0);
  61. end;
  62. function BeginThread(sa : Pointer;stacksize : dword; ThreadFunction : tthreadfunc;p : pointer;creationFlags : dword; var ThreadId : TThreadID) : DWord;
  63. begin
  64. Result:=CurrentTM.BeginThread(sa,stacksize,threadfunction,P,creationflags,ThreadID);
  65. end;
  66. procedure EndThread(ExitCode : DWord);
  67. begin
  68. CurrentTM.EndThread(ExitCode);
  69. end;
  70. function SuspendThread (threadHandle : TThreadID) : dword;
  71. begin
  72. Result:=CurrentTM.SuspendThread(ThreadHandle);
  73. end;
  74. function ResumeThread (threadHandle : TThreadID) : dword;
  75. begin
  76. Result:=CurrentTM.ResumeThread(ThreadHandle);
  77. end;
  78. procedure ThreadSwitch;
  79. begin
  80. CurrentTM.ThreadSwitch;
  81. end;
  82. function KillThread (threadHandle : TThreadID) : dword;
  83. begin
  84. Result:=CurrentTM.KillThread(ThreadHandle);
  85. end;
  86. function WaitForThreadTerminate (threadHandle : TThreadID; TimeoutMs : longint) : dword;
  87. begin
  88. Result:=CurrentTM.WaitForThreadTerminate(ThreadHandle,TimeOutMS);
  89. end;
  90. function ThreadSetPriority (threadHandle : TThreadID; Prio: longint): boolean;
  91. begin
  92. Result:=CurrentTM.ThreadSetPriority(ThreadHandle,Prio);
  93. end;
  94. function ThreadGetPriority (threadHandle : TThreadID): longint;
  95. begin
  96. Result:=CurrentTM.ThreadGetPriority(ThreadHandle);
  97. end;
  98. function GetCurrentThreadId : TThreadID;
  99. begin
  100. Result:=CurrentTM.GetCurrentThreadID();
  101. end;
  102. procedure InitCriticalSection(var cs : TRTLCriticalSection);
  103. begin
  104. CurrentTM.InitCriticalSection(cs);
  105. end;
  106. procedure DoneCriticalsection(var cs : TRTLCriticalSection);
  107. begin
  108. CurrentTM.DoneCriticalSection(cs);
  109. end;
  110. procedure EnterCriticalsection(var cs : TRTLCriticalSection);
  111. begin
  112. CurrentTM.EnterCriticalSection(cs);
  113. end;
  114. procedure LeaveCriticalsection(var cs : TRTLCriticalSection);
  115. begin
  116. CurrentTM.LeaveCriticalSection(cs);
  117. end;
  118. Function GetThreadManager(Var TM : TThreadManager) : Boolean;
  119. begin
  120. TM:=CurrentTM;
  121. Result:=True;
  122. end;
  123. Function SetThreadManager(Const NewTM : TThreadManager; Var OldTM : TThreadManager) : Boolean;
  124. begin
  125. GetThreadManager(OldTM);
  126. Result:=SetThreadManager(NewTM);
  127. end;
  128. Function SetThreadManager(Const NewTM : TThreadManager) : Boolean;
  129. begin
  130. Result:=True;
  131. If Assigned(CurrentTM.DoneManager) then
  132. Result:=CurrentTM.DoneManager();
  133. If Result then
  134. begin
  135. CurrentTM:=NewTM;
  136. If Assigned(CurrentTM.InitManager) then
  137. Result:=CurrentTM.InitManager();
  138. end;
  139. end;
  140. function BasicEventCreate(EventAttributes : Pointer; AManualReset,InitialState : Boolean;const Name : ansistring):pEventState;
  141. begin
  142. result:=currenttm.BasicEventCreate(EventAttributes,AManualReset,InitialState, Name);
  143. end;
  144. procedure basiceventdestroy(state:peventstate);
  145. begin
  146. currenttm.basiceventdestroy(state);
  147. end;
  148. procedure basiceventResetEvent(state:peventstate);
  149. begin
  150. currenttm.basiceventResetEvent(state);
  151. end;
  152. procedure basiceventSetEvent(state:peventstate);
  153. begin
  154. currenttm.basiceventSetEvent(state);
  155. end;
  156. function basiceventWaitFor(Timeout : Cardinal;state:peventstate) : longint;
  157. begin
  158. result:=currenttm.basiceventWaitFor(Timeout,state);
  159. end;
  160. function RTLEventCreate :PRTLEvent;
  161. begin
  162. result:=currenttm.rtleventcreate();
  163. end;
  164. procedure RTLeventdestroy(state:pRTLEvent);
  165. begin
  166. currenttm.rtleventdestroy(state);
  167. end;
  168. procedure RTLeventSetEvent(state:pRTLEvent);
  169. begin
  170. currenttm.rtleventsetEvent(state);
  171. end;
  172. procedure RTLeventResetEvent(state:pRTLEvent);
  173. begin
  174. currenttm.rtleventResetEvent(state);
  175. end;
  176. procedure RTLeventStartWait(state:pRTLEvent);
  177. begin
  178. currenttm.rtleventStartWait(state);
  179. end;
  180. procedure RTLeventWaitFor(state:pRTLEvent);
  181. begin
  182. currenttm.rtleventWaitFor(state);
  183. end;
  184. procedure RTLeventWaitFor(state:pRTLEvent;timeout : longint);
  185. begin
  186. currenttm.rtleventWaitForTimeout(state,timeout);
  187. end;
  188. procedure RTLeventsync(m:trtlmethod;p:tprocedure);
  189. begin
  190. currenttm.rtleventsync(m,p);
  191. end;
  192. { ---------------------------------------------------------------------
  193. ThreadManager which gives run-time error. Use if no thread support.
  194. ---------------------------------------------------------------------}
  195. {$ifndef DISABLE_NO_THREAD_MANAGER}
  196. { resourcestrings are not supported by the system unit,
  197. they are in the objpas unit and not available for fpc/tp modes }
  198. const
  199. SNoThreads = 'This binary has no thread support compiled in.';
  200. SRecompileWithThreads = 'Recompile the application with a thread-driver in the program uses clause before other units using thread.';
  201. Procedure NoThreadError;
  202. begin
  203. If IsConsole then
  204. begin
  205. Writeln(StdErr,SNoThreads);
  206. Writeln(StdErr,SRecompileWithThreads);
  207. end;
  208. RunError(232)
  209. end;
  210. function NoBeginThread(sa : Pointer;stacksize : dword;
  211. ThreadFunction : tthreadfunc;p : pointer;
  212. creationFlags : dword; var ThreadId : TThreadID) : DWord;
  213. begin
  214. NoThreadError;
  215. end;
  216. procedure NoEndThread(ExitCode : DWord);
  217. begin
  218. NoThreadError;
  219. end;
  220. function NoThreadHandler (threadHandle : TThreadID) : dword;
  221. begin
  222. NoThreadError;
  223. end;
  224. procedure NoThreadSwitch; {give time to other threads}
  225. begin
  226. NoThreadError;
  227. end;
  228. function NoWaitForThreadTerminate (threadHandle : TThreadID; TimeoutMs : longint) : dword; {0=no timeout}
  229. begin
  230. NoThreadError;
  231. end;
  232. function NoThreadSetPriority (threadHandle : TThreadID; Prio: longint): boolean; {-15..+15, 0=normal}
  233. begin
  234. NoThreadError;
  235. end;
  236. function NoThreadGetPriority (threadHandle : TThreadID): longint;
  237. begin
  238. NoThreadError;
  239. end;
  240. function NoGetCurrentThreadId : TThreadID;
  241. begin
  242. if IsMultiThread then
  243. NoThreadError
  244. else
  245. ThreadingAlreadyUsed:=true;
  246. result:=ThreadID;
  247. end;
  248. procedure NoCriticalSection(var CS);
  249. begin
  250. if IsMultiThread then
  251. NoThreadError
  252. else
  253. ThreadingAlreadyUsed:=true;
  254. end;
  255. procedure NoInitThreadvar(var offset : dword;size : dword);
  256. begin
  257. NoThreadError;
  258. end;
  259. function NoRelocateThreadvar(offset : dword) : pointer;
  260. begin
  261. NoThreadError;
  262. end;
  263. procedure NoAllocateThreadVars;
  264. begin
  265. NoThreadError;
  266. end;
  267. procedure NoReleaseThreadVars;
  268. begin
  269. NoThreadError;
  270. end;
  271. function noBasicEventCreate(EventAttributes : Pointer; AManualReset,InitialState : Boolean;const Name : ansistring):pEventState;
  272. begin
  273. NoThreadError;
  274. end;
  275. procedure nobasiceventdestroy(state:peventstate);
  276. begin
  277. NoThreadError;
  278. end;
  279. procedure nobasiceventResetEvent(state:peventstate);
  280. begin
  281. NoThreadError;
  282. end;
  283. procedure nobasiceventSetEvent(state:peventstate);
  284. begin
  285. NoThreadError;
  286. end;
  287. function nobasiceventWaitFor(Timeout : Cardinal;state:peventstate) : longint;
  288. begin
  289. NoThreadError;
  290. end;
  291. function NORTLEventCreate :PRTLEvent;
  292. begin
  293. if IsMultiThread then
  294. NoThreadError
  295. else
  296. ThreadingAlreadyUsed:=true
  297. end;
  298. procedure NORTLeventdestroy(state:pRTLEvent);
  299. begin
  300. if IsMultiThread then
  301. NoThreadError
  302. else
  303. ThreadingAlreadyUsed:=true
  304. end;
  305. procedure NORTLeventSetEvent(state:pRTLEvent);
  306. begin
  307. NoThreadError;
  308. end;
  309. procedure NORTLeventStartWait(state:pRTLEvent);
  310. begin
  311. NoThreadError;
  312. end;
  313. procedure NORTLeventWaitFor(state:pRTLEvent);
  314. begin
  315. NoThreadError;
  316. end;
  317. procedure NORTLeventWaitForTimeout(state:pRTLEvent;timeout : longint);
  318. begin
  319. NoThreadError;
  320. end;
  321. procedure NORTLeventsync(m:trtlmethod;p:tprocedure);
  322. begin
  323. NoThreadError;
  324. end;
  325. Var
  326. NoThreadManager : TThreadManager;
  327. Procedure SetNoThreadManager;
  328. begin
  329. With NoThreadManager do
  330. begin
  331. InitManager :=Nil;
  332. DoneManager :=Nil;
  333. BeginThread :=@NoBeginThread;
  334. EndThread :=@NoEndThread;
  335. SuspendThread :=@NoThreadHandler;
  336. ResumeThread :=@NoThreadHandler;
  337. KillThread :=@NoThreadHandler;
  338. ThreadSwitch :=@NoThreadSwitch;
  339. WaitForThreadTerminate :=@NoWaitForThreadTerminate;
  340. ThreadSetPriority :=@NoThreadSetPriority;
  341. ThreadGetPriority :=@NoThreadGetPriority;
  342. GetCurrentThreadId :=@NoGetCurrentThreadId;
  343. InitCriticalSection :=@NoCriticalSection;
  344. DoneCriticalSection :=@NoCriticalSection;
  345. EnterCriticalSection :=@NoCriticalSection;
  346. LeaveCriticalSection :=@NoCriticalSection;
  347. InitThreadVar :=@NoInitThreadVar;
  348. RelocateThreadVar :=@NoRelocateThreadVar;
  349. AllocateThreadVars :=@NoAllocateThreadVars;
  350. ReleaseThreadVars :=@NoReleaseThreadVars;
  351. BasicEventCreate :=@NoBasicEventCreate;
  352. basiceventdestroy :=@Nobasiceventdestroy;
  353. basiceventResetEvent :=@NobasiceventResetEvent;
  354. basiceventSetEvent :=@NobasiceventSetEvent;
  355. basiceventWaitFor :=@NobasiceventWaitFor;
  356. rtlEventCreate :=@NortlEventCreate;
  357. rtleventdestroy :=@Nortleventdestroy;
  358. rtleventSetEvent :=@NortleventSetEvent;
  359. rtleventStartWait :=@NortleventStartWait;
  360. rtleventWaitFor :=@NortleventWaitFor;
  361. rtleventsync :=@Nortleventsync;
  362. rtleventwaitfortimeout :=@NortleventWaitForTimeout;
  363. end;
  364. SetThreadManager(NoThreadManager);
  365. end;
  366. {$endif DISABLE_NO_THREAD_MANAGER}
  367. {
  368. $Log: thread.inc,v $
  369. Revision 1.30 2005/04/20 07:41:48 hajny
  370. * two more (TThreadID)
  371. Revision 1.29 2005/04/17 17:19:41 hajny
  372. * one more TThreadID fix
  373. Revision 1.28 2005/04/14 20:42:14 florian
  374. * fixed more TThreadID stuff
  375. Revision 1.27 2005/04/13 20:15:47 florian
  376. * TThread on linux fixed
  377. Revision 1.26 2005/04/09 17:26:08 florian
  378. + classes.mainthreadid is set now
  379. + rtleventresetevent
  380. + rtleventwairfor with timeout
  381. + checksynchronize with timeout
  382. * race condition in synchronize fixed
  383. Revision 1.25 2005/04/03 19:29:28 florian
  384. * proper error message if the cthreads unit is included too late
  385. uses clause
  386. Revision 1.24 2005/02/26 11:40:38 florian
  387. * rtl event init/destroy throws only an error if it's used in a mult threaded program
  388. Revision 1.23 2005/02/25 22:02:46 florian
  389. * another "transfer to linux"-commit
  390. Revision 1.22 2005/02/14 17:13:29 peter
  391. * truncate log
  392. Revision 1.21 2005/02/07 17:36:54 peter
  393. can't use resourcestrings in the system unit
  394. Revision 1.20 2005/02/06 11:20:52 peter
  395. * threading in system unit
  396. * removed systhrds unit
  397. Revision 1.19 2005/01/21 21:45:57 armin
  398. * applied patch to compile go32v2 from Tomas (tested by John)
  399. Revision 1.18 2005/01/16 14:46:57 florian
  400. * critical sections can be used in programs without threading driver, they have no effect then
  401. }