+ proper implementation of MS Windows-like 'critical sections'

git-svn-id: trunk@19739 -
This commit is contained in:
Tomas Hajny 2011-12-04 00:47:17 +00:00
parent a4804a3c25
commit 4d981acad3

View File

@ -1,6 +1,6 @@
{ {
This file is part of the Free Pascal run time library. This file is part of the Free Pascal run time library.
Copyright (c) 2002-2010 by Tomas Hajny, Copyright (c) 2002-2011 by Tomas Hajny,
member of the Free Pascal development team. member of the Free Pascal development team.
OS/2 threading support implementation OS/2 threading support implementation
@ -47,19 +47,16 @@ function DosCreateThread (var TID: cardinal; Address: pointer;
aParam: pointer; Flags: cardinal; StackSize: cardinal): cardinal; cdecl; aParam: pointer; Flags: cardinal; StackSize: cardinal): cardinal; cdecl;
external 'DOSCALLS' index 311; external 'DOSCALLS' index 311;
function DosCreateMutExSem (Name: PChar; var Handle: longint; Attr: cardinal; function DosCreateMutExSem (Name: PChar; var Handle: THandle; Attr: cardinal;
State: boolean): cardinal; cdecl; external 'DOSCALLS' index 331; State: boolean): cardinal; cdecl; external 'DOSCALLS' index 331;
function DosCloseMutExSem (Handle: longint): cardinal; cdecl; function DosCloseMutExSem (Handle: THandle): cardinal; cdecl;
external 'DOSCALLS' index 333; external 'DOSCALLS' index 333;
function DosQueryMutExSem (Handle: longint; var PID, TID, Count: cardinal): function DosRequestMutExSem (Handle: THandle; Timeout: cardinal): cardinal;
cardinal; cdecl; external 'DOSCALLS' index 336; cdecl; external 'DOSCALLS' index 334;
function DosRequestMutExSem (Handle:longint; Timeout: cardinal): cardinal; cdecl; function DosReleaseMutExSem (Handle: THandle): cardinal; cdecl;
external 'DOSCALLS' index 334;
function DosReleaseMutExSem (Handle: longint): cardinal; cdecl;
external 'DOSCALLS' index 335; external 'DOSCALLS' index 335;
function DosSuspendThread (TID:cardinal): cardinal; cdecl; function DosSuspendThread (TID:cardinal): cardinal; cdecl;
@ -74,10 +71,6 @@ function DosKillThread (TID: cardinal): cardinal; cdecl;
function DosWaitThread (var TID: cardinal; Option: cardinal): cardinal; cdecl; function DosWaitThread (var TID: cardinal; Option: cardinal): cardinal; cdecl;
external 'DOSCALLS' index 349; external 'DOSCALLS' index 349;
function DosEnterCritSec:cardinal; cdecl; external 'DOSCALLS' index 232;
function DosExitCritSec:cardinal; cdecl; external 'DOSCALLS' index 233;
procedure DosSleep (MSec: cardinal); cdecl; external 'DOSCALLS' index 229; procedure DosSleep (MSec: cardinal); cdecl; external 'DOSCALLS' index 229;
{ {
@ -352,6 +345,15 @@ begin
end; end;
function GetOS2ThreadPriority (ThreadHandle: dword): longint;
begin
{$WARNING TODO!}
{
DosQuerySysState
}
end;
function SysThreadSetPriority (ThreadHandle: dword; Prio: longint): boolean; function SysThreadSetPriority (ThreadHandle: dword; Prio: longint): boolean;
{-15..+15, 0=normal} {-15..+15, 0=normal}
var var
@ -361,8 +363,9 @@ begin
{ {
SysThreadSetPriority:=WinThreadSetPriority(threadHandle,Prio); SysThreadSetPriority:=WinThreadSetPriority(threadHandle,Prio);
Find out current priority first using DosGetInfoBlocks, then calculate delta Find out current priority first using GetOS2ThreadPriority defined above, then
(recalculate the scale from -15..+15 on input to -31..+31 used by OS/2). calculate delta (translate the input scale -15..+15 based on MSDN docs to
-31..+31 used by OS/2).
SysThreadSetPriority := DosSetPriority (dpThread, dpSameClass, Delta, SysThreadSetPriority := DosSetPriority (dpThread, dpSameClass, Delta,
ThreadHandle); ThreadHandle);
@ -376,7 +379,8 @@ begin
{ {
SysThreadGetPriority:=WinThreadGetPriority(threadHandle); SysThreadGetPriority:=WinThreadGetPriority(threadHandle);
DosGetInfoBlocks - recalculate the scale afterwards to -15..+15 Use GetOS2ThreadPriority defined above and translate the OS/2 value 0..31
to -15..+15 based on MSDN docs.
} }
end; end;
@ -395,28 +399,40 @@ end;
Delphi/Win32 compatibility Delphi/Win32 compatibility
*****************************************************************************} *****************************************************************************}
{ DosEnter/ExitCritSec have quite a few limitations, so let's try to avoid
them. I'm not sure whether mutex semaphores are SMP-safe, though... :-( }
procedure SysInitCriticalSection (var CS); procedure SysInitCriticalSection (var CS);
begin begin
{$WARNING TODO!} if DosCreateMutExSem (nil, THandle (CS), 0, false) <> 0 then
FPC_ThreadError;
end; end;
procedure SysDoneCriticalSection (var CS); procedure SysDoneCriticalSection (var CS);
begin begin
{$WARNING TODO!} (* Trying to release first since this might apparently be the expected *)
(* behaviour in Delphi according to comment in the Unix implementation. *)
repeat
until DosReleaseMutExSem (THandle (CS)) <> 0;
if DosCloseMutExSem (THandle (CS)) <> 0 then
FPC_ThreadError;
end; end;
procedure SysEnterCriticalSection (var CS); procedure SysEnterCriticalSection (var CS);
begin begin
{$WARNING TODO!} if DosRequestMutExSem (THandle (CS), cardinal (-1)) <> 0 then
FPC_ThreadError;
end;
function SysTryEnterCriticalSection (var CS): longint;
begin
if DosRequestMutExSem (THandle (CS), 0) = 0 then
Result := 1
else
Result := 0;
end; end;
procedure SysLeaveCriticalSection (var CS); procedure SysLeaveCriticalSection (var CS);
begin begin
{$WARNING TODO!} if DosReleaseMutExSem (THandle (CS)) <> 0 then
FPC_ThreadError;
end; end;
@ -526,12 +542,6 @@ begin
end; end;
function SysTryEnterCriticalSection (var CS): longint;
begin
{$WARNING TODO!}
end;
procedure IntRTLEventWaitForTimeout (AEvent: PRTLEvent; Timeout: longint); procedure IntRTLEventWaitForTimeout (AEvent: PRTLEvent; Timeout: longint);
begin begin
{$WARNING TODO!} {$WARNING TODO!}
@ -566,8 +576,8 @@ begin
SuspendThread :=@SysSuspendThread; SuspendThread :=@SysSuspendThread;
ResumeThread :=@SysResumeThread; ResumeThread :=@SysResumeThread;
KillThread :=@SysKillThread; KillThread :=@SysKillThread;
ThreadSwitch :=@SysThreadSwitch;
CloseThread :=@SysCloseThread; CloseThread :=@SysCloseThread;
ThreadSwitch :=@SysThreadSwitch;
WaitForThreadTerminate :=@SysWaitForThreadTerminate; WaitForThreadTerminate :=@SysWaitForThreadTerminate;
ThreadSetPriority :=@SysThreadSetPriority; ThreadSetPriority :=@SysThreadSetPriority;
ThreadGetPriority :=@SysThreadGetPriority; ThreadGetPriority :=@SysThreadGetPriority;
@ -583,8 +593,8 @@ begin
ReleaseThreadVars :=@SysReleaseThreadVars; ReleaseThreadVars :=@SysReleaseThreadVars;
BasicEventCreate :=@IntBasicEventCreate; BasicEventCreate :=@IntBasicEventCreate;
BasicEventDestroy :=@IntBasicEventDestroy; BasicEventDestroy :=@IntBasicEventDestroy;
BasicEventResetEvent :=@IntBasicEventResetEvent;
BasicEventSetEvent :=@IntBasicEventSetEvent; BasicEventSetEvent :=@IntBasicEventSetEvent;
BasicEventResetEvent :=@IntBasicEventResetEvent;
BasiceventWaitFor :=@IntBasiceventWaitFor; BasiceventWaitFor :=@IntBasiceventWaitFor;
RTLEventCreate :=@IntRTLEventCreate; RTLEventCreate :=@IntRTLEventCreate;
RTLEventDestroy :=@IntRTLEventDestroy; RTLEventDestroy :=@IntRTLEventDestroy;