{ $Id$ This file is part of the Free Pascal Run time library. Copyright (c) 2000 by the Free Pascal development team OS independent thread functions/overloads See the File COPYING.FPC, included in this distribution, for details about the copyright. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. **********************************************************************} Var CurrentTM : TThreadManager; {***************************************************************************** Threadvar initialization *****************************************************************************} procedure InitThread(stklen:cardinal); begin SysResetFPU; { ExceptAddrStack and ExceptObjectStack are threadvars } { so every thread has its on exception handling capabilities } SysInitExceptions; { Open all stdio fds again } SysInitStdio; InOutRes:=0; // ErrNo:=0; { Stack checking } StackLength:=stklen; StackBottom:=Sptr - StackLength; ThreadID := CurrentTM.GetCurrentThreadID(); end; {***************************************************************************** Overloaded functions *****************************************************************************} function BeginThread(sa : Pointer;stacksize : dword; ThreadFunction : tthreadfunc;p : pointer;creationFlags : dword; var ThreadId : Longint) : DWord; begin BeginThread:=BeginThread(nil,StackSize,ThreadFunction,p,creationFlags,Dword(THreadId)); end; function BeginThread(ThreadFunction : tthreadfunc) : DWord; var dummy : dword; begin BeginThread:=BeginThread(nil,DefaultStackSize,ThreadFunction,nil,0,dummy); end; function BeginThread(ThreadFunction : tthreadfunc;p : pointer) : DWord; var dummy : dword; begin BeginThread:=BeginThread(nil,DefaultStackSize,ThreadFunction,p,0,dummy); end; function BeginThread(ThreadFunction : tthreadfunc;p : pointer;var ThreadId : DWord) : DWord; begin BeginThread:=BeginThread(nil,DefaultStackSize,ThreadFunction,p,0,ThreadId); end; function BeginThread(ThreadFunction : tthreadfunc;p : pointer;var ThreadId : Longint) : DWord; begin BeginThread:=BeginThread(nil,DefaultStackSize,ThreadFunction,p,0,Dword(ThreadId)); end; procedure EndThread; begin EndThread(0); end; function BeginThread(sa : Pointer;stacksize : dword; ThreadFunction : tthreadfunc;p : pointer;creationFlags : dword; var ThreadId : DWord) : DWord; begin Result:=CurrentTM.BeginThread(sa,stacksize,threadfunction,P,creationflags,ThreadID); end; procedure EndThread(ExitCode : DWord); begin CurrentTM.EndThread(ExitCode); end; function SuspendThread (threadHandle : dword) : dword; begin Result:=CurrentTM.SuspendThread(ThreadHandle); end; function ResumeThread (threadHandle : dword) : dword; begin Result:=CurrentTM.ResumeThread(ThreadHandle); end; procedure ThreadSwitch; begin CurrentTM.ThreadSwitch; end; function KillThread (threadHandle : dword) : dword; begin Result:=CurrentTM.KillThread(ThreadHandle); end; function WaitForThreadTerminate (threadHandle : dword; TimeoutMs : longint) : dword; begin Result:=CurrentTM.WaitForThreadTerminate(ThreadHandle,TimeOutMS); end; function ThreadSetPriority (threadHandle : dword; Prio: longint): boolean; begin Result:=CurrentTM.ThreadSetPriority(ThreadHandle,Prio); end; function ThreadGetPriority (threadHandle : dword): Integer; begin Result:=CurrentTM.ThreadGetPriority(ThreadHandle); end; function GetCurrentThreadId : dword; begin Result:=CurrentTM.GetCurrentThreadID(); end; procedure InitCriticalSection(var cs : TRTLCriticalSection); begin CurrentTM.InitCriticalSection(cs); end; procedure DoneCriticalsection(var cs : TRTLCriticalSection); begin CurrentTM.DoneCriticalSection(cs); end; procedure EnterCriticalsection(var cs : TRTLCriticalSection); begin CurrentTM.EnterCriticalSection(cs); end; procedure LeaveCriticalsection(var cs : TRTLCriticalSection); begin CurrentTM.LeaveCriticalSection(cs); end; Function GetThreadManager(Var TM : TThreadManager) : Boolean; begin TM:=CurrentTM; Result:=True; end; Function SetThreadManager(Const NewTM : TThreadManager; Var OldTM : TThreadManager) : Boolean; begin GetThreadManager(OldTM); Result:=SetThreadManager(NewTM); end; Function SetThreadManager(Const NewTM : TThreadManager) : Boolean; begin Result:=True; If Assigned(CurrentTM.DoneManager) then Result:=CurrentTM.DoneManager(); If Result then begin CurrentTM:=NewTM; If Assigned(CurrentTM.InitManager) then Result:=CurrentTM.InitManager(); end; end; { --------------------------------------------------------------------- ThreadManager which gives run-time error. Use if no thread support. ---------------------------------------------------------------------} Resourcestring SNoThreads = 'This binary has no thread support compiled in.'; SRecompileWithThreads = 'Recompile the application with a thread-driver in the program uses clause.'; Procedure NoThreadError; begin If IsConsole then begin Writeln(StdErr,SNoThreads); Writeln(StdErr,SRecompileWithThreads); end; RunError(232) end; function NoBeginThread(sa : Pointer;stacksize : dword; ThreadFunction : tthreadfunc;p : pointer; creationFlags : dword; var ThreadId : DWord) : DWord; begin NoThreadError; end; procedure NoEndThread(ExitCode : DWord); begin NoThreadError; end; function NoThreadHandler (threadHandle : dword) : dword; begin NoThreadError; end; procedure NoThreadSwitch; {give time to other threads} begin NoThreadError; end; function NoWaitForThreadTerminate (threadHandle : dword; TimeoutMs : longint) : dword; {0=no timeout} begin NoThreadError; end; function NoThreadSetPriority (threadHandle : dword; Prio: longint): boolean; {-15..+15, 0=normal} begin NoThreadError; end; function NoThreadGetPriority (threadHandle : dword): Integer; begin NoThreadError; end; function NoGetCurrentThreadId : dword; begin NoThreadError; end; procedure NoCriticalSection(var CS); begin NoThreadError; end; procedure NoInitThreadvar(var offset : dword;size : dword); begin NoThreadError; end; function NoRelocateThreadvar(offset : dword) : pointer; begin NoThreadError; end; procedure NoAllocateThreadVars; begin NoThreadError; end; procedure NoReleaseThreadVars; begin NoThreadError; end; Var NoThreadManager : TThreadManager; Procedure SetNoThreadManager; begin With NoThreadManager do begin InitManager :=Nil; DoneManager :=Nil; BeginThread :=@NoBeginThread; EndThread :=@NoEndThread; SuspendThread :=@NoThreadHandler; ResumeThread :=@NoThreadHandler; KillThread :=@NoThreadHandler; ThreadSwitch :=@NoThreadSwitch; WaitForThreadTerminate :=@NoWaitForThreadTerminate; ThreadSetPriority :=@NoThreadSetPriority; ThreadGetPriority :=@NoThreadGetPriority; GetCurrentThreadId :=@NoGetCurrentThreadId; InitCriticalSection :=@NoCriticalSection; DoneCriticalSection :=@NoCriticalSection; EnterCriticalSection :=@NoCriticalSection; LeaveCriticalSection :=@NoCriticalSection; InitThreadVar :=@NoInitThreadVar; RelocateThreadVar :=@NoRelocateThreadVar; AllocateThreadVars :=@NoAllocateThreadVars; ReleaseThreadVars :=@NoReleaseThreadVars; end; SetThreadManager(NoThreadManager); end; { $Log$ Revision 1.8 2004-01-21 20:11:06 peter * fixed compile for unix Revision 1.7 2004/01/20 23:13:53 hajny * ExecuteProcess fixes, ProcessID and ThreadID added Revision 1.6 2003/11/29 17:33:09 michael + Removed dummy variable from SetNothreadManager Revision 1.5 2003/11/29 17:29:32 michael + Added overloaded version of SetThreadManager without old parameter Revision 1.4 2003/11/26 20:10:59 michael + New threadmanager implementation Revision 1.3 2002/11/14 12:40:06 jonas * the BeginThread() variant that allowed you to specify the stacksize still passed DefaultStackSize to the OS-specific routines Revision 1.2 2002/10/16 19:04:27 michael + More system-independent thread routines Revision 1.1 2002/10/14 19:39:17 peter * threads unit added for thread support }