函数 int32_t sync_test_lock(void)
- 一、主要涉及两个函数mpm_sync_lock_acquire(void*lock,int32_t user_id)和mpm_sync_lock_release(void* lock, int32_t user_id)顾名思义就是锁的获得和锁的释放。
- 二、函数 int32_t mpm_sync_lock_acquire(void *lock,int32_t user_id );
- 源码
int32_t mpm_sync_lock_acquire(void *lock, int32_t user_id)
{
mpm_sync_lock_t *inst = (mpm_sync_lock_t *)lock;
mpm_sync_lock_user_t *users = &inst->users[0];
int32_t i, ret = MPM_SYNC_LOCK_ERROR_NONE;
if ( inst == NULL )
ret = MPM_SYNC_LOCK_ERROR_HANDLE;
else if ( ( user_id < 0) || (user_id >= inst->num_users) )
ret = MPM_SYNC_LOCK_ERROR_USER_ID;
else if ( ( users[user_id].number > 0 ) || (users[user_id].entering == 1))
ret = MPM_SYNC_LOCK_ERROR_DBL_LOCK;
else
{
/* Take a number */
users[user_id].entering = 1;
/* number[i] = 1 + max(number[1:N]) */
users[user_id].number = 0;
for ( i = 0; i < inst->num_users; i++)
{
if ( users[user_id].number < users[i].number )
{
users[user_id].number = users[i].number;
}
}
users[user_id].number++;
users[user_id].entering = 0;
for ( i = 0; i < inst->num_users; i++ )
{
/* Wait for the other guy to get a number */
while ( users[i].entering);
while ( ( users[i].number != 0) && // This guy is waiting...
( ( users[i].number < users[user_id].number ) || // They have a better number...
( ( users[i].number == users[user_id].number ) && // They have the same number...
( i < user_id ) // They are more important than you.
)
)
);
}
}
return ( ret );
}
- 数据结构mpm_sync_lock_user_t & mpm_sync_lock_t
typedef struct {
volatile int32_t entering;
volatile int32_t number;
} mpm_sync_lock_user_t;
typedef struct {
int32_t num_users;
mpm_sync_lock_user_t users[1];
} mpm_sync_lock_t;
- 在本函数所用的面包店算法简介:顾客(进程)进入面包店(临界区)之前需要排队领号,号码从小到大一次发放。假如我现在去面包店(当前进程),那么我首先抽号,再依次与门口所有的人比较,如果我票号最小,我直接进去,如果你比我小,等你进去面包店,我再与剩下的所有人比较。参考:http://zh.wikipedia.org/zh-cn/Lamport%E9%9D%A2%E5%8C%85%E5%BA%97%E7%AE%97%E6%B3%95
- 知道了面包店算法就不难理解函数代码:
- 从数据结构说起,mpm_sync_lock_user_t这个结构体里面的成员变量entering{true,false}和number{从小到大}分别表示core[i]正在获取它的排队号和core[i]的当前排队登记号。
- 遵循面包店算法,拿号,如下图所示:
- 遵循面包店算法,遵循规则{(a,b)<(c,d)}进行比较,当两个core同时访问lock内存区的核具有相同的number时,coreID较小的具有较高的优先级。,如下图所示:
-三、 函数 int32_t mpm_sync_lock_release(void *lock,int32_t user_id );
- 源码
int32_t mpm_sync_lock_release(void *lock, int32_t user_id)
{
mpm_sync_lock_t *inst = (mpm_sync_lock_t *)lock;
mpm_sync_lock_user_t *users = &inst->users[0];
int32_t ret = MPM_SYNC_LOCK_ERROR_NONE;
if ( inst == NULL )
ret = MPM_SYNC_LOCK_ERROR_HANDLE;
else if ( ( user_id < 0) || (user_id >= inst->num_users) )
ret = MPM_SYNC_LOCK_ERROR_USER_ID;
else if ( users[user_id].number == 0 )
ret = MPM_SYNC_LOCK_ERROR_DBL_UNLOCK;
else
users[user_id].number = 0;
return ( ret );
}
-四、 面包店算法伪代码
// declaration and initial values of global variables
Entering: array [1..NUM_THREADS] of bool = {false};
Number: array [1..NUM_THREADS] of integer = {0};
lock(integer i) {
Entering[i] = true;
Number[i] = 1 + max(Number[1], ..., Number[NUM_THREADS]);
Entering[i] = false;
for (j = 1; j <= NUM_THREADS; j++) {
// Wait until thread j receives its number:
while (Entering[j]) { /* nothing */ }
// Wait until all threads with smaller numbers or with the same
// number, but with higher priority, finish their work:
while ((Number[j] != 0) && ((Number[j], j) < (Number[i], i))) { /* nothing */ }
}
}
unlock(integer i) {
Number[i] = 0;
}
Thread(integer i) {
while (true) {
lock(i);//对应mpm_sync_lock_acquire()
// The critical section goes here...
unlock(i);//对应mpm_sync_lock_release()
// non-critical section...
}
}