Normal view

There are new articles available, click to refresh the page.
Before yesterdayNews from the Ada programming language world

How to rename standard library functions

I am unsuccessfully trying to rename Put_Line() as print().

I get this is silly, but it's just for my ease. Is this possible?

My code so far:

with Ada.Text_IO;

use Ada.Text_IO;

procedure Hello is

function print renames Put_Line;

begin

print("Hello, test world!");

New_Line;

print("I am an Ada program with package use.");

end Hello;

submitted by /u/SachemAgogic
[link] [comments]

find image tags with alt attribute without double quotes and replace with empty double quotes

<img src="first.jpg" alt="first" width="500" height="600" />
<img src="second.jpg" alt width="500" height="600" />
<img src="third.jpg" alt="third" width="500" height="600" />
<img src="fourth.jpg" alt width="500" height="600" />
<img src="fifth.jpg" alt="" width="500" height="600" />

find image tags with alt attribute without double quotes and replace with empty double quotes for ADA accessibility, I need to jquery to find second and fourth img tags replace with alt="" just like fifth. This is sample html markup, a page can have this instances 10 or 20 instances, all these should be replaced with alt=""

I tried this below didn't work

$(function() {
  $("img").each(function() {
    if (this.alt) {
      console.log(this.alt);
    } else {
      $(this).attr('alt', "");
    }
  });
});

How to add Headers in AWS (ada web server)?

I have been trying to add Headers (specifically for CORS) to my server response for hours now, but I cant find a way in ada with AWS. Can someone help me? ( So far I have found only ways to add the Headers to the Client, but not as a Server Response)

Please ignore that the code is a bit messy, this is my first real project in Ada and I am just trying things out.

with AWS.Client;
with AWS.Response;
with AWS.Server;
with AWS.Server.Status;
with AWS.Status;
with Ada.Text_IO;
with Ada.Strings.Unbounded;
with AWS.Headers;

procedure aws_test is:

   WS      : AWS.Server.HTTP;
   Headers : AWS.Headers.List;

   function HW_CB (Request : in AWS.Status.Data) return AWS.Response.Data is
      URI : constant String := AWS.Status.URI (Request);

      Test_Data : AWS.Response.Data :=
        AWS.Client.Get (URL => "http://192.168.190.129");

      Test_String   : constant String := AWS.Response.Message_Body (Test_Data);
      para          : Ada.Strings.Unbounded.Unbounded_String;
      test          : Integer         := 1;
      response_data : AWS.Response.Data;

    begin

      AWS.Headers.Add
        (Table => Headers, Name => "Access-Control-Allow-Origin",
         Value => "*");
      -- Allow common methods
      AWS.Headers.Add
        (Table => Headers, Name => "Access-Control-Allow-Methods",
         Value => "POST, GET, OPTIONS, PUT, DELETE");

      -- Allow all headers requested in the actual request
      AWS.Headers.Add
        (Table => Headers, Name => "Access-Control-Allow-Headers",
         Value => "*");

      -- Set max age to 86400 seconds (24 hours)
      AWS.Headers.Add
        (Table => Headers, Name => "Access-Control-Max-Age", Value => "86400");

      if URI = "/api/login" then
         -- ADD HERE
         test := test + 1;
         para := AWS.Status.Binary_Data (Request);

         Ada.Text_IO.Put_Line (Ada.Strings.Unbounded.To_String (para));
         -- Ada.Text_IO.Put_Line (Test_String);

         response_data := AWS.Response.Build ("text/html", "<p>Hello world !");
         AWS.Response.Set.Add_Header
           (response_data, Name => "Access-Control-Max-Age", Value => "86400");
         return response_data;
      else
         return AWS.Response.Build ("text/html", "<p>Hum...");
      end if;
    end HW_CB;

    begin
     AWS.Server.Start
      (WS, "Hotel AI", Callback => HW_CB'Unrestricted_Access, Port => 8_080);
     delay 20.0;
     AWS.Server.Shutdown (WS);
     while AWS.Server.Status.Is_Shutdown (WS) = False loop
      delay 5.0;
     end loop;
    end aws_test;

I just would like to add Headers so I dont get CORS flagged in Javascript. Thank you very much for your Help ( I am a bit struggling to find good resources on these topics in the web )

I have already tried several possible ways (as well with the help of AI etc.), bu tI couldn't even really find good examples on Github or in the documentation

How do I read a binary file in BigEndian order to a record?

I have a binary file format that is written in BigEndian order. The files are of varying size so I can't use Sequential_IO for this, as I need to read different types.

The problem is, when using Stream_IO, I can't find a way to use BigEndian, and Scalar_Storage_Order also doesn't affect anything. Also, I'm a very fresh beginner at Ada and overall tips and suggestions to the code are very welcome.

share.adb:
with Ada.Text_IO;
with Ada.Streams.Stream_IO; use Ada.Streams.Stream_IO;
with Ada.Streams;           use Ada.Streams;

package body Share is

   procedure Read_Share (Segment_Size : Positive; Required_Shares : Positive)
   is
      --  Ceiling function
      Block_Size : constant Positive :=
        (Segment_Size + (Required_Shares - 1)) / Required_Shares;
      type Block is array (Integer range 0 .. Block_Size) of Byte;

      S               : Stream_Access;
      Share_File      : File_Type;
      My_Share_Header : Share_Header;
   begin
      Open (Share_File, In_File, "../go-tahoe/3");
      S := Stream (Share_File);
      Share_Header'Read (S, My_Share_Header);
      My_Share_Header.Block_Size := Unsigned_32 (Block_Size);
      Display_Share_Content (My_Share_Header);

      Close (Share_File);
      --  Read_Blocks (My_Share_Header, Share_File);

      --  Now My_Share contains the values read from the binary file
   end Read_Share;

   procedure Display_Share_Content (My_Share_Header : Share_Header) is
   begin
      Ada.Text_IO.Put_Line
        ("Share version: " &
         Interfaces.Unsigned_32'Image (My_Share_Header.Version));
      Ada.Text_IO.Put_Line
        ("Share Data Length: " &
         Interfaces.Unsigned_32'Image (My_Share_Header.Data_Length));
      Ada.Text_IO.Put_Line
        ("Lease Number: " &
         Interfaces.Unsigned_32'Image (My_Share_Header.Lease_number));
      Ada.Text_IO.Put_Line
        ("Share version: " &
         Interfaces.Unsigned_32'Image (My_Share_Header.Version));
      Ada.Text_IO.Put_Line
        ("Block Size: " &
         Interfaces.Unsigned_32'Image (My_Share_Header.Block_Size));
      Ada.Text_IO.Put_Line
        ("Data Size: " &
         Interfaces.Unsigned_32'Image (My_Share_Header.Data_Size));
      Ada.Text_IO.Put_Line
        ("Data offset: " &
         Interfaces.Unsigned_32'Image (My_Share_Header.Data_Offset));
      Ada.Text_IO.Put_Line
        ("Plaintext hash tree offset: " &
         Interfaces.Unsigned_32'Image
           (My_Share_Header.Plaintext_Hash_Tree_Offset));
      Ada.Text_IO.Put_Line
        ("Crypttext hash tree offset: " &
         Interfaces.Unsigned_32'Image
           (My_Share_Header.Crypttext_Hash_Tree_Offset));
      Ada.Text_IO.Put_Line
        ("Block hashes offset: " &
         Interfaces.Unsigned_32'Image (My_Share_Header.Block_Hashes_Offset));
      Ada.Text_IO.Put_Line
        ("Share hashes offset: " &
         Interfaces.Unsigned_32'Image (My_Share_Header.Share_Hashes_Offset));
      Ada.Text_IO.Put_Line
        ("URI Extension Length and URI Extension block offset: " &
         Interfaces.Unsigned_32'Image (My_Share_Header.URI_Extension_Offset));
   end Display_Share_Content;

   procedure Read_Blocks
     (My_Share_Header : Share_Header; Share_File : File_Type)
   is
      Total_Blocks : Interfaces.Unsigned_32 := My_Share_Header.Data_Size;
   begin
      Ada.Text_IO.Put ("");

   end Read_Blocks;
end Share;

share.ads:
with Interfaces; use Interfaces;
with System;     use System;
with Ada.Streams.Stream_IO;

package Share is

   type Byte is new Interfaces.Unsigned_8;
   type Kilobyte is array (Integer range 0 .. 1_023) of Byte;
   type Kilobyte_array is array (Integer range <>) of Kilobyte;

   type Share_Header is record
      Version                    : Unsigned_32;
      Data_Length                : Unsigned_32;
      Lease_number               : Unsigned_32;
      Version_Junk               : Unsigned_32;
      --  unused as it can be calculated from the URI
      Block_Size                 : Unsigned_32;
      Data_Size                  : Unsigned_32;
      Data_Offset                : Unsigned_32;
      Plaintext_Hash_Tree_Offset : Unsigned_32;
      Crypttext_Hash_Tree_Offset : Unsigned_32;
      Block_Hashes_Offset        : Unsigned_32;
      Share_Hashes_Offset        : Unsigned_32;
      URI_Extension_Offset       : Unsigned_32;
   end record;

   for Share_Header use record
      Version at 0 range 0 .. 32;
      --  Data_Length                : Unsigned_32;
      --  Lease_number               : Unsigned_32;
      --  Version_Junk               : Unsigned_32;
      --  --  unused as it can be calculated from the URI
      --  Block_Size                 : Unsigned_32;
      --  Data_Size                  : Unsigned_32;
      --  Data_Offset                : Unsigned_32;
      --  Plaintext_Hash_Tree_Offset : Unsigned_32;
      --  Crypttext_Hash_Tree_Offset : Unsigned_32;
      --  Block_Hashes_Offset        : Unsigned_32;
      --  Share_Hashes_Offset        : Unsigned_32;
      --  URI_Extension_Offset       : Unsigned_32;
   end record;

   for Share_Header'Bit_Order use High_Order_First;
   for Share_Header'Scalar_Storage_Order use High_Order_First;

   procedure Read_Share (Segment_Size : Positive; Required_Shares : Positive);
   procedure Display_Share_Content (My_Share_Header : Share_Header);
   procedure Read_Blocks
     (My_Share_Header : Share_Header;
      Share_File      : Ada.Streams.Stream_IO.File_Type);
end Share;

Tried defining the component clauses to not much success, different bit orders, modifying the Stream_IO storage arrays.

Ada BFD 1.3.0

20 August 2023 at 14:14
[Ada/ada-bfd-1.3.jpg](Ada/ada-bfd-1.3.jpg)
    1. Integration with Alire

For Linux users only, the Ada BFD(https://github.com/stcarrez/ada-bfd) has an associated Alire crate which allows you to use it easily. To get access to the Alire crate, you should add the AWA Alire index(https://github.com/stcarrez/awa-alire-index) in your Alire configuration as follows:

``` alr index add=https://github.com/stcarrez/awa-alire-index.git name awa ```

Then, you can get access to the crate by using

``` alr with bfdada ```

Let's see how to use this library...

    1. Declarations

The Ada BFD(https://github.com/stcarrez/ada-bfd) library provides a set of Ada bindings that give access to the BFD library. A binary file such as an object file, an executable or an archive is represented by the `Bfd.Files.File_Type` limited type. The symbol table is represented by the `Bfd.Symbols.Symbol_Table` limited type. These two types hold internal data used and managed by the BFD library.

```ada with Bfd.Files; with Bfd.Sections; with Bfd.Symbols; ...

 File    : Bfd.Files.File_Type;
 Symbols : Bfd.Symbols.Symbol_Table;

```

    1. Opening the BFD file

The first step is to use the `Open` procedure to read the object or executable file whose path is given as argument. The `File_Type` parameter will be initialized to get access to the binary file information. The `Check_Format` function must then be called to let the BFD library gather the file format information and verify that it is an object file or an executable.

```ada Bfd.Files.Open (File, Path, ""); if Bfd.Files.Check_Format (File, Bfd.Files.OBJECT) then

   ...

end if; ```

The `File_Type` uses finalization so that it will close and reclaim resources automatically.

    1. Loading the symbol table

The symbol table is loaded by using the `Read_Symbols` procedure.

```ada

  Bfd.Symbols.Read_Symbols (File, Symbols);

```

The resources used by the symbol table will be freed when the symbol table instance is finalized.

    1. Find nearest line

Once the symbol table is loaded, we can use the `Find_Nearest_Line` function to find the nearest line of a function knowing some address. This is almost a part of that function that the addr2line (1)(https://www.man7.org/linux/man-pages/man1/addr2line.1.html) command is using.

```ada File_Name, Func_Name : Ada.Strings.Unbounded.Unbounded_String; Text_Section : Bfd.Sections.Section; Line : Natural; Pc : constant Bfd.Vma_Type := ...; ...

  Text_Section := Bfd.Sections.Find_Section (File, ".text");
  Bfd.Symbols.Find_Nearest_Line (File    => File,
                                 Sec     => Text_Section,
                                 Symbols => Symbols,
                                 Addr    => Pc,
                                 Name    => File_Name,
                                 Func    => Func_Name,
                                 Line    => Line);

```

One tricky aspect of using `Find_Nearest_Line` is the fact that the address we are giving must **sometimes** be converted to an offset within the text region. With Address space layout randomization (ASLR)(https://en.wikipedia.org/wiki/Address_space_layout_randomization) a program is mapped at a random address when it executes. Before calling `Find_Nearest_Line`, we must subtract the base address of the memory region. We must now find the virtual address of the start of the text region that is mapped in memory. While the program is running, you can find the base address of the program by looking at the `/proc/self/maps` file. This special file indicates the list of memory regions used by the process with the addresses, flags and other information. Without ASLR, the program is almost always loaded at the `0x00400000` address.

``` 00400000-007f9000 r-xp 00000000 fd:01 12067645 /home/... 009f8000-009fa000 r--p 003f8000 fd:01 12067645 /home/... 009fa000-00a01000 rw-p 003fa000 fd:01 12067645 /home/... ```

But when it is mapped at a random address, we get a different address each time the program is launched:

``` 55d5983d9000-55d598592000 r--p 00000000 fc:02 1573554 /... 55d598592000-55d599376000 r-xp 001b9000 fc:02 1573554 /... 55d599376000-55d5997ed000 r--p 00f9d000 fc:02 1573554 /... 55d5997ee000-55d5998bb000 r--p 01414000 fc:02 1573554 /... 55d5998bb000-55d5998c6000 rw-p 014e1000 fc:02 1573554 /... ```

In that case, the value to use it the first address of first `r--p` region associated with the program (here `0x55d5983d9000`).

Another method to know the virtual base address is to use the dl_iterate_phdr (3)(https://man7.org/linux/man-pages/man3/dl_iterate_phdr.3.html) function and look at the shared objects which are loaded. This function must be executed by the program itself: it gets as parameter a callback function which is called for each loaded shared object and a data parameter that will be passed to the callback.

```

  1. include <dlfcn.h>

static int dl_callback (struct dl_phdr_info* info, size_t size, void* data) {

 /* VM base address is: info->dlpi_addr */
 return 0;

} ...

  dl_iterate_phdr (dl_callback, 0);

```

When the callback is called, you can get the name of the shared object by looking at `info->dlpi_name` and the virtual base address by looking at `info->dlpi_addr`.

Ada BFD(https://github.com/stcarrez/ada-bfd) is a very specific library that is not always easy to use due to the complexity of binary program representation (ELF, DWARF, ...) and program execution. It is however used in very specific contexts such as the Muen Separation Kernel(https://muen.codelabs.ch/) and the Memory Analysis Tool(https://github.com/stcarrez/mat).

HAC for native targets

20 August 2023 at 13:57
Note for subscribers: if you are interested in my Ada programming articles only, you can use this RSS feed link.

HAC (the HAC Ada Compiler) was since the first of its previous lives, from Pascal-S, in 1973, to recent commits, translating high-level language exclusively to the machine code of a fictitious machine (a Virtual Machine, abbreviated VM).

For writing a tiny compiler, a VM is very convenient:

  • You (the compiler creator) can model and adapt it to your needs.
  • You don't depend on hardware.
  • You don't need to rewrite the code generation for each new hardware.
  • You can make the VM running on many hardwares (hence the success of the JVM and .NET around year 2000).


The HAC VM and its users are enjoying all these advantages.

However, there is a flip side:

  • A VM is much slower than a real machine (but till year 2000, it didn't matter; you could say: don't worry, just wait a few months for a more powerful computer).
  • Since year 2000, the speed of microprocessors stopped doubling every six months (hence the declining interest in Virtual Machines). Despite the improvements in cache, RAM, and the multiplication of cores, the per-core performance improvement is slower and slower.
  • Supporting only a VM gives the impression that your compiler can only compile to a VM.


Well, so far, the latter blame was objectively correct regarding HAC until a few weeks ago.
Now it is changing!
We have begun an abstract framework for emitting machine code.
With that framework, HAC can, on demand, emit code for its captive VM or for any implemented machine.
So you read well, it is not a just-in-time compiler translating VM instructions to native ones.
We are implementing a direct Ada-to-native compiler - and cross-compiler, since HAC doesn't know on which machine it is running!

The framework looks like this:

with HAC_Sys.Defs;

package HAC_Sys.Targets is

  type Machine is limited interface;

  type Abstract_Machine_Reference is access Machine'Class;

  --------------------
  --  Informations  --
  --------------------

  function Name (m : Machine) return String is abstract;
  function CPU (m : Machine) return String is abstract;
  function OS (m : Machine) return String is abstract;
  function Null_Terminated_String_Literals (m : Machine) return Boolean is abstract;

  ----------------------------
  --  Machine Instructions  --
  ----------------------------

  procedure Emit_Arithmetic_Binary_Instruction
    (m         : in out Machine;
     operator  :        Defs.Arithmetic_Binary_Operator;
     base_typ  :        Defs.Numeric_Typ) is abstract;

...


The code emission in the compiler is being changed (very slowly, be patient!) for going through this new abstract machine mechanism.
So far we have two implementations:

  • The HAC VM - that way, we ensure HAC-for-HAC-VM works exactly as previously and can pass the test suite.
  • A real target: the AMD64, running under Windows; the machine code is emitted in Assembler form, for the Flat Assembler (FASM).


The development for multiple targets is embryonic so far.
However, we can already compile a "hello world"-style program:

with HAT;

procedure Native is
  use HAT;
  a : Integer;
begin
  --  a := 1;  --  Variables: TBD.
  Put_Line ("Hello ...");
  Put_Line ("... world!");
  Put_Line (12340 + 5);
  Put_Line (12350 - 5);
  Put_Line (2469 * 5);
  Put_Line (61725 / 5);
end Native;


With the command:
hac -tamd64_windows_console_fasm native.adb

HAC produces this:

;  Assembler file for the Flat Assembler - https://flatassembler.net/

format PE64 console
entry _start
include 'include\win64a.inc'

section '.code' code readable executable

_start:
         push                9
         push                1
         push                -1
         push                -1
         pop                 r14
         pop                 r13
         pop                 r12
         pop                 r11
         add                 r12, _hac_strings_pool
         ccall               [printf], r12
         ccall               [printf], _hac_end_of_line
         push                10
         push                11
         push                -1
         push                -1
         pop                 r14
         pop                 r13
         pop                 r12
         pop                 r11
         add                 r12, _hac_strings_pool
         ccall               [printf], r12
         ccall               [printf], _hac_end_of_line
         push                12340
         push                5
         pop                 r11
         pop                 rax
         add                 rax, r11
         push                rax
         push                20
         push                10
         push                -1
         pop                 r14
         pop                 r13
         pop                 r12
         pop                 r11
         ccall               [printf], _hac_decimal_format, r11
         ccall               [printf], _hac_end_of_line
         push                12350
         push                5
         pop                 r11
         pop                 rax
         sub                 rax, r11
         push                rax
         push                20
         push                10
         push                -1
         pop                 r14
         pop                 r13
         pop                 r12
         pop                 r11
         ccall               [printf], _hac_decimal_format, r11
         ccall               [printf], _hac_end_of_line
         push                2469
         push                5
         pop                 r11
         pop                 rax
         imul                rax, r11
         push                rax
         push                20
         push                10
         push                -1
         pop                 r14
         pop                 r13
         pop                 r12
         pop                 r11
         ccall               [printf], _hac_decimal_format, r11
         ccall               [printf], _hac_end_of_line
         push                61725
         push                5
         pop                 r11
         pop                 rax
         xor                 rdx, rdx
         idiv                r11
         push                rax
         push                20
         push                10
         push                -1
         pop                 r14
         pop                 r13
         pop                 r12
         pop                 r11
         ccall               [printf], _hac_decimal_format, r11
         ccall               [printf], _hac_end_of_line
         stdcall             [ExitProcess],0

section '.data' data readable writeable
_hac_end_of_line  db 10, 0
_hac_decimal_format  db "%d", 0
_hac_strings_pool db "XHello ...", \
    0, "... world!", 0

section '.idata' import data readable
library kernel,'kernel32.dll',\
        msvcrt,'msvcrt.dll'
import  kernel,\
        ExitProcess,'ExitProcess'
import  msvcrt,\
        printf,'printf'

As you can see, the assembler code needs badly some simplification, but, anyway: it works.
FASM produces from it a relatively small 2048-byte executable which writes

Hello ...
... world!
12345
12345
12345
12345


The executable is full of zeroes, due to alignments. The non-zero bytes (more or less, the actual machine code and data) take 605 bytes.

Some Web links for HAC:

Main URL: https://hacadacompiler.sourceforge.io/
Sources, site #1: HAC Ada Compiler download | SourceForge.net
Sources, site #2: GitHub - zertovitch/hac: HAC Ada Compiler - a small, quick Ada compiler fully in Ada
Alire Crate: Alire - Hac

Ada scale exceeds maximum value of 18

Dear Ada Enthusiasts,

type Long_Money_Type is delta 10.0**(-22) digits 38;

On The First Machine Ubuntu Linux 64 bit GNAT 8.3.0 this works.
On The Second Machine Alpine Linux 64 Bit GNAT 10.3.1 20211027 i get this error:

adx-lib-money.ads:14:29: scale exceeds maximum value of 18
adx-lib-money.ads:14:54: digits value out of range, maximum is 18

Is There an way to change the maximum value ?

Unexpected Ada Type Compatibility

Why are Volts, Amps, and Ohms compatible?


with ada.text_io; use ada.text_io;
                                                                    
procedure main is                                                   
    type Volts is delta 1.0 / 2.0 ** 12 range -45_000.0 .. 45_000.0;
    type Amps is delta 1.0 / 2.0 ** 16 range -1_000.0 .. 1_000.0;   
    type Ohms is delta 0.125 range 0.0 .. 1.0E8;                    
                                                                    
    V : Volts := 1.0;                                               
    A : Amps := 1.0;                                                
    R1 : Ohms := 1.0;                                               
    R2 : Ohms := 1.0;                                               
                                                                   
begin                                             
                     
    v := A * (R1 + R2);
                       
    put_line(V'Img);   
                       
end main;  

If the types the types are defined as new Float I get the following exception during compilation:


main.adb:22:12: error: invalid operand types for operator "*"
main.adb:22:12: error: left operand has type "Amps" defined at line 5
main.adb:22:12: error: right operand has type "Ohms" defined at line 6

I expected the use of type with Volts to define a new type that was incompatible with the other types as it wasn't an explicit subtype of the fixed point type.

What is the difference between `long_integer` and `integer` in ada language?

with ada.text_io;

procedure numbers is 

   int1 : integer := 2147483647; --almost 4 bytes
   int2 : integer := -2147483647;

   lng1 : long_integer := 2147483647;
   lng2 : long_integer := -2147483647;

begin 

   ada.text_io.put_line(int1'image);
   ada.text_io.put_line(int2'image);

   ada.text_io.put_line(lng1'image);
   ada.text_io.put_line(lng2'image);

end numbers;

result :

 2147483647
-2147483647
 2147483647
-2147483647

I am new to this programming language and suddenly found this long_integer and integer datatypes in the ada language are the same in size and the type of data they can represent is there any key difference between these two datatypes ?

Gtkada widget from scratch

I don’t have a lot of hope for this but anyway.

I need to create a widget to select a range (like a scale widget but with two cursors, one for the lower bound and another for the upper bound). This needs to be built "from scratch". According to the Gtkada documentation, I just have to take a look at the gtkdial example (gtkdial seems to be the classic example for gtk to build widget from scratch).

The example is clearly out of date, a lot of functions, packages and events don’t exist anymore.

For example Gtk.Widget.Realize_Handling is gone (instead we have on_Realize I think), the function Get_Count doesn’t exist as the event "size_request"… I tried to do it on my own by reading and understanding the source code, but I’ m still a beginner with GTK.

Do you know if an up-to-date version of this example exists?

What are the semantics of Ada task priorities on Linux?

Background: I'm working on porting an Ada project from Vxworks to a Linux platform. The project heavily relies on usage of Ada's dynamic task priorities.

I've done a couple experiments which have left me confused. Ada task priorities seem to have no effect on the underlying Linux priority/niceness. Two identical tasks with different priorities take equally long to complete, even when pinned to one CPU core.

Question: What are the semantics of Ada tasks on Linux? Why am I seeing no effect from setting task priorities?

❌
❌