Forum > FPC development
[SOLVED] Improvement of rtl/linux/system.pp procedure InitTLS;
lagprogramming:
Looking at the procedure I've noticed that variable "i" is declared as integer. When I moved the mouse over it, Lazarus wrote that integer is an alias for smallint.
Later the code contains "for i:=1 to phnum do", where variable "phnum" is of type dword. This means that some valid iterations might not be executed inside the loop.
The modified code removes variable "i" and replaces the line "for i:=1 to phnum do" with "for phnum:=phnum downto 1 do".
You might also be interested in reading the forum post Miscellaneous>Suggestions>Optimization of for loops in the near zero range
Existing code
--- Code: Pascal [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---procedure InitTLS; [public,alias:'FPC_INITTLS']; const PT_TLS = 7; PT_DYNAMIC = 2; type{$ifdef CPU64} tphdr = record p_type, p_flags : dword; p_offset, p_vaddr, p_paddr, p_filesz, p_memsz, p_align : qword; end;{$else CPU64} tphdr = record p_type, p_offset, p_vaddr, p_paddr, p_filesz, p_memsz, p_flags, p_align : dword; end;{$endif CPU64} pphdr = ^tphdr; var phdr : pphdr; phnum : dword; i : integer; tls : pointer; auxp : ppointer; found : boolean; size : SizeUInt; begin auxp:=ppointer(envp); { skip environment } while assigned(auxp^) do inc(auxp); inc(auxp); phdr:=nil; phnum:=0; { now we are at the auxillary vector } while assigned(auxp^) do begin case plongint(auxp)^ of 3: phdr:=pphdr(ppointer(auxp+1)^); 5: phnum:=pdword(auxp+1)^; end; inc(auxp,2); end; found:=false; size:=0; for i:=1 to phnum do begin case phdr^.p_type of PT_TLS: begin found:=true; inc(size,phdr^.p_memsz); size:=Align(size,phdr^.p_align); end; PT_DYNAMIC: { if the program header contains a dynamic section, the program is linked dynamically so the dynamic linker takes care of the allocation of the TLS segment. We cannot allocate it by ourself anyways as PT_TLS provides only the size of TLS data of the executable itself } exit; end; inc(phdr); end; if found then begin{$ifdef CPUI386} { threadvars should start at a page boundary, add extra space for the TCB } size:=Align(size,4096)+sizeof(Pointer);{$endif CPUI386}{$ifdef CPUX86_64} { threadvars should start at a page boundary, add extra space for the TCB } size:=Align(size,4096)+sizeof(Pointer);{$endif CPUX86_64} tls:=Fpmmap(nil,size,3,MAP_PRIVATE+MAP_ANONYMOUS,-1,0); fpset_tls(tls,size); end; end;{$endif INITTLS}
New code
--- Code: Pascal [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---procedure InitTLS; [public,alias:'FPC_INITTLS']; const PT_TLS = 7; PT_DYNAMIC = 2; type{$ifdef CPU64} tphdr = record p_type, p_flags : dword; p_offset, p_vaddr, p_paddr, p_filesz, p_memsz, p_align : qword; end;{$else CPU64} tphdr = record p_type, p_offset, p_vaddr, p_paddr, p_filesz, p_memsz, p_flags, p_align : dword; end;{$endif CPU64} pphdr = ^tphdr; var phdr : pphdr; phnum : dword; tls : pointer; auxp : ppointer; found : boolean; size : SizeUInt; begin auxp:=ppointer(envp); { skip environment } while assigned(auxp^) do inc(auxp); inc(auxp); phdr:=nil; phnum:=0; { now we are at the auxillary vector } while assigned(auxp^) do begin case plongint(auxp)^ of 3: phdr:=pphdr(ppointer(auxp+1)^); 5: phnum:=pdword(auxp+1)^; end; inc(auxp,2); end; found:=false; size:=0; for phnum:=phnum downto 1 do begin case phdr^.p_type of PT_TLS: begin found:=true; inc(size,phdr^.p_memsz); size:=Align(size,phdr^.p_align); end; PT_DYNAMIC: { if the program header contains a dynamic section, the program is linked dynamically so the dynamic linker takes care of the allocation of the TLS segment. We cannot allocate it by ourself anyways as PT_TLS provides only the size of TLS data of the executable itself } exit; end; inc(phdr); end; if found then begin{$ifdef CPUI386} { threadvars should start at a page boundary, add extra space for the TCB } size:=Align(size,4096)+sizeof(Pointer);{$endif CPUI386}{$ifdef CPUX86_64} { threadvars should start at a page boundary, add extra space for the TCB } size:=Align(size,4096)+sizeof(Pointer);{$endif CPUX86_64} tls:=Fpmmap(nil,size,3,MAP_PRIVATE+MAP_ANONYMOUS,-1,0); fpset_tls(tls,size); end; end;{$endif INITTLS}
Blaazen:
Is it really SmallInt? Sometimes hovering variables at design-time gives wrong info because there can be some conditions, i.e. this:
--- Code: Pascal [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---const TBITS_SHIFT ={$if sizeof(TBitsBase) = sizeof(word)} 4{$elseif sizeof(TBitsBase) = sizeof(dword)} 5{$elseif sizeof(TBitsBase) = sizeof(qword)} 6{$else}{$error unknown TBitsBase}{$endif} ; TBITS_MASK = 1 shl TBITS_SHIFT - 1;Hovering TBITS_SHIFT shows 4 at design-time while it is 6 at runtime (64-bit Linux, file: bits.inc).
lagprogramming:
--- Quote from: Blaazen on March 24, 2023, 03:56:17 pm ---Is it really SmallInt? Sometimes hovering variables at design-time gives wrong info because there can be some conditions, i.e. this:
--- End quote ---
I don't think it matters much.
According to Free Pascal Language Reference Guide Types>Base types>Ordinal types: "The integer type is an alias to the smallint type in the default Free Pascal mode. It is an alias for the longint type in either Delphi or ObjFPC mode."
So, the maximum value of an integer type is longint, which is smaller than the maximum value of a dword(longword). Notice that variable "phnum" is dword type. This means that iterations between high(integer) and high(dword) won't run.
The proposed code removes the variable "i" which will get rid of any error regarding the compatibility between integer and dword variable types.
marcov:
Linux' system.pp unit includes sysunixh.inc which includes systemh.inc which contains $mode objfpc
PascalDragon:
--- Quote from: marcov on March 26, 2023, 01:10:29 pm ---Linux' system.pp unit includes sysunixh.inc which includes systemh.inc which contains $mode objfpc
--- End quote ---
Which will not change the declaration of Integer inside the System unit, because the Integer = LongInt alias is declared in unit ObjPas which is not included inside the System unit.
Navigation
[0] Message Index
[#] Next page