*/
case PTRACE_KILL:
ret = 0;
- if (child->state == TASK_ZOMBIE)
+ if (child->exit_state == EXIT_ZOMBIE)
break;
child->exit_code = SIGKILL;
/* make sure single-step breakpoint is gone. */
/* make sure single-step breakpoint is gone. */
child->ptrace &= ~PT_SINGLESTEP;
ptrace_cancel_bpt(child);
- if (child->state != TASK_ZOMBIE) {
+ if (child->exit_state != EXIT_ZOMBIE) {
child->exit_code = SIGKILL;
wake_up_process(child);
}
/* make sure single-step breakpoint is gone. */
child->ptrace &= ~PT_SINGLESTEP;
ptrace_cancel_bpt(child);
- if (child->state != TASK_ZOMBIE) {
+ if (child->exit_state != EXIT_ZOMBIE) {
child->exit_code = SIGKILL;
wake_up_process(child);
}
case PTRACE_KILL:
ret = 0;
- if (child->state == TASK_ZOMBIE)
+ if (child->exit_state == EXIT_ZOMBIE)
break;
child->exit_code = SIGKILL;
case PTRACE_KILL: {
ret = 0;
- if (child->state == TASK_ZOMBIE) /* already dead */
+ if (child->exit_state == EXIT_ZOMBIE) /* already dead */
break;
child->exit_code = SIGKILL;
h8300_disable_trace(child);
long tmp;
ret = 0;
- if (child->state == TASK_ZOMBIE) /* already dead */
+ if (child->exit_state == EXIT_ZOMBIE) /* already dead */
break;
child->exit_code = SIGKILL;
clear_tsk_thread_flag(child, TIF_SINGLESTEP);
return -EINVAL;
}
- if (task->state == TASK_ZOMBIE) {
+ if (task->exit_state == EXIT_ZOMBIE) {
DPRINT(("cannot attach to zombie task [%d]\n", task->pid));
return -EBUSY;
}
* sigkill. Perhaps it should be put in the status
* that it wants to exit.
*/
- if (child->state == TASK_ZOMBIE) /* already dead */
+ if (child->exit_state == EXIT_ZOMBIE) /* already dead */
goto out_tsk;
child->exit_code = SIGKILL;
ret = 0;
unregister_all_debug_traps(child);
invalidate_cache();
- if (child->state == TASK_ZOMBIE) /* already dead */
+ if (child->exit_state == EXIT_ZOMBIE) /* already dead */
break;
child->exit_code = SIGKILL;
wake_up_process(child);
long tmp;
ret = 0;
- if (child->state == TASK_ZOMBIE) /* already dead */
+ if (child->exit_state == EXIT_ZOMBIE) /* already dead */
break;
child->exit_code = SIGKILL;
/* make sure the single step bit is not set. */
long tmp;
ret = 0;
- if (child->state == TASK_ZOMBIE) /* already dead */
+ if (child->exit_state == EXIT_ZOMBIE) /* already dead */
break;
child->exit_code = SIGKILL;
/* make sure the single step bit is not set. */
*/
case PTRACE_KILL:
ret = 0;
- if (child->state == TASK_ZOMBIE) /* already dead */
+ if (child->exit_state == EXIT_ZOMBIE) /* already dead */
break;
child->exit_code = SIGKILL;
wake_up_process(child);
*/
case PTRACE_KILL:
ret = 0;
- if (child->state == TASK_ZOMBIE) /* already dead */
+ if (child->exit_state == EXIT_ZOMBIE) /* already dead */
break;
child->exit_code = SIGKILL;
wake_up_process(child);
* that it wants to exit.
*/
DBG(("sys_ptrace(KILL)\n"));
- if (child->state == TASK_ZOMBIE) /* already dead */
+ if (child->exit_state == EXIT_ZOMBIE) /* already dead */
goto out_tsk;
child->exit_code = SIGKILL;
goto out_wake_notrap;
*/
case PTRACE_KILL: {
ret = 0;
- if (child->state == TASK_ZOMBIE) /* already dead */
+ if (child->exit_state == EXIT_ZOMBIE) /* already dead */
break;
child->exit_code = SIGKILL;
/* make sure the single step bit is not set. */
*/
case PTRACE_KILL: {
ret = 0;
- if (child->state == TASK_ZOMBIE) /* already dead */
+ if (child->exit_state == EXIT_ZOMBIE) /* already dead */
break;
child->exit_code = SIGKILL;
/* make sure the single step bit is not set. */
*/
case PTRACE_KILL: {
ret = 0;
- if (child->state == TASK_ZOMBIE) /* already dead */
+ if (child->exit_state == EXIT_ZOMBIE) /* already dead */
break;
child->exit_code = SIGKILL;
/* make sure the single step bit is not set. */
* perhaps it should be put in the status that it wants to
* exit.
*/
- if (child->state == TASK_ZOMBIE) /* already dead */
+ if (child->exit_state == EXIT_ZOMBIE) /* already dead */
return 0;
child->exit_code = SIGKILL;
/* make sure the single step bit is not set. */
*/
case PTRACE_KILL: {
ret = 0;
- if (child->state == TASK_ZOMBIE) /* already dead */
+ if (child->exit_state == EXIT_ZOMBIE) /* already dead */
break;
child->exit_code = SIGKILL;
wake_up_process(child);
*/
case PTRACE_KILL: {
ret = 0;
- if (child->state == TASK_ZOMBIE) /* already dead */
+ if (child->exit_state == EXIT_ZOMBIE) /* already dead */
break;
child->exit_code = SIGKILL;
wake_up_process(child);
* exit.
*/
case PTRACE_KILL: {
- if (child->state == TASK_ZOMBIE) { /* already dead */
+ if (child->exit_state == EXIT_ZOMBIE) { /* already dead */
pt_succ_return(regs, 0);
goto out_tsk;
}
* exit.
*/
case PTRACE_KILL: {
- if (child->state == TASK_ZOMBIE) { /* already dead */
+ if (child->exit_state == EXIT_ZOMBIE) { /* already dead */
pt_succ_return(regs, 0);
goto out_tsk;
}
*/
case PTRACE_KILL: {
ret = 0;
- if (child->state == TASK_ZOMBIE) /* already dead */
+ if (child->exit_state == EXIT_ZOMBIE) /* already dead */
break;
child->exit_code = SIGKILL;
wake_up_process(child);
panic("write of switch_pipe failed, err = %d", -err);
reading = 1;
- if((from->state == TASK_ZOMBIE) || (from->state == TASK_DEAD))
+ if((from->exit_state == EXIT_ZOMBIE) || (from->exit_state == EXIT_DEAD))
os_kill_process(os_getpid(), 0);
err = os_read_file(from->thread.mode.tt.switch_pipe[0], &c, sizeof(c));
* in case it has not already killed itself.
*/
prev_sched = current->thread.prev_sched;
- if((prev_sched->state == TASK_ZOMBIE) ||
- (prev_sched->state == TASK_DEAD))
+ if((prev_sched->exit_state == EXIT_ZOMBIE) ||
+ (prev_sched->exit_state == EXIT_DEAD))
os_kill_process(prev_sched->thread.mode.tt.extern_pid, 1);
/* This works around a nasty race with 'jail'. If we are switching
*/
case PTRACE_KILL:
rval = 0;
- if (child->state == TASK_ZOMBIE) /* already dead */
+ if (child->exit_state == EXIT_ZOMBIE) /* already dead */
break;
child->exit_code = SIGKILL;
wake_up_process(child);
long tmp;
ret = 0;
- if (child->state == TASK_ZOMBIE) /* already dead */
+ if (child->exit_state == EXIT_ZOMBIE) /* already dead */
break;
clear_tsk_thread_flag(child, TIF_SINGLESTEP);
child->exit_code = SIGKILL;
if (current->pid != current->tgid) {
struct task_struct *leader = current->group_leader, *parent;
struct dentry *proc_dentry1, *proc_dentry2;
- unsigned long state, ptrace;
+ unsigned long exit_state, ptrace;
/*
* Wait for the thread group leader to be a zombie.
* It should already be zombie at this point, most
* of the time.
*/
- while (leader->state != TASK_ZOMBIE)
+ while (leader->exit_state != EXIT_ZOMBIE)
yield();
spin_lock(&leader->proc_lock);
list_del(¤t->tasks);
list_add_tail(¤t->tasks, &init_task.tasks);
current->exit_signal = SIGCHLD;
- state = leader->state;
+ exit_state = leader->exit_state;
write_unlock_irq(&tasklist_lock);
spin_unlock(&leader->proc_lock);
proc_pid_flush(proc_dentry1);
proc_pid_flush(proc_dentry2);
- if (state != TASK_ZOMBIE)
+ if (exit_state != EXIT_ZOMBIE)
BUG();
release_task(leader);
}
static inline const char * get_task_state(struct task_struct *tsk)
{
- unsigned int state = tsk->state & (TASK_RUNNING |
- TASK_INTERRUPTIBLE |
- TASK_UNINTERRUPTIBLE |
- TASK_ZOMBIE |
- TASK_DEAD |
- TASK_STOPPED |
- TASK_TRACED);
+ unsigned int state = (tsk->state & (TASK_RUNNING |
+ TASK_INTERRUPTIBLE |
+ TASK_UNINTERRUPTIBLE |
+ TASK_STOPPED |
+ TASK_TRACED)) |
+ (tsk->exit_state & (EXIT_ZOMBIE |
+ EXIT_DEAD));
const char **p = &task_state_array[0];
while (state) {
#define TASK_UNINTERRUPTIBLE 2
#define TASK_STOPPED 4
#define TASK_TRACED 8
-#define TASK_ZOMBIE 16
-#define TASK_DEAD 32
+#define EXIT_ZOMBIE 16
+#define EXIT_DEAD 32
#define __set_task_state(tsk, state_value) \
do { (tsk)->state = (state_value); } while (0)
/* task state */
struct linux_binfmt *binfmt;
+ long exit_state;
int exit_code, exit_signal;
int pdeath_signal; /* The signal sent when the parent dies */
/* ??? */
*/
zap_leader = 0;
leader = p->group_leader;
- if (leader != p && thread_group_empty(leader) && leader->state == TASK_ZOMBIE) {
+ if (leader != p && thread_group_empty(leader) && leader->exit_state == EXIT_ZOMBIE) {
BUG_ON(leader->exit_signal == -1);
do_notify_parent(leader, leader->exit_signal);
/*
do_each_task_pid(pgrp, PIDTYPE_PGID, p) {
if (p == ignored_task
- || p->state >= TASK_ZOMBIE
+ || p->exit_state >= EXIT_ZOMBIE
|| p->real_parent->pid == 1)
continue;
if (process_group(p->real_parent) != pgrp
* Make sure we're not reparenting to ourselves and that
* the parent is not a zombie.
*/
- BUG_ON(p == reaper || reaper->state >= TASK_ZOMBIE);
+ BUG_ON(p == reaper || reaper->state >= EXIT_ZOMBIE || reaper->exit_state >= EXIT_ZOMBIE);
p->real_parent = reaper;
if (p->parent == p->real_parent)
BUG();
/* If we'd notified the old parent about this child's death,
* also notify the new parent.
*/
- if (p->state == TASK_ZOMBIE && p->exit_signal != -1 &&
+ if (p->exit_state == EXIT_ZOMBIE && p->exit_signal != -1 &&
thread_group_empty(p))
do_notify_parent(p, p->exit_signal);
else if (p->state == TASK_TRACED) {
reaper = child_reaper;
break;
}
- } while (reaper->state >= TASK_ZOMBIE);
+ } while (reaper->exit_state >= EXIT_ZOMBIE);
/*
* There are only two places where our children can be:
} else {
/* reparent ptraced task to its real parent */
__ptrace_unlink (p);
- if (p->state == TASK_ZOMBIE && p->exit_signal != -1 &&
+ if (p->exit_state == EXIT_ZOMBIE && p->exit_signal != -1 &&
thread_group_empty(p))
do_notify_parent(p, p->exit_signal);
}
* zombie forever since we prevented it from self-reap itself
* while it was being traced by us, to be able to see it in wait4.
*/
- if (unlikely(ptrace && p->state == TASK_ZOMBIE && p->exit_signal == -1))
+ if (unlikely(ptrace && p->exit_state == EXIT_ZOMBIE && p->exit_signal == -1))
list_add(&p->ptrace_list, to_release);
}
list_for_each_safe(_p, _n, &father->ptrace_children) {
do_notify_parent(tsk, SIGCHLD);
}
- state = TASK_ZOMBIE;
+ state = EXIT_ZOMBIE;
if (tsk->exit_signal == -1 && tsk->ptrace == 0)
- state = TASK_DEAD;
- tsk->state = state;
+ state = EXIT_DEAD;
+ tsk->exit_state = state;
/*
* Clear these here so that update_process_times() won't try to deliver
}
/* If the process is dead, release it - nobody will wait for it */
- if (state == TASK_DEAD)
+ if (state == EXIT_DEAD)
release_task(tsk);
/* PF_DEAD causes final put_task_struct after we schedule. */
mpol_free(tsk->mempolicy);
tsk->mempolicy = NULL;
#endif
+
+ BUG_ON(!(current->flags & PF_DEAD));
schedule();
BUG();
/* Avoid "noreturn function does return". */
}
/*
- * Handle sys_wait4 work for one task in state TASK_ZOMBIE. We hold
+ * Handle sys_wait4 work for one task in state EXIT_ZOMBIE. We hold
* read_lock(&tasklist_lock) on entry. If we return zero, we still hold
* the lock and this task is uninteresting. If we return nonzero, we have
* released the lock and the system call should return.
int exit_code = p->exit_code;
int why, status;
- if (unlikely(p->state != TASK_ZOMBIE))
+ if (unlikely(p->exit_state != EXIT_ZOMBIE))
return 0;
if (unlikely(p->exit_signal == -1 && p->ptrace == 0))
return 0;
* Try to move the task's state to DEAD
* only one thread is allowed to do this:
*/
- state = xchg(&p->state, TASK_DEAD);
- if (state != TASK_ZOMBIE) {
- BUG_ON(state != TASK_DEAD);
+ state = xchg(&p->exit_state, EXIT_DEAD);
+ if (state != EXIT_ZOMBIE) {
+ BUG_ON(state != EXIT_DEAD);
return 0;
}
if (unlikely(p->exit_signal == -1 && p->ptrace == 0)) {
/*
* Now we are sure this task is interesting, and no other
- * thread can reap it because we set its state to TASK_DEAD.
+ * thread can reap it because we set its state to EXIT_DEAD.
*/
read_unlock(&tasklist_lock);
if (!retval && infop)
retval = put_user(p->uid, &infop->si_uid);
if (retval) {
- p->state = TASK_ZOMBIE;
+ // TODO: is this safe?
+ p->exit_state = EXIT_ZOMBIE;
return retval;
}
retval = p->pid;
/* Double-check with lock held. */
if (p->real_parent != p->parent) {
__ptrace_unlink(p);
- p->state = TASK_ZOMBIE;
+ // TODO: is this safe?
+ p->exit_state = EXIT_ZOMBIE;
/*
* If this is not a detached task, notify the parent.
* If it's still not detached after that, don't release
/*
* This uses xchg to be atomic with the thread resuming and setting
* it. It must also be done with the write lock held to prevent a
- * race with the TASK_ZOMBIE case.
+ * race with the EXIT_ZOMBIE case.
*/
exit_code = xchg(&p->exit_code, 0);
- if (unlikely(p->state >= TASK_ZOMBIE)) {
+ if (unlikely(p->exit_state >= EXIT_ZOMBIE)) {
/*
* The task resumed and then died. Let the next iteration
- * catch it in TASK_ZOMBIE. Note that exit_code might
+ * catch it in EXIT_ZOMBIE. Note that exit_code might
* already be zero here if it resumed and did _exit(0).
* The task itself is dead and won't touch exit_code again;
* other processors in this function are locked out.
if (retval != 0) /* He released the lock. */
goto end;
break;
- case TASK_ZOMBIE:
- /*
- * Eligible but we cannot release it yet:
- */
- if (ret == 2)
- goto check_continued;
- if (!likely(options & WEXITED))
- continue;
- retval = wait_task_zombie(
- p, (options & WNOWAIT),
- infop, stat_addr, ru);
- if (retval != 0) /* He released the lock. */
- goto end;
- break;
- case TASK_DEAD:
- continue;
default:
+ // case EXIT_DEAD:
+ if (p->exit_state == EXIT_DEAD)
+ continue;
+ // case EXIT_ZOMBIE:
+ if (p->exit_state == EXIT_ZOMBIE) {
+ /*
+ * Eligible but we cannot release
+ * it yet:
+ */
+ if (ret == 2)
+ goto check_continued;
+ if (!likely(options & WEXITED))
+ continue;
+ retval = wait_task_zombie(
+ p, (options & WNOWAIT),
+ infop, stat_addr, ru);
+ /* He released the lock. */
+ if (retval != 0)
+ goto end;
+ break;
+ }
check_continued:
if (!unlikely(options & WCONTINUED))
continue;
void __put_task_struct(struct task_struct *tsk)
{
- WARN_ON(!(tsk->state & (TASK_DEAD | TASK_ZOMBIE)));
+ WARN_ON(!(tsk->exit_state & (EXIT_DEAD | EXIT_ZOMBIE)));
WARN_ON(atomic_read(&tsk->usage));
WARN_ON(tsk == current);
/* ok, now we should be set up.. */
p->exit_signal = (clone_flags & CLONE_THREAD) ? -1 : (clone_flags & CSIGNAL);
p->pdeath_signal = 0;
+ p->exit_state = 0;
/* Perform scheduler related setup */
sched_fork(p);
{
if ((p == current) ||
(p->flags & PF_NOFREEZE) ||
- (p->state == TASK_ZOMBIE) ||
- (p->state == TASK_DEAD) ||
+ (p->exit_state == EXIT_ZOMBIE) ||
+ (p->exit_state == EXIT_DEAD) ||
(p->state == TASK_STOPPED) ||
(p->state == TASK_TRACED))
return 0;
write_lock_irq(&tasklist_lock);
__ptrace_unlink(child);
/* .. and wake it up. */
- if (child->state != TASK_ZOMBIE)
+ if (child->exit_state != EXIT_ZOMBIE)
wake_up_process(child);
write_unlock_irq(&tasklist_lock);
/*
* A task struct has one reference for the use as "current".
- * If a task dies, then it sets TASK_ZOMBIE in tsk->state and calls
- * schedule one last time. The schedule call will never return,
+ * If a task dies, then it sets EXIT_ZOMBIE in tsk->exit_state and
+ * calls schedule one last time. The schedule call will never return,
* and the scheduled task must drop that reference.
- * The test for TASK_ZOMBIE must occur while the runqueue locks are
+ * The test for EXIT_ZOMBIE must occur while the runqueue locks are
* still held, otherwise prev could be scheduled on another cpu, die
* there before we look at prev->state, and then the reference would
* be dropped twice.
* schedule() atomically, we ignore that path for now.
* Otherwise, whine if we are scheduling when we should not be.
*/
- if (likely(!(current->state & (TASK_DEAD | TASK_ZOMBIE)))) {
+ if (likely(!(current->exit_state & (EXIT_DEAD | EXIT_ZOMBIE)))) {
if (unlikely(in_atomic())) {
printk(KERN_ERR "scheduling while atomic: "
"%s/0x%08x/%d\n",
spin_lock_irq(&rq->lock);
+ if (unlikely(current->flags & PF_DEAD))
+ current->state = EXIT_DEAD;
/*
* if entering off of a kernel preemption go straight
* to picking the next task.
struct runqueue *rq = cpu_rq(dead_cpu);
/* Must be exiting, otherwise would be on tasklist. */
- BUG_ON(tsk->state != TASK_ZOMBIE && tsk->state != TASK_DEAD);
+ BUG_ON(tsk->exit_state != EXIT_ZOMBIE && tsk->exit_state != EXIT_DEAD);
/* Cannot have done final schedule yet: would have vanished. */
BUG_ON(tsk->flags & PF_DEAD);
* Don't bother zombies and stopped tasks (but
* SIGKILL will punch through stopped state)
*/
- mask = TASK_DEAD | TASK_ZOMBIE | TASK_TRACED;
+ mask = EXIT_DEAD | EXIT_ZOMBIE | TASK_TRACED;
if (sig != SIGKILL)
mask |= TASK_STOPPED;
/*
* Don't bother with already dead threads
*/
- if (t->state & (TASK_ZOMBIE|TASK_DEAD))
+ if (t->exit_state & (EXIT_ZOMBIE|EXIT_DEAD))
continue;
/*
psecs = (p->utime += user);
psecs += (p->stime += system);
- if (!unlikely(p->state & (TASK_DEAD|TASK_ZOMBIE)) &&
+ if (p->signal && !unlikely(p->state & (EXIT_DEAD|EXIT_ZOMBIE)) &&
psecs / HZ >= p->signal->rlim[RLIMIT_CPU].rlim_cur) {
/* Send SIGXCPU every second.. */
if (!(psecs % HZ))