Commit 4883c96a authored by Linus Torvalds's avatar Linus Torvalds Committed by Paul Mackerras

Clean up and fix locking around signal rendering

parent 7c8142e6
...@@ -180,18 +180,37 @@ static inline char * task_state(struct task_struct *p, char *buffer) ...@@ -180,18 +180,37 @@ static inline char * task_state(struct task_struct *p, char *buffer)
return buffer; return buffer;
} }
static char * render_sigset_t(const char *header, sigset_t *set, char *buffer)
{
int i, len;
len = strlen(header);
memcpy(buffer, header, len);
buffer += len;
i = _NSIG;
do {
int x = 0;
i -= 4;
if (sigismember(set, i+1)) x |= 1;
if (sigismember(set, i+2)) x |= 2;
if (sigismember(set, i+3)) x |= 4;
if (sigismember(set, i+4)) x |= 8;
*buffer++ = (x < 10 ? '0' : 'a' - 10) + x;
} while (i >= 4);
*buffer++ = '\n';
*buffer = 0;
return buffer;
}
static void collect_sigign_sigcatch(struct task_struct *p, sigset_t *ign, static void collect_sigign_sigcatch(struct task_struct *p, sigset_t *ign,
sigset_t *catch) sigset_t *catch)
{ {
struct k_sigaction *k; struct k_sigaction *k;
int i; int i;
sigemptyset(ign);
sigemptyset(catch);
read_lock(&tasklist_lock);
if (p->sighand) {
spin_lock_irq(&p->sighand->siglock);
k = p->sighand->action; k = p->sighand->action;
for (i = 1; i <= _NSIG; ++i, ++k) { for (i = 1; i <= _NSIG; ++i, ++k) {
if (k->sa.sa_handler == SIG_IGN) if (k->sa.sa_handler == SIG_IGN)
...@@ -199,32 +218,36 @@ static void collect_sigign_sigcatch(struct task_struct *p, sigset_t *ign, ...@@ -199,32 +218,36 @@ static void collect_sigign_sigcatch(struct task_struct *p, sigset_t *ign,
else if (k->sa.sa_handler != SIG_DFL) else if (k->sa.sa_handler != SIG_DFL)
sigaddset(catch, i); sigaddset(catch, i);
} }
spin_unlock_irq(&p->sighand->siglock);
}
read_unlock(&tasklist_lock);
} }
static inline char * task_sig(struct task_struct *p, char *buffer) static inline char * task_sig(struct task_struct *p, char *buffer)
{ {
sigset_t ign, catch; sigset_t pending, shpending, blocked, ignored, caught;
buffer += sprintf(buffer, "SigPnd:\t"); sigemptyset(&pending);
buffer = render_sigset_t(&p->pending.signal, buffer); sigemptyset(&shpending);
*buffer++ = '\n'; sigemptyset(&blocked);
buffer += sprintf(buffer, "ShdPnd:\t"); sigemptyset(&ignored);
buffer = render_sigset_t(&p->signal->shared_pending.signal, buffer); sigemptyset(&caught);
*buffer++ = '\n';
buffer += sprintf(buffer, "SigBlk:\t");
buffer = render_sigset_t(&p->blocked, buffer);
*buffer++ = '\n';
collect_sigign_sigcatch(p, &ign, &catch); /* Gather all the data with the appropriate locks held */
buffer += sprintf(buffer, "SigIgn:\t"); read_lock(&tasklist_lock);
buffer = render_sigset_t(&ign, buffer); if (p->sighand) {
*buffer++ = '\n'; spin_lock_irq(&p->sighand->siglock);
buffer += sprintf(buffer, "SigCgt:\t"); /* Linux 2.0 uses "SigCgt" */ pending = p->pending.signal;
buffer = render_sigset_t(&catch, buffer); shpending = p->signal->shared_pending.signal;
*buffer++ = '\n'; blocked = p->blocked;
collect_sigign_sigcatch(p, &ignored, &caught);
spin_unlock_irq(&p->sighand->siglock);
}
read_unlock(&tasklist_lock);
/* render them all */
buffer = render_sigset_t("SigPnd:\t", &pending, buffer);
buffer = render_sigset_t("ShdPnd:\t", &shpending, buffer);
buffer = render_sigset_t("SigBlk:\t", &blocked, buffer);
buffer = render_sigset_t("SigIgn:\t", &ignored, buffer);
buffer = render_sigset_t("SigCgt:\t", &caught, buffer);
return buffer; return buffer;
} }
......
...@@ -151,8 +151,6 @@ static inline void sigfillset(sigset_t *set) ...@@ -151,8 +151,6 @@ static inline void sigfillset(sigset_t *set)
} }
} }
extern char * render_sigset_t(sigset_t *set, char *buffer);
/* Some extensions for manipulating the low 32 signals in particular. */ /* Some extensions for manipulating the low 32 signals in particular. */
static inline void sigaddsetmask(sigset_t *set, unsigned long mask) static inline void sigaddsetmask(sigset_t *set, unsigned long mask)
......
...@@ -2095,21 +2095,6 @@ static void show_task(task_t * p) ...@@ -2095,21 +2095,6 @@ static void show_task(task_t * p)
} }
} }
char * render_sigset_t(sigset_t *set, char *buffer)
{
int i = _NSIG, x;
do {
i -= 4, x = 0;
if (sigismember(set, i+1)) x |= 1;
if (sigismember(set, i+2)) x |= 2;
if (sigismember(set, i+3)) x |= 4;
if (sigismember(set, i+4)) x |= 8;
*buffer++ = (x < 10 ? '0' : 'a' - 10) + x;
} while (i >= 4);
*buffer = 0;
return buffer;
}
void show_state(void) void show_state(void)
{ {
task_t *g, *p; task_t *g, *p;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment