LDD3 勘误(P270,第三段)

来源:互联网 发布:机锋网推荐的淘宝 编辑:程序博客网 时间:2024/06/06 01:45

今天有位同学在微博上私信我,指出了 LDD3 翻译中的一个错误。仔细看了下上下文,发现的确有这个问题。原翻译:

如果没有这个屏障,编辑器可能会优化出一个新的变量并将其直接赋值给 *index。

这句话说的是下面这段代码:

unsigned long new = *index  + delta;barrier(); *index = (new >= (short_buffer + PAGE_SIZE)) ? short_buffer : new;

正确的翻译应该是:

如果没有这个屏障,编译器可能会将 new 变量优化掉,从而导致将错误的值赋值给 *index。

注解

也许这段文字最初的翻译是正确的,但在审校时,因为考虑到 new 是 C++ 的一个关键词,尽管内核代码是 C 编写的,作为内核开发者,也应尽量避免使用 new 作为变量名。所以,审校者(本人),可能将原始正确的翻译给修改错了。当然,审校者忽略了这样一个事实:这段代码不是正式的内核代码,而只是示例驱动程序的代码。

如果没有调用 barrier();编译器优化后的结果可能相当于下面的代码:

*index = ((*index + delta) >= (short_buffer + PAGE_SIZE)) ? short_buffer: (*index + delta);

这条语句其实相当于:

if ((*index + delta) >= (short_buffer + PAGE_SIZE)) {    *index = short_buffer;}else {    *index = (*index + delta);}

写成上面这样的形式就好理解多了。在这个条件判断和赋值语句中,由于多次引用 *index 的值,在判断和赋值之间,可能会出现其他线程修改 index 指针值的情况,从而产生一个竞态。这就是原文所指的 index 发生反转的情形。

如果增加了对 barrier() 的调用,将阻止编译器的优化,于是判断和赋值之间就不会发生 index 反转的情形。这样就可以避免使用锁,最终可以节省系统资源且可以让系统运行更加顺畅。

当然,本人仍然建议不使用 new 这个名字来命名变量,而应该使用 new_index 这样的变量名。


0 0