阿达Ravenscar任务配置文件的形式化模型与应用
在软件开发领域,尤其是涉及实时系统和并发编程时,对系统的性能、可预测性和功能性有着极高的要求。本文将深入探讨相关技术,包括受保护对象的任务执行机制、系统需求分析、形式化验证以及在实际应用中的实现等内容。
受保护对象的任务执行机制
每个受保护入口都关联着一个队列,用变量
ECount
表示。当任务进行入口调用时,会根据屏障(
Barrier
)的状态和锁的状态来决定具体的执行流程。
1.
屏障为假时的情况
:如果调用时屏障为假,任务会获取锁并进入队列。在队列中等待时,任务不持有锁,会处于
Entry.Q
状态,直到在通道
Eg?
上进行同步操作。之后执行入口代码,任何异常都会传播到调用任务,最后在信号
Ef!
上同步以完成过程执行。
2.
屏障为真且锁空闲时的情况
:若屏障为真且锁空闲,任务会立即获取锁并执行入口代码。完成后释放锁,并在通道
Ex!
或
Ee!
上进行同步。
任务锁的处理由一个单独的自动机管理,如下所示:
Lock
Lock
Lock
Lock
Lock
Lock
Lock
Lock
Lock
Lock
Lock
Lock
Lock
Lock
Lock
Lock
Lock
AAAAAAAAAAAAAAAAA
BBBBBBBBBBBBBBBBB
Seize?, Lockp:=1
Seize?, Lockp:=1
Seize?, Lockp:=1
Seize?, Lockp:=1
Seize?, Lockp:=1
Seize?, Lockp:=1
Seize?, Lockp:=1
Seize?, Lockp:=1
Seize?, Lockp:=1
Seize?, Lockp:=1
Seize?, Lockp:=1
Seize?, Lockp:=1
Seize?, Lockp:=1
Seize?, Lockp:=1
Seize?, Lockp:=1
Seize?, Lockp:=1
Seize?, Lockp:=1
Release?, Lockp:=0
Release?, Lockp:=0
Release?, Lockp:=0
Release?, Lockp:=0
Release?, Lockp:=0
Release?, Lockp:=0
Release?, Lockp:=0
Release?, Lockp:=0
Release?, Lockp:=0
Release?, Lockp:=0
Release?, Lockp:=0
Release?, Lockp:=0
Release?, Lockp:=0
Release?, Lockp:=0
Release?, Lockp:=0
Release?, Lockp:=0
Release?, Lockp:=0
当任务想要获取锁时,需要在
Seize?
上同步,变量
Lockp
赋值为 1 表示任务持有锁;释放锁时,在
Release?
上同步,将
Lockp
设为 0。
系统需求分析
为了分析系统的各种属性,需要验证受保护对象的以下非形式化需求和期望功能:
1.
性能需求
:用户代码的最坏情况执行时间(WCET)被设置为任意选择的值,具体如下表所示:
| 代码类型 | 时间单位 |
| ---- | ---- |
| 过程代码 | 100 |
| 入口代码 | 50 |
| 函数代码 | 10 |
2.
可预测性需求
:确保组件之间严格同步和控制,系统应无死锁和活锁。如果有任务在队列中,当过程代码执行且屏障为真时,该任务必须被允许执行,并且允许调用任务之间有任意顺序。
3.
功能性需求
:任何时候都不能有多个任务同时执行受保护对象的主体。
形式化验证
使用 Uppaal 的符号模型检查器对上述非形式化需求进行形式化验证。Uppaal 能够检查可达性属性,可分析的属性形式如下:
-
' ::= 82φ | 93φ
-
φ ::= a | φ1 ^ φ2 | :φ
其中,
a
是原子公式,可以是原子时钟/数据约束或组件位置。原子时钟/数据约束可以是单个时钟/数据变量的整数边界,或两个时钟/数据变量差值的整数边界。直观地说,
82φ
要求所有可达状态都满足
φ
,
93φ
表示某些可达状态必须满足
φ
。
具体验证的属性如下:
1.
同一时间只有一个任务执行受保护对象主体
:
-
A[] not(EntryCall.C and ProcedureCall.C)
-
A[] not(EntryCall.C and FunctionCall.C)
-
A[] not(ProcedureCall.C and FunctionCall.C)
2.
执行受保护对象后所有八种可能的结束状态都是可能的
:
-
E<> (EntryCall.G and ProcedureCall.G and FunctionCall.F)
-
E<> (EntryCall.G and ProcedureCall.G and FunctionCall.G)
-
E<> (EntryCall.G and ProcedureCall.H and FunctionCall.F)
-
E<> (EntryCall.G and ProcedureCall.H and FunctionCall.G)
-
E<> (EntryCall.H and ProcedureCall.G and FunctionCall.F)
-
E<> (EntryCall.H and ProcedureCall.G and FunctionCall.G)
-
E<> (EntryCall.H and ProcedureCall.H and FunctionCall.F)
-
E<> (EntryCall.H and ProcedureCall.H and FunctionCall.G)
3.
队列中的任务在屏障为真时总是被允许执行
:
-
A[] not(Entry.Q and Procedure.E and Barrier==1)
-
A[] not(Entry.Q and Procedure.F and Barrier==1)
4.
任务进行过程调用到调用完成有上界时间
:自动机
ProcedureCall
中的时钟
TP1
在信号
Ps!
同步时赋值为 0,在
ProcedureCall.E
状态下,
TP1
不会超过 160 个时间单位(10 + 50 + 100),即
A[] (ProcedureCall.E imply not(TP1 > 160))
。
验证结果
使用 Uppaal 对系统的 14 个属性进行了验证,模型检查器返回所有属性都满足,即:
Property 1 (line 1) is satisfied.
Property 2 (line 2) is satisfied.
Property 3 (line 3) is satisfied ...
Property 14 (line 14) is satisfied.
受保护对象的扩展测试
由于 Uppaal 等模型检查方法难以处理任意数量的任务,进行了一个实验,使用三个任务执行函数主体、两个任务执行过程和一个任务(受 Ravenscar 模型限制)执行入口。同样的测试表明所有属性仍然满足。
实际应用中的实现
在实际应用中,如 Top Layer Networks 的 AppSwitch™ 软件,由于应用的性质和对效率的需求,需要构建一个高效支持 Ravenscar 配置文件的 Ada 运行时系统。
1.
AppSwitch™ 的背景和目的
:企业网络中,网络使用常与业务目标冲突,如大数据库邮件消息会影响紧急数据库查询,带宽密集的网页浏览可能阻塞电子商务。AppSwitch™ 系列 LAN/WAN 交换机旨在通过自动分析应用流量并执行服务质量(QoS)策略,提高网络效率并降低运营成本。
2.
AppSwitch™ 的硬件和软件架构
-
核心组件
:AppSwitch™ 的核心是流分类技术的硬件和软件组件,能够深入分析传入数据包的第 7 层头部,确定源地址、目标地址和应用类型。预配置的应用配置文件库(APL)支持流分类和优先级设置,并且可扩展以适应未来应用和企业业务需求。
-
数据包处理流程
:当流的第一个数据包到达时,使用连接设置过程子架构选择 APL 中合适的配置文件,并在会话数据库中记录相关信息。后续数据包根据会话数据和所选配置文件进行交换。会话数据库中的状态数据可智能调整 QoS 优先级。输出端有数千个队列用于扩展流的数量和优先级。
-
整体架构
:除了处理 LAN 连接的组件,AppSwitch™ 还包括一个 WAN 子系统,用于集成处理 T1 和电话线。来自 LAN 和 WAN 连接的传入数据包经过媒体访问控制功能(MOM)组件进行分类和规范化,然后通过 TopWire 传输到转发引擎(FE 芯片 + QM 芯片)进行应用交换。输出数据包经过 MOM 组件恢复规范化后传输到目标地址。
下面是 AppSwitch™ 数据包处理的流程图:
graph LR
A[Incoming Data] --> B[MOM Components]
B --> C[Canonicalization]
C --> D[TopWire]
D --> E[Forwarding Engine]
E --> F[Application Switching]
F --> G[TopWire]
G --> H[MOM Components]
H --> I[Reverse Canonicalization]
I --> J[Output to LAN/WAN]
综上所述,通过对受保护对象的任务执行机制、系统需求的分析和验证,以及在实际应用中的实现,我们可以看到相关技术在提高系统性能、可预测性和功能性方面的重要作用。在未来的开发中,可以进一步完善这些技术,以满足更复杂的应用需求。同时,形式化验证方法在确保系统正确性方面具有显著优势,尤其是在处理并发系统时,能够避免代码检查和测试中难以覆盖所有情况的问题。
阿达Ravenscar任务配置文件的形式化模型与应用
实现选择与优化
在实现过程中,为了提高分析效率,做出了一些对应于实现选择的决策:
1.
将入口队列建模为单个变量
:没有使用实际的队列,而是将入口队列建模为单个变量。由于 Ravenscar 约束中只有单个调用者能够调用任何任务入口这一属性不是静态的,需要对应用进行运行时检查或详细的形式化分析来证明该属性。这里选择依靠对应用代码的分析来消除运行时检查。
2.
消除多个受保护函数调用者
:对于使用即时继承上限协议的单 CPU 系统,多个读者是不可能的,因此不需要不同的锁,从而消除了多个受保护函数调用者。
后续工作展望
完成受保护对象的工作后,下一步将对调度器进行建模,使其符合即时继承上限协议,并将调度与受保护对象的模型集成。最终阶段将对中断进行建模,整合各个部分,并对可以使用 Ravenscar 模型的小型应用进行形式化验证。
形式化验证与系统认证
形式化验证和系统认证是确保系统正确性的两种不同方法。
| 方法 | 特点 | 优势 | 劣势 |
| ---- | ---- | ---- | ---- |
| 形式化验证 | 使用符号模型检查器等工具对系统的逻辑属性进行验证 | 能够检查整个状态空间,对于并发系统的验证更可靠,能发现代码检查和测试难以发现的问题 | 需要构建形式化模型,对技术要求较高 |
| 系统认证 | 依靠开发产品(如机器代码、可执行映像和测试程序)进行认证 | 基于实际的开发成果,与实际系统联系紧密 | 难以覆盖所有可能的任务和状态组合,尤其是在并发情况下 |
在能够验证形式化模型与实际代码之间的转换时,形式化验证比代码检查和测试更有说服力,特别是在验证并发时。因为代码检查和测试中,同时存在的任务和状态的复杂性使得人类几乎不可能覆盖所有可能性,而形式化方法可以让计算机检查整个状态空间。
总结
本文围绕受保护对象的任务执行机制、系统需求分析、形式化验证以及实际应用中的实现展开了详细的探讨。
-
任务执行机制
:通过队列和锁的管理,确保任务的有序执行,避免多个任务同时执行受保护对象的主体。
-
系统需求分析
:明确了性能、可预测性和功能性方面的需求,为系统的设计和验证提供了依据。
-
形式化验证
:使用 Uppaal 对系统的多个属性进行验证,结果表明所有属性都得到满足,证明了系统的正确性。
-
实际应用
:以 AppSwitch™ 为例,展示了如何在实际项目中应用相关技术,提高网络效率和可管理性。
以下是整个系统的工作流程 mermaid 流程图:
graph LR
classDef startend fill:#F5EBFF,stroke:#BE8FED,stroke-width:2px
classDef process fill:#E5F6FF,stroke:#73A6FF,stroke-width:2px
A([任务调用]):::startend --> B{屏障状态}:::process
B -- 屏障为假 --> C[进入队列等待]:::process
C --> D[同步 Eg?]:::process
D --> E[执行入口代码]:::process
E --> F[同步 Ef!]:::process
F --> G[完成执行]:::process
B -- 屏障为真且锁空闲 --> H[获取锁]:::process
H --> I[执行入口代码]:::process
I --> J[释放锁]:::process
J --> K[同步 Ex! 或 Ee!]:::process
K --> G
G --> L{是否有更多任务}:::process
L -- 是 --> A
L -- 否 --> M([结束]):::startend
通过这些技术和方法,我们可以构建出性能良好、可预测性强且功能正确的系统。在未来的开发中,可以进一步优化和扩展这些技术,以适应更复杂的应用场景和需求。同时,形式化验证和实际应用的结合将为软件开发提供更可靠的保障。