mirror of
https://github.com/drasko/codezero.git
synced 2026-01-27 18:23:13 +01:00
exit() almost there.
- Implemented reasonable way to suspend task.
- A task that has a pending suspend would be interrupted
from its sleep via the suspender task.
- If suspend was raised and right after, task became about to sleep,
then scheduler wakes it up.
- If suspend was raised when task was in user mode, then an irq suspends it.
- Also suspends are checked at the end of a syscall so that if suspend was
raised because of a syscall from the task, the task is suspended before it
goes back to user mode.
- This mechanism is very similar to signals, and it may lead as a base for
implementing signal handling.
- Implemented common vma dropping for shadow vm object dropping and task exiting.
This commit is contained in:
@@ -59,7 +59,7 @@ int wait_on(struct waitqueue_head *wqh)
|
||||
}
|
||||
|
||||
/* Wake up all */
|
||||
void wake_up_all(struct waitqueue_head *wqh, int sync)
|
||||
void wake_up_all(struct waitqueue_head *wqh, unsigned int flags)
|
||||
{
|
||||
BUG_ON(wqh->sleepers < 0);
|
||||
spin_lock(&wqh->slock);
|
||||
@@ -72,11 +72,12 @@ void wake_up_all(struct waitqueue_head *wqh, int sync)
|
||||
BUG_ON(list_empty(&wqh->task_list));
|
||||
list_del_init(&wq->task_list);
|
||||
wqh->sleepers--;
|
||||
sleeper->flags |= TASK_INTERRUPTED;
|
||||
if (flags & WAKEUP_INTERRUPT)
|
||||
sleeper->flags |= TASK_INTERRUPTED;
|
||||
printk("(%d) Waking up (%d)\n", current->tid, sleeper->tid);
|
||||
spin_unlock(&wqh->slock);
|
||||
|
||||
if (sync)
|
||||
if (flags & WAKEUP_SYNC)
|
||||
sched_resume_sync(sleeper);
|
||||
else
|
||||
sched_resume_async(sleeper);
|
||||
@@ -85,7 +86,7 @@ void wake_up_all(struct waitqueue_head *wqh, int sync)
|
||||
}
|
||||
|
||||
/* Wake up single waiter */
|
||||
void wake_up(struct waitqueue_head *wqh, int sync)
|
||||
void wake_up(struct waitqueue_head *wqh, unsigned int flags)
|
||||
{
|
||||
BUG_ON(wqh->sleepers < 0);
|
||||
spin_lock(&wqh->slock);
|
||||
@@ -98,11 +99,12 @@ void wake_up(struct waitqueue_head *wqh, int sync)
|
||||
BUG_ON(list_empty(&wqh->task_list));
|
||||
list_del_init(&wq->task_list);
|
||||
wqh->sleepers--;
|
||||
sleeper->flags |= TASK_INTERRUPTED;
|
||||
if (flags & WAKEUP_INTERRUPT)
|
||||
sleeper->flags |= TASK_INTERRUPTED;
|
||||
printk("(%d) Waking up (%d)\n", current->tid, sleeper->tid);
|
||||
spin_unlock(&wqh->slock);
|
||||
|
||||
if (sync)
|
||||
if (flags & WAKEUP_SYNC)
|
||||
sched_resume_sync(sleeper);
|
||||
else
|
||||
sched_resume_async(sleeper);
|
||||
@@ -116,7 +118,7 @@ void wake_up(struct waitqueue_head *wqh, int sync)
|
||||
* as we were peeking on it, returns -1. @sync makes us immediately
|
||||
* yield or else leave it to scheduler's discretion.
|
||||
*/
|
||||
int wake_up_task(struct ktcb *task, int sync)
|
||||
int wake_up_task(struct ktcb *task, unsigned int flags)
|
||||
{
|
||||
struct waitqueue_head *wqh;
|
||||
struct waitqueue *wq;
|
||||
@@ -158,7 +160,8 @@ int wake_up_task(struct ktcb *task, int sync)
|
||||
wqh->sleepers--;
|
||||
task->waiting_on = 0;
|
||||
task->wq = 0;
|
||||
task->flags |= TASK_INTERRUPTED;
|
||||
if (flags & WAKEUP_INTERRUPT)
|
||||
task->flags |= TASK_INTERRUPTED;
|
||||
spin_unlock(&wqh->slock);
|
||||
spin_unlock(&task->waitlock);
|
||||
|
||||
@@ -167,7 +170,7 @@ int wake_up_task(struct ktcb *task, int sync)
|
||||
* safely resume it without locks as this is the only
|
||||
* code path that can resume the task.
|
||||
*/
|
||||
if (sync)
|
||||
if (flags & WAKEUP_SYNC)
|
||||
sched_resume_sync(task);
|
||||
else
|
||||
sched_resume_async(task);
|
||||
@@ -175,5 +178,3 @@ int wake_up_task(struct ktcb *task, int sync)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user