thread.inc 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492
  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:SizeUInt);
  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. function BeginThread(ThreadFunction : tthreadfunc) : TThreadID;
  35. var
  36. dummy : TThreadID;
  37. begin
  38. BeginThread:=BeginThread(nil,DefaultStackSize,ThreadFunction,nil,0,dummy);
  39. end;
  40. function BeginThread(ThreadFunction : tthreadfunc;p : pointer) : TThreadID;
  41. var
  42. dummy : TThreadID;
  43. begin
  44. BeginThread:=BeginThread(nil,DefaultStackSize,ThreadFunction,p,0,dummy);
  45. end;
  46. function BeginThread(ThreadFunction : tthreadfunc;p : pointer;var ThreadId : TThreadID) : TThreadID;
  47. begin
  48. BeginThread:=BeginThread(nil,DefaultStackSize,ThreadFunction,p,0,ThreadId);
  49. end;
  50. function BeginThread(ThreadFunction : tthreadfunc;p : pointer;
  51. var ThreadId : TThreadID; const stacksize: SizeUInt) : TThreadID;
  52. begin
  53. BeginThread:=BeginThread(nil,stacksize,ThreadFunction,p,0,ThreadId);
  54. end;
  55. procedure EndThread;
  56. begin
  57. EndThread(0);
  58. end;
  59. function BeginThread(sa : Pointer;stacksize : SizeUInt; ThreadFunction : tthreadfunc;p : pointer;creationFlags : dword; var ThreadId : TThreadID) : TThreadID;
  60. begin
  61. Result:=CurrentTM.BeginThread(sa,stacksize,threadfunction,P,creationflags,ThreadID);
  62. end;
  63. procedure EndThread(ExitCode : DWord);
  64. begin
  65. CurrentTM.EndThread(ExitCode);
  66. end;
  67. function SuspendThread (threadHandle : TThreadID) : dword;
  68. begin
  69. Result:=CurrentTM.SuspendThread(ThreadHandle);
  70. end;
  71. function ResumeThread (threadHandle : TThreadID) : dword;
  72. begin
  73. Result:=CurrentTM.ResumeThread(ThreadHandle);
  74. end;
  75. procedure ThreadSwitch;
  76. begin
  77. CurrentTM.ThreadSwitch;
  78. end;
  79. function KillThread (threadHandle : TThreadID) : dword;
  80. begin
  81. Result:=CurrentTM.KillThread(ThreadHandle);
  82. end;
  83. function WaitForThreadTerminate (threadHandle : TThreadID; TimeoutMs : longint) : dword;
  84. begin
  85. Result:=CurrentTM.WaitForThreadTerminate(ThreadHandle,TimeOutMS);
  86. end;
  87. function ThreadSetPriority (threadHandle : TThreadID; Prio: longint): boolean;
  88. begin
  89. Result:=CurrentTM.ThreadSetPriority(ThreadHandle,Prio);
  90. end;
  91. function ThreadGetPriority (threadHandle : TThreadID): longint;
  92. begin
  93. Result:=CurrentTM.ThreadGetPriority(ThreadHandle);
  94. end;
  95. function GetCurrentThreadId : TThreadID;
  96. begin
  97. Result:=CurrentTM.GetCurrentThreadID();
  98. end;
  99. procedure InitCriticalSection(var cs : TRTLCriticalSection);
  100. begin
  101. CurrentTM.InitCriticalSection(cs);
  102. end;
  103. procedure DoneCriticalsection(var cs : TRTLCriticalSection);
  104. begin
  105. CurrentTM.DoneCriticalSection(cs);
  106. end;
  107. procedure EnterCriticalsection(var cs : TRTLCriticalSection);
  108. begin
  109. CurrentTM.EnterCriticalSection(cs);
  110. end;
  111. procedure LeaveCriticalsection(var cs : TRTLCriticalSection);
  112. begin
  113. CurrentTM.LeaveCriticalSection(cs);
  114. end;
  115. Function GetThreadManager(Var TM : TThreadManager) : Boolean;
  116. begin
  117. TM:=CurrentTM;
  118. Result:=True;
  119. end;
  120. Function SetThreadManager(Const NewTM : TThreadManager; Var OldTM : TThreadManager) : Boolean;
  121. begin
  122. GetThreadManager(OldTM);
  123. Result:=SetThreadManager(NewTM);
  124. end;
  125. Function SetThreadManager(Const NewTM : TThreadManager) : Boolean;
  126. begin
  127. Result:=True;
  128. If Assigned(CurrentTM.DoneManager) then
  129. Result:=CurrentTM.DoneManager();
  130. If Result then
  131. begin
  132. CurrentTM:=NewTM;
  133. If Assigned(CurrentTM.InitManager) then
  134. Result:=CurrentTM.InitManager();
  135. end;
  136. end;
  137. function BasicEventCreate(EventAttributes : Pointer; AManualReset,InitialState : Boolean;const Name : ansistring):pEventState;
  138. begin
  139. result:=currenttm.BasicEventCreate(EventAttributes,AManualReset,InitialState, Name);
  140. end;
  141. procedure basiceventdestroy(state:peventstate);
  142. begin
  143. currenttm.basiceventdestroy(state);
  144. end;
  145. procedure basiceventResetEvent(state:peventstate);
  146. begin
  147. currenttm.basiceventResetEvent(state);
  148. end;
  149. procedure basiceventSetEvent(state:peventstate);
  150. begin
  151. currenttm.basiceventSetEvent(state);
  152. end;
  153. function basiceventWaitFor(Timeout : Cardinal;state:peventstate) : longint;
  154. begin
  155. result:=currenttm.basiceventWaitFor(Timeout,state);
  156. end;
  157. function RTLEventCreate :PRTLEvent;
  158. begin
  159. result:=currenttm.rtleventcreate();
  160. end;
  161. procedure RTLeventdestroy(state:pRTLEvent);
  162. begin
  163. currenttm.rtleventdestroy(state);
  164. end;
  165. procedure RTLeventSetEvent(state:pRTLEvent);
  166. begin
  167. currenttm.rtleventsetEvent(state);
  168. end;
  169. procedure RTLeventResetEvent(state:pRTLEvent);
  170. begin
  171. currenttm.rtleventResetEvent(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 RTLeventWaitFor(state:pRTLEvent;timeout : longint);
  182. begin
  183. currenttm.rtleventWaitForTimeout(state,timeout);
  184. end;
  185. procedure RTLeventsync(m:trtlmethod;p:tprocedure);
  186. begin
  187. currenttm.rtleventsync(m,p);
  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 : PtrUInt;
  208. ThreadFunction : tthreadfunc;p : pointer;
  209. creationFlags : dword; var ThreadId : TThreadID) : TThreadID;
  210. begin
  211. NoThreadError;
  212. end;
  213. procedure NoEndThread(ExitCode : DWord);
  214. begin
  215. NoThreadError;
  216. end;
  217. function NoThreadHandler (threadHandle : TThreadID) : 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 : TThreadID; TimeoutMs : longint) : dword; {0=no timeout}
  226. begin
  227. NoThreadError;
  228. end;
  229. function NoThreadSetPriority (threadHandle : TThreadID; Prio: longint): boolean; {-15..+15, 0=normal}
  230. begin
  231. NoThreadError;
  232. end;
  233. function NoThreadGetPriority (threadHandle : TThreadID): longint;
  234. begin
  235. NoThreadError;
  236. end;
  237. function NoGetCurrentThreadId : TThreadID;
  238. begin
  239. if IsMultiThread then
  240. NoThreadError
  241. else
  242. ThreadingAlreadyUsed:=true;
  243. result:=ThreadID;
  244. end;
  245. procedure NoCriticalSection(var CS);
  246. begin
  247. if IsMultiThread then
  248. NoThreadError
  249. else
  250. ThreadingAlreadyUsed:=true;
  251. end;
  252. procedure NoInitThreadvar(var offset : dword;size : dword);
  253. begin
  254. NoThreadError;
  255. end;
  256. function NoRelocateThreadvar(offset : dword) : pointer;
  257. begin
  258. NoThreadError;
  259. end;
  260. procedure NoAllocateThreadVars;
  261. begin
  262. NoThreadError;
  263. end;
  264. procedure NoReleaseThreadVars;
  265. begin
  266. NoThreadError;
  267. end;
  268. function noBasicEventCreate(EventAttributes : Pointer; AManualReset,InitialState : Boolean;const Name : ansistring):pEventState;
  269. begin
  270. NoThreadError;
  271. end;
  272. procedure nobasiceventdestroy(state:peventstate);
  273. begin
  274. NoThreadError;
  275. end;
  276. procedure nobasiceventResetEvent(state:peventstate);
  277. begin
  278. NoThreadError;
  279. end;
  280. procedure nobasiceventSetEvent(state:peventstate);
  281. begin
  282. NoThreadError;
  283. end;
  284. function nobasiceventWaitFor(Timeout : Cardinal;state:peventstate) : longint;
  285. begin
  286. NoThreadError;
  287. end;
  288. function NORTLEventCreate :PRTLEvent;
  289. begin
  290. if IsMultiThread then
  291. NoThreadError
  292. else
  293. ThreadingAlreadyUsed:=true
  294. end;
  295. procedure NORTLeventdestroy(state:pRTLEvent);
  296. begin
  297. if IsMultiThread then
  298. NoThreadError
  299. else
  300. ThreadingAlreadyUsed:=true
  301. end;
  302. procedure NORTLeventSetEvent(state:pRTLEvent);
  303. begin
  304. NoThreadError;
  305. end;
  306. procedure NORTLeventStartWait(state:pRTLEvent);
  307. begin
  308. NoThreadError;
  309. end;
  310. procedure NORTLeventWaitFor(state:pRTLEvent);
  311. begin
  312. NoThreadError;
  313. end;
  314. procedure NORTLeventWaitForTimeout(state:pRTLEvent;timeout : longint);
  315. begin
  316. NoThreadError;
  317. end;
  318. procedure NORTLeventsync(m:trtlmethod;p:tprocedure);
  319. begin
  320. NoThreadError;
  321. end;
  322. Var
  323. NoThreadManager : TThreadManager;
  324. Procedure SetNoThreadManager;
  325. begin
  326. With NoThreadManager do
  327. begin
  328. InitManager :=Nil;
  329. DoneManager :=Nil;
  330. BeginThread :=@NoBeginThread;
  331. EndThread :=@NoEndThread;
  332. SuspendThread :=@NoThreadHandler;
  333. ResumeThread :=@NoThreadHandler;
  334. KillThread :=@NoThreadHandler;
  335. ThreadSwitch :=@NoThreadSwitch;
  336. WaitForThreadTerminate :=@NoWaitForThreadTerminate;
  337. ThreadSetPriority :=@NoThreadSetPriority;
  338. ThreadGetPriority :=@NoThreadGetPriority;
  339. GetCurrentThreadId :=@NoGetCurrentThreadId;
  340. InitCriticalSection :=@NoCriticalSection;
  341. DoneCriticalSection :=@NoCriticalSection;
  342. EnterCriticalSection :=@NoCriticalSection;
  343. LeaveCriticalSection :=@NoCriticalSection;
  344. InitThreadVar :=@NoInitThreadVar;
  345. RelocateThreadVar :=@NoRelocateThreadVar;
  346. AllocateThreadVars :=@NoAllocateThreadVars;
  347. ReleaseThreadVars :=@NoReleaseThreadVars;
  348. BasicEventCreate :=@NoBasicEventCreate;
  349. basiceventdestroy :=@Nobasiceventdestroy;
  350. basiceventResetEvent :=@NobasiceventResetEvent;
  351. basiceventSetEvent :=@NobasiceventSetEvent;
  352. basiceventWaitFor :=@NobasiceventWaitFor;
  353. rtlEventCreate :=@NortlEventCreate;
  354. rtleventdestroy :=@Nortleventdestroy;
  355. rtleventSetEvent :=@NortleventSetEvent;
  356. rtleventStartWait :=@NortleventStartWait;
  357. rtleventWaitFor :=@NortleventWaitFor;
  358. rtleventsync :=@Nortleventsync;
  359. rtleventwaitfortimeout :=@NortleventWaitForTimeout;
  360. end;
  361. SetThreadManager(NoThreadManager);
  362. end;
  363. {$endif DISABLE_NO_THREAD_MANAGER}