Очистить буферный кеш в Mac OS X

Есть ли способ программно очистить буферный кеш на Mac, предпочтительнее в C?

В принципе, я ищу эквивалент источника команды 10.5 (и больше) purge. EDIT: Теперь я вижу, что это часть инструментов CHUD, для которых кажется, что источник не доступен напрямую. Тем не менее, я все еще ищу код, который бы сделал то же самое.

Ответ 1

Я разобрал эту функцию (_utilPurgeDiskBuffers) из структуры CHUD. Функция не кажется очень сложной, но поскольку я не программист MacOS, импорт и называемые sys API не имеют для меня большого смысла.

Первое, что делает API, - это вызвать другую функцию, а именно _miscUtilsUserClientConnect_internal. Эта функция, похоже, устанавливает соединение с расширением ядра CHUD.
Для этого он вызывает _getCHUDUtilsKextService, который пытается найти расширение ядра CHUD, перечислив все kexts, используя IORegistryCreateIterator, импортированный из набора I/O. После того, как 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 был обнулен раньше.

Будем надеяться, что некоторые из вас смогут больше понять из этих системных вызовов. Если вы хотите получить дополнительную информацию, сообщите мне.

Update:
Чтобы начать работу, просто возьмите пример AppleSamplePCIClient.c из SDK набора IO. Это в основном то, что делает приложение очистки от инструментов CHUD.
Единственное, что вам нужно изменить, это параметры для окончательного вызова _IOConnectMethodStructureIStr. Возьмите их из списка демонтажа выше. Я не могу проверить все это, так как у меня нет Mac.

Ответ 2

Кажется, что

Вы можете использовать usr/bin/purge (тип очистки в терминале), чтобы очистить диск кеш (неактивная память), или вы можете сделать много случайных чтений с жесткого диска сделать то же самое.

Взято из комментарий от пользователя оружие.

Ответ 3

Вы можете использовать sync(2) несколько раз (как в известной идиоме sync; sync; sync). Я не могу найти исходный код purge, но он может быть только частью доступных пакетов man в коде 10.5.6

Ответ 4

Разве вас не интересовало бы выключение кеша для файла? В зависимости от того, чего вы пытаетесь достичь, это может быть альтернативой. Хорошее резюме здесь.

UBC можно очистить, запустив 'purge' который выделяет много памяти для чтобы очистить кеш.

fcntl(fd, F_GLOBAL_NOCACHE, 1)  

можно использовать отключение кеширования для определенного файл. Это можно сделать в любом процессе и файл можно закрыть после.

Ответ 5

Если у вас нет исходного кода для инструмента, который вы хотите эмулировать (как это имеет место здесь), есть несколько способов сделать это.

1/Из вашего кода C просто вызовите инструмент с вызовом функции system(). Это работает хорошо, пока нет видимого эффекта (например, открытие графического окна). Например, вы можете использовать system("/path/to/purge -purgargs >/dev/null 2>&1");.

2/Обратно - создайте код, чтобы увидеть, как он это делает. Это несколько сложнее, поскольку для этого потребуется знание языка ассемблера, системных вызовов и многих других вещей.

3/Обратитесь к разработчикам, чтобы получить советы о том, как это было сделано. Это не должно быть "отправить мне код, чтобы я мог его разорвать и заработать". Вы могли бы рассказать это как "Я заинтересован в использовании чистки для разработки, но я не уверен, что именно" или "У меня проблемы с безопасностью при запуске кода, полномочия, которые не позволят мне запустить его, если мы не знаем точно, что он делает". Затем вы запишите свой код, чтобы сделать то же самое.

Я, я бы просто использовал вариант 1, если это было возможно (я по сути ленив:-). Если вы собираетесь написать инструмент, чтобы конкурировать с чисткой (и это будет трудно дать ему бесплатно), вариант 2, вероятно, лучший выбор.