Каков наилучший способ предстать в стеке для потока pthreads? - PullRequest
6 голосов
/ 19 апреля 2011

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

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

Однако, для стеков pthread они будут распределяться также с использованием MAP_GROWSDOWN?Если это так, каков наилучший способ их предаваривания, учитывая, что:

  1. Мы не знаем, сколько (известного) размера стека потребляется при запуске libc
  2. Мыя не хочу выделять стеку больше памяти, чем необходимо

Я знаю, что могу использовать pthread_attr_setstack для передачи в стеке, выделенном вручную, но это усложняет очистку посленить, и поэтому я предпочел бы избежать этого, если это возможно.

Как таковой, каков наилучший способ выполнить этот предварительный вызов?Было бы достаточно, если бы был простой способ узнать нижнюю границу стека (чуть выше защитной страницы);в этот момент я мог бы просто написать на каждой странице оттуда текущий указатель стека.

Обратите внимание, что переносимость не имеет значения;мы были бы рады иметь решение, которое работает только под x86-32 и Linux.

Ответы [ 2 ]

3 голосов
/ 19 апреля 2011

Если вы используете pthread_attr_setstacksize, у вас все еще может быть автоматическое распределение с известным размером.

glibc nptl оставляет защитные страницы между стеками, так что вы также можете установить обработчик SEGV и просто набрасывать, пока выошибка, а затем longjmp из цикла.Это было бы ужасно!

Редактировать: Действительно непортативный способ - открыть /proc/self/maps, чтобы найти свои стеки!

1 голос
/ 18 декабря 2012

да.если вы вызвали mlockall (MCL_CURRENT | MCL_FUTURE) до pthread_create, при запуске потока произойдет сбой страницы для стека потоков.и после этого при обращении к стеку в потоке снова не будет ошибок страницы.поэтому люди всегда устанавливают подходящий размер потока для вновь созданного потока, чтобы избежать блокировки слишком большого объема памяти для будущих будущих потоков.взгляните на: https://rt.wiki.kernel.org/index.php/Threaded_RT-application_with_memory_locking_and_stack_handling_example

Если вы измените размер стека потока на 7 МБ, вы увидите: Начальное количество: Pagefaults, Major: 0 (разрешено> = 0), Minor: 190 (разрешено> =0) генерируется mlockall (): Pagefaults, Major: 0 (разрешено> = 0), Minor: 393 (Allowed> = 0) malloc () и генерируется прикосновение: Pagefaults, Major: 0 (разрешено> = 0), Minor: 25633(Разрешено> = 0) 2-й malloc () и используется сгенерированное: Pagefaults, Major: 0 (Allowed 0), Minor: 0 (Allowed 0)

Посмотрите на вывод команды ps -leyf и убедитесь, чтоRSS теперь около 100 [МБ] Нажмите для выхода. Я RT-нить со стеком, который не генерирует сбои страниц во время использования, stacksize = 7340032. Вызвано созданием нити: Pagefaults, Major: 0 (Allowed> = 0),Незначительное: 1797 (разрешено> = 0), вызванное использованием стека потока: Pagefaults, Major: 0 (разрешено 0), незначительное значение: 0 (разрешено 0)

1797 сбоев страниц при создании потока, оно составляет около 7 МБ,-barry

...