Linux0.11 BADNESS宏分析
BADNESS宏主要在getblk函数中使用,用于获取一个进可能开销小的缓冲区
定义
#define BADNESS(bh) (((bh)->b_dirt<<1)+(bh)->b_lock)
通过以上的宏可以看出
- 一个b_dirt和b_lock的缓冲区开销最大
- 其次是一个b_dirt的缓冲区
- 再次是一个b_lock的缓冲区
- 最后是一个既干净又未锁定的缓冲区
代码片段如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 | repeat: /* * 先根据dev和block在高速缓存hash表中获取,如果存在直接返回 */ if ((bh = get_hash_table(dev, block))) return bh; /* * tmp指向缓冲区头部 * 下面的代码意思是需要找到一个b_count为0的高速缓存 * 一直对BANDNESS不理解,再次解释一下 * * BANDNESS = bh->b_dirt*2 + bh->b_lock * 分析如下 * * 从free_list开始遍历 * 第一次的时候bh为空因此可以进入if (!bh || BADNESS(tmp) < BADNESS(bh)) * 将从free_list找到的可用tmp赋值为bh * 如果此bh的lock和dirt都为0,则直接可以用这个bh,否则继续进入循环 * 此时又找到一个tmp,然后利用BADNESS宏进行对比 * 可以发现系统倾向于选择一个lock和dirt都为0的缓冲区,如果实在找不到 * 那就选择一个lock置位的,最后如果实在找不到那就找一个lock和dirt都为1的 * 如果所有的b_count都在用,则睡眠一会在重新查找 * BADNESS值越小表示使用该块的系统开销越小,优先选择该块。 * 是否标记dirt对BADNES的计算结果有很大影响。 * 如果块既“未锁定”又是“干净的”,则可以使用直接退出循环 */ tmp = free_list; do { if (tmp->b_count) continue ; /* * 如果bh为空,第一次肯定为空 */ if (!bh || BADNESS(tmp) < BADNESS(bh)) { bh = tmp; if (!BADNESS(tmp)) break ; } /* and repeat until we find something good */ } while ((tmp = tmp->b_next_free) != free_list); /* * 如果没有找到,则睡眠一会儿,然后继续找 */ if (!bh) { sleep_on(&buffer_wait); goto repeat; } /* * 根据上面的BADNESS分析,获取的缓冲区如果上锁,需求等待解锁 * wait_on_buffer会引起任务切换,因此需要再次检查该缓冲区的使用情况 * */ wait_on_buffer(bh); if (bh->b_count) goto repeat; /* * 如果该缓冲区已经被修改,则需要和磁盘进行同步并等待该缓冲区解锁 * */ while (bh->b_dirt) { sync_dev(bh->b_dev); wait_on_buffer(bh); if (bh->b_count) goto repeat; } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律