Как работает функция sched setaffinity ()?
Я пытаюсь понять, как работает linux syscall sched_setaffinity (). Это продолжение моего вопроса здесь.
У меня есть это руководство, которое объясняет, как использовать syscall и имеет довольно аккуратный (рабочий!) образец.
Поэтому я загрузил Linux 2.6.27.19 исходники ядра.
Я сделал "grep" для строк, содержащих этот syscall, и получил 91 результат. Ничего не обещаю.
В конечном счете, я пытаюсь понять, как работает ядро. возможность установки указателя инструкции для конкретного ядра (или процессора.)
Я знаком с тем, как работают одноядерные программы с одним потоком. Можно было бы выдать инструкцию 'jmp foo', и это в основном устанавливает IP-адрес в адрес памяти метки 'foo'. Но когда у вас есть несколько ядер, вы должны сказать " fetch The next instruction at memory address foo, и установить указатель инструкции для core number 2 , чтобы начать выполнение там."
Где, в сборке код, мы указываем, какое ядро выполняет эту операцию?
Вернемся к коду ядра: что здесь важно? Файл ' kernel/sched.c 'имеет функцию sched_setaffinity (), но возвращает тип "long", что несовместимо с его справочной страницей. Так что же здесь важно? Какой из этих модулей показывает выданные инструкции по сборке? Какой модуль читает 'task_struct', смотрит на' cpus_allowed ' член, а затем переводит его в инструкцию? (У меня тоже есть пролистал исходный код glibc - но я думаю, что он просто вызывает код ядра для выполнения этой задачи.)
4 ответа:
Планировщик фактически работает на каждом из процессоров, поэтому он получает возможность решить, какую задачу выполнить дальше на этом конкретном процессоре.
sched_setaffinity()
просто сообщает планировщику, на каких процессорах разрешено работать этому процессу / потоку, а затем вызывает повторное расписание.Если вас интересует, как вы можете вызвать некоторый код на других процессорах, я предлагаю вам взглянуть на
smp_call_function_single()
. В случае, если мы хотим вызвать что-то на другом процессоре, это вызываетgeneric_exec_single()
. Последний просто добавляет функцию к Очередь вызовов целевого процессора и заставляет перепланировать через некоторый IPI материал (если очередь была пуста).Суть такова: нет никакого фактического варианта SMP инструкции
_jmp_
. Вместо этого код, запущенный на других процессорах, взаимодействует для выполнения задачи.
Я думаю, что вы не понимаете, что ядро работает на всех ядрах процессора. При каждом прерывании таймера (~1000 в секунду) планировщик запускается на каждом процессоре и выбирает процесс для запуска. Нет ни одного процессора, который каким-то образом говорит другим, чтобы запустить процесс.
sched_setaffinity()
работает, просто устанавливая флаги на процесс. Планировщик считывает эти флаги и не будет запускать этот процесс на своем процессоре, если он не установлен.
Где в ассемблерном коде мы указываем, какое ядро выполняет эту операцию?
Здесь нет никакой сборки. Каждая задача (поток) назначается одному процессору (или ядру в ваших терминах) одновременно. Чтобы остановить работу на данном процессоре и возобновить работу на другом, задача должна " мигрировать " (также это). Когда задача мигрирует с одного процессора на другой, планировщик выбирает процессор, который больше простаивает среди процессоров, разрешенных
sched_setaffinity()
.Никаких магических инструкций по сборке не выдается. Ядро имеет более низкоуровневый взгляд на аппаратное обеспечение, каждый процессор-это отдельный объект, очень отличающийся от того, как он выглядит для процессов пользовательского пространства (в пользовательском пространстве процессоры почти невидимы).
Проверьте это: B руководство по программированию операционной системы