trace-clock-32-to-64.c 中synthetic_tsc 结构 设计分析初步

AUTHOR: Joseph Yang (杨红刚) <ganggexiongqi@gmail.com>
CONTENT: trace-clock-32-to-64.c 中synthetic_tsc 结构 设计分析初步
NOTE: linux2.6.38.6
LAST MODIFIED:10-09-2011
-----------------------------------------------------------------------------------------------------------
Distributed and Embedded System Lab (分布式嵌入式系统实验室,兰州大学)
===============================================================


static DEFINE_SPINLOCK(synthetic_tsc_lock); // 用来保护synthetic_tsc_refcount, synthetic_tsc_enabled

         //tsc_timer, synthetic_tsc
static int synthetic_tsc_refcount;  /* Number of readers */
static int synthetic_tsc_enabled;   /* synth. TSC enabled on all online CPUs */

static DEFINE_PER_CPU(struct timer_list, tsc_timer); //在该内核定时器的回调函数
                                          //用于在硬件时钟源溢出前,做出溢出处理,更新“伪时钟“的值。
static unsigned int precalc_expire; // 该值用来设置内核定时器tsc_timer的定时间隔。

struct synthetic_tsc_struct {
    union {
        u64 val;
        struct {
#ifdef __BIG_ENDIAN
            u32 ms32;
            u32 ls32;
#else
            u32 ls32;
            u32 ms32;
#endif
        } sel;
    } tsc[2];
    unsigned int index; /* Index of the current synth. tsc. */
};

static DEFINE_PER_CPU(struct synthetic_tsc_struct, synthetic_tsc);//每个CPU一个“伪tsc时钟”

外部接口:
EXPORT_SYMBOL_GPL(trace_clock_read_synthetic_tsc);
EXPORT_SYMBOL_GPL(get_synthetic_tsc);
EXPORT_SYMBOL_GPL(put_synthetic_tsc);
=========================================================================
会直接修改 synthetic_tsc 值的函数:
 1. static void update_synthetic_tsc(void) //* Called from IPI or timer interrupt */
 2. void _trace_clock_write_synthetic_tsc(u64 value) // 使用时关中断
 3. static void prepare_synthetic_tsc(int cpu) // 初始化时使用
 -------------------------------synthetic tsc 的设计
 1. 时钟源
     利用硬件时钟源(32位)作为更新的依据。
  2. 利用双缓冲区同步对时钟的读写。[见后面 synthetic_tsc_struct结构的分析 ]
  3. 异步地更新时钟的值:
        - 在硬件源“溢出前“// 使用内核定时器,在回调函数中实现
        - 读取时钟值时
        - 初始化时和显示地设置时钟的值时
        
 ------------ synthetic_tsc_struct结构的分析
         对于为什么下面的结构这样设计,我的理解: //这么设计的好处,您的观点请留言!!
         简化 synthetic_tsc_struct 结构为,
         struct   synthetic_tsc_struct {
                data[2];
                index; /* 对索引的更新都是 原子的*/
         }synthetic_tsc;
         
         写synthetic_tsc:
                      1>  new_index = 1 - synthetic_tsc.index; // 非原子的
                      2> synthetic_tsc.data[new_index] = NEW_VAL; // 非原子的
                      ---------------------------------------------------------------------------
                      3> synthetic_tsc.index = new_index; // 原子的
           
          对 synthetic_tsc的读操作,没有更新 index 也没有改变 synthetic_tsc中的data的值。
          (读操作:1. 原子的获得index
                               2. 读取  )
          
          而对 synthetic_tsc执行写操作函数有三个:
          static void update_synthetic_tsc(void) ///* Called from IPI or timer interrupt */
          void _trace_clock_write_synthetic_tsc(u64 value) //关中断时使用
           static void prepare_synthetic_tsc(int cpu) // 初始化是使用          
        
        使用这些函数的实体有:
                 1. tsc_timer_fct       // 更新 synthetic tsc的值
                 2. hotcpu_callback  // 在CPU状态改变时,合理设置 synthetic tsc 和 tsc_timer
                 
        导出的函数有:
                         EXPORT_SYMBOL_GPL(trace_clock_read_synthetic_tsc); //****
                         EXPORT_SYMBOL_GPL(get_synthetic_tsc);
                         EXPORT_SYMBOL_GPL(put_synthetic_tsc);

             这样我的总结就是:
                          有多个 实体 在 写 synthetic tsc,而有多个实体在读  synthetic tsc。
                          但是写操作被严格控制(如关中断时,或者 在 timer interrupt 中,
                                                                            或者在初始化时)
                           最重要的是对 index的更新是原子的,这样就保证了多个读操作
                           和写操作不会产生竞争,从而也避免的锁的使用。
                           
                           不知道的我的理解对不对?
     ----------------写和写之间要严格控制
     写和写之间是有冲突的,这个冲突也会影响到读进程。
     所以写和写之间要严格控制。???怎么控制的呢???
     比如:两个写进程 W1, W2,一个读进程R1
                   初始时, data[0] = 0, data[1] = 1, index = 0
                   在下面的序列中会有冲突,
                   W1: read index // index = 0
                           index1 = 1- index // index1 = 1
                   W2: read index // index = 0
                           index2 = 1- index // index2 = 1                   
                   W1: write data[index1] = 7 // data[1] = 7
                   W1: index = index1 // index = 1
                   R1: atomic read index // index* = 1
                   W2: write data[index2] = 8 // data[1] = 8  // <----------<<<< [1]
                   W2: index = index2 // index = 1
                   
                  [1]步骤不是原子的,如果W2在写操作的过程中被打断,转到R1读取
                  data[1] 的值,则 R1读到的值是被破坏的值。产生了冲突!!!
 ---------------  synthetic tsc 的设计评价
  1. 解决了哪些问题?
      - 硬件时钟源溢出的处理
      - 同步时钟的读写
      - CPU热插拔事件处理
 
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值