openMPM源码分析(三)

 函数 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较小的具有较高的优先级。,如下图所示:
openMPM源码分析(三)_第1张图片
 

    -三、 函数 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...
       }
   }


你可能感兴趣的:(多核,面包店算法,openMPM)