有没有一种方法在 Mac 上以编程方式清除缓冲区高速缓存,最好使用 C 语言?
基本上,我正在寻找相当于10.5(及更高版本)中 purge
命令的源代码等价物。编辑:我现在看到这是 CHUD 工具的一部分,但似乎源代码不直接可用。然而,我仍在寻找一些能够实现相同功能的代码。
有没有一种方法在 Mac 上以编程方式清除缓冲区高速缓存,最好使用 C 语言?
基本上,我正在寻找相当于10.5(及更高版本)中 purge
命令的源代码等价物。编辑:我现在看到这是 CHUD 工具的一部分,但似乎源代码不直接可用。然而,我仍在寻找一些能够实现相同功能的代码。
我已经反汇编了问题中的函数(_utilPurgeDiskBuffers
)从CHUD框架中。该函数似乎并不是非常复杂,但由于我不是MacOS程序员,所以导入和调用的系统API对我来说没有太多意义。
该API要做的第一件事是调用另一个函数,即_miscUtilsUserClientConnect_internal
。该函数似乎建立了与CHUD内核扩展的连接。
为此,它调用_getCHUDUtilsKextService
,该函数尝试使用从I/O kit导入的IORegistryCreateIterator
枚举所有kexts以定位CHUD内核扩展。找到kext后,通过_IOServiceOpen
打开它。
这时,我们就有了与CHUD kext的连接(至少在我的反编译列表中是这样的)。
最后,调用IOConnectMethodStructureIStructureO
,我想这里进行了真正的奇迹。
不知道一些内部细节或函数签名,参数对我来说毫无意义。
以下是反汇编的代码:
__text:4B0157A7 lea eax, [ebp+var_1C]
__text:4B0157AA mov dword ptr [esp+14h], 0
__text:4B0157B2 mov [esp+10h], eax
__text:4B0157B6 mov [esp+0Ch], eax
__text:4B0157BA mov dword ptr [esp+8], 0
__text:4B0157C2 mov dword ptr [esp+4], 0Eh
__text:4B0157CA mov [esp], edx
__text:4B0157CD call _IOConnectMethodStructureIStr
请注意,var_1C
在此之前已被清零。
希望你们中的一些人能够更好地理解那些系统调用。如果需要更多信息,请告诉我。
更新:
为了让您开始,只需从IO kit SDK中获取AppleSamplePCIClient.c
示例。这基本上就是CHUD工具中的Purge应用程序所做的事情。
唯一需要更改的是最终_IOConnectMethodStructureIStr
调用的参数。从上面的反汇编列表中获取它们即可。由于我没有Mac,无法测试所有这些东西。
如果您只是想针对某个文件关闭缓存,那么这也许是一种替代方案。具体取决于你的目标是什么。这里有一个很好的总结。
UBC can be cleared by running 'purge' which allocates a lot of memory to force the cache to clear.
fcntl(fd, F_GLOBAL_NOCACHE, 1)
can be used turn caching off for a particular file. This can be done in any process and the file can be closed after.
F_NOCACHE
没有直接等价于O_DIRECT
。 - Aktau你可以多次使用 sync(2)
(就像众所周知的习语 sync; sync; sync
)。 我似乎找不到 purge
的源代码,但它可能只是可在 10.5.6 代码中 获得的 man 包的一部分。
system()
函数调用该工具。只要没有可见的影响(比如打开一个图形窗口),这种方法就很有效。例如,你可以使用system("/path/to/purge -purgargs >/dev/null 2>&1");
。