thread.inc 12 KB

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