tinySTM工作流程:●Main函数开始●Stm_init定义线程副本数据●Main函数开始pthread_create创建多线程●stm_init_thread线程初始化●●●●stm_start事务开始事务操作stm_commit事务提交stm_exit_thread线程退出●pthread_join结束多线程●●Stm_exit结束事务函数结束事务,进程及共享内存的关系:进程1共享内存●●事务线程附:同一个线程内部的事务之间的关系暂不考虑事务状态转移图:附:同一个线程内部的事务之间的关系暂不考虑TX_IDLETX_ACTIVETX_ABORTEDTX_COMMITTEDstm_init_threadstm_rollbackstm_startstm_commitTinySTM数据结构元素类型意义DESIGN0,1,2写内存方式CommitTimeLocking(WRITE_BACK_ETL,WRITE_BACK_CTL,WRITE_THROUGH)CMChar*冲突管理SUICIDE(自毁)(SUICIDE,DELAY,BACKOFF,PRIORITY)0.全局变量TinySTM数据结构1.locks(全局锁指针)数组staticvolatilestm_word_tlocks[LOCK_ARRAY_SIZE];lock最后一位表示是否锁上了如果锁上了,前面的位表示一个指向当前在写内存的事务的TX如果没有锁上,前面的位表示版本号附:1)CTL模式是不加全局锁的。2)数组的每一个元素对应一个内存数据,根据内存数据的地址得到索引TinySTM数据结构元素类型意义attrStm_tx_attr_t*包含事务id,和是否只读StatusStm_word_t事务状态(TX_IDLE空闲,TX_COMMITTED以提交,TX_ACTIVE活动的可以读或写,TX_ABORTED中断)R_setR_set_t读集W_setW_set_t写集NestingInt嵌套等级(只是记录嵌套等级,不进行任何操作,为了控制提交和回滚的粒度)2.stm_tx_t事务控制块TinySTM数据结构3.w_set_t写集元素类型意义EntriesW_entry_t*数据列表Nb_entriesInt数据条数SizeInt列表总长度Nb_acuiredInt已获得锁的数目TinySTM数据结构4.w_entry_t写集里面的数据元素类型意义AddrStm_word_t*数据地址ValueStm_word_t数据值MaskStm_word_t数据掩码VersionStm_word_t数据版本tinySTM工作流程:●Main函数开始●Stm_init定义线程副本数据●Main函数开始●stm_init_thread线程初始化●●●●stm_start事务开始事务操作stm_commit事务提交stm_exit_thread线程退出●pthread_join结束多线程●●Stm_exit结束事务函数结束pthread_create创建多线程TinySTM初始化stm_init相关操作:操作变量操作作用Thread_tx创建(pthread_key_create)指向线程副本数据Sigactionact定义(局部变量)Stm_word_tlocks[]赋0值Stm_word_tgclock赋0值Inttx_count赋0值Inttx_overflow赋0值Sigactionact:__sighandler_tSa_handler:信号处理函数,定义为signal_catcherSigset_tsa_mask:信号集,注册SIGBUS(硬件错误)和SIGSEGV(无效内存引用)两个信号tinySTM工作流程:●Main函数开始●Stm_init定义线程副本数据●线程初始化●stm_init_thread线程初始化●●●●stm_start事务开始事务操作stm_commit事务提交stm_exit_thread线程退出●pthread_join结束多线程●●Stm_exit结束事务函数结束pthread_create创建多线程TinySTM线程初始化Stm_init_thread定义变量stm_tx_t*txTinySTM最重要的一个结构,记录事务的状态相关操作:元素初值意义StatusTX_IDLE状态r_set.nb_entries0读集数据个数r_set.sizeRW_SET_SIZE读集大小w.set.entries给写集分配内存空间Thread_tx(pthread_key_t)Tx线程副本数据id注意:每个线程都会有一个thread_tx的全局变量,在stm_init里面初始化。通过pthread_setspecific(thread_tx,tx);将tx绑定到thread_txtinySTM工作流程:●Main函数开始●Stm_init定义线程副本数据●事务开始●stm_init_thread线程初始化●●●●stm_start事务开始事务操作stm_commit事务提交stm_exit_thread线程退出●pthread_join结束多线程●●Stm_exit结束事务函数结束pthread_create创建多线程TinySTM开始事务Stm_start如果嵌套等级为0,不做任何操作。嵌套事务在这里先不予考虑。相关操作:tinySTM工作流程:●Main函数开始●Stm_init定义线程副本数据●事务操作status=TX_ACTIVE●stm_init_thread线程初始化●●●●stm_start事务开始事务操作stm_commit事务提交stm_exit_thread线程退出●pthread_join结束多线程●●Stm_exit结束事务函数结束pthread_create创建多线程TinySTM读取内存Stm_load读共享内存相关操作:1.判断tx的status是否为TX_ACTINE2.判断是否被修改过,如果被修改过就直接读写集(writeset),然后返回3.否则1)读取数据(读取前后都判断版本号,确保读取过程中数据没有改变)2)生成读集记录,初始化其中的数据版本和锁指针TinySTM写内存Stm_write写共享内存相关操作:1.判断tx的status是否为TX_ACTINE2.判断是要写的地址是否在写集中有副本,有就直接写副本,没有则拷贝一个副本(版本号等于原版本号)3.写副本附:1.CTL模式不加锁,直接写副本tinySTM工作流程:●Main函数开始●Stm_init定义线程副本数据●事务提交status=TX_COMMITEDpthread_create创建多线程●stm_init_thread线程初始化●●●●stm_start事务开始事务操作stm_commit事务提交stm_exit_thread线程退出●pthread_join结束多线程●●Stm_exit结束事务函数结束TinySTM事务提交Stm_commit将写集的条目更新到内存。相关操作:1.得到写集中所有条目的锁,并将版本加12.checkifallreadaddressesarestillvalidnow3.将写集中的数据写到内存,释放锁4.设置事务状态为COMMITTED读集中记录被锁住读集中记录没有被锁住读集数据版本和全局版本一致读集数据版本和全局版本一致返回1返回0本线程正在写此内存其他线程正在写此内存返回0读集和写集此数据版本相同读集和写集此数据版本不同返回0返回1tinySTM工作流程:●Main函数开始●Stm_init定义线程副本数据●线程退出pthread_create创建多线程●stm_init_thread线程初始化●●●●stm_start事务开始事务操作stm_commit事务提交stm_exit_thread线程退出●pthread_join结束多线程●●Stm_exit结束事务函数结束TinySTM线程退出Stm_exit_thread释放一些内存相关操作:1.free(tx-r_set.entries)释放事务的读集2.free(tx-w_set.entries)释放事务的写集3.free(tx)释放事务tinySTM工作流程:●Main函数开始●Stm_init定义线程副本数据●事务结束pthread_create创建多线程●stm_init_thread线程初始化●●●●stm_start事务开始事务操作stm_commit事务提交stm_exit_thread线程退出●pthread_join结束多线程●●Stm_exit结束事务函数结束TinySTM事务结束Stm_exitvoidstm_exit(){PRINT_DEBUG(==stm_exit()\n);#ifndefTLSpthread_key_delete(thread_tx);#endif/*!TLS*/#ifdefROLLOVER_CLOCKpthread_cond_destroy(&tx_reset);pthread_mutex_destroy(&tx_count_mutex);#endif/*ROLLOVER_CLOCK*/#ifdefEPOCH_GCgc_exit();#endif/*EPOCH_GC*/}