mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-13 08:19:27 +02:00
--- Merging r48876 into '.':
U packages/rtl-objpas/src/inc/fmtbcd.pp --- Recording mergeinfo for merge of r48876 into '.': G . --- Merging r49021 into '.': U packages/fcl-process/src/win/process.inc --- Recording mergeinfo for merge of r49021 into '.': G . # revisions: 48876,49021 r48876 | marco | 2021-03-04 11:37:50 +0100 (Thu, 04 Mar 2021) | 1 line Changed paths: M /trunk/packages/rtl-objpas/src/inc/fmtbcd.pp * Patch from Lacak. Better fix for mantis 30853 r49021 | marco | 2021-03-20 22:45:19 +0100 (Sat, 20 Mar 2021) | 1 line Changed paths: M /trunk/packages/fcl-process/src/win/process.inc * also assign threadid. mantis 38645 git-svn-id: branches/fixes_3_2@49039 -
This commit is contained in:
parent
994797ef11
commit
ae86b74955
1
.gitattributes
vendored
1
.gitattributes
vendored
@ -17834,6 +17834,7 @@ tests/webtbs/tw38151.pp svneol=native#text/pascal
|
|||||||
tests/webtbs/tw38238.pp svneol=native#text/pascal
|
tests/webtbs/tw38238.pp svneol=native#text/pascal
|
||||||
tests/webtbs/tw3827.pp svneol=native#text/plain
|
tests/webtbs/tw3827.pp svneol=native#text/plain
|
||||||
tests/webtbs/tw3829.pp svneol=native#text/plain
|
tests/webtbs/tw3829.pp svneol=native#text/plain
|
||||||
|
tests/webtbs/tw38306.pp -text svneol=native#text/pascal
|
||||||
tests/webtbs/tw3833.pp svneol=native#text/plain
|
tests/webtbs/tw3833.pp svneol=native#text/plain
|
||||||
tests/webtbs/tw38337.pp svneol=native#text/plain
|
tests/webtbs/tw38337.pp svneol=native#text/plain
|
||||||
tests/webtbs/tw3840.pp svneol=native#text/plain
|
tests/webtbs/tw3840.pp svneol=native#text/plain
|
||||||
|
@ -285,6 +285,7 @@ Var
|
|||||||
Raise EProcess.CreateFmt(SErrCannotExecute,[FCommandLine,GetLastError]);
|
Raise EProcess.CreateFmt(SErrCannotExecute,[FCommandLine,GetLastError]);
|
||||||
FProcessHandle:=FProcessInformation.hProcess;
|
FProcessHandle:=FProcessInformation.hProcess;
|
||||||
FThreadHandle:=FProcessInformation.hThread;
|
FThreadHandle:=FProcessInformation.hThread;
|
||||||
|
FThreadId:=FProcessInformation.dwThreadId;
|
||||||
FProcessID:=FProcessINformation.dwProcessID;
|
FProcessID:=FProcessINformation.dwProcessID;
|
||||||
Finally
|
Finally
|
||||||
if POUsePipes in Options then
|
if POUsePipes in Options then
|
||||||
|
@ -14,6 +14,11 @@
|
|||||||
|
|
||||||
unit gdeque;
|
unit gdeque;
|
||||||
|
|
||||||
|
{
|
||||||
|
Implements a generic double ended queue.
|
||||||
|
(See: https://en.wikipedia.org/wiki/Double-ended_queue)
|
||||||
|
}
|
||||||
|
|
||||||
interface
|
interface
|
||||||
|
|
||||||
type
|
type
|
||||||
@ -30,10 +35,18 @@ type
|
|||||||
procedure SetValue(position:SizeUInt; value:T);inline;
|
procedure SetValue(position:SizeUInt; value:T);inline;
|
||||||
function GetValue(position:SizeUInt):T;inline;
|
function GetValue(position:SizeUInt):T;inline;
|
||||||
function GetMutable(position:SizeUInt):PT;inline;
|
function GetMutable(position:SizeUInt):PT;inline;
|
||||||
procedure IncreaseCapacity();inline;
|
procedure IncreaseCapacity();
|
||||||
|
protected
|
||||||
|
procedure MoveSimpleData(StartIndex: SizeUInt; Offset: SizeInt; NrElems: SizeUInt);
|
||||||
|
procedure MoveManagedData(StartIndex: SizeUInt; Offset: SizeInt; NrElems: SizeUInt);
|
||||||
|
procedure MoveData(StartIndex: SizeUInt; Offset: SizeInt; NrElems: SizeUInt);
|
||||||
|
procedure ClearSingleDataEntry(Index: SizeUInt); virtual;
|
||||||
|
procedure ClearData; virtual;
|
||||||
|
property Data: TArr read FData;
|
||||||
public
|
public
|
||||||
function Size():SizeUInt;inline;
|
function Size():SizeUInt;inline;
|
||||||
constructor Create();
|
constructor Create();
|
||||||
|
destructor Destroy(); override;
|
||||||
Procedure Clear;
|
Procedure Clear;
|
||||||
procedure PushBack(value:T);inline;
|
procedure PushBack(value:T);inline;
|
||||||
procedure PushFront(value:T);inline;
|
procedure PushFront(value:T);inline;
|
||||||
@ -59,8 +72,15 @@ begin
|
|||||||
FStart:=0;
|
FStart:=0;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
destructor TDeque.Destroy();
|
||||||
|
begin
|
||||||
|
Clear;
|
||||||
|
inherited Destroy;
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TDeque.Clear;
|
procedure TDeque.Clear;
|
||||||
begin
|
begin
|
||||||
|
ClearData;
|
||||||
FDataSize:=0;
|
FDataSize:=0;
|
||||||
FStart:=0;
|
FStart:=0;
|
||||||
end;
|
end;
|
||||||
@ -87,6 +107,7 @@ procedure TDeque.PopFront();inline;
|
|||||||
begin
|
begin
|
||||||
if(FDataSize>0) then
|
if(FDataSize>0) then
|
||||||
begin
|
begin
|
||||||
|
ClearSingleDataEntry(FStart);
|
||||||
inc(FStart);
|
inc(FStart);
|
||||||
dec(FDataSize);
|
dec(FDataSize);
|
||||||
if(FStart=FCapacity) then
|
if(FStart=FCapacity) then
|
||||||
@ -97,7 +118,10 @@ end;
|
|||||||
procedure TDeque.PopBack();inline;
|
procedure TDeque.PopBack();inline;
|
||||||
begin
|
begin
|
||||||
if(FDataSize>0) then
|
if(FDataSize>0) then
|
||||||
|
begin
|
||||||
|
ClearSingleDataEntry((FStart+FDataSize-1)mod FCapacity);
|
||||||
dec(FDataSize);
|
dec(FDataSize);
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TDeque.PushFront(value:T);inline;
|
procedure TDeque.PushFront(value:T);inline;
|
||||||
@ -127,6 +151,7 @@ end;
|
|||||||
procedure TDeque.SetValue(position:SizeUInt; value:T);inline;
|
procedure TDeque.SetValue(position:SizeUInt; value:T);inline;
|
||||||
begin
|
begin
|
||||||
Assert(position < size, 'Deque access out of range');
|
Assert(position < size, 'Deque access out of range');
|
||||||
|
ClearSingleDataEntry((FStart+position)mod FCapacity);
|
||||||
FData[(FStart+position)mod FCapacity]:=value;
|
FData[(FStart+position)mod FCapacity]:=value;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -142,7 +167,68 @@ begin
|
|||||||
GetMutable:=@FData[(FStart+position) mod FCapacity];
|
GetMutable:=@FData[(FStart+position) mod FCapacity];
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TDeque.IncreaseCapacity;inline;
|
|
||||||
|
procedure TDeque.MoveSimpleData(StartIndex: SizeUInt; Offset: SizeInt; NrElems: SizeUInt);
|
||||||
|
begin
|
||||||
|
Move(FData[StartIndex], FData[StartIndex+Offset], NrElems*SizeOf(T));
|
||||||
|
if Offset>0 then
|
||||||
|
FillChar(FData[StartIndex], NrElems*SizeOf(T), 0)
|
||||||
|
else
|
||||||
|
FillChar(FData[StartIndex+NrElems+Offset], -Offset*SizeOf(T), 0);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TDeque.MoveManagedData(StartIndex: SizeUInt; Offset: SizeInt; NrElems: SizeUInt);
|
||||||
|
var
|
||||||
|
i: SizeUInt;
|
||||||
|
begin
|
||||||
|
//since we always move blocks where Abs(Offset)>=NrElems, there is no need for
|
||||||
|
//2 seperate loops (1 for ngeative and 1 for positive Offsett)
|
||||||
|
for i := 0 to NrElems-1 do
|
||||||
|
begin
|
||||||
|
Finalize(FData[StartIndex+i+Offset]);
|
||||||
|
FData[StartIndex+i+Offset] := FData[StartIndex+i];
|
||||||
|
Finalize(FData[StartIndex+i]);
|
||||||
|
FillChar(FData[StartIndex+i], SizeOf(T), 0);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TDeque.MoveData(StartIndex: SizeUInt; Offset: SizeInt; NrElems: SizeUInt);
|
||||||
|
begin
|
||||||
|
if IsManagedType(T) then
|
||||||
|
MoveManagedData(StartIndex, Offset, NrElems)
|
||||||
|
else
|
||||||
|
MoveSimpleData(StartIndex, Offset, NrElems);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TDeque.ClearSingleDataEntry(Index: SizeUInt);
|
||||||
|
begin
|
||||||
|
if IsManagedType(T) then
|
||||||
|
begin
|
||||||
|
Finalize(FData[Index]);
|
||||||
|
FillChar(FData[Index], SizeOf(T), 0);
|
||||||
|
end
|
||||||
|
else
|
||||||
|
FData[Index] := default(T);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TDeque.ClearData;
|
||||||
|
var
|
||||||
|
i: SizeUint;
|
||||||
|
begin
|
||||||
|
if IsManagedType(T) then
|
||||||
|
for i := Low(FData) to High(FData) do
|
||||||
|
Finalize(FData[i]);
|
||||||
|
FillChar(FData[Low(FData)], SizeUInt(Length(FData))*SizeOf(T), 0);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TDeque.IncreaseCapacity;
|
||||||
|
function Min(const A,B: SizeUInt): SizeUInt; inline; //no need to drag in the entire Math unit ;-)
|
||||||
|
begin
|
||||||
|
if (A<B) then
|
||||||
|
Result:=A
|
||||||
|
else
|
||||||
|
Result:=B;
|
||||||
|
end;
|
||||||
const
|
const
|
||||||
// if size is small, multiply by 2;
|
// if size is small, multiply by 2;
|
||||||
// if size bigger but <256M, inc by 1/8*size;
|
// if size bigger but <256M, inc by 1/8*size;
|
||||||
@ -151,7 +237,7 @@ const
|
|||||||
cSizeBig = 256*1024*1024;
|
cSizeBig = 256*1024*1024;
|
||||||
var
|
var
|
||||||
i,OldEnd,
|
i,OldEnd,
|
||||||
DataSize:SizeUInt;
|
DataSize,CurLast,EmptyElems,Elems:SizeUInt;
|
||||||
begin
|
begin
|
||||||
OldEnd:=FCapacity;
|
OldEnd:=FCapacity;
|
||||||
DataSize:=FCapacity*SizeOf(T);
|
DataSize:=FCapacity*SizeOf(T);
|
||||||
@ -165,11 +251,26 @@ begin
|
|||||||
FCapacity:=FCapacity+FCapacity div 8
|
FCapacity:=FCapacity+FCapacity div 8
|
||||||
else
|
else
|
||||||
FCapacity:=FCapacity+FCapacity div 16;
|
FCapacity:=FCapacity+FCapacity div 16;
|
||||||
|
|
||||||
SetLength(FData, FCapacity);
|
SetLength(FData, FCapacity);
|
||||||
if (FStart>0) then
|
if (FStart>0) then
|
||||||
for i:=0 to FStart-1 do
|
begin
|
||||||
FData[OldEnd+i]:=FData[i];
|
if (FCapacity-OldEnd>=FStart) then //we have room to move all items in one go
|
||||||
|
begin
|
||||||
|
MoveData(0, OldEnd ,FStart)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin //we have to move things around in chunks: we have more data in front of FStart than we have newly created unused elements
|
||||||
|
CurLast := OldEnd-1;
|
||||||
|
EmptyElems:=FCapacity-1-CurLast;
|
||||||
|
while (FStart>0) do
|
||||||
|
begin
|
||||||
|
Elems := Min(EmptyElems, FStart);
|
||||||
|
MoveData(0, CurLast+1, Elems);
|
||||||
|
MoveData(Elems, -Elems, FCapacity-Elems);
|
||||||
|
Dec(FStart, Elems);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TDeque.Reserve(cap:SizeUInt);inline;
|
procedure TDeque.Reserve(cap:SizeUInt);inline;
|
||||||
|
@ -797,10 +797,12 @@ INTERFACE
|
|||||||
{$endif}
|
{$endif}
|
||||||
|
|
||||||
function __get_null : tBCD; Inline;
|
function __get_null : tBCD; Inline;
|
||||||
|
function __get_zero : tBCD; Inline;
|
||||||
function __get_one : tBCD; Inline;
|
function __get_one : tBCD; Inline;
|
||||||
|
|
||||||
PROPERTY
|
PROPERTY
|
||||||
NullBCD : tBCD Read __get_null;
|
NullBCD : tBCD Read __get_null;
|
||||||
|
ZeroBCD : tBCD Read __get_zero;
|
||||||
OneBCD : tBCD Read __get_one;
|
OneBCD : tBCD Read __get_one;
|
||||||
|
|
||||||
//{$define __lo_bh := 1 * ( -( MaxFmtBCDFractionSize * 1 + 2 ) ) }
|
//{$define __lo_bh := 1 * ( -( MaxFmtBCDFractionSize * 1 + 2 ) ) }
|
||||||
@ -887,16 +889,20 @@ IMPLEMENTATION
|
|||||||
OneBCD_ : tBCD;
|
OneBCD_ : tBCD;
|
||||||
|
|
||||||
function __get_null : tBCD; Inline;
|
function __get_null : tBCD; Inline;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
__get_null := NullBCD_;
|
__get_null := NullBCD_;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function __get_zero : tBCD; Inline;
|
||||||
|
begin
|
||||||
|
__get_zero := NullBCD_;
|
||||||
|
__get_zero.Precision := 1;
|
||||||
|
end;
|
||||||
|
|
||||||
function __get_one : tBCD; Inline;
|
function __get_one : tBCD; Inline;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
__get_one := OneBCD_;
|
__get_one := OneBCD_;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
type
|
type
|
||||||
range_digits = 1..maxfmtbcdfractionsize;
|
range_digits = 1..maxfmtbcdfractionsize;
|
||||||
@ -1584,7 +1590,7 @@ IMPLEMENTATION
|
|||||||
begin
|
begin
|
||||||
_SELECT
|
_SELECT
|
||||||
_WHEN aValue = 0
|
_WHEN aValue = 0
|
||||||
_THEN result := NullBCD;
|
_THEN result := ZeroBCD;
|
||||||
_WHEN aValue = 1
|
_WHEN aValue = 1
|
||||||
_THEN result := OneBCD;
|
_THEN result := OneBCD;
|
||||||
_WHEN aValue = low ( myInttype )
|
_WHEN aValue = low ( myInttype )
|
||||||
@ -4130,12 +4136,6 @@ begin
|
|||||||
else { array or something like that }
|
else { array or something like that }
|
||||||
not_implemented;
|
not_implemented;
|
||||||
end;
|
end;
|
||||||
// peephole, avoids problems with databases, mantis #30853
|
|
||||||
if (Result.Precision = 0) and (Result.SignSpecialPlaces = 0) then
|
|
||||||
begin
|
|
||||||
Result.Precision := 10;
|
|
||||||
Result.SignSpecialPlaces := 2;
|
|
||||||
end;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function VarToBCD ( const aValue : Variant ) : tBCD;
|
function VarToBCD ( const aValue : Variant ) : tBCD;
|
||||||
|
39
tests/webtbs/tw38306.pp
Normal file
39
tests/webtbs/tw38306.pp
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
{ %OPT=-gh }
|
||||||
|
{$mode objfpc}
|
||||||
|
program gqueue_test;
|
||||||
|
|
||||||
|
uses
|
||||||
|
gqueue;
|
||||||
|
|
||||||
|
type
|
||||||
|
TIntQueue = specialize TQueue<Integer>;
|
||||||
|
|
||||||
|
var
|
||||||
|
IntQueue: TIntQueue;
|
||||||
|
PushCnt: Integer;
|
||||||
|
|
||||||
|
procedure Push2Pop1;
|
||||||
|
var
|
||||||
|
i: Integer;
|
||||||
|
begin
|
||||||
|
for i:= 0 to 1000000 do begin
|
||||||
|
IntQueue.Push(PushCnt);
|
||||||
|
inc(PushCnt);
|
||||||
|
IntQueue.Push(PushCnt);
|
||||||
|
inc(PushCnt);
|
||||||
|
IntQueue.Pop();
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
var
|
||||||
|
i: Integer;
|
||||||
|
begin
|
||||||
|
try
|
||||||
|
IntQueue:= TIntQueue.Create;
|
||||||
|
Push2Pop1;
|
||||||
|
WriteLn('Ready');
|
||||||
|
finally
|
||||||
|
IntQueue.Free;
|
||||||
|
end;
|
||||||
|
end.
|
||||||
|
|
Loading…
Reference in New Issue
Block a user