thread.inc 12 KB

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