Помимо malloc / free, нужна ли программе ОС для предоставления чего-либо еще? - PullRequest
9 голосов
/ 13 октября 2008

Я работаю над проектированием ядра (которое я собираюсь назвать «ядром», просто чтобы оно было другим, но оно в основном то же самое) для ОС, над которой я работаю. Специфика самой ОС не имеет значения, если я не могу запустить многозадачность, управление памятью и другие базовые вещи, поэтому мне нужно сначала поработать над этим. У меня есть некоторые квесты о разработке подпрограммы malloc.

Я полагаю, что malloc () будет либо частью самого ядра (я склоняюсь к этому), либо частью программы, но мне придется написать собственную реализацию C стандартная библиотека в любом случае, поэтому я могу написать malloc. Мой вопрос на самом деле довольно прост в этом отношении, как C (или C ++) управляет своей кучей?

То, чему меня всегда учили в теоретических классах, - это то, что куча - это постоянно расширяющийся кусок памяти, начинающийся с определенного адреса и во многих отношениях ведущий себя как стек. Таким образом, я знаю, что переменные, объявленные в глобальной области видимости, находятся в начале, и больше переменных «помещаются» в кучу, поскольку они объявлены в соответствующих областях, а переменные, которые выходят из области видимости, просто остаются в пространстве памяти, но это пространство помечается как свободное, поэтому куча может расширяться больше, если это необходимо.

Что мне нужно знать, так это то, как C фактически справляется с динамически расширяющейся кучей таким образом? Создает ли скомпилированная программа C свои собственные вызовы подпрограммы malloc и обрабатывает свою собственную кучу, или мне нужно предоставить ей автоматически расширяющееся пространство? Кроме того, как программа C знает, где начинается куча?

О, и я знаю, что те же понятия применимы и к другим языкам, но я хотел бы, чтобы любые примеры были на C / C ++, потому что мне больше всего нравится этот язык. Я также хотел бы не беспокоиться о других вещах, таких как стек, так как я думаю, что могу справиться с такими вещами самостоятельно.

Итак, я полагаю, что мой реальный вопрос, кроме malloc / free (который обрабатывает получение и освобождение страниц для себя и т. Д.), Нужна ли программе ОС для предоставления чего-либо еще?

Спасибо!

РЕДАКТИРОВАТЬ Меня больше интересует то, как С использует malloc в связи с кучей, чем фактические действия самой процедуры malloc. Если это помогает, я делаю это на x86, но C - кросс-компилятор, так что это не должно иметь значения. ^ _ ^

РЕДАКТИРОВАТЬ ДАЛЬШЕ: Я понимаю, что я могу запутаться в терминах. Меня учили, что в «куче» программа хранит такие вещи, как глобальные / локальные переменные. Я привык иметь дело со "стеком" в программировании на ассемблере, и я только что понял, что, скорее всего, имею в виду это. Небольшое исследование с моей стороны показывает, что «куча» чаще используется для обозначения общего объема памяти, который программа выделила для себя, или общего количества (и порядка) страниц памяти, предоставленных ОС.

Итак, с учетом этого, как мне справиться с постоянно расширяющимся стеком ? (кажется, что мой класс теории Си был слегка ... ущербным.)

Ответы [ 7 ]

15 голосов
/ 13 октября 2008

malloc обычно реализуется во время выполнения C в пользовательском пространстве, полагаясь на системные системные вызовы ОС для отображения на страницах виртуальной памяти. Задача malloc и free состоит в том, чтобы управлять теми страницами памяти, которые имеют фиксированный размер (обычно 4 КБ, но иногда больше), и разбивать их на части, которые могут использовать приложения.

См., Например, реализацию GNU libc .

Чтобы упростить реализацию, ознакомьтесь с классом MIT , выпущенным в прошлом году. В частности, посмотрите заключительный лабораторный проспект и посмотрите на lib/malloc.c. Этот код использует операционную систему JOS, разработанную в классе. Он работает так, что он читает таблицы страниц (предоставляемые ОС только для чтения) в поисках несопоставленных диапазонов виртуальных адресов. Затем он использует системные вызовы sys_page_alloc и sys_page_unmap для отображения и отмены отображения страниц в текущем процессе.

13 голосов
/ 13 октября 2008

Существует несколько способов решения проблемы.

Чаще всего программы на С имеют свои собственные функции malloc / free. Это будет работать для небольших объектов. Первоначально (и как только память исчерпана) диспетчер памяти запросит у ОС дополнительную память. Традиционные методы для этого - mmap и sbrk в вариантах unix (GlobalAlloc / LocalAlloc в Win32).

Я предлагаю вам взглянуть на Doug Lea, распределитель памяти (google: dlmalloc) с точки зрения поставщика памяти (например, ОС). Этот распределитель является на высшем уровне в очень хорошем и имеет хуки для всех основных операционных систем. Если вы хотите знать, что высокопроизводительный распределитель ожидает от ОС, этот код - ваш первый выбор.

4 голосов
/ 13 октября 2008

Вы путаете кучу и стек?

Я спрашиваю, потому что вы упоминаете «постоянно расширяющийся кусок памяти», область видимости и добавление переменных в кучу по мере их объявления. Это точно звучит так, будто вы говорите о стеке.

В наиболее распространенных реализациях C объявления автоматических переменных, таких как

int i;

обычно приводит к тому, что я размещаюсь в стеке. В общем случае malloc не будет вмешиваться, если вы явно не вызовете его или не вызовете какой-то библиотечный вызов, который вы делаете.

Я бы порекомендовал посмотреть на «Программирование на Expert C» Питера Ван Дер Линдена, чтобы узнать, как программы на C обычно работают со стеком и кучей.

1 голос
/ 13 октября 2008

Читайте об управлении виртуальной памятью (подкачки). Это сильно зависит от процессора, и каждая ОС реализует управление виртуальной машиной специально для каждого поддерживаемого процессора. Если вы пишете свою ОС для x86 / amd64, прочтите соответствующие руководства.

1 голос
/ 13 октября 2008

Обязательное чтение: Кнут - Искусство компьютерного программирования, Том 1, Глава 2, Раздел 2.5. В противном случае, вы можете прочитать Kernighan & Ritchie "Язык программирования C", чтобы увидеть реализацию; или вы можете прочитать Plauger «Стандартная библиотека C», чтобы увидеть другую реализацию.

Я считаю, что то, что вам нужно делать внутри вашего ядра, будет несколько отличаться от того, что видят программы вне ядра. В частности, выделение памяти в ядре для программ будет связано с виртуальной памятью и т. Д., Тогда как программы вне кода просто видят результаты того, что предоставило ядро.

0 голосов
/ 14 июля 2009

Опасно Опасно! Если вы даже рассматриваете возможность разработки ядра, вы должны быть в курсе стоимости ваших ресурсов и их относительно ограниченной доступности ...

Одна вещь, касающаяся рекурсии, заключается в том, что она очень дорогая (по крайней мере, в области ядра), вы не увидите много функций, написанных для продолжения без посторонней помощи, иначе ваше ядро ​​начнет паниковать.

Чтобы подчеркнуть мою точку зрения здесь (на stackoverflow.com, хе), прочитайте этот пост из блога NT Debugging о переполнении стека ядра, в частности,

· На платформах x86 стек режима ядра 12K .

· На 64-разрядных платформах стек режима ядра - 24K . (64-разрядный платформы включают в себя системы с процессоры, использующие AMD64 архитектура и процессоры, использующие Архитектура Intel EM64T).

· На платформах на базе Itanium стек режима ядра 32K с 32K бэк-магазин.

Это действительно не так уж много;

Обычные подозреваемые


1. Свободное использование стека.

2. Вызов функций рекурсивно.

Если вы немного перечитаете блог, вы увидите, насколько сложной может быть разработка ядра с довольно уникальным набором проблем. Ты класс теории не ошибся, это было просто, просто. ;)

Если перейти от теории -> разработка ядра примерно настолько значительна для context switch, насколько это возможно (возможно, сохраните некоторое взаимодействие с гипервизором в миксе !!).

Во всяком случае, никогда не принимайте, не проверяйте и не проверяйте свои ожидания.

0 голосов
/ 13 октября 2008

Как правило, библиотека C обрабатывает реализацию malloc, запрашивая память у ОС (либо через анонимную mmap, либо, в более старых системах, sbrk) по мере необходимости. Так что ваша сторона ядра должна обрабатывать выделение целых страниц с помощью одного из этих способов.

Тогда до malloc можно выделить память таким образом, чтобы не слишком сильно фрагментировать свободную память. Я не слишком au fait с деталями этого, хотя; однако, термин арена приходит на ум. Если я смогу найти ссылку, я обновлю этот пост.

...