ll,sc是MIPS32指令集架构中较特殊的加载存储指令,用来实现信号量控制。
RMW
Read-Modify-Write,在多线程系统中,需要RMW操作序列保证对某个资源的独占性,读取内存某个地址的数据,读取的数据经过修改,然后再保存回内存原地址,因为个过程不能被打扰 ,因此需要建立一个临界区域,临界区域中的操作通常称为原子操作 。操作系统建立临界区域到方式通常是信号量机制。 wait(semaphore); 原子操作; signal(semaphore); semaphore =1表示信号量使用中,semaphore =0表示信号量空闲。 进行原子操作前,使用wait函数查询semaphore 的值,如果为1则等待,否则置1,开始执行原子操作。操作结束后,signal函数将semaphore 置0,其他线程可以执行原子操作。 wait函数的执行也是原子操作,先检测后设置 操作,这种操作不希望外部设备中断,也不希望被其他线程打断。
ll、sc
31-26 | 25-21 | 20-16 | 15-0 | useage | function |
---|
LL(110000) | base | rt | offset | ll rt,offset(base) | 从内存中指定的加载处,读取一个字节,然后符号扩展至32位,保存到地址为rt的通用寄存器中 | SC(111000) | base | rt | offset | sc rt,offset(base) | 如果RMW序列没有受到干扰,即LLbit为1,那么将地址为rt的通用寄存器值保存到内存中指定的存储地址处,同时设置地址为rt的通用寄存器值为1,设置LLbit为0.如果RMW序列受到干扰,也就是LLbit为0,那么不修改内存,同时设置地址为rt的通用寄存器值为0 |
加载地址=signed_extended(offset)+GPR[base] 存储地址=signed_extended(offset)+GPR[base] ll指令将处理器内部的一个链接状态为LLbit置为1,表明发生一个链接加载操作,并将链接加载的地址保存到一个特殊寄存器LLAddr中 ,ll执行完后,进行一定操作(修改加载得到的数据),然后执行sc指令,可以看做是一个RMW序列。如果RMW序列受到干扰,处理器会设置链接状态LLbit为0。 执行sc指令时,会对ll指令开始的RMW序列进行检查,判断是否受到干扰,即判断LLbit是否为1,若LLbit为1,操作是原子的,sc指令会对ll指令加载数据的地址进行写回操作,并设置一个通用寄存器的值为1,表示成功,反之不进行写回操作,并设置一个通用寄存器值为0,表示失败 。
数据流图修改
在回写阶段新增了一个Lbit寄存器,其中存储的就是链接状态位,只有在回写阶段才会写LLbit寄存器,要将LLbit寄存器的值传递到访存阶段,以便指令sc进行判断
系统结构修改
在访存阶段的MEM模块中进行分析,ll,sc指令,设置对LLbit寄存器的访问信息,通过LLbit_we_o(表示是否写操作),LLbit_value_o(表示要写入的值)接口输出,这些信息通过MEM/WB模块传递到回写阶段,最终修改LLbit寄存器。 LLbit寄存器的值通过LLbit_o接口输出到MEM模块的接口LLbit_i,当sc指令进入访存阶段时会使用该值。 由于对LLbit寄存器的修改是在回写阶段最后的时钟上升沿进行的,如果直接采用LLbit模块给出的LLbit寄存器的值,可能不是正确的值,解决该问题还是数据前推,将回写阶段指令对LLbit寄存器的操作信息前推到访存阶段,访存阶段依据这些情况,确定正确的LLbit寄存器的值 MEM/WB模块输出信号wb_LLbit_we,wb_LLbit_value也要送到MEM模块,解决数据相关的问题。
测试文件
34011234
ac010000
34015678
e0010000
8c010000
00000000
34010000
c0010000
00000000
20210001
e0010000
8c010000
0800000c
00000000
仿真结果 reg1
|