mORMot and Open Source friends
Check-in [606597ced5]
Not logged in

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:{5785} reduce unnecessary calls to GetTick64() OS function (clock_gettime) during normal socket processing
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 606597ced53f7165012143bb097fd6d658c80c0b
User & Date: ab 2020-03-09 11:33:30
Context
2020-03-09
13:13
{5786} refined TSynLocker / TSynObjectListLocked documentation about thread-safety check-in: d5e9c2752d user: ab tags: trunk
11:33
{5785} reduce unnecessary calls to GetTick64() OS function (clock_gettime) during normal socket processing check-in: 606597ced5 user: ab tags: trunk
00:41
{5784} introducing TSynList/TSynObjectList/TSynObjectListLocked check-in: 1cd7d503dd user: ab tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to SynCommons.pas.

25082
25083
25084
25085
25086
25087
25088

25089
25090
25091
25092
25093
25094
25095
        jnz     @loop
@ok:    add     eax, ecx
        ret
@null:  db      $f3 // rep ret
end;

procedure YearToPChar(Y: PtrUInt; P: PUTF8Char);

asm // eax=Y, edx=P
        push    edx
        mov     ecx, eax
        mov     edx, 1374389535 // use power of two reciprocal to avoid division
        mul     edx
        shr     edx, 5          // now edx=Y div 100
        movzx   eax, word ptr[TwoDigitLookup + edx * 2]






>







25082
25083
25084
25085
25086
25087
25088
25089
25090
25091
25092
25093
25094
25095
25096
        jnz     @loop
@ok:    add     eax, ecx
        ret
@null:  db      $f3 // rep ret
end;

procedure YearToPChar(Y: PtrUInt; P: PUTF8Char);
{$ifdef FPC}nostackframe; assembler;{$endif}
asm // eax=Y, edx=P
        push    edx
        mov     ecx, eax
        mov     edx, 1374389535 // use power of two reciprocal to avoid division
        mul     edx
        shr     edx, 5          // now edx=Y div 100
        movzx   eax, word ptr[TwoDigitLookup + edx * 2]

Changes to SynCrtSock.pas.

5025
5026
5027
5028
5029
5030
5031
5032
5033
5034
5035
5036
5037
5038
5039
....
5040
5041
5042
5043
5044
5045
5046


5047
5048
5049
5050
5051
5052
5053
5054
5055
....
5256
5257
5258
5259
5260
5261
5262
5263
5264
5265
5266
5267
5268
5269
5270
....
5282
5283
5284
5285
5286
5287
5288


5289
5290
5291
5292
5293
5294
5295
5296
5297
5298

5299
5300
5301
5302
5303
5304
5305
.....
12295
12296
12297
12298
12299
12300
12301
12302
12303
12304
12305
12306
12307
12308
12309
.....
12320
12321
12322
12323
12324
12325
12326


12327
12328
12329
12330
12331
12332
12333
12334

12335
12336
12337
12338
12339
12340
12341
function TCrtSocket.TrySndLow(P: pointer; Len: integer): boolean;
var sent: integer;
    endtix: Int64;
begin
  result := Len=0;
  if (self=nil) or (fSock<=0) or (Len<=0) or (P=nil) then
    exit;
  endtix := GetTick64+TimeOut;
  repeat
    {$ifdef MSWINDOWS}
    if fSecure.Initialized then
      sent := fSecure.Send(fSock, P, Len) else
    {$endif MSWINDOWS}
      sent := AsynchSend(fSock, P, Len);
    if sent>0 then begin
................................................................................
      inc(fBytesOut,sent);
      dec(Len,sent);
      if Len<=0 then
        break;
      inc(PByte(P),sent);
    end else if WSAIsFatalError then
      exit; // fatal socket error


    if GetTick64>endtix then
      exit; // identify timeout as error
    SleepHiRes(1);
  until false;
  result := true;
end;

procedure TCrtSocket.Write(const Data: SockString);
begin
................................................................................
var expected,read: PtrInt;
    start, diff: Int64;
begin
  result := false;
  if (self<>nil) and (fSock>0) and (Buffer<>nil) and (Length>0) then begin
    expected := Length;
    Length := 0;
    start := GetTick64;
    repeat
      read := expected-Length;
      {$ifdef MSWINDOWS}
      if fSecure.Initialized then
        read := fSecure.Receive(fSock,Buffer,read) else
      {$endif MSWINDOWS}
        read := AsynchRecv(fSock,Buffer,read);
................................................................................
      end else begin
        inc(fBytesIn,read);
        inc(Length,read);
        if StopBeforeLength or (Length=expected) then
          break; // good enough for now
        inc(PByte(Buffer),read);
      end;


      diff := GetTick64-start;
      if diff>=TimeOut then begin
        {$ifdef SYNCRTDEBUGLOW}
        TSynLog.Add.Log(sllCustom2, 'TrySockRecv: timeout (diff=%>%)',[diff,TimeOut],self);
        {$endif}
        exit; // identify read timeout as error
      end;
      if diff<100 then
        SleepHiRes(0) else
        SleepHiRes(1);

    until false;
    result := true;
  end;
end;

function TCrtSocket.SockReceivePending(TimeOutMS: integer): TCrtSocketPending;
var res: integer;
................................................................................
var p,n: integer;
    elapsed,start: Int64;
begin
  result := false;
  byte(notif.events) := 0;
  if (timeoutMS<0) or fTerminated then
    exit;
  start := GetTick64;
  repeat
    // non-blocking search within fPoll[]
    EnterCriticalSection(fPollLock);
    try
      // check if some already notified as pending in fPoll[]
      if GetOneWithinPending(notif) then
        exit;
................................................................................
    finally
      LeaveCriticalSection(fPollLock);
      result := byte(notif.events)<>0; // exit would comes here and set result
    end;
    // wait a little for something to happen
    if fTerminated or (timeoutMS=0) then
      exit;


    elapsed := GetTick64-start; // allow multi-threaded process
    if elapsed>timeoutMS then
      exit else
    if elapsed>300 then
      SleepHiRes(50) else
    if elapsed>50 then
      SleepHiRes(10) else
      SleepHiRes(1);

  until fTerminated;
end;

procedure TPollSockets.Terminate;
begin
  if self<>nil then
    fTerminated := true;






|







 







>
>
|
|







 







|







 







>
>
|
|
|
|
|
|
|
|
|
|
>







 







|







 







>
>
|
|
|
|
|
|
|
|
>







5025
5026
5027
5028
5029
5030
5031
5032
5033
5034
5035
5036
5037
5038
5039
....
5040
5041
5042
5043
5044
5045
5046
5047
5048
5049
5050
5051
5052
5053
5054
5055
5056
5057
....
5258
5259
5260
5261
5262
5263
5264
5265
5266
5267
5268
5269
5270
5271
5272
....
5284
5285
5286
5287
5288
5289
5290
5291
5292
5293
5294
5295
5296
5297
5298
5299
5300
5301
5302
5303
5304
5305
5306
5307
5308
5309
5310
.....
12300
12301
12302
12303
12304
12305
12306
12307
12308
12309
12310
12311
12312
12313
12314
.....
12325
12326
12327
12328
12329
12330
12331
12332
12333
12334
12335
12336
12337
12338
12339
12340
12341
12342
12343
12344
12345
12346
12347
12348
12349
function TCrtSocket.TrySndLow(P: pointer; Len: integer): boolean;
var sent: integer;
    endtix: Int64;
begin
  result := Len=0;
  if (self=nil) or (fSock<=0) or (Len<=0) or (P=nil) then
    exit;
  endtix := 0;
  repeat
    {$ifdef MSWINDOWS}
    if fSecure.Initialized then
      sent := fSecure.Send(fSock, P, Len) else
    {$endif MSWINDOWS}
      sent := AsynchSend(fSock, P, Len);
    if sent>0 then begin
................................................................................
      inc(fBytesOut,sent);
      dec(Len,sent);
      if Len<=0 then
        break;
      inc(PByte(P),sent);
    end else if WSAIsFatalError then
      exit; // fatal socket error
    if endtix=0 then // measure time elapsed only if write was not finished
      endtix := GetTick64+TimeOut else
      if GetTick64>endtix then
        exit; // identify timeout as error
    SleepHiRes(1);
  until false;
  result := true;
end;

procedure TCrtSocket.Write(const Data: SockString);
begin
................................................................................
var expected,read: PtrInt;
    start, diff: Int64;
begin
  result := false;
  if (self<>nil) and (fSock>0) and (Buffer<>nil) and (Length>0) then begin
    expected := Length;
    Length := 0;
    start := 0;
    repeat
      read := expected-Length;
      {$ifdef MSWINDOWS}
      if fSecure.Initialized then
        read := fSecure.Receive(fSock,Buffer,read) else
      {$endif MSWINDOWS}
        read := AsynchRecv(fSock,Buffer,read);
................................................................................
      end else begin
        inc(fBytesIn,read);
        inc(Length,read);
        if StopBeforeLength or (Length=expected) then
          break; // good enough for now
        inc(PByte(Buffer),read);
      end;
      if start=0 then // measure time elapsed only if read was not finished
        start := GetTick64 else begin
        diff := GetTick64-start;
        if diff>=TimeOut then begin
          {$ifdef SYNCRTDEBUGLOW}
          TSynLog.Add.Log(sllCustom2, 'TrySockRecv: timeout (diff=%>%)',[diff,TimeOut],self);
          {$endif}
          exit; // identify read timeout as error
        end;
        if diff<100 then
          SleepHiRes(0) else
          SleepHiRes(1);
      end;
    until false;
    result := true;
  end;
end;

function TCrtSocket.SockReceivePending(TimeOutMS: integer): TCrtSocketPending;
var res: integer;
................................................................................
var p,n: integer;
    elapsed,start: Int64;
begin
  result := false;
  byte(notif.events) := 0;
  if (timeoutMS<0) or fTerminated then
    exit;
  start := 0;
  repeat
    // non-blocking search within fPoll[]
    EnterCriticalSection(fPollLock);
    try
      // check if some already notified as pending in fPoll[]
      if GetOneWithinPending(notif) then
        exit;
................................................................................
    finally
      LeaveCriticalSection(fPollLock);
      result := byte(notif.events)<>0; // exit would comes here and set result
    end;
    // wait a little for something to happen
    if fTerminated or (timeoutMS=0) then
      exit;
    if start=0 then // measure time elapsed only if we wait
      start := GetTick64 else begin
      elapsed := GetTick64-start; // allow multi-threaded process
      if elapsed>timeoutMS then
        exit else
      if elapsed>300 then
        SleepHiRes(50) else
      if elapsed>50 then
        SleepHiRes(10) else
        SleepHiRes(1);
    end;
  until fTerminated;
end;

procedure TPollSockets.Terminate;
begin
  if self<>nil then
    fTerminated := true;

Changes to SynopseCommit.inc.

1
'1.18.5784'
|
1
'1.18.5785'