c - 如何将位图中的位映射到伙伴分配器中的物理页?

标签 c memory memory-management kernel allocation

我使用位图创建了自己的伙伴分配器(用于管理内核的物理内存),每个位对应于特定大小的页 block 。 由于我映射了整个 4GiB 地址空间,逻辑上第 1 位将代表 4GiB block ,接下来的两位将代表 2GiB 的 block ,接下来的四位将代表 1GiB 的 block ,依此类推,直到我们达到 4KiB 的单个 block (页面大小)。 获取位的子级就像记下位位置、bitN 和:
左节点 = 位N * 2
右节点 =bitN * 2 + 1
获取任何位的父级将按 bitN/2 计算。

从某种意义上说,整个位图看起来像:

bit number: [1] [2 3] [4 5 6 7] [8 9 10 11 12 13 14 15] [16 ... etc.]
holds block: 4G  2G    1G        512M                    256M  - 4KiB


我可以为每个相同大小的 block 映射唯一的物理地址,但由于采用此方案的方式,地址将重叠,这意味着可以返回相同的物理地址,例如,对于 4KiB block 或 16KiB block 。对于 2 的幂的位数尤其如此 - 位 1、2、4、8 等将始终指向最左边的物理 block ,即地址 0。位 3、6、12、24 等。也将始终指向从地址 2GiB 开始的同一 block ,但该 block 可以是任何(有效)大小! 一个很好的输出示例是:

(assume address 0 is valid and isn't considered NULL for the sake of the example)
allocate(1) -- allocate 1 page, returns address 0x00000000. Valid usable range is 0-4095 (0x00000000 - 0x00001000).
allocate(524288) -- allocate 512k pages (2GiB), returns address 0x80000000. Valid usable range is 0x80000000-0xFFFFFFFF.
free((uint32_t *)0) -- free address 0. Page is reclaimed and merged with its free buddies.
allocate(16) -- allocate 16 pages, returns address 0x00000000! Same address but now with a bigger usable range of 0-65535!


正如您所看到的,通过此实现,相同的地址可以指向任何大小的 block ,我想知道如何获取此 block 大小,以便我可以索引位图并开始合并伙伴。但我花了几个小时试图找出如何进行反向映射,从位图中查找与地址相对应的位! 我在分配任何数量的页面时都没有问题,并且获得了唯一的地址,但是一旦必须释放它们,我不知道如何索引回位图! 有什么想法如何解决这个问题吗?

最佳答案

在我看来,每个 block 至少需要两位信息。一位用于跟踪 block 是否已被分割,另一位用于跟踪 block 是否已分配或空闲。一种可能的编码:

00 - page is part of a larger block
01 - block has been split
10 - free block
11 - allocated block

关于c - 如何将位图中的位映射到伙伴分配器中的物理页?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29071093/

相关文章:

java - Pod OOM - Xmx 未被尊重

c++ - 愚蠢的STL问题

c - 使用结构读取二进制文件以查找记录

c - 如何在 c 中正确格式化打印数字行?

arrays - 将文件捕获到数组中并在 while 循环中使用该数组

ios - tvOS 应用内存问题 : How to resolve it?

c++ - 在大型并发数组中组织已用和未用元素的有效方法

python - 使用 itertools 的排列爆炸内存

c# - 如何使用 ffmpeg 进行视频到图像的转换?

c - 多个文件中的 Extern 和可能的双重定义