peterson算法是通过软件实现互斥的算法,它的实现简单巧妙。
算法说明:
使用一个bool数组和一个整型变量,前者用来表示是否需要使用共享资源,后者表示谁可以使用共享资源。
//使用一个布尔数组和整形变量
volatile bool lock[] = {false, false};
volatile int turn;
进入lock函数首先将lock[0]变量置为true,turn置为1,说明进程或核心需要用到资源,之后判断另一个进程或核心有没有用到资源,如果用到则block等待,没有用到就执行后边的操作,并且获得了该资源的使用权。另一个同理。
//Lock/unlock logic for CPU 1
lock[0] = true;
turn = 1;
while (lock[1] == true && turn == 1)
{
// busy wait
}
// critical section
...
// end of critical section
lock[0] = false;
//Lock/unlock logic for CPU 2
lock[1] = true;
turn = 0;
while (lock[0] == true && turn == 0)
{
// busy wait
}
// critical section
...
// end of critical section
lock[1] = false;
对于特殊情况,有可能core1将turn置为1并等待时,core2又将turn置为0也等待,但下一个循环turn就是确定的0,这样core1便获得了使用权,所以这种方式能够很好的实现互锁。
双核应用实例:
//Shared variables: a boolean array and an integer
volatile bool will_lock_uart[] = {false, false};
volatile int uart_turn;
//lock & unlock for Core 1
#if defined(CORE_1)
#pragma ghs section text=default
void Core1_Lock_Uart()
{
will_lock_uart[0] = true;
uart_turn= 1;
while (will_lock_uart[1] == true && uart_turn== 1)
{
// busy wait
}
}
void Core1_Unlock_Uart()
{
will_lock_uart[0] = false;
}
#endif //defined(CORE_1)
//lock & unlock for Core 2
#if defined(CORE_2)
void Core2_Lock_Uart()
{
will_lock_uart[1] = true;
uart_turn= 0;
while (will_lock_uart[0] == true && uart_turn== 0)
{
// busy wait
}
}
void Core2_Unlock_Uart()
{
will_lock_uart[1] = false;
}
#endif //defined(CORE_2)