summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2014-02-22 14:34:05 +0000
committerChris Wilson <chris@chris-wilson.co.uk>2014-02-22 16:58:58 +0000
commit64fc1bb9c87e95ff484ecd11f391b1c0d556d584 (patch)
tree588dd8dd1a8ab862ea7e22c596d25d2bdf835490
parent900499bff962a63e1d9b5f808d1deb65d55754a2 (diff)
sna: Allow SIGBUS/SEGV to kill the thread
To handle sigtrapping of the threads, we allow the threads to handle their async signals and upon hitting the trap, we kill the thread. All the rest of the threads are reaped by the main xserver thread afterwards. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r--src/sna/sna.h3
-rw-r--r--src/sna/sna_accel.c8
-rw-r--r--src/sna/sna_threads.c81
-rw-r--r--src/sna/sna_trapezoids.c30
-rw-r--r--src/sna/sna_trapezoids_boxes.c2
-rw-r--r--src/sna/sna_trapezoids_imprecise.c6
-rw-r--r--src/sna/sna_trapezoids_mono.c2
-rw-r--r--src/sna/sna_trapezoids_precise.c10
8 files changed, 82 insertions, 60 deletions
diff --git a/src/sna/sna.h b/src/sna/sna.h
index 329853dd..46516322 100644
--- a/src/sna/sna.h
+++ b/src/sna/sna.h
@@ -1015,7 +1015,8 @@ void sna_acpi_fini(struct sna *sna);
void sna_threads_init(void);
int sna_use_threads (int width, int height, int threshold);
-void sna_threads_run(void (*func)(void *arg), void *arg);
+void sna_threads_run(int id, void (*func)(void *arg), void *arg);
+void sna_threads_trap(int sig);
void sna_threads_wait(void);
void sna_threads_kill(void);
diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c
index 64b60c2d..4af48756 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -408,10 +408,12 @@ volatile sig_atomic_t sigtrap;
static int sigtrap_handler(int sig)
{
- if (sigtrap) {
- /* XXX rate-limited squawk? */
+ /* XXX rate-limited squawk? */
+ DBG(("%s(sig=%d) sigtrap=%d\n", __FUNCTION__, sig, sigtrap));
+ sna_threads_trap(sig);
+
+ if (sigtrap)
siglongjmp(sigjmp[--sigtrap], sig);
- }
return -1;
}
diff --git a/src/sna/sna_threads.c b/src/sna/sna_threads.c
index a15e66a8..eac69640 100644
--- a/src/sna/sna_threads.c
+++ b/src/sna/sna_threads.c
@@ -53,7 +53,9 @@ static void *__run__(void *arg)
/* Disable all signals in the slave threads as X uses them for IO */
sigfillset(&signals);
- pthread_sigmask(SIG_BLOCK, &signals, NULL);
+ sigdelset(&signals, SIGBUS);
+ sigdelset(&signals, SIGSEGV);
+ pthread_sigmask(SIG_SETMASK, &signals, NULL);
pthread_mutex_lock(&t->mutex);
while (1) {
@@ -66,6 +68,7 @@ static void *__run__(void *arg)
pthread_mutex_lock(&t->mutex);
t->func = NULL;
+ t->arg = NULL;
pthread_cond_signal(&t->cond);
}
pthread_mutex_unlock(&t->mutex);
@@ -141,7 +144,7 @@ void sna_threads_init(void)
if (threads == NULL)
goto bail;
- for (n = 0; n < max_threads; n++) {
+ for (n = 1; n < max_threads; n++) {
pthread_mutex_init(&threads[n].mutex, NULL);
pthread_cond_init(&threads[n].cond, NULL);
@@ -151,41 +154,46 @@ void sna_threads_init(void)
goto bail;
}
+ threads[0].thread = pthread_self();
return;
bail:
max_threads = 0;
}
-void sna_threads_run(void (*func)(void *arg), void *arg)
+void sna_threads_run(int id, void (*func)(void *arg), void *arg)
{
- int n;
-
assert(max_threads > 0);
+ assert(pthread_self() == threads[0].thread);
+ assert(id > 0 && id < max_threads);
- for (n = 0; n < max_threads; n++) {
- if (threads[n].func)
- continue;
+ assert(threads[id].func == NULL);
- pthread_mutex_lock(&threads[n].mutex);
- if (threads[n].func) {
- pthread_mutex_unlock(&threads[n].mutex);
- continue;
- }
+ pthread_mutex_lock(&threads[id].mutex);
+ threads[id].func = func;
+ threads[id].arg = arg;
+ pthread_cond_signal(&threads[id].cond);
+ pthread_mutex_unlock(&threads[id].mutex);
+}
- goto execute;
- }
+void sna_threads_trap(int sig)
+{
+ pthread_t t = pthread_self();
+ int n;
- n = rand() % max_threads;
- pthread_mutex_lock(&threads[n].mutex);
- while (threads[n].func)
- pthread_cond_wait(&threads[n].cond, &threads[n].mutex);
+ if (t == threads[0].thread)
+ return;
+
+ for (n = 1; threads[n].thread != t; n++)
+ ;
-execute:
- threads[n].func = func;
- threads[n].arg = arg;
+ pthread_mutex_lock(&threads[n].mutex);
+ threads[n].func = NULL;
+ threads[n].arg = &threads[n];
pthread_cond_signal(&threads[n].cond);
pthread_mutex_unlock(&threads[n].mutex);
+
+ pthread_exit(&sig);
}
void sna_threads_wait(void)
@@ -193,15 +201,21 @@ void sna_threads_wait(void)
int n;
assert(max_threads > 0);
+ assert(pthread_self() == threads[0].thread);
- for (n = 0; n < max_threads; n++) {
- if (threads[n].func == NULL)
- continue;
+ for (n = 1; n < max_threads; n++) {
+ if (threads[n].func != NULL) {
+ pthread_mutex_lock(&threads[n].mutex);
+ while (threads[n].func)
+ pthread_cond_wait(&threads[n].cond, &threads[n].mutex);
+ pthread_mutex_unlock(&threads[n].mutex);
+ }
- pthread_mutex_lock(&threads[n].mutex);
- while (threads[n].func)
- pthread_cond_wait(&threads[n].cond, &threads[n].mutex);
- pthread_mutex_unlock(&threads[n].mutex);
+ if (threads[n].arg != NULL) {
+ ERR(("%s: thread %d died\n", __func__, n));
+ sna_threads_kill();
+ return;
+ }
}
}
@@ -209,13 +223,14 @@ void sna_threads_kill(void)
{
int n;
- ERR(("kill %d threads\n", max_threads));
+ ERR(("%s: kill %d threads\n", __func__, max_threads));
assert(max_threads > 0);
+ assert(pthread_self() == threads[0].thread);
- for (n = 0; n < max_threads; n++)
+ for (n = 1; n < max_threads; n++)
pthread_cancel(threads[n].thread);
- for (n = 0; n < max_threads; n++)
+ for (n = 1; n < max_threads; n++)
pthread_join(threads[n].thread, NULL);
max_threads = 0;
@@ -316,7 +331,7 @@ void sna_image_composite(pixman_op_t op,
data[n].dst_y = y;
y += dy;
- sna_threads_run(thread_composite, &data[n]);
+ sna_threads_run(n, thread_composite, &data[n]);
}
assert(y < dst_y + height);
diff --git a/src/sna/sna_trapezoids.c b/src/sna/sna_trapezoids.c
index ac2f764d..71016e88 100644
--- a/src/sna/sna_trapezoids.c
+++ b/src/sna/sna_trapezoids.c
@@ -385,21 +385,25 @@ trapezoids_fallback(struct sna *sna,
dy = (height + num_threads - 1) / num_threads;
num_threads -= (num_threads-1) * dy >= bounds.y2 - bounds.y1;
- for (n = 1; n < num_threads; n++) {
- threads[n] = threads[0];
- threads[n].ptr += (y - bounds.y1) * threads[n].stride;
- threads[n].bounds.y1 = y;
- threads[n].bounds.y2 = y += dy;
-
- sna_threads_run(rasterize_traps_thread, &threads[n]);
- }
+ if (sigtrap_get() == 0) {
+ for (n = 1; n < num_threads; n++) {
+ threads[n] = threads[0];
+ threads[n].ptr += (y - bounds.y1) * threads[n].stride;
+ threads[n].bounds.y1 = y;
+ threads[n].bounds.y2 = y += dy;
+
+ sna_threads_run(n, rasterize_traps_thread, &threads[n]);
+ }
- assert(y < threads[0].bounds.y2);
- threads[0].ptr += (y - bounds.y1) * threads[0].stride;
- threads[0].bounds.y1 = y;
- rasterize_traps_thread(&threads[0]);
+ assert(y < threads[0].bounds.y2);
+ threads[0].ptr += (y - bounds.y1) * threads[0].stride;
+ threads[0].bounds.y1 = y;
+ rasterize_traps_thread(&threads[0]);
- sna_threads_wait();
+ sna_threads_wait();
+ sigtrap_put();
+ } else
+ sna_threads_kill();
format = PIXMAN_a8;
depth = 8;
diff --git a/src/sna/sna_trapezoids_boxes.c b/src/sna/sna_trapezoids_boxes.c
index d6f0c371..2a476dc0 100644
--- a/src/sna/sna_trapezoids_boxes.c
+++ b/src/sna/sna_trapezoids_boxes.c
@@ -1186,7 +1186,7 @@ composite_unaligned_boxes_inplace(struct sna *sna,
thread[i] = thread[0];
thread[i].y1 = y;
thread[i].y2 = y += dy;
- sna_threads_run(rectilinear_inplace_thread, &thread[i]);
+ sna_threads_run(i, rectilinear_inplace_thread, &thread[i]);
}
assert(y < clip.extents.y2);
diff --git a/src/sna/sna_trapezoids_imprecise.c b/src/sna/sna_trapezoids_imprecise.c
index 93823bb0..a6da2d80 100644
--- a/src/sna/sna_trapezoids_imprecise.c
+++ b/src/sna/sna_trapezoids_imprecise.c
@@ -1988,7 +1988,7 @@ imprecise_trapezoid_span_converter(struct sna *sna,
threads[n].extents.y1 = y;
threads[n].extents.y2 = y += h;
- sna_threads_run(span_thread, &threads[n]);
+ sna_threads_run(n, span_thread, &threads[n]);
}
assert(y < threads[0].extents.y2);
@@ -2857,7 +2857,7 @@ trapezoid_span_inplace__x8r8g8b8(CARD8 op,
threads[n].extents.y1 = y;
threads[n].extents.y2 = y += h;
- sna_threads_run(inplace_x8r8g8b8_thread, &threads[n]);
+ sna_threads_run(n, inplace_x8r8g8b8_thread, &threads[n]);
}
assert(y < threads[0].extents.y2);
@@ -3135,7 +3135,7 @@ imprecise_trapezoid_span_inplace(struct sna *sna,
threads[n].extents.y1 = y;
threads[n].extents.y2 = y += h;
- sna_threads_run(inplace_thread, &threads[n]);
+ sna_threads_run(n, inplace_thread, &threads[n]);
}
assert(y < threads[0].extents.y2);
diff --git a/src/sna/sna_trapezoids_mono.c b/src/sna/sna_trapezoids_mono.c
index ca316d7e..fe77ffdc 100644
--- a/src/sna/sna_trapezoids_mono.c
+++ b/src/sna/sna_trapezoids_mono.c
@@ -852,7 +852,7 @@ mono_trapezoids_span_converter(struct sna *sna,
threads[n].extents.y1 = y;
threads[n].extents.y2 = y += h;
- sna_threads_run(mono_span_thread, &threads[n]);
+ sna_threads_run(n, mono_span_thread, &threads[n]);
}
threads[0].extents.y1 = y;
diff --git a/src/sna/sna_trapezoids_precise.c b/src/sna/sna_trapezoids_precise.c
index bc0a7e7c..f0e8266e 100644
--- a/src/sna/sna_trapezoids_precise.c
+++ b/src/sna/sna_trapezoids_precise.c
@@ -1913,7 +1913,7 @@ precise_trapezoid_span_converter(struct sna *sna,
threads[n].extents.y1 = y;
threads[n].extents.y2 = y += h;
- sna_threads_run(span_thread, &threads[n]);
+ sna_threads_run(n, span_thread, &threads[n]);
}
assert(y < threads[0].extents.y2);
@@ -2139,7 +2139,7 @@ precise_trapezoid_mask_converter(CARD8 op, PicturePtr src, PicturePtr dst,
threads[n].extents.y1 = y;
threads[n].extents.y2 = y += h;
- sna_threads_run(mask_thread, &threads[n]);
+ sna_threads_run(n, mask_thread, &threads[n]);
}
assert(y < threads[0].extents.y2);
@@ -2855,7 +2855,7 @@ trapezoid_span_inplace__x8r8g8b8(CARD8 op,
threads[n].extents.y1 = y;
threads[n].extents.y2 = y += h;
- sna_threads_run(inplace_x8r8g8b8_thread, &threads[n]);
+ sna_threads_run(n, inplace_x8r8g8b8_thread, &threads[n]);
}
assert(y < threads[0].extents.y2);
@@ -3134,7 +3134,7 @@ precise_trapezoid_span_inplace(struct sna *sna,
threads[n].extents.y1 = y;
threads[n].extents.y2 = y += h;
- sna_threads_run(inplace_thread, &threads[n]);
+ sna_threads_run(n, inplace_thread, &threads[n]);
}
assert(y < threads[0].extents.y2);
@@ -3281,7 +3281,7 @@ precise_trapezoid_span_fallback(CARD8 op, PicturePtr src, PicturePtr dst,
threads[n].extents.y1 = y;
threads[n].extents.y2 = y += h;
- sna_threads_run(mask_thread, &threads[n]);
+ sna_threads_run(n, mask_thread, &threads[n]);
}
assert(y < threads[0].extents.y2);