分享

ETAS AUTOSAR中Spinlock学习笔记

 Kuai2012 2023-01-17 发布于北京

现在的车载控制器,多核的MCU用的是越来越多了,对于不同核之间的共享数据保护,也是必须的,其中Spinlock就是常用的一种。

01.

Spinlock介绍

Spinlock也即自旋锁,是一种轻量级的多核间的数据同步机制。一个任务想要访问被Spinlock保护的共享资源,必须先得到锁,在访问完共享资源后释放锁。如果在获取自旋锁时,没有任何执行单元保持该锁,那么将立即得到锁;如果在获取自旋锁时锁已经有持有者, 那么需要自旋等待该锁的保持者释放了锁。

在ETAS的AUTOSAR中,实现Spinlock的两个基本操作获取锁xx_GetLockInternal()和释放锁xx_ReleaseLockInternal()。

对于获取锁接口,其内部的实现原理如下:

  • 第一步先判断是哪个核上的任务正在使用xx_GetLockInternal();

  • 判断锁是否已经被同当前核获取过但没有释放,如果是的话,就进行锁嵌套累加, 继续执行代码,如果没有被当前核获取过再进行下一步判断;

  • 挂起正在使用xx_GetLockInternal()的当前核的中断,确保当前任务不被切换,也就是说不被高优先级任务或者中断任务打断;

  • 测试锁的状态,该才做必须以原子操作访问Spinlock的锁标志。

  • 如果锁状态被本核占用则进行锁嵌套,如果是其他核占用则首先释放该核中断, 然后重复执行上面两步测试锁的状态,直到其他核释放了锁。如果锁状态为空闲, 则设置其为占用状态,这就成功地抢占了锁。

对于释放锁接口,其内部的实现原理如下:

  • 首先判断是哪个核上的线程正在使用xx_ReleaseLockInternal();

  • 判断当前锁是否被该核占用,如果不是说明接口调用不匹配则复位,如果是则进行 下一步的判断;

  • 判断锁是否被本核嵌套, 如果是则嵌套次数减减, 如果没有则清除锁的状态;

  • 释放该核的中断。

02.

Spinlock使用原则

所有临界区代码都需要加锁保护,否则就达不到保护效果。也就是,访问共享资源的多个任务需要协同工作共同加锁才能保证不出错。在实际写代码时,有时会忘掉这个,导致出现各种稀奇古怪的问题,并且很难排查。

Spinlock保护的代码执行时间要尽量短, 因为临界区太大,持有时间太长,其他任务可能面临长时间等待,降低了系统性能。

Spinlock 所保护的代码在执行过程中不能睡眠, 任务在持有自旋锁时如果进入 Sleep状态,则可能导致死锁。

    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多