mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-05-02 09:13:43 +02:00
362 lines
8.9 KiB
PHP
362 lines
8.9 KiB
PHP
{
|
|
$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
|
|
*****************************************************************************}
|
|
{$ifndef CPU64}
|
|
{$ifndef unix}
|
|
function BeginThread(sa : Pointer;stacksize : dword;
|
|
ThreadFunction : tthreadfunc;p : pointer;creationFlags : dword;
|
|
var ThreadId : Longint) : DWord;
|
|
begin
|
|
BeginThread:=BeginThread(nil,StackSize,ThreadFunction,p,creationFlags,THandle(THreadId));
|
|
end;
|
|
{$endif unix}
|
|
{$endif CPU64}
|
|
|
|
function BeginThread(ThreadFunction : tthreadfunc) : DWord;
|
|
var
|
|
dummy : THandle;
|
|
begin
|
|
BeginThread:=BeginThread(nil,DefaultStackSize,ThreadFunction,nil,0,dummy);
|
|
end;
|
|
|
|
|
|
function BeginThread(ThreadFunction : tthreadfunc;p : pointer) : DWord;
|
|
var
|
|
dummy : THandle;
|
|
begin
|
|
BeginThread:=BeginThread(nil,DefaultStackSize,ThreadFunction,p,0,dummy);
|
|
end;
|
|
|
|
|
|
function BeginThread(ThreadFunction : tthreadfunc;p : pointer;var ThreadId : THandle) : DWord;
|
|
begin
|
|
BeginThread:=BeginThread(nil,DefaultStackSize,ThreadFunction,p,0,ThreadId);
|
|
end;
|
|
|
|
|
|
{$ifndef CPU64}
|
|
{$ifndef unix}
|
|
function BeginThread(ThreadFunction : tthreadfunc;p : pointer;var ThreadId : Longint) : DWord;
|
|
begin
|
|
BeginThread:=BeginThread(nil,DefaultStackSize,ThreadFunction,p,0,THandle(ThreadId));
|
|
end;
|
|
{$endif unix}
|
|
{$endif CPU64}
|
|
|
|
procedure EndThread;
|
|
begin
|
|
EndThread(0);
|
|
end;
|
|
|
|
function BeginThread(sa : Pointer;stacksize : dword; ThreadFunction : tthreadfunc;p : pointer;creationFlags : dword; var ThreadId : THandle) : 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 : THandle) : 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.10 2004-02-22 23:22:49 florian
|
|
* fixed BeginThread on unix
|
|
|
|
Revision 1.9 2004/02/22 16:48:39 florian
|
|
* several 64 bit issues fixed
|
|
|
|
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
|
|
|
|
}
|