render: keep lock while pushing dirty rows to worker queue

Instead of locking the queue for each dirty row we append, and
signaling a condition variable, just keep the lock while going through
the visible rows.

Release the lock once done.

Since we take the lock *before* posting the 'start' semaphore, all
workers will be waiting for the lock to be released.

Then, one at a time they'll get the lock and pick a row to
render. The queue will never get empty - when all rows have been
rendered, each worker will pick a 'frame done' "job" from the queue,
and break the rendering loop.
This commit is contained in:
Daniel Eklöf 2020-07-13 13:27:23 +02:00
parent 669d36afa8
commit 09bdf20aa0
No known key found for this signature in database
GPG key ID: 5BBD4992C116573F
3 changed files with 3 additions and 19 deletions

View file

@ -507,13 +507,6 @@ initialize_render_workers(struct terminal *term)
goto err_sem_destroy;
}
if ((err = cnd_init(&term->render.workers.cond)) != thrd_success) {
LOG_ERR(
"failed to instantiate render worker condition variable: %s (%d)",
thrd_err_as_string(err), err);
goto err_sem_destroy;
}
term->render.workers.threads = calloc(
term->render.workers.count, sizeof(term->render.workers.threads[0]));
@ -1165,7 +1158,6 @@ term_destroy(struct terminal *term)
sem_post(&term->render.workers.start);
tll_push_back(term->render.workers.queue, -2);
}
cnd_broadcast(&term->render.workers.cond);
}
mtx_unlock(&term->render.workers.lock);
@ -1198,7 +1190,6 @@ term_destroy(struct terminal *term)
}
}
free(term->render.workers.threads);
cnd_destroy(&term->render.workers.cond);
mtx_destroy(&term->render.workers.lock);
sem_destroy(&term->render.workers.start);
sem_destroy(&term->render.workers.done);