очистить буферный кеш в Mac OS X
Вопрос
Есть ли способ программно очистить буферный кеш на Mac, желательно на C?
По сути, я ищу эквивалент источника версии 10,5 (и выше). purge
команда. РЕДАКТИРОВАТЬ: Теперь я вижу, что это часть инструментов CHUD, исходный код которых, похоже, недоступен напрямую.Тем не менее, я все еще ищу код, который сделает то же самое.
Решение
Я дизассемблировал рассматриваемую функцию (_utilPurgeDiskBuffers
) из структуры CHUD.Функция не кажется очень сложной, но поскольку я не программист MacOS, импорт и вызываемые sys API не имеют для меня особого смысла.
Первое, что делает API, — это вызывает другую функцию, а именно: _miscUtilsUserClientConnect_internal
.Кажется, эта функция устанавливает соединение с расширением ядра CHUD.
Для этого он вызывает _getCHUDUtilsKextService
который пытается найти расширение ядра CHUD, перечисляя все кексты с помощью IORegistryCreateIterator
импортирован из комплекта ввода-вывода.После того, как kext найден, он открывается через _IOServiceOpen
.
На этом этапе у нас есть соединение с кекстом CHUD (по крайней мере, я так понимаю из дизассемблированного листинга).
Наконец звонок в 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
раньше обнулялся.
Надеюсь, некоторые из вас смогут понять больше смысла из этих системных вызовов.Если вам нужна дополнительная информация, дайте мне знать.
Обновлять:
Для начала просто возьмите AppleSamplePCIClient.c
пример из SDK комплекта ввода-вывода.По сути, это делает то же, что и приложение очистки из инструментов CHUD.
Единственное, что вам придется изменить, это параметры окончательного варианта. _IOConnectMethodStructureIStr
вызов.Возьмите их из дизассембл-листа выше.Я не могу протестировать все это, так как у меня нет Mac.
Другие советы
Похоже, что
Вы можете использовать usr / bin / purge (введите purge в терминале) очистить диск кеш (неактивная память), или вы можете сделать много случайных чтений с жесткого диска сделать то же самое .
Взято из комментарий от пользователя оружие .
Вы можете использовать sync(2)
несколько раз (как в известной фразеологии sync; sync; sync
). Кажется, я не могу найти исходный код purge
, но он может быть только частью доступных пакетов man в коде 10.5.6
Разве вам не интересно отключить кеш для файла? В зависимости от того, чего вы пытаетесь достичь, это может быть альтернативой. Хорошая сводка здесь .
UBC можно очистить, запустив 'purge' который выделяет много памяти принудительно очистить кеш.
fcntl(fd, F_GLOBAL_NOCACHE, 1)
можно использовать для отключения кэширования файл. Это можно сделать в любом процессе и файл может быть закрыт после.
Если у вас нет исходного кода для инструмента, который вы хотите эмулировать (как в данном случае), существует несколько способов сделать это.
1 / Из вашего кода C просто вызовите инструмент с помощью вызова функции system()
. Это работает хорошо, пока нет видимого эффекта (например, открытие графического окна). Вы можете использовать system("/path/to/purge -purgargs >/dev/null 2>&1");
, например.
2 / Обратный инжиниринг кода, чтобы увидеть, как он на самом деле это делает. Это несколько сложнее, так как для этого потребуются знания языка ассемблера, системные вызовы и многое другое.
3 / Свяжитесь с разработчиками, чтобы получить советы о том, как это было сделано. Это не должно быть "!", Пришлите мне код, чтобы я мог его сорвать и заработать & Quot; вопрос. Вы можете сформулировать это как & Quot; у меня есть интерес к использованию purge для разработки, но я точно не знаю, что делает & Quot; или & "У меня есть проблемы с безопасностью при запуске кода, его возможности не позволят мне запустить его, если мы не будем точно знать, что он делает &". Затем вы пишете свой код, чтобы сделать то же самое.
Я, я бы просто использовал вариант 1, если это возможно (я по своей природе ленив :-). Если вы собираетесь написать инструмент, чтобы конкурировать с продувкой (и это будет сложно, если он бесплатный), вариант 2, вероятно, является лучшим выбором.