当前位置: 首页 > 工具软件 > Mnemosyne > 使用案例 >

mnemosyne事务模块源码分析

车子平
2023-12-01
事务:
mtm_pwbetl_beginTransaction_internal()   //开始事务
|__ PM_START_TX()             //事务开始的信号
|__ return beginTransaction_internal (tx, prop, srcloc, 1, __env)
                 |__ assert(tx->mode == MTM_MODE_pwbnl || tx->mode == MTM_MODE_pwbetl)          //检查模式
                 |__ pwb_prepare_transaction(tx)                              //对事务进行初始化


mtm_pwbetl_commitTransaction(mtm_tx_t *tx, const _ITM_srcLocation *loc)                                            //事务提交
|__ if (!trycommit_transaction(tx, 1))                                             //如果尝试提交事务不成功
       |__ mtm_pwb_restart_transaction(tx, RESTART_VALIDATE_COMMIT)   //如果尝试提交不成功,则重启事务,重启的原因是RESTART_VALIDATE_COMMIT
|__ if (tx->status == TX_COMMITTED)                           //如果尝试提交事务成功,则判断事务状态是否为TX_COMMITTED
      |__ tx->status= TX_IDLE                //???如果条件成立,则将事务状态设置为TX_IDLE
|__ PM_END_TX()                                                         //事务结束信号

进入到  trycommit_transaction()
  trycommit_transaction(tx,1)
              |__ if(pwb_trycommit(tx, enable_isolation))                          // 如果提交成功
                    |__ if(tx->nesting > 0)                           //如果有嵌套事务
                    |__ return true                                      //返回true
              |__ switch(tx->mode)                                 //判断事务模式
                    |__ 
              |__ mtm_useraction_list_run (tx->commit_action_list, 0)            //遍历提交的事务包含的动作列表
                    |__ 
               |__ tx->status = TX_COMMITTED                    //将事务状态设置为TX_COMMITTED
                |__ return true

进入到pwb_trycommit()函数
pwb_trycommit()
|__ assert((tx->mode == MTM_MODE_pwbnl && !enable_isolation) || 
           (tx->mode == MTM_MODE_pwbetl && enable_isolation));        //检查模式
|__ assert(tx->status == TX_ACTIVE)                                                        //检查事务状态
|__ if (--tx->nesting > 0)                                                                     //如果事务嵌套级别减1之后仍大于0,则直接返回true,结束
      |__ return true
|__ if (modedata->w_set.nb_entries > 0)                                         //如果写集的条目数大于0
       |__ t = FETCH_INC_CLOCK + 1                                             //更新事务并获取提交的时间戳
       |__ if (t >= VERSION_MAX)                              //如果获取的提交时间戳大于最大版本号,则退出并返回错误
             |__ return false
      |__ if(enable_isolation)
            |__ if (modedata->start != t - 1 && !mtm_validate(tx, modedata))            //验证读集
                  |__ cm_visible_read(tx)                           //如果以上if语句成立(即版本错误且验证失败),则利用可见读来退出
                  |__ rerturn false
      |__ M_TMLOG_COMMIT(tx->pcm_storeset, modedata->ptmlog, t))      //确保持久性事务日志是稳定的???返回M_R_SUCCESS
      |__ for (i = modedata->w_set.nb_entries; i > 0; i--, w++)               //遍历写集,其中w为写集条目
             |__ if (w->mask != 0)
                   |__ PCM_WB_STORE_ALIGNED_MASKED(tx->pcm_storeset, w->addr, w->value, w->mask)                                                                                              //将写集中的条目写入内存(以字节对齐的方式写入)
                         |__ write_aligned_masked(addr,val,mask)
             |__ if (w->next_cache_neighbor == NULL)        //当遍历到缓存行的最后一个条目时,将缓存航刷入持久性内存
                    |__ if (enable_isolation)                
                          |__ if (((uintptr_t) w->addr >= PSEGMENT_RESERVED_REGION_START &&
(uintptr_t) w->addr < (PSEGMENT_RESERVED_REGION_START + PSEGMENT_RESERVED_REGION_SIZE)))                 //如果允许隔离,那么写集中可能包含非持久性的写入,需要将其过滤掉
                                 |__ PCM_WB_FLUSH(tx->pcm_storeset, w->addr)      //将持久性的写刷入
               |__ if (w->next == NULL)                               //遍历到最后一个条目
                     |__ ATOMIC_STORE_REL(w->lock, LOCK_SET_TIMESTAMP(t))          //将写集中最后覆盖的地址的锁移除
      |__ PCM_WB_FENCE(tx->pcm_storeset)                //设置内存屏障
      |__ M_TMLOG_TRUNCATE_SYNC(tx->pcm_storeset, modedata->ptmlog)   //截断日志,即清除事务日志文件中的非活动记录
|__ cm_reset(tx)                                                   //重置CM
|__ return true                                                     //返回成功

mtm_pwbetl_rollbackTransaction(mtm_tx_t *tx, const _ITM_srcLocation *loc)      //事务回滚
|__ assert ((tx->prop & pr_hasNoAbort) == 0);
|__ rollback_transaction (tx)                                         //调用事务回滚函数
      |__ pwb_rollback (tx)
            |__ assert(tx->mode == MTM_MODE_pwbnl || MTM_MODE_pwbetl)        //检查模式
            |__ assert(tx->status == TX_ACTIVE)                           //检查事务状态
            |__ M_TMLOG_ABORT(tx->pcm_storeset, modedata->ptmlog, 0)   //在日志中标记事务为退出
           |__ M_TMLOG_TRUNCATE_SYNC(tx->pcm_storeset, modedata->ptmlog)  //截断日志,即清除事务日志文件中的非活动记录
            |__ i = modedata->w_set.nb_entries
            |__ if (i > 0)                                                                //如果写集中仍有条目
                    |__ for (; i > 0; i--, w++)                                   //遍历写集中的条目,其中w为具体条目
                            |__ if (w->next == NULL)                            //如果写集中没有条目了
                                   |__ ATOMIC_STORE(w->lock, LOCK_SET_TIMESTAMP(w->version))   //移除锁
                    |__ ATOMIC_MB_WRITE                                      //确保所有的锁版本都是可见的
           |__ tx->retries++                                                      //记录事务连续退出的次数
           |__ tx->status = TX_ABORTED                                //将事务状态设为TX_ABORTED
           |__ tx->nesting = 0                                                   //将事务嵌套级别设为0
      |__ switch (tx->mode)                                              //判断事务模式
            |__ 
      |__ mtm_useraction_list_run (tx->undo_action_list, 1)      //列出该事务中未完成的动作列表


mtm_pwbetl_abortTransaction (mtm_tx_t *tx, 
_ITM_abortReason reason,const _ITM_srcLocation *loc)                                          //事务退出
|__ assert (reason == userAbort || reason == userRetry)           //验证事务退出的原因
|__ assert ((reason == userAbort && (tx->prop & pr_hasNoAbort) == 0) ||  (reason == userRetry && 1));
|__  if (reason == userAbort)                                                   //如果事务推出的原因是userAbort=1
       |__ rollback_transaction (tx)                                              //直接回滚事务
|__ else if (reason == userRetry)                                              //如果事务退出原因是userRetry=2
       |__ mtm_pwb_restart_transaction(tx, RESTART_USER_RETRY)        //重启事务
 类似资料: