Реализация системного стека без переполнения в ANSI C - PullRequest
7 голосов
/ 14 апреля 2011

Я только что читал о том, как Google Go по умолчанию создает каждый поток с уменьшенным размером стека, а затем ссылается на новые стеки, если произойдет переполнение (см. Стр. 16 в здесь ).Мне было интересно, как лучше всего это сделать на C.

Я должен сказать, что я не эксперт по C, так что, возможно, есть лучший способ обнаружить переполнение стека на C, но, учитывая мое невежество, вот какЯ думал, что реализую это:

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

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

Итак, будет ли чище/ лучший способ реализовать это?

Спасибо!

Ответы [ 2 ]

9 голосов
/ 14 апреля 2011

См. Возможность GCC с разделенным стеком .Я считаю, что это было изначально реализовано для поддержки Go.Это в значительной степени работает, как вы предлагаете.

РЕДАКТИРОВАТЬ: В приведенном ниже комментарии обсуждается другая система, которая делает кучу распределения записей активации.

2 голосов
/ 14 апреля 2011

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

...