Ada程序适用于Linux但不适用于GPS Windows 10

时间:2016-09-17 09:08:14

标签: linux windows cpu ada affinity

提前感谢您的帮助。我目前正在做一些关于ada编程的初学者工作,我从http://libre.adacore.com/download/configurations#安装了GNAT Programming Studio(GPS) 我有Windows 10 64位。我在学校获得了以下代码:

pragma Task_Dispatching_Policy(FIFO_Within_Priorities);

with Ada.Text_IO; use Ada.Text_IO;
with Ada.Real_Time; use Ada.Real_Time;

procedure PeriodicTasks is

    Start : Time;

    package Duration_IO is new Ada.Text_IO.Fixed_IO(Duration);
    package Int_IO is new Ada.Text_IO.Integer_IO(Integer);

    task type T(Id: Integer; Period : Integer) is
        pragma Priority(Id);
    end;

    task body T is
        Next : Time;
        X : Integer;
    begin
        Next := Start;
        loop
            Next := Next + Milliseconds(Period);
            -- Some dummy function
            X := 0;
            for Index in 1..5000000 loop
                X := X + Index;
            end loop;
            Duration_IO.Put(To_Duration(Clock - Start), 3, 3);
            Put(" : ");
            Int_IO.Put(Id, 2);
            Put_Line("");
            delay until Next;
        end loop;
    end T;

    -- Example Task
    Task_P10 : T(10, 250);
    Task_P12 : T(12, 500);
    Task_P14 : T(14, 500);
    Task_P16 : T(16, 250);
    Task_P18 : T(18, 500);
    Task_P20 : T(20, 250);
begin
    Start := Clock;
    null;
end PeriodicTasks;

我在GPS中打开文件,构建它(没有错误)并运行它但它没有显示任何打印输出。我听说有时你会遇到多核CPU的问题,所以每次打开gps.exe时,CPU亲和力都只设置为一个CPU,它总是"以管理员身份运行"。但是,这也没有用,我没有输出。 我决定使用Oracle Virtual Box并设置一个只有一个处理器的Ubuntu OS(32位)。安装了使用gnatmake编译的GNAT工具,使用./periodictasks运行,然后猜测该程序是做了它应该做的事情并打印出信息。

在这么长的故事之后,有人知道为什么会这样吗?它可能是64位与32位的情况吗?

非常感谢!

2 个答案:

答案 0 :(得分:2)

直到最近,GNAT默认情况下都没有检查整数溢出。它确实检查了约束错误,例如将0分配给Positive

我们中的许多人认为这是编译器开发人员的一个奇怪的选择,因为它导致了许多问题,其根本原因是无法处理整数溢出。最近的变化让我们假设开发人员现在同意了!

由于声明

,您的问题就出现了
for Index in 1..5000000 loop
   X := X + Index;
end loop;

最终会得到X~10 ^ 13,它不适合32位整数(它适合64位整数,但如果不是,则大多数为Long_Long_Integer所有GNAT平台)。

您的Windows编译器可能是GNAT GPL 2016,它显示了新的行为,而Ubuntu编译器是较旧的FSF GCC。

您可以使用编译器开关-gnato0告诉Windows编译器使用旧行为。

您可以使用编译器开关-gnato告诉您的Ubuntu编译器使用新行为。

要获取任务中未处理的异常(否则会无声地死亡)的异常消息,您可以添加

GNAT.Exception_Traces.Trace_On (GNAT.Exception_Traces.Unhandled_Raise);

在主程序的开头。

答案 1 :(得分:2)

  

在执行开始时,会打印垃圾,打印信息的唯一任务是Task_P20& Task_P18

§9.2 Task Execution - Task Activation中所述,任务在PeriodicTasks的第一个语句执行之前一起激活。虽然所有任务都在运行,但是,在初始化 Start之前,部分或全部任务可能会尝试生成输出。至少要将Start初始化为尽可能接近其声明,

Start : Time := Clock;

并将身体留空,

begin
    null;
end PeriodicTasks;

此外,无法激活的任务将成为已完成的任务,不会产生任何输出。