thread.inc 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493
  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:cardinal);
  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. procedure EndThread;
  51. begin
  52. EndThread(0);
  53. end;
  54. function BeginThread(sa : Pointer;stacksize : dword; ThreadFunction : tthreadfunc;p : pointer;creationFlags : dword; var ThreadId : TThreadID) : TThreadID;
  55. begin
  56. Result:=CurrentTM.BeginThread(sa,stacksize,threadfunction,P,creationflags,ThreadID);
  57. end;
  58. function BeginThread(sa : Pointer;stacksize : qword; ThreadFunction : tthreadfunc;p : pointer;creationFlags : dword; var ThreadId : TThreadID) : TThreadID;
  59. begin
  60. Result:=CurrentTM.BeginThread(sa,stacksize,threadfunction,P,creationflags,ThreadID);
  61. end;
  62. procedure EndThread(ExitCode : DWord);
  63. begin
  64. CurrentTM.EndThread(ExitCode);
  65. end;
  66. function SuspendThread (threadHandle : TThreadID) : dword;
  67. begin
  68. Result:=CurrentTM.SuspendThread(ThreadHandle);
  69. end;
  70. function ResumeThread (threadHandle : TThreadID) : dword;
  71. begin
  72. Result:=CurrentTM.ResumeThread(ThreadHandle);
  73. end;
  74. procedure ThreadSwitch;
  75. begin
  76. CurrentTM.ThreadSwitch;
  77. end;
  78. function KillThread (threadHandle : TThreadID) : dword;
  79. begin
  80. Result:=CurrentTM.KillThread(ThreadHandle);
  81. end;
  82. function WaitForThreadTerminate (threadHandle : TThreadID; TimeoutMs : longint) : dword;
  83. begin
  84. Result:=CurrentTM.WaitForThreadTerminate(ThreadHandle,TimeOutMS);
  85. end;
  86. function ThreadSetPriority (threadHandle : TThreadID; Prio: longint): boolean;
  87. begin
  88. Result:=CurrentTM.ThreadSetPriority(ThreadHandle,Prio);
  89. end;
  90. function ThreadGetPriority (threadHandle : TThreadID): longint;
  91. begin
  92. Result:=CurrentTM.ThreadGetPriority(ThreadHandle);
  93. end;
  94. function GetCurrentThreadId : TThreadID;
  95. begin
  96. Result:=CurrentTM.GetCurrentThreadID();
  97. end;
  98. procedure InitCriticalSection(var cs : TRTLCriticalSection);
  99. begin
  100. CurrentTM.InitCriticalSection(cs);
  101. end;
  102. procedure DoneCriticalsection(var cs : TRTLCriticalSection);
  103. begin
  104. CurrentTM.DoneCriticalSection(cs);
  105. end;
  106. procedure EnterCriticalsection(var cs : TRTLCriticalSection);
  107. begin
  108. CurrentTM.EnterCriticalSection(cs);
  109. end;
  110. procedure LeaveCriticalsection(var cs : TRTLCriticalSection);
  111. begin
  112. CurrentTM.LeaveCriticalSection(cs);
  113. end;
  114. Function GetThreadManager(Var TM : TThreadManager) : Boolean;
  115. begin
  116. TM:=CurrentTM;
  117. Result:=True;
  118. end;
  119. Function SetThreadManager(Const NewTM : TThreadManager; Var OldTM : TThreadManager) : Boolean;
  120. begin
  121. GetThreadManager(OldTM);
  122. Result:=SetThreadManager(NewTM);
  123. end;
  124. Function SetThreadManager(Const NewTM : TThreadManager) : Boolean;
  125. begin
  126. Result:=True;
  127. If Assigned(CurrentTM.DoneManager) then
  128. Result:=CurrentTM.DoneManager();
  129. If Result then
  130. begin
  131. CurrentTM:=NewTM;
  132. If Assigned(CurrentTM.InitManager) then
  133. Result:=CurrentTM.InitManager();
  134. end;
  135. end;
  136. function BasicEventCreate(EventAttributes : Pointer; AManualReset,InitialState : Boolean;const Name : ansistring):pEventState;
  137. begin
  138. result:=currenttm.BasicEventCreate(EventAttributes,AManualReset,InitialState, Name);
  139. end;
  140. procedure basiceventdestroy(state:peventstate);
  141. begin
  142. currenttm.basiceventdestroy(state);
  143. end;
  144. procedure basiceventResetEvent(state:peventstate);
  145. begin
  146. currenttm.basiceventResetEvent(state);
  147. end;
  148. procedure basiceventSetEvent(state:peventstate);
  149. begin
  150. currenttm.basiceventSetEvent(state);
  151. end;
  152. function basiceventWaitFor(Timeout : Cardinal;state:peventstate) : longint;
  153. begin
  154. result:=currenttm.basiceventWaitFor(Timeout,state);
  155. end;
  156. function RTLEventCreate :PRTLEvent;
  157. begin
  158. result:=currenttm.rtleventcreate();
  159. end;
  160. procedure RTLeventdestroy(state:pRTLEvent);
  161. begin
  162. currenttm.rtleventdestroy(state);
  163. end;
  164. procedure RTLeventSetEvent(state:pRTLEvent);
  165. begin
  166. currenttm.rtleventsetEvent(state);
  167. end;
  168. procedure RTLeventResetEvent(state:pRTLEvent);
  169. begin
  170. currenttm.rtleventResetEvent(state);
  171. end;
  172. procedure RTLeventStartWait(state:pRTLEvent);
  173. begin
  174. currenttm.rtleventStartWait(state);
  175. end;
  176. procedure RTLeventWaitFor(state:pRTLEvent);
  177. begin
  178. currenttm.rtleventWaitFor(state);
  179. end;
  180. procedure RTLeventWaitFor(state:pRTLEvent;timeout : longint);
  181. begin
  182. currenttm.rtleventWaitForTimeout(state,timeout);
  183. end;
  184. procedure RTLeventsync(m:trtlmethod;p:tprocedure);
  185. begin
  186. currenttm.rtleventsync(m,p);
  187. end;
  188. { ---------------------------------------------------------------------
  189. ThreadManager which gives run-time error. Use if no thread support.
  190. ---------------------------------------------------------------------}
  191. {$ifndef DISABLE_NO_THREAD_MANAGER}
  192. { resourcestrings are not supported by the system unit,
  193. they are in the objpas unit and not available for fpc/tp modes }
  194. const
  195. SNoThreads = 'This binary has no thread support compiled in.';
  196. SRecompileWithThreads = 'Recompile the application with a thread-driver in the program uses clause before other units using thread.';
  197. Procedure NoThreadError;
  198. begin
  199. If IsConsole then
  200. begin
  201. Writeln(StdErr,SNoThreads);
  202. Writeln(StdErr,SRecompileWithThreads);
  203. end;
  204. RunError(232)
  205. end;
  206. function NoBeginThread(sa : Pointer;stacksize : PtrUInt;
  207. ThreadFunction : tthreadfunc;p : pointer;
  208. creationFlags : dword; var ThreadId : TThreadID) : TThreadID;
  209. begin
  210. NoThreadError;
  211. end;
  212. procedure NoEndThread(ExitCode : DWord);
  213. begin
  214. NoThreadError;
  215. end;
  216. function NoThreadHandler (threadHandle : TThreadID) : dword;
  217. begin
  218. NoThreadError;
  219. end;
  220. procedure NoThreadSwitch; {give time to other threads}
  221. begin
  222. NoThreadError;
  223. end;
  224. function NoWaitForThreadTerminate (threadHandle : TThreadID; TimeoutMs : longint) : dword; {0=no timeout}
  225. begin
  226. NoThreadError;
  227. end;
  228. function NoThreadSetPriority (threadHandle : TThreadID; Prio: longint): boolean; {-15..+15, 0=normal}
  229. begin
  230. NoThreadError;
  231. end;
  232. function NoThreadGetPriority (threadHandle : TThreadID): longint;
  233. begin
  234. NoThreadError;
  235. end;
  236. function NoGetCurrentThreadId : TThreadID;
  237. begin
  238. if IsMultiThread then
  239. NoThreadError
  240. else
  241. ThreadingAlreadyUsed:=true;
  242. result:=ThreadID;
  243. end;
  244. procedure NoCriticalSection(var CS);
  245. begin
  246. if IsMultiThread then
  247. NoThreadError
  248. else
  249. ThreadingAlreadyUsed:=true;
  250. end;
  251. procedure NoInitThreadvar(var offset : dword;size : dword);
  252. begin
  253. NoThreadError;
  254. end;
  255. function NoRelocateThreadvar(offset : dword) : pointer;
  256. begin
  257. NoThreadError;
  258. end;
  259. procedure NoAllocateThreadVars;
  260. begin
  261. NoThreadError;
  262. end;
  263. procedure NoReleaseThreadVars;
  264. begin
  265. NoThreadError;
  266. end;
  267. function noBasicEventCreate(EventAttributes : Pointer; AManualReset,InitialState : Boolean;const Name : ansistring):pEventState;
  268. begin
  269. NoThreadError;
  270. end;
  271. procedure nobasiceventdestroy(state:peventstate);
  272. begin
  273. NoThreadError;
  274. end;
  275. procedure nobasiceventResetEvent(state:peventstate);
  276. begin
  277. NoThreadError;
  278. end;
  279. procedure nobasiceventSetEvent(state:peventstate);
  280. begin
  281. NoThreadError;
  282. end;
  283. function nobasiceventWaitFor(Timeout : Cardinal;state:peventstate) : longint;
  284. begin
  285. NoThreadError;
  286. end;
  287. function NORTLEventCreate :PRTLEvent;
  288. begin
  289. if IsMultiThread then
  290. NoThreadError
  291. else
  292. ThreadingAlreadyUsed:=true
  293. end;
  294. procedure NORTLeventdestroy(state:pRTLEvent);
  295. begin
  296. if IsMultiThread then
  297. NoThreadError
  298. else
  299. ThreadingAlreadyUsed:=true
  300. end;
  301. procedure NORTLeventSetEvent(state:pRTLEvent);
  302. begin
  303. NoThreadError;
  304. end;
  305. procedure NORTLeventStartWait(state:pRTLEvent);
  306. begin
  307. NoThreadError;
  308. end;
  309. procedure NORTLeventWaitFor(state:pRTLEvent);
  310. begin
  311. NoThreadError;
  312. end;
  313. procedure NORTLeventWaitForTimeout(state:pRTLEvent;timeout : longint);
  314. begin
  315. NoThreadError;
  316. end;
  317. procedure NORTLeventsync(m:trtlmethod;p:tprocedure);
  318. begin
  319. NoThreadError;
  320. end;
  321. Var
  322. NoThreadManager : TThreadManager;
  323. Procedure SetNoThreadManager;
  324. begin
  325. With NoThreadManager do
  326. begin
  327. InitManager :=Nil;
  328. DoneManager :=Nil;
  329. BeginThread :=@NoBeginThread;
  330. EndThread :=@NoEndThread;
  331. SuspendThread :=@NoThreadHandler;
  332. ResumeThread :=@NoThreadHandler;
  333. KillThread :=@NoThreadHandler;
  334. ThreadSwitch :=@NoThreadSwitch;
  335. WaitForThreadTerminate :=@NoWaitForThreadTerminate;
  336. ThreadSetPriority :=@NoThreadSetPriority;
  337. ThreadGetPriority :=@NoThreadGetPriority;
  338. GetCurrentThreadId :=@NoGetCurrentThreadId;
  339. InitCriticalSection :=@NoCriticalSection;
  340. DoneCriticalSection :=@NoCriticalSection;
  341. EnterCriticalSection :=@NoCriticalSection;
  342. LeaveCriticalSection :=@NoCriticalSection;
  343. InitThreadVar :=@NoInitThreadVar;
  344. RelocateThreadVar :=@NoRelocateThreadVar;
  345. AllocateThreadVars :=@NoAllocateThreadVars;
  346. ReleaseThreadVars :=@NoReleaseThreadVars;
  347. BasicEventCreate :=@NoBasicEventCreate;
  348. basiceventdestroy :=@Nobasiceventdestroy;
  349. basiceventResetEvent :=@NobasiceventResetEvent;
  350. basiceventSetEvent :=@NobasiceventSetEvent;
  351. basiceventWaitFor :=@NobasiceventWaitFor;
  352. rtlEventCreate :=@NortlEventCreate;
  353. rtleventdestroy :=@Nortleventdestroy;
  354. rtleventSetEvent :=@NortleventSetEvent;
  355. rtleventStartWait :=@NortleventStartWait;
  356. rtleventWaitFor :=@NortleventWaitFor;
  357. rtleventsync :=@Nortleventsync;
  358. rtleventwaitfortimeout :=@NortleventWaitForTimeout;
  359. end;
  360. SetThreadManager(NoThreadManager);
  361. end;
  362. {$endif DISABLE_NO_THREAD_MANAGER}