ну тогда ты никак не решашь вот эту задачу "Но встаёт вопрос — вот ты mbuf оттуда удалил, а когда его убивать? Вдруг пока ты его удалял его кто0то взял (указатель на него) в локальную переменную и пямощас работает?"
Именно эту. Живой коннект не будет всё время жить в локальных переменных, он вернётся в очередь живых
Ну смотри. У тебя есть, скажем, очередь mbuf'ов. Не фокус сделать без локов добавление туда mbuf'а и удаление оттуда mbuf'а. На CAS'ах. Но встаёт вопрос — вот ты mbuf оттуда удалил, а когда его убивать? Вдруг пока ты его удалял его кто0то взял (указатель на него) в локальную переменную и пямощас работает? Мы добавляем его в список "к удалению, добавлен в эпоху X". Когда все сказали что они закончили с эпохой X можно чистить этот список на удаление до эпохи X.
вот пример из динамических стейтов: у тебя есть куча SLIST'ов в хеш таблице, её элементы это стейты. Используя epoch, ты можешь без локов искать среди всех этих элементов нужный стейт. У тебя есть гарантия, что код который чистит стейты по таймауту в какой-то момент не возьмёт и не освободит память, пока к ней пытается обращаться код на другом ядре.
Ну, она не новая, прямо скажем. Как и всё. RCU по сути устроен так же, а это IBM'овский патент чуть не 80-х годов прошлого века. Тут, как всегда, дьявол в деталях — как эффективно сделать вход-выход из эпохи на многоядерном железе
Заметим, что это довольно специфический, но GC. И как любой GC он увеличивает потребление памяти. Мы (ну, такое, широкое мы) надеемся, что этим мы покупаем throughput, так как существенно уменьшаем число блокирующих операций.
ну да, вот одна из недавних проблем, интеловцы жаловались. у них есть ixl драйвер, который обрабатывает большой поток pps, они делают kldunload if_ixl, и всё. Там при выгрузке делается epoch_drain, который не может никак завершиться
вот пример из динамических стейтов: у тебя есть куча SLIST'ов в хеш таблице, её элементы это стейты. Используя epoch, ты можешь без локов искать среди всех этих элементов нужный стейт. У тебя есть гарантия, что код который чистит стейты по таймауту в какой-то момент не возьмёт и не освободит память, пока к ней пытается обращаться код на другом ядре.
я не понял, кто стейт? отдельный SLIST или отдельный элемент SLIST?