thread.inc 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548
  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. function BeginThread(sa : Pointer;stacksize : dword;
  38. ThreadFunction : tthreadfunc;p : pointer;creationFlags : dword;
  39. var ThreadId : Longint) : DWord;
  40. begin
  41. BeginThread:=BeginThread(nil,StackSize,ThreadFunction,p,creationFlags,THandle(THreadId));
  42. end;
  43. {$endif unix}
  44. {$endif CPU64}
  45. function BeginThread(ThreadFunction : tthreadfunc) : DWord;
  46. var
  47. dummy : THandle;
  48. begin
  49. BeginThread:=BeginThread(nil,DefaultStackSize,ThreadFunction,nil,0,dummy);
  50. end;
  51. function BeginThread(ThreadFunction : tthreadfunc;p : pointer) : DWord;
  52. var
  53. dummy : THandle;
  54. begin
  55. BeginThread:=BeginThread(nil,DefaultStackSize,ThreadFunction,p,0,dummy);
  56. end;
  57. function BeginThread(ThreadFunction : tthreadfunc;p : pointer;var ThreadId : THandle) : DWord;
  58. begin
  59. BeginThread:=BeginThread(nil,DefaultStackSize,ThreadFunction,p,0,ThreadId);
  60. end;
  61. {$ifndef CPU64}
  62. {$ifndef unix}
  63. function BeginThread(ThreadFunction : tthreadfunc;p : pointer;var ThreadId : Longint) : DWord;
  64. begin
  65. BeginThread:=BeginThread(nil,DefaultStackSize,ThreadFunction,p,0,THandle(ThreadId));
  66. end;
  67. {$endif unix}
  68. {$endif CPU64}
  69. procedure EndThread;
  70. begin
  71. EndThread(0);
  72. end;
  73. function BeginThread(sa : Pointer;stacksize : dword; ThreadFunction : tthreadfunc;p : pointer;creationFlags : dword; var ThreadId : THandle) : DWord;
  74. begin
  75. Result:=CurrentTM.BeginThread(sa,stacksize,threadfunction,P,creationflags,ThreadID);
  76. end;
  77. procedure EndThread(ExitCode : DWord);
  78. begin
  79. CurrentTM.EndThread(ExitCode);
  80. end;
  81. function SuspendThread (threadHandle : dword) : dword;
  82. begin
  83. Result:=CurrentTM.SuspendThread(ThreadHandle);
  84. end;
  85. function ResumeThread (threadHandle : dword) : dword;
  86. begin
  87. Result:=CurrentTM.ResumeThread(ThreadHandle);
  88. end;
  89. procedure ThreadSwitch;
  90. begin
  91. CurrentTM.ThreadSwitch;
  92. end;
  93. function KillThread (threadHandle : dword) : dword;
  94. begin
  95. Result:=CurrentTM.KillThread(ThreadHandle);
  96. end;
  97. function WaitForThreadTerminate (threadHandle : dword; TimeoutMs : longint) : dword;
  98. begin
  99. Result:=CurrentTM.WaitForThreadTerminate(ThreadHandle,TimeOutMS);
  100. end;
  101. function ThreadSetPriority (threadHandle : dword; Prio: longint): boolean;
  102. begin
  103. Result:=CurrentTM.ThreadSetPriority(ThreadHandle,Prio);
  104. end;
  105. function ThreadGetPriority (threadHandle : dword): Integer;
  106. begin
  107. Result:=CurrentTM.ThreadGetPriority(ThreadHandle);
  108. end;
  109. function GetCurrentThreadId : dword;
  110. begin
  111. Result:=CurrentTM.GetCurrentThreadID();
  112. end;
  113. procedure InitCriticalSection(var cs : TRTLCriticalSection);
  114. begin
  115. CurrentTM.InitCriticalSection(cs);
  116. end;
  117. procedure DoneCriticalsection(var cs : TRTLCriticalSection);
  118. begin
  119. CurrentTM.DoneCriticalSection(cs);
  120. end;
  121. procedure EnterCriticalsection(var cs : TRTLCriticalSection);
  122. begin
  123. CurrentTM.EnterCriticalSection(cs);
  124. end;
  125. procedure LeaveCriticalsection(var cs : TRTLCriticalSection);
  126. begin
  127. CurrentTM.LeaveCriticalSection(cs);
  128. end;
  129. Function GetThreadManager(Var TM : TThreadManager) : Boolean;
  130. begin
  131. TM:=CurrentTM;
  132. Result:=True;
  133. end;
  134. Function SetThreadManager(Const NewTM : TThreadManager; Var OldTM : TThreadManager) : Boolean;
  135. begin
  136. GetThreadManager(OldTM);
  137. Result:=SetThreadManager(NewTM);
  138. end;
  139. Function SetThreadManager(Const NewTM : TThreadManager) : Boolean;
  140. begin
  141. Result:=True;
  142. If Assigned(CurrentTM.DoneManager) then
  143. Result:=CurrentTM.DoneManager();
  144. If Result then
  145. begin
  146. CurrentTM:=NewTM;
  147. If Assigned(CurrentTM.InitManager) then
  148. Result:=CurrentTM.InitManager();
  149. end;
  150. end;
  151. function BasicEventCreate(EventAttributes : Pointer; AManualReset,InitialState : Boolean;const Name : ansistring):pEventState;
  152. begin
  153. result:=currenttm.BasicEventCreate(EventAttributes,AManualReset,InitialState, Name);
  154. end;
  155. procedure basiceventdestroy(state:peventstate);
  156. begin
  157. currenttm.basiceventdestroy(state);
  158. end;
  159. procedure basiceventResetEvent(state:peventstate);
  160. begin
  161. currenttm.basiceventResetEvent(state);
  162. end;
  163. procedure basiceventSetEvent(state:peventstate);
  164. begin
  165. currenttm.basiceventSetEvent(state);
  166. end;
  167. function basiceventWaitFor(Timeout : Cardinal;state:peventstate) : longint;
  168. begin
  169. result:=currenttm.basiceventWaitFor(Timeout,state);
  170. end;
  171. function RTLEventCreate :PRTLEvent;
  172. begin
  173. result:=currenttm.rtleventcreate();
  174. end;
  175. procedure RTLeventdestroy(state:pRTLEvent);
  176. begin
  177. currenttm.rtleventdestroy(state);
  178. end;
  179. procedure RTLeventSetEvent(state:pRTLEvent);
  180. begin
  181. currenttm.rtleventsetEvent(state);
  182. end;
  183. procedure RTLeventStartWait(state:pRTLEvent);
  184. begin
  185. currenttm.rtleventStartWait(state);
  186. end;
  187. procedure RTLeventWaitFor(state:pRTLEvent);
  188. begin
  189. currenttm.rtleventWaitFor(state);
  190. end;
  191. procedure RTLeventsync(m:trtlmethod;p:tprocedure);
  192. begin
  193. currenttm.rtleventsync(m,p);
  194. end;
  195. procedure RTLchecksynchronize;
  196. begin
  197. currenttm.rtlchksyncunix;
  198. end;
  199. { ---------------------------------------------------------------------
  200. ThreadManager which gives run-time error. Use if no thread support.
  201. ---------------------------------------------------------------------}
  202. {$ifndef DISABLE_NO_THREAD_MANAGER}
  203. Resourcestring
  204. SNoThreads = 'This binary has no thread support compiled in.';
  205. SRecompileWithThreads = 'Recompile the application with a thread-driver in the program uses clause.';
  206. Procedure NoThreadError;
  207. begin
  208. If IsConsole then
  209. begin
  210. Writeln(StdErr,SNoThreads);
  211. Writeln(StdErr,SRecompileWithThreads);
  212. end;
  213. RunError(232)
  214. end;
  215. function NoBeginThread(sa : Pointer;stacksize : dword;
  216. ThreadFunction : tthreadfunc;p : pointer;
  217. creationFlags : dword; var ThreadId : THandle) : DWord;
  218. begin
  219. NoThreadError;
  220. end;
  221. procedure NoEndThread(ExitCode : DWord);
  222. begin
  223. NoThreadError;
  224. end;
  225. function NoThreadHandler (threadHandle : dword) : dword;
  226. begin
  227. NoThreadError;
  228. end;
  229. procedure NoThreadSwitch; {give time to other threads}
  230. begin
  231. NoThreadError;
  232. end;
  233. function NoWaitForThreadTerminate (threadHandle : dword; TimeoutMs : longint) : dword; {0=no timeout}
  234. begin
  235. NoThreadError;
  236. end;
  237. function NoThreadSetPriority (threadHandle : dword; Prio: longint): boolean; {-15..+15, 0=normal}
  238. begin
  239. NoThreadError;
  240. end;
  241. function NoThreadGetPriority (threadHandle : dword): Integer;
  242. begin
  243. NoThreadError;
  244. end;
  245. function NoGetCurrentThreadId : dword;
  246. begin
  247. NoThreadError;
  248. end;
  249. procedure NoCriticalSection(var CS);
  250. begin
  251. NoThreadError;
  252. end;
  253. procedure NoInitThreadvar(var offset : dword;size : dword);
  254. begin
  255. NoThreadError;
  256. end;
  257. function NoRelocateThreadvar(offset : dword) : pointer;
  258. begin
  259. NoThreadError;
  260. end;
  261. procedure NoAllocateThreadVars;
  262. begin
  263. NoThreadError;
  264. end;
  265. procedure NoReleaseThreadVars;
  266. begin
  267. NoThreadError;
  268. end;
  269. function noBasicEventCreate(EventAttributes : Pointer; AManualReset,InitialState : Boolean;const Name : ansistring):pEventState;
  270. begin
  271. NoThreadError;
  272. end;
  273. procedure nobasiceventdestroy(state:peventstate);
  274. begin
  275. NoThreadError;
  276. end;
  277. procedure nobasiceventResetEvent(state:peventstate);
  278. begin
  279. NoThreadError;
  280. end;
  281. procedure nobasiceventSetEvent(state:peventstate);
  282. begin
  283. NoThreadError;
  284. end;
  285. function nobasiceventWaitFor(Timeout : Cardinal;state:peventstate) : longint;
  286. begin
  287. NoThreadError;
  288. end;
  289. function NORTLEventCreate :PRTLEvent;
  290. begin
  291. NoThreadError;
  292. end;
  293. procedure NORTLeventdestroy(state:pRTLEvent);
  294. begin
  295. NoThreadError;
  296. end;
  297. procedure NORTLeventSetEvent(state:pRTLEvent);
  298. begin
  299. NoThreadError;
  300. end;
  301. procedure NORTLeventStartWait(state:pRTLEvent);
  302. begin
  303. NoThreadError;
  304. end;
  305. procedure NORTLeventWaitFor(state:pRTLEvent);
  306. begin
  307. NoThreadError;
  308. end;
  309. procedure NORTLeventsync(m:trtlmethod;p:tprocedure);
  310. begin
  311. NoThreadError;
  312. end;
  313. procedure NORTLChkSyncUnix;
  314. begin
  315. NoThreadError;
  316. end;
  317. Var
  318. NoThreadManager : TThreadManager;
  319. Procedure SetNoThreadManager;
  320. begin
  321. With NoThreadManager do
  322. begin
  323. InitManager :=Nil;
  324. DoneManager :=Nil;
  325. BeginThread :=@NoBeginThread;
  326. EndThread :=@NoEndThread;
  327. SuspendThread :=@NoThreadHandler;
  328. ResumeThread :=@NoThreadHandler;
  329. KillThread :=@NoThreadHandler;
  330. ThreadSwitch :=@NoThreadSwitch;
  331. WaitForThreadTerminate :=@NoWaitForThreadTerminate;
  332. ThreadSetPriority :=@NoThreadSetPriority;
  333. ThreadGetPriority :=@NoThreadGetPriority;
  334. GetCurrentThreadId :=@NoGetCurrentThreadId;
  335. InitCriticalSection :=@NoCriticalSection;
  336. DoneCriticalSection :=@NoCriticalSection;
  337. EnterCriticalSection :=@NoCriticalSection;
  338. LeaveCriticalSection :=@NoCriticalSection;
  339. InitThreadVar :=@NoInitThreadVar;
  340. RelocateThreadVar :=@NoRelocateThreadVar;
  341. AllocateThreadVars :=@NoAllocateThreadVars;
  342. ReleaseThreadVars :=@NoReleaseThreadVars;
  343. BasicEventCreate :=@NoBasicEventCreate;
  344. basiceventdestroy :=@Nobasiceventdestroy;
  345. basiceventResetEvent :=@NobasiceventResetEvent;
  346. basiceventSetEvent :=@NobasiceventSetEvent;
  347. basiceventWaitFor :=@NobasiceventWaitFor;
  348. rtlEventCreate :=@NortlEventCreate;
  349. rtleventdestroy :=@Nortleventdestroy;
  350. rtleventSetEvent :=@NortleventSetEvent;
  351. rtleventStartWait :=@NortleventStartWait;
  352. rtleventWaitFor :=@NortleventWaitFor;
  353. rtleventsync :=@Nortleventsync;
  354. rtlchksyncunix :=@nortlchksyncunix;
  355. end;
  356. SetThreadManager(NoThreadManager);
  357. end;
  358. {$endif DISABLE_NO_THREAD_MANAGER}
  359. {
  360. $Log$
  361. Revision 1.17 2004-12-28 14:20:03 marco
  362. * tthread patch from neli
  363. Revision 1.16 2004/12/27 15:28:40 marco
  364. * checksynchronize now in interface win32 uses the default impl.
  365. unix uses systhrds, rest empty implementation.
  366. Revision 1.15 2004/12/23 20:58:22 peter
  367. * fix rtlcreateevent
  368. Revision 1.14 2004/12/23 15:08:58 marco
  369. * 2nd synchronize attempt. cthreads<->systhrds difference was not ok, but
  370. only showed on make install should be fixed now.
  371. Revision 1.13 2004/12/22 21:29:24 marco
  372. * rtlevent kraam. Checked (compile): Linux, FreeBSD, Darwin, Windows
  373. Check work: ask Neli.
  374. Revision 1.12 2004/09/19 18:55:30 armin
  375. * added define DISABLE_NO_THREAD_MANAGER to avoid warnings if thread manager is always present
  376. Revision 1.11 2004/05/23 20:26:20 marco
  377. * wrappers and nothread prototypes for the basic* functions
  378. Revision 1.10 2004/02/22 23:22:49 florian
  379. * fixed BeginThread on unix
  380. Revision 1.9 2004/02/22 16:48:39 florian
  381. * several 64 bit issues fixed
  382. Revision 1.8 2004/01/21 20:11:06 peter
  383. * fixed compile for unix
  384. Revision 1.7 2004/01/20 23:13:53 hajny
  385. * ExecuteProcess fixes, ProcessID and ThreadID added
  386. Revision 1.6 2003/11/29 17:33:09 michael
  387. + Removed dummy variable from SetNothreadManager
  388. Revision 1.5 2003/11/29 17:29:32 michael
  389. + Added overloaded version of SetThreadManager without old parameter
  390. Revision 1.4 2003/11/26 20:10:59 michael
  391. + New threadmanager implementation
  392. Revision 1.3 2002/11/14 12:40:06 jonas
  393. * the BeginThread() variant that allowed you to specify the stacksize
  394. still passed DefaultStackSize to the OS-specific routines
  395. Revision 1.2 2002/10/16 19:04:27 michael
  396. + More system-independent thread routines
  397. Revision 1.1 2002/10/14 19:39:17 peter
  398. * threads unit added for thread support
  399. }