LINUX.ORG.RU

[C] Приостановить процесс используя scheduler

 


0

0

Подскажите, как можно используя информацию из task_struct остановить определенный процесс с помощью функций scheduler'a и потом снова его запустить когда понадобиться. Т.е. "поставить на паузу" и потом unpause сделать. Ну и чтобы это всё было smp safe. Заранее благодарен.

anonymous

Посмотреть как это делают сигналы SIGSTOP && SIGCONT

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

А чем конкретно не устраивает SIGSTOP/SIGCONT?

Teak ★★★★★
()

Если ты в ядре, можно попробовать просто на время убирать процесс из списка планируемых...., можно тупо проставлять что он спит - task_struct же доступен...

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

а как конкретно это делать ? я пытался делать set_task_state(task,TASK_STOPPED) и shedule() но он блин после этого сам меняет таск стейт..и не работает нифига

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

> я пытался делать set_task_state(task,TASK_STOPPED) и shedule()

конечно же это не будет работать. SIGSTOP надо слать, или ptrace.
и незачем это делать в kernel-space.

вы бы лучше проблему описали внятно. что значит "остановить определенный
процесс" ? и, главное, зачем. TASK_STOPPED task может быть пробужден
другой задачей, так что это "ненадежно", но в вашем случае это возможно
не проблема.

> Если ты в ядре, можно попробовать просто на время убирать процесс из
> списка планируемых

не выйдет. кроме того, спящий процесс и так deactivated, те его нет
в этом списке.

в принципе, наверное можно сделать что-то вроде

	#define TASK_STEAL_HACK	16 // just random "not valid" bit

	void steal_task(struct task_struct *t)
	{
		struct rq *rq;
		unsigned long flags;

	retry:
		set_cpus_allowed(current, cpumask_of_cpu(task_cpu(t)));

		rq = task_rq_lock(t, flags);

		if (task_cpu(t) != task_cpu(current)) {
			task_rq_unlock(rq, &flags);
			goto rerty;
		}

		// we own this CPU, t can't run or migrate

		if (t->se.on_rq)
			deactivate_task(rq, t, 0);

		t->state = TASK_STEAL_HACK;

		task_rq_unlock(rq, &flags);

		// ... restore ->cpus_allowed ...
	}

по идее, задача украдена и никто не может ее разбудить. однако мы
не можем корректно "вернуть все назад", тк неизвестно были ли какие
нибудь wakeup's in between, поэтому все, что мы можем сделать, это

	try_to_wake_up(t, TASK_STEAL_HACK, 0)

, и надеятся что задача правильно обработает "false wakeup", она
должна, но не все драйвера написаны правильно.

однако я бы не советовал играться с этим кодом ;)

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