LINUX.ORG.RU

save/load состояние устройства в qemu


0

2

Имеется pci устройство, которое обрабатывает некоторые команды. Запись в него и чтение из него происходит через callback'и MemoryRegion'a. Формат команд абсолютно разный. При поступлении команды мы находим нужный обработчик, входим в него, далее необходимо выйти из него, чтобы получить данные, потом опять войти в обработчик, возможно получить ещё данные, то есть постоянный вход/выход. Чтобы это всё работало сейчас все обработчики разбиты по кускам и сделана стейт машина, которая переключается между ними. В данном случае легко сделать сохранение/восстановление устройства, так как всё хранится в структурах.
Но есть огромные минусы. Дабавляются новые более сложные команды, растёт стейт-машина, отлаживать становится всё сложнее и сложнее. К тому же, когда обработчики разбиты по кускам - код очень сложно читабельный и вероятность наделать ошибок сильно возрастает.
Есть мысли запускать обработчики в отдельном потоке или использовать coroutine. Тогда обработчики будут в виде отдельных функций, когда надо что-то записать/почитать просто делаем yield(), а после продолжаем исполнение с этой же самой точки. Всё хорошо, но не понятно как сохранять состояние. Coroutine работает за счёт переключения стэка и нельзя его просто сохранить, так как при след запуске будут совершенно другие адреса.
Есть 2 дурацкие идеи, мб у кого будут умные?-)
зы. надеюсь не слишком запутанно написал

всё сохраняемое состояние выделить во внешней памяти через malloc.

функции должны изменять состояние детерминированно в определённом порядке.

dimon555 ★★★★★
()
Ответ на: комментарий от dimon555

Сейчас так и сделано и функции всё изменяют детерминированно. За это отвечает стейт-машина. Но при добавлении новой команды или изменении её формата, стейт-машина может разрастись, что усложнит отладку, увеличит кол-во ошибок. Да и вообще хотелось бы новые команды уметь добавлять в виде плагинов, а не переписывать стейт-машину.
Как я писал выше хочется обойтись вообще без стейт-машины, чтобы обработчик каждой команды был в виде одной функции, например, используя coroutine:

void handler(void *opaque)
{
    // читаем входные данные побайтово
    while(true) {
        ...
        if (всё прочитали)
            break;
        else
            yield();
    }

    // обрабатываем
    ...

    if (есть ещё входные данные)
	yield();
    else
	return;

    // читаем входные данные побайтово
    while(true) {
        ...
        if (всё прочитали)
            break;
        else
            yield();
    }

    // обрабатываем
    ...
}
Если запрос на сохранение придёт после обработки команды, то проблемы нет. Но если придёт во время обработки, то состояние то я сохранить могу, но после загрузки функция обработчика будет исполняться заново, а не с того места, где она прервалась. И это проблема

barzebuba
() автор топика
Ответ на: комментарий от barzebuba

не могу представить, что это за устройство.

стейт машина описывается конечным автоматом, какие могут быть с ней проблемы, если только у тебя не гугол состояний.

ну составляй обработчики в список и обновляй последний.

вся симуляция должно стопиться, пока отрабатывают обработчики устройства, если конечно это устройство не создано работать асинхронно и имеет свой собственный clock. Поэтому команда на сохранение не должна приходить во время работы функций, изменяющих состояние.

dimon555 ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.