Потоки ядра против таймеров - PullRequest
0 голосов
/ 06 декабря 2010

Я пишу модуль ядра, который использует настроенную систему печати на экране. Обычно каждый раз, когда задействовано print, строка вставляется в связанный список. Каждые X секунд мне нужно обрабатывать список и выполнять некоторые операции со строками перед их печатью.

В принципе, у меня есть два варианта реализации такого фильтра:

1) Таймер (который перезапускается в конце)

2) Нить ядра, которая спит в течение X секунд

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

Таймер AFAIK работает в контексте прерывания, поэтому он не может спать, но как быть с потоками ядра? Могут ли они спать? Если да, есть ли причина не использовать их в моем проекте? Какое еще решение можно использовать?

Подводя итог: моя функция фильтра имеет только 3 требования:

1) Должен уметь printk

2) При использовании списка все остальные, которые пытаются получить доступ к списку, должны блокироваться, пока функция фильтра не завершит выполнение

3) Должен запускаться каждые X секунд (не в режиме реального времени)

Ответы [ 2 ]

2 голосов
/ 07 декабря 2010

kthreads разрешено спать.(Однако, не все kthreads предлагают сонное выполнение всем клиентам. Например, softirqd не будет.) Но опять же, вы также можете использовать спин-блокировки (и связанные с ними затраты) и обойтись без дополнительного потока (это в основном то, что делает таймер, используетspinlock_bh).Это действительно компромисс.

1 голос
/ 07 декабря 2010

каждый раз, когда задействовано print, строка вставляется в связанный список

Я действительно не знаю, имели ли вы в виду print или printk.Но если вы говорите о printk(), вам нужно было бы выделить память, и у вас возникли проблемы, потому что printk() может быть вызвано в атомарном контексте.Это оставляет вам возможность использовать циклический буфер (и, следовательно, вы должны быть терпимы к удалению некоторых строк, потому что у вас может не хватить памяти для сохранения всех строк).

Каждые X секунд, которые мне нужныобработать список и выполнить некоторые операции со строками перед их печатью.

В этом случае я бы даже не делал поток ядра: я бы делал обработку в print(), если не слишком дорого.

В противном случае я бы создал новый системный вызов:

  • sys_get_strings() или что-то подобное, что могло бы вывести весь связанный список в пространство пользователя (и удалить записи из списка при копировании).

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

Вы также можете создать новое устройство, которое скажет, что /dev/print-on-screen:

  • dev_open выделит память, а print()больше не будет недоступен, но будет передавать данные в предварительно выделенную память устройства (в случае print() будет использоваться в атомарном контексте и все).
  • dev_release будет выбрасывать все
  • dev_read даст вам строки
  • dev_write может что-то сделать в вашей системе печати на экране
...