Skip to content

Commit

Permalink
Use spinlock to protect work queue and shared process state.
Browse files Browse the repository at this point in the history
No need to put thread to sleep until the mutex gets unlocked.
  • Loading branch information
twaik committed Jan 5, 2025
1 parent d94308b commit 28a8291
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 14 deletions.
9 changes: 8 additions & 1 deletion app/src/main/cpp/lorie/renderer.c
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,8 @@ static volatile bool surfaceChanged = false;
static volatile LorieBuffer* pendingBuffer = NULL;
static volatile jobject pendingSurface = NULL;

volatile struct lorie_shared_server_state* state = NULL;
static pthread_spinlock_t stateLock;
static volatile struct lorie_shared_server_state* state = NULL;
static struct {
GLuint id;
LorieBuffer_Desc desc;
Expand Down Expand Up @@ -174,6 +175,8 @@ int renderer_init(JNIEnv* env) {

(*env)->GetJavaVM(env, &vm);

pthread_spin_init(&stateLock, false);

jclass Surface = (*env)->FindClass(env, "android/view/Surface");
Surface_release = (*env)->GetMethodID(env, Surface, "release", "()V");
Surface_destroy = (*env)->GetMethodID(env, Surface, "destroy", "()V");
Expand Down Expand Up @@ -317,7 +320,9 @@ void renderer_test_capabilities(int* legacy_drawing, uint8_t* flip) {
}

__unused void renderer_set_shared_state(struct lorie_shared_server_state* new_state) {
pthread_spin_lock(&stateLock);
state = new_state;
pthread_spin_unlock(&stateLock);
}

void renderer_set_buffer(JNIEnv* env, LorieBuffer* buf) {
Expand Down Expand Up @@ -582,7 +587,9 @@ __noreturn static void* renderer_thread(void* closure) {
while (!state || (!state->drawRequested && !surfaceChanged && !bufferChanged && (!state || (!state->cursor.moved && !state->cursor.updated))))
pthread_cond_wait(&state->cond, &m);

pthread_spin_lock(&stateLock);
renderer_redraw_locked(env);
pthread_spin_unlock(&stateLock);
}
pthread_mutex_unlock(&m);
}
Expand Down
26 changes: 13 additions & 13 deletions app/src/main/cpp/patches/xserver.patch
Original file line number Diff line number Diff line change
Expand Up @@ -211,81 +211,81 @@ index f9b7b06d9..f4b2aeddc 100644

WorkQueuePtr workQueue;
static WorkQueuePtr *workQueueLast = &workQueue;
+pthread_mutex_t workQueueLock = PTHREAD_MUTEX_INITIALIZER;
+static pthread_spinlock_t workQueueLock;
+
+__attribute__((constructor)) static void workQueueLockInit (void) {
+ pthread_mutex_init(&workQueueLock, NULL);
+ pthread_spin_init(&workQueueLock, FALSE);
+}

void
ClearWorkQueue(void)
{
WorkQueuePtr q, *p;

+ pthread_mutex_lock(&workQueueLock);
+ pthread_spin_lock(&workQueueLock);
p = &workQueue;
while ((q = *p)) {
*p = q->next;
free(q);
}
workQueueLast = p;
+ pthread_mutex_unlock(&workQueueLock);
+ pthread_spin_unlock(&workQueueLock);
}

void
@@ -525,6 +532,7 @@
{
WorkQueuePtr q, *p;

+ pthread_mutex_lock(&workQueueLock);
+ pthread_spin_lock(&workQueueLock);
p = &workQueue;
/*
* Scan the work queue once, calling each function. Those
@@ -533,16 +541,20 @@
* QueueWorkProc.
*/
while ((q = *p)) {
+ pthread_mutex_unlock(&workQueueLock);
+ pthread_spin_unlock(&workQueueLock);
if ((*q->function) (q->client, q->closure)) {
+ pthread_mutex_lock(&workQueueLock);
+ pthread_spin_lock(&workQueueLock);
/* remove q from the list */
*p = q->next; /* don't fetch until after func called */
free(q);
}
else {
+ pthread_mutex_lock(&workQueueLock);
+ pthread_spin_lock(&workQueueLock);
p = &q->next; /* don't fetch until after func called */
}
}
workQueueLast = p;
+ pthread_mutex_unlock(&workQueueLock);
+ pthread_spin_unlock(&workQueueLock);
}

void
@@ -550,6 +562,7 @@
{
WorkQueuePtr q, *p;

+ pthread_mutex_lock(&workQueueLock);
+ pthread_spin_lock(&workQueueLock);
p = &workQueue;
while ((q = *p)) {
if (q->client && q->client->clientGone) {
@@ -563,6 +576,7 @@
}
}
workQueueLast = p;
+ pthread_mutex_unlock(&workQueueLock);
+ pthread_spin_unlock(&workQueueLock);
}

Bool
@@ -578,8 +592,10 @@
q->client = client;
q->closure = closure;
q->next = NULL;
+ pthread_mutex_lock(&workQueueLock);
+ pthread_spin_lock(&workQueueLock);
*workQueueLast = q;
workQueueLast = &q->next;
+ pthread_mutex_unlock(&workQueueLock);
+ pthread_spin_unlock(&workQueueLock);
return TRUE;
}

0 comments on commit 28a8291

Please sign in to comment.