thread.inc 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554
  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 : THandle) : 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 : dword) : dword;
  72. begin
  73. Result:=CurrentTM.SuspendThread(ThreadHandle);
  74. end;
  75. function ResumeThread (threadHandle : dword) : dword;
  76. begin
  77. Result:=CurrentTM.ResumeThread(ThreadHandle);
  78. end;
  79. procedure ThreadSwitch;
  80. begin
  81. CurrentTM.ThreadSwitch;
  82. end;
  83. function KillThread (threadHandle : dword) : dword;
  84. begin
  85. Result:=CurrentTM.KillThread(ThreadHandle);
  86. end;
  87. function WaitForThreadTerminate (threadHandle : dword; TimeoutMs : longint) : dword;
  88. begin
  89. Result:=CurrentTM.WaitForThreadTerminate(ThreadHandle,TimeOutMS);
  90. end;
  91. function ThreadSetPriority (threadHandle : dword; Prio: longint): boolean;
  92. begin
  93. Result:=CurrentTM.ThreadSetPriority(ThreadHandle,Prio);
  94. end;
  95. function ThreadGetPriority (threadHandle : dword): longint;
  96. begin
  97. Result:=CurrentTM.ThreadGetPriority(ThreadHandle);
  98. end;
  99. function GetCurrentThreadId : dword;
  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 RTLeventStartWait(state:pRTLEvent);
  174. begin
  175. currenttm.rtleventStartWait(state);
  176. end;
  177. procedure RTLeventWaitFor(state:pRTLEvent);
  178. begin
  179. currenttm.rtleventWaitFor(state);
  180. end;
  181. procedure RTLeventsync(m:trtlmethod;p:tprocedure);
  182. begin
  183. currenttm.rtleventsync(m,p);
  184. end;
  185. procedure RTLchecksynchronize;
  186. begin
  187. currenttm.rtlchksyncunix;
  188. end;
  189. { ---------------------------------------------------------------------
  190. ThreadManager which gives run-time error. Use if no thread support.
  191. ---------------------------------------------------------------------}
  192. {$ifndef DISABLE_NO_THREAD_MANAGER}
  193. { resourcestrings are not supported by the system unit,
  194. they are in the objpas unit and not available for fpc/tp modes }
  195. const
  196. SNoThreads = 'This binary has no thread support compiled in.';
  197. SRecompileWithThreads = 'Recompile the application with a thread-driver in the program uses clause before other units using thread.';
  198. Procedure NoThreadError;
  199. begin
  200. If IsConsole then
  201. begin
  202. Writeln(StdErr,SNoThreads);
  203. Writeln(StdErr,SRecompileWithThreads);
  204. end;
  205. RunError(232)
  206. end;
  207. function NoBeginThread(sa : Pointer;stacksize : dword;
  208. ThreadFunction : tthreadfunc;p : pointer;
  209. creationFlags : dword; var ThreadId : THandle) : DWord;
  210. begin
  211. NoThreadError;
  212. end;
  213. procedure NoEndThread(ExitCode : DWord);
  214. begin
  215. NoThreadError;
  216. end;
  217. function NoThreadHandler (threadHandle : dword) : dword;
  218. begin
  219. NoThreadError;
  220. end;
  221. procedure NoThreadSwitch; {give time to other threads}
  222. begin
  223. NoThreadError;
  224. end;
  225. function NoWaitForThreadTerminate (threadHandle : dword; TimeoutMs : longint) : dword; {0=no timeout}
  226. begin
  227. NoThreadError;
  228. end;
  229. function NoThreadSetPriority (threadHandle : dword; Prio: longint): boolean; {-15..+15, 0=normal}
  230. begin
  231. NoThreadError;
  232. end;
  233. function NoThreadGetPriority (threadHandle : dword): longint;
  234. begin
  235. NoThreadError;
  236. end;
  237. function NoGetCurrentThreadId : dword;
  238. begin
  239. NoThreadError;
  240. end;
  241. procedure NoCriticalSection(var CS);
  242. begin
  243. if IsMultiThread then
  244. NoThreadError;
  245. end;
  246. procedure NoInitThreadvar(var offset : dword;size : dword);
  247. begin
  248. NoThreadError;
  249. end;
  250. function NoRelocateThreadvar(offset : dword) : pointer;
  251. begin
  252. NoThreadError;
  253. end;
  254. procedure NoAllocateThreadVars;
  255. begin
  256. NoThreadError;
  257. end;
  258. procedure NoReleaseThreadVars;
  259. begin
  260. NoThreadError;
  261. end;
  262. function noBasicEventCreate(EventAttributes : Pointer; AManualReset,InitialState : Boolean;const Name : ansistring):pEventState;
  263. begin
  264. NoThreadError;
  265. end;
  266. procedure nobasiceventdestroy(state:peventstate);
  267. begin
  268. NoThreadError;
  269. end;
  270. procedure nobasiceventResetEvent(state:peventstate);
  271. begin
  272. NoThreadError;
  273. end;
  274. procedure nobasiceventSetEvent(state:peventstate);
  275. begin
  276. NoThreadError;
  277. end;
  278. function nobasiceventWaitFor(Timeout : Cardinal;state:peventstate) : longint;
  279. begin
  280. NoThreadError;
  281. end;
  282. function NORTLEventCreate :PRTLEvent;
  283. begin
  284. NoThreadError;
  285. end;
  286. procedure NORTLeventdestroy(state:pRTLEvent);
  287. begin
  288. NoThreadError;
  289. end;
  290. procedure NORTLeventSetEvent(state:pRTLEvent);
  291. begin
  292. NoThreadError;
  293. end;
  294. procedure NORTLeventStartWait(state:pRTLEvent);
  295. begin
  296. NoThreadError;
  297. end;
  298. procedure NORTLeventWaitFor(state:pRTLEvent);
  299. begin
  300. NoThreadError;
  301. end;
  302. procedure NORTLeventsync(m:trtlmethod;p:tprocedure);
  303. begin
  304. NoThreadError;
  305. end;
  306. procedure NORTLChkSyncUnix;
  307. begin
  308. NoThreadError;
  309. end;
  310. Var
  311. NoThreadManager : TThreadManager;
  312. Procedure SetNoThreadManager;
  313. begin
  314. With NoThreadManager do
  315. begin
  316. InitManager :=Nil;
  317. DoneManager :=Nil;
  318. BeginThread :=@NoBeginThread;
  319. EndThread :=@NoEndThread;
  320. SuspendThread :=@NoThreadHandler;
  321. ResumeThread :=@NoThreadHandler;
  322. KillThread :=@NoThreadHandler;
  323. ThreadSwitch :=@NoThreadSwitch;
  324. WaitForThreadTerminate :=@NoWaitForThreadTerminate;
  325. ThreadSetPriority :=@NoThreadSetPriority;
  326. ThreadGetPriority :=@NoThreadGetPriority;
  327. GetCurrentThreadId :=@NoGetCurrentThreadId;
  328. InitCriticalSection :=@NoCriticalSection;
  329. DoneCriticalSection :=@NoCriticalSection;
  330. EnterCriticalSection :=@NoCriticalSection;
  331. LeaveCriticalSection :=@NoCriticalSection;
  332. InitThreadVar :=@NoInitThreadVar;
  333. RelocateThreadVar :=@NoRelocateThreadVar;
  334. AllocateThreadVars :=@NoAllocateThreadVars;
  335. ReleaseThreadVars :=@NoReleaseThreadVars;
  336. BasicEventCreate :=@NoBasicEventCreate;
  337. basiceventdestroy :=@Nobasiceventdestroy;
  338. basiceventResetEvent :=@NobasiceventResetEvent;
  339. basiceventSetEvent :=@NobasiceventSetEvent;
  340. basiceventWaitFor :=@NobasiceventWaitFor;
  341. rtlEventCreate :=@NortlEventCreate;
  342. rtleventdestroy :=@Nortleventdestroy;
  343. rtleventSetEvent :=@NortleventSetEvent;
  344. rtleventStartWait :=@NortleventStartWait;
  345. rtleventWaitFor :=@NortleventWaitFor;
  346. rtleventsync :=@Nortleventsync;
  347. rtlchksyncunix :=@nortlchksyncunix;
  348. end;
  349. SetThreadManager(NoThreadManager);
  350. end;
  351. {$endif DISABLE_NO_THREAD_MANAGER}
  352. {
  353. $Log$
  354. Revision 1.21 2005-02-07 17:36:54 peter
  355. can't use resourcestrings in the system unit
  356. Revision 1.20 2005/02/06 11:20:52 peter
  357. * threading in system unit
  358. * removed systhrds unit
  359. Revision 1.19 2005/01/21 21:45:57 armin
  360. * applied patch to compile go32v2 from Tomas (tested by John)
  361. Revision 1.18 2005/01/16 14:46:57 florian
  362. * critical sections can be used in programs without threading driver, they have no effect then
  363. Revision 1.17 2004/12/28 14:20:03 marco
  364. * tthread patch from neli
  365. Revision 1.16 2004/12/27 15:28:40 marco
  366. * checksynchronize now in interface win32 uses the default impl.
  367. unix uses systhrds, rest empty implementation.
  368. Revision 1.15 2004/12/23 20:58:22 peter
  369. * fix rtlcreateevent
  370. Revision 1.14 2004/12/23 15:08:58 marco
  371. * 2nd synchronize attempt. cthreads<->systhrds difference was not ok, but
  372. only showed on make install should be fixed now.
  373. Revision 1.13 2004/12/22 21:29:24 marco
  374. * rtlevent kraam. Checked (compile): Linux, FreeBSD, Darwin, Windows
  375. Check work: ask Neli.
  376. Revision 1.12 2004/09/19 18:55:30 armin
  377. * added define DISABLE_NO_THREAD_MANAGER to avoid warnings if thread manager is always present
  378. Revision 1.11 2004/05/23 20:26:20 marco
  379. * wrappers and nothread prototypes for the basic* functions
  380. Revision 1.10 2004/02/22 23:22:49 florian
  381. * fixed BeginThread on unix
  382. Revision 1.9 2004/02/22 16:48:39 florian
  383. * several 64 bit issues fixed
  384. Revision 1.8 2004/01/21 20:11:06 peter
  385. * fixed compile for unix
  386. Revision 1.7 2004/01/20 23:13:53 hajny
  387. * ExecuteProcess fixes, ProcessID and ThreadID added
  388. Revision 1.6 2003/11/29 17:33:09 michael
  389. + Removed dummy variable from SetNothreadManager
  390. Revision 1.5 2003/11/29 17:29:32 michael
  391. + Added overloaded version of SetThreadManager without old parameter
  392. Revision 1.4 2003/11/26 20:10:59 michael
  393. + New threadmanager implementation
  394. Revision 1.3 2002/11/14 12:40:06 jonas
  395. * the BeginThread() variant that allowed you to specify the stacksize
  396. still passed DefaultStackSize to the OS-specific routines
  397. Revision 1.2 2002/10/16 19:04:27 michael
  398. + More system-independent thread routines
  399. Revision 1.1 2002/10/14 19:39:17 peter
  400. * threads unit added for thread support
  401. }