
Комментарии 4
Вместо магических чисел можно было бы использовать человеческие имена (тем же путем, что прокидывается context_off, можно было прокинуть все отдельные смещения).
Не очень понял прикол с Lswitch_return. Если в Context.rip всегда будет одно и то же значение, то зачем вообще неявная адресация? jmp всегда будет приземляться сразу после себя. Грубо говоря, если switch_contextведет себя как обычная функция и всегда возвращается туда, откуда была вызвана (в изначальном контексте, в который переключаемся) - то смысла в rip в принципе нет.
Про имена согласен, это правильное замечание. Прокинуть offset_of! для каждого поля можно тем же способом, и тогда ручная синхронизация чисел с ассемблером исчезает вместе с необходимостью её проверять. Стоит переделать.
Про rip: он не всегда одинаковый. У потока, который уже переключался, там действительно .Lswitch_return. Но у потока, запускаемого впервые, rip заполняется при создании и указывает на точку входа. Косвенный переход нужен, чтобы обе ситуации обрабатывались одним кодом.
И switch_context возвращается не туда, откуда была вызвана: стек к моменту прыжка уже чужой, и управление уходит туда, где остановился другой поток. Возврат в вызывающий код произойдёт когда-нибудь потом, когда этот поток снова выберут.
64 байта и одна константа: разбор переключения контекста в ядре на Rust